blob: 5acf2abfa029ed4aaa2dad106005bf790ae0b581 [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; }
reed@google.com7453d0e2011-06-24 20:45:40 +000022bool SkFlate::Deflate(SkStream*, SkWStream*) { return false; }
23bool SkFlate::Inflate(SkStream*, SkWStream*) { return false; }
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000024#else
25
26// static
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000027bool SkFlate::HaveFlate() {
vandebo@chromium.org4b83c632011-04-01 18:33:22 +000028#ifdef SK_DEBUG
29 return false;
30#else
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000031 return true;
vandebo@chromium.org4b83c632011-04-01 18:33:22 +000032#endif
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000033}
34
35namespace {
36
37#include SK_ZLIB_INCLUDE
38
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +000039// static
40const size_t kBufferSize = 1024;
41
reed@google.com7453d0e2011-06-24 20:45:40 +000042bool doFlate(bool compress, SkStream* src, SkWStream* dst) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000043 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();
vandebo@chromium.orgee34e352010-12-02 22:55:33 +000062 if (input == NULL || inputLength == 0) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000063 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 }
vandebo@chromium.orgee34e352010-12-02 22:55:33 +000081 if (rc != Z_OK)
82 break;
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000083 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);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000096 }
97 while (rc == Z_OK) {
98 if (compress)
99 rc = deflate(&flateData, Z_FINISH);
100 else
101 rc = inflate(&flateData, Z_FINISH);
vandebo@chromium.orgee34e352010-12-02 22:55:33 +0000102 if (flateData.avail_out < kBufferSize) {
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000103 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
reed@google.com7453d0e2011-06-24 20:45:40 +0000122bool SkFlate::Deflate(SkStream* src, SkWStream* dst) {
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +0000123 return doFlate(true, src, dst);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000124}
125
126// static
reed@google.com7453d0e2011-06-24 20:45:40 +0000127bool SkFlate::Inflate(SkStream* src, SkWStream* dst) {
vandebo@chromium.orgc7a38f32011-04-05 20:11:32 +0000128 return doFlate(false, src, dst);
vandebo@chromium.orga09ef972010-12-01 22:17:20 +0000129}
130
131#endif
132