• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "SkFlate.h"
18 #include "SkStream.h"
19 
20 #ifndef SK_ZLIB_INCLUDE
HaveFlate()21 bool SkFlate::HaveFlate() { return false; }
Deflate(SkStream *,SkDynamicMemoryWStream *)22 bool SkFlate::Deflate(SkStream*, SkDynamicMemoryWStream*) { return false; }
Inflate(SkStream *,SkDynamicMemoryWStream *)23 bool SkFlate::Inflate(SkStream*, SkDynamicMemoryWStream*) { return false; }
24 #else
25 
26 // static
HaveFlate()27 bool SkFlate::HaveFlate() {
28 #ifdef SK_DEBUG
29     return false;
30 #else
31     return true;
32 #endif
33 }
34 
35 namespace {
36 
37 #include SK_ZLIB_INCLUDE
38 
39 // static
40 const size_t kBufferSize = 1024;
41 
doFlate(bool compress,SkStream * src,SkDynamicMemoryWStream * dst)42 bool doFlate(bool compress, SkStream* src, SkDynamicMemoryWStream* dst) {
43     uint8_t inputBuffer[kBufferSize];
44     uint8_t outputBuffer[kBufferSize];
45     z_stream flateData;
46     flateData.zalloc = NULL;
47     flateData.zfree = NULL;
48     flateData.next_in = NULL;
49     flateData.avail_in = 0;
50     flateData.next_out = outputBuffer;
51     flateData.avail_out = kBufferSize;
52     int rc;
53     if (compress)
54         rc = deflateInit(&flateData, Z_DEFAULT_COMPRESSION);
55     else
56         rc = inflateInit(&flateData);
57     if (rc != Z_OK)
58         return false;
59 
60     uint8_t* input = (uint8_t*)src->getMemoryBase();
61     size_t inputLength = src->getLength();
62     if (input == NULL || inputLength == 0) {
63         input = NULL;
64         flateData.next_in = inputBuffer;
65         flateData.avail_in = 0;
66     } else {
67         flateData.next_in = input;
68         flateData.avail_in = inputLength;
69     }
70 
71     rc = Z_OK;
72     while (true) {
73         if (flateData.avail_out < kBufferSize) {
74             if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) {
75                 rc = Z_BUF_ERROR;
76                 break;
77             }
78             flateData.next_out = outputBuffer;
79             flateData.avail_out = kBufferSize;
80         }
81         if (rc != Z_OK)
82             break;
83         if (flateData.avail_in == 0) {
84             if (input != NULL)
85                 break;
86             size_t read = src->read(&inputBuffer, kBufferSize);
87             if (read == 0)
88                 break;
89             flateData.next_in = inputBuffer;
90             flateData.avail_in = read;
91         }
92         if (compress)
93             rc = deflate(&flateData, Z_NO_FLUSH);
94         else
95             rc = inflate(&flateData, Z_NO_FLUSH);
96     }
97     while (rc == Z_OK) {
98         if (compress)
99             rc = deflate(&flateData, Z_FINISH);
100         else
101             rc = inflate(&flateData, Z_FINISH);
102         if (flateData.avail_out < kBufferSize) {
103             if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out))
104                 return false;
105             flateData.next_out = outputBuffer;
106             flateData.avail_out = kBufferSize;
107         }
108     }
109 
110     if (compress)
111         deflateEnd(&flateData);
112     else
113         inflateEnd(&flateData);
114     if (rc == Z_STREAM_END)
115         return true;
116     return false;
117 }
118 
119 }
120 
121 // static
Deflate(SkStream * src,SkDynamicMemoryWStream * dst)122 bool SkFlate::Deflate(SkStream* src, SkDynamicMemoryWStream* dst) {
123     return doFlate(true, src, dst);
124 }
125 
126 // static
Inflate(SkStream * src,SkDynamicMemoryWStream * dst)127 bool SkFlate::Inflate(SkStream* src, SkDynamicMemoryWStream* dst) {
128     return doFlate(false, src, dst);
129 }
130 
131 #endif
132 
133