blob: 3bae8a9334319136171a160055adf37eff4ce115 [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; }
24bool SkFlate::Inflate(SkStream*, SkWStream*) { return false; }
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000025#else
26
27// static
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000028bool SkFlate::HaveFlate() {
vandebo@chromium.org4b83c632011-04-01 18:33:22 +000029#ifdef SK_DEBUG
30 return false;
31#else
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000032 return true;
vandebo@chromium.org4b83c632011-04-01 18:33:22 +000033#endif
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000034}
35
36namespace {
37
38#include SK_ZLIB_INCLUDE
39
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +000040// static
41const size_t kBufferSize = 1024;
42
reed@google.com7453d0e2011-06-24 20:45:40 +000043bool doFlate(bool compress, SkStream* src, SkWStream* dst) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000044 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
reed@google.com7453d0e2011-06-24 20:45:40 +0000123bool SkFlate::Deflate(SkStream* src, SkWStream* dst) {
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +0000124 return doFlate(true, src, dst);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000125}
126
reed@google.com314e9b32011-06-27 17:41:22 +0000127bool SkFlate::Deflate(const void* ptr, size_t len, SkWStream* dst) {
128 SkMemoryStream stream(ptr, len);
129 return doFlate(true, &stream, dst);
130}
131
132bool SkFlate::Deflate(const SkData* data, SkWStream* dst) {
133 if (data) {
134 SkMemoryStream stream(data->data(), data->size());
135 return doFlate(true, &stream, dst);
136 }
137 return false;
138}
139
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000140// static
reed@google.com7453d0e2011-06-24 20:45:40 +0000141bool SkFlate::Inflate(SkStream* src, SkWStream* dst) {
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +0000142 return doFlate(false, src, dst);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000143}
144
145#endif
146