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