blob: 985961360ee57603f683cc075c0c96473f001bb4 [file] [log] [blame]
vandebo@chromium.orga09ef972010-12-01 22:17:20 +00001/*
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
21bool SkFlate::HaveFlate() { return false; }
22bool SkFlate::Deflate(SkStream*, SkDynamicMemoryWStream*) { return false; }
23bool SkFlate::Inflate(SkStream*, SkDynamicMemoryWStream*) { return false; }
24#else
25
26// static
27const size_t SkFlate::kBufferSize = 1024;
28
29// static
30bool SkFlate::HaveFlate() {
vandebo@chromium.org4b83c632011-04-01 18:33:22 +000031#ifdef SK_DEBUG
32 return false;
33#else
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000034 return true;
vandebo@chromium.org4b83c632011-04-01 18:33:22 +000035#endif
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000036}
37
38namespace {
39
40#include SK_ZLIB_INCLUDE
41
42bool doFlate(bool compress, const size_t kBufferSize, SkStream* src,
43 SkDynamicMemoryWStream* dst) {
44 uint8_t inputBuffer[kBufferSize];
45 uint8_t outputBuffer[kBufferSize];
46 z_stream flateData;
47 flateData.zalloc = NULL;
48 flateData.zfree = NULL;
49 flateData.next_in = NULL;
50 flateData.avail_in = 0;
51 flateData.next_out = outputBuffer;
52 flateData.avail_out = kBufferSize;
53 int rc;
54 if (compress)
55 rc = deflateInit(&flateData, Z_DEFAULT_COMPRESSION);
56 else
57 rc = inflateInit(&flateData);
58 if (rc != Z_OK)
59 return false;
60
61 uint8_t* input = (uint8_t*)src->getMemoryBase();
62 size_t inputLength = src->getLength();
vandebo@chromium.orgee34e352010-12-02 22:55:33 +000063 if (input == NULL || inputLength == 0) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000064 input = NULL;
65 flateData.next_in = inputBuffer;
66 flateData.avail_in = 0;
67 } else {
68 flateData.next_in = input;
69 flateData.avail_in = inputLength;
70 }
71
72 rc = Z_OK;
73 while (true) {
74 if (flateData.avail_out < kBufferSize) {
75 if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) {
76 rc = Z_BUF_ERROR;
77 break;
78 }
79 flateData.next_out = outputBuffer;
80 flateData.avail_out = kBufferSize;
81 }
vandebo@chromium.orgee34e352010-12-02 22:55:33 +000082 if (rc != Z_OK)
83 break;
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000084 if (flateData.avail_in == 0) {
85 if (input != NULL)
86 break;
87 size_t read = src->read(&inputBuffer, kBufferSize);
88 if (read == 0)
89 break;
90 flateData.next_in = inputBuffer;
91 flateData.avail_in = read;
92 }
93 if (compress)
94 rc = deflate(&flateData, Z_NO_FLUSH);
95 else
96 rc = inflate(&flateData, Z_NO_FLUSH);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000097 }
98 while (rc == Z_OK) {
99 if (compress)
100 rc = deflate(&flateData, Z_FINISH);
101 else
102 rc = inflate(&flateData, Z_FINISH);
vandebo@chromium.orgee34e352010-12-02 22:55:33 +0000103 if (flateData.avail_out < kBufferSize) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000104 if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out))
105 return false;
106 flateData.next_out = outputBuffer;
107 flateData.avail_out = kBufferSize;
108 }
109 }
110
111 if (compress)
112 deflateEnd(&flateData);
113 else
114 inflateEnd(&flateData);
115 if (rc == Z_STREAM_END)
116 return true;
117 return false;
118}
119
120}
121
122// static
123bool SkFlate::Deflate(SkStream* src, SkDynamicMemoryWStream* dst) {
124 return doFlate(true, kBufferSize, src, dst);
125}
126
127// static
128bool SkFlate::Inflate(SkStream* src, SkDynamicMemoryWStream* dst) {
129 return doFlate(false, kBufferSize, src, dst);
130}
131
132#endif
133