• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2010 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #include "SkData.h"
11 #include "SkFlate.h"
12 #include "SkStream.h"
13 
14 #ifndef SK_ZLIB_INCLUDE
HaveFlate()15 bool SkFlate::HaveFlate() { return false; }
Deflate(SkStream *,SkWStream *)16 bool SkFlate::Deflate(SkStream*, SkWStream*) { return false; }
Deflate(const void *,size_t,SkWStream *)17 bool SkFlate::Deflate(const void*, size_t, SkWStream*) { return false; }
Deflate(const SkData *,SkWStream *)18 bool SkFlate::Deflate(const SkData*, SkWStream*) { return false; }
Inflate(SkStream *,SkWStream *)19 bool SkFlate::Inflate(SkStream*, SkWStream*) { return false; }
20 #else
21 
22 // static
HaveFlate()23 bool SkFlate::HaveFlate() {
24     return true;
25 }
26 
27 namespace {
28 
29 #include SK_ZLIB_INCLUDE
30 
31 // static
32 const size_t kBufferSize = 1024;
33 
doFlate(bool compress,SkStream * src,SkWStream * dst)34 bool doFlate(bool compress, SkStream* src, SkWStream* dst) {
35     uint8_t inputBuffer[kBufferSize];
36     uint8_t outputBuffer[kBufferSize];
37     z_stream flateData;
38     flateData.zalloc = NULL;
39     flateData.zfree = NULL;
40     flateData.next_in = NULL;
41     flateData.avail_in = 0;
42     flateData.next_out = outputBuffer;
43     flateData.avail_out = kBufferSize;
44     int rc;
45     if (compress)
46         rc = deflateInit(&flateData, Z_DEFAULT_COMPRESSION);
47     else
48         rc = inflateInit(&flateData);
49     if (rc != Z_OK)
50         return false;
51 
52     uint8_t* input = (uint8_t*)src->getMemoryBase();
53     size_t inputLength = src->getLength();
54     if (input == NULL || inputLength == 0) {
55         input = NULL;
56         flateData.next_in = inputBuffer;
57         flateData.avail_in = 0;
58     } else {
59         flateData.next_in = input;
60         flateData.avail_in = inputLength;
61     }
62 
63     rc = Z_OK;
64     while (true) {
65         if (flateData.avail_out < kBufferSize) {
66             if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) {
67                 rc = Z_BUF_ERROR;
68                 break;
69             }
70             flateData.next_out = outputBuffer;
71             flateData.avail_out = kBufferSize;
72         }
73         if (rc != Z_OK)
74             break;
75         if (flateData.avail_in == 0) {
76             if (input != NULL)
77                 break;
78             size_t read = src->read(&inputBuffer, kBufferSize);
79             if (read == 0)
80                 break;
81             flateData.next_in = inputBuffer;
82             flateData.avail_in = read;
83         }
84         if (compress)
85             rc = deflate(&flateData, Z_NO_FLUSH);
86         else
87             rc = inflate(&flateData, Z_NO_FLUSH);
88     }
89     while (rc == Z_OK) {
90         if (compress)
91             rc = deflate(&flateData, Z_FINISH);
92         else
93             rc = inflate(&flateData, Z_FINISH);
94         if (flateData.avail_out < kBufferSize) {
95             if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out))
96                 return false;
97             flateData.next_out = outputBuffer;
98             flateData.avail_out = kBufferSize;
99         }
100     }
101 
102     if (compress)
103         deflateEnd(&flateData);
104     else
105         inflateEnd(&flateData);
106     if (rc == Z_STREAM_END)
107         return true;
108     return false;
109 }
110 
111 }
112 
113 // static
Deflate(SkStream * src,SkWStream * dst)114 bool SkFlate::Deflate(SkStream* src, SkWStream* dst) {
115     return doFlate(true, src, dst);
116 }
117 
Deflate(const void * ptr,size_t len,SkWStream * dst)118 bool SkFlate::Deflate(const void* ptr, size_t len, SkWStream* dst) {
119     SkMemoryStream stream(ptr, len);
120     return doFlate(true, &stream, dst);
121 }
122 
Deflate(const SkData * data,SkWStream * dst)123 bool SkFlate::Deflate(const SkData* data, SkWStream* dst) {
124     if (data) {
125         SkMemoryStream stream(data->data(), data->size());
126         return doFlate(true, &stream, dst);
127     }
128     return false;
129 }
130 
131 // static
Inflate(SkStream * src,SkWStream * dst)132 bool SkFlate::Inflate(SkStream* src, SkWStream* dst) {
133     return doFlate(false, src, dst);
134 }
135 
136 #endif
137 
138