blob: ea5fef971702c1ea61b5ab5519d2d0c5149ac576 [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
reed@google.com314e9b32011-06-27 17:41:22 +000017#include "SkData.h"
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000018#include "SkFlate.h"
19#include "SkStream.h"
20
21#ifndef SK_ZLIB_INCLUDE
22bool SkFlate::HaveFlate() { return false; }
reed@google.com7453d0e2011-06-24 20:45:40 +000023bool SkFlate::Deflate(SkStream*, SkWStream*) { return false; }
epoger@google.comb14ef732011-07-21 13:56:34 +000024bool SkFlate::Deflate(const void*, size_t, SkWStream*) { return false; }
25bool SkFlate::Deflate(const SkData*, SkWStream*) { return false; }
reed@google.com7453d0e2011-06-24 20:45:40 +000026bool SkFlate::Inflate(SkStream*, SkWStream*) { return false; }
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000027#else
28
29// static
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000030bool SkFlate::HaveFlate() {
31 return true;
32}
33
34namespace {
35
36#include SK_ZLIB_INCLUDE
37
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +000038// static
39const size_t kBufferSize = 1024;
40
reed@google.com7453d0e2011-06-24 20:45:40 +000041bool doFlate(bool compress, SkStream* src, SkWStream* dst) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000042 uint8_t inputBuffer[kBufferSize];
43 uint8_t outputBuffer[kBufferSize];
44 z_stream flateData;
45 flateData.zalloc = NULL;
46 flateData.zfree = NULL;
47 flateData.next_in = NULL;
48 flateData.avail_in = 0;
49 flateData.next_out = outputBuffer;
50 flateData.avail_out = kBufferSize;
51 int rc;
52 if (compress)
53 rc = deflateInit(&flateData, Z_DEFAULT_COMPRESSION);
54 else
55 rc = inflateInit(&flateData);
56 if (rc != Z_OK)
57 return false;
58
59 uint8_t* input = (uint8_t*)src->getMemoryBase();
60 size_t inputLength = src->getLength();
vandebo@chromium.orgee34e352010-12-02 22:55:33 +000061 if (input == NULL || inputLength == 0) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000062 input = NULL;
63 flateData.next_in = inputBuffer;
64 flateData.avail_in = 0;
65 } else {
66 flateData.next_in = input;
67 flateData.avail_in = inputLength;
68 }
69
70 rc = Z_OK;
71 while (true) {
72 if (flateData.avail_out < kBufferSize) {
73 if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) {
74 rc = Z_BUF_ERROR;
75 break;
76 }
77 flateData.next_out = outputBuffer;
78 flateData.avail_out = kBufferSize;
79 }
vandebo@chromium.orgee34e352010-12-02 22:55:33 +000080 if (rc != Z_OK)
81 break;
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000082 if (flateData.avail_in == 0) {
83 if (input != NULL)
84 break;
85 size_t read = src->read(&inputBuffer, kBufferSize);
86 if (read == 0)
87 break;
88 flateData.next_in = inputBuffer;
89 flateData.avail_in = read;
90 }
91 if (compress)
92 rc = deflate(&flateData, Z_NO_FLUSH);
93 else
94 rc = inflate(&flateData, Z_NO_FLUSH);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000095 }
96 while (rc == Z_OK) {
97 if (compress)
98 rc = deflate(&flateData, Z_FINISH);
99 else
100 rc = inflate(&flateData, Z_FINISH);
vandebo@chromium.orgee34e352010-12-02 22:55:33 +0000101 if (flateData.avail_out < kBufferSize) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000102 if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out))
103 return false;
104 flateData.next_out = outputBuffer;
105 flateData.avail_out = kBufferSize;
106 }
107 }
108
109 if (compress)
110 deflateEnd(&flateData);
111 else
112 inflateEnd(&flateData);
113 if (rc == Z_STREAM_END)
114 return true;
115 return false;
116}
117
118}
119
120// static
reed@google.com7453d0e2011-06-24 20:45:40 +0000121bool SkFlate::Deflate(SkStream* src, SkWStream* dst) {
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +0000122 return doFlate(true, src, dst);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000123}
124
reed@google.com314e9b32011-06-27 17:41:22 +0000125bool SkFlate::Deflate(const void* ptr, size_t len, SkWStream* dst) {
126 SkMemoryStream stream(ptr, len);
127 return doFlate(true, &stream, dst);
128}
129
130bool SkFlate::Deflate(const SkData* data, SkWStream* dst) {
131 if (data) {
132 SkMemoryStream stream(data->data(), data->size());
133 return doFlate(true, &stream, dst);
134 }
135 return false;
136}
137
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000138// static
reed@google.com7453d0e2011-06-24 20:45:40 +0000139bool SkFlate::Inflate(SkStream* src, SkWStream* dst) {
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +0000140 return doFlate(false, src, dst);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000141}
142
143#endif
144