diff options
author | 2010-12-01 22:17:20 +0000 | |
---|---|---|
committer | 2010-12-01 22:17:20 +0000 | |
commit | a09ef977b6799f01cd3fd64725fb3069da8be4bc (patch) | |
tree | e7ce250b8c1ac3d85c135cdadba633004d64e473 /src/core/SkFlate.cpp | |
parent | ca735ff61746fd230998b05fd9b9ec52e90c39e0 (diff) |
Add deflate support to SkPDFStream.
Review URL: http://codereview.appspot.com/3326043
git-svn-id: http://skia.googlecode.com/svn/trunk@627 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkFlate.cpp')
-rw-r--r-- | src/core/SkFlate.cpp | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/src/core/SkFlate.cpp b/src/core/SkFlate.cpp new file mode 100644 index 0000000000..a9adece75e --- /dev/null +++ b/src/core/SkFlate.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SkFlate.h" +#include "SkStream.h" + +#ifndef SK_ZLIB_INCLUDE +bool SkFlate::HaveFlate() { return false; } +bool SkFlate::Deflate(SkStream*, SkDynamicMemoryWStream*) { return false; } +bool SkFlate::Inflate(SkStream*, SkDynamicMemoryWStream*) { return false; } +#else + +// static +const size_t SkFlate::kBufferSize = 1024; + +// static +bool SkFlate::HaveFlate() { + return true; +} + +namespace { + +#include SK_ZLIB_INCLUDE + +bool doFlate(bool compress, const size_t kBufferSize, SkStream* src, + SkDynamicMemoryWStream* dst) { + uint8_t inputBuffer[kBufferSize]; + uint8_t outputBuffer[kBufferSize]; + z_stream flateData; + flateData.zalloc = NULL; + flateData.zfree = NULL; + flateData.next_in = NULL; + flateData.avail_in = 0; + flateData.next_out = outputBuffer; + flateData.avail_out = kBufferSize; + int rc; + if (compress) + rc = deflateInit(&flateData, Z_DEFAULT_COMPRESSION); + else + rc = inflateInit(&flateData); + if (rc != Z_OK) + return false; + + uint8_t* input = (uint8_t*)src->getMemoryBase(); + size_t inputLength = src->getLength(); + if (input == NULL || inputLength < 0) { + input = NULL; + flateData.next_in = inputBuffer; + flateData.avail_in = 0; + } else { + flateData.next_in = input; + flateData.avail_in = inputLength; + } + + rc = Z_OK; + while (true) { + if (flateData.avail_out < kBufferSize) { + if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) { + rc = Z_BUF_ERROR; + break; + } + flateData.next_out = outputBuffer; + flateData.avail_out = kBufferSize; + } + if (flateData.avail_in == 0) { + if (input != NULL) + break; + size_t read = src->read(&inputBuffer, kBufferSize); + if (read == 0) + break; + flateData.next_in = inputBuffer; + flateData.avail_in = read; + } + if (compress) + rc = deflate(&flateData, Z_NO_FLUSH); + else + rc = inflate(&flateData, Z_NO_FLUSH); + if (rc != Z_OK) + break; + } + while (rc == Z_OK) { + if (compress) + rc = deflate(&flateData, Z_FINISH); + else + rc = inflate(&flateData, Z_FINISH); + if (flateData.avail_out > 0) { + if (!dst->write(outputBuffer, kBufferSize - flateData.avail_out)) + return false; + flateData.next_out = outputBuffer; + flateData.avail_out = kBufferSize; + } + } + + if (compress) + deflateEnd(&flateData); + else + inflateEnd(&flateData); + if (rc == Z_STREAM_END) + return true; + return false; +} + +} + +// static +bool SkFlate::Deflate(SkStream* src, SkDynamicMemoryWStream* dst) { + return doFlate(true, kBufferSize, src, dst); +} + +// static +bool SkFlate::Inflate(SkStream* src, SkDynamicMemoryWStream* dst) { + return doFlate(false, kBufferSize, src, dst); +} + +#endif + |