ee34e35c8c
Review URL: http://codereview.appspot.com/3393041 git-svn-id: http://skia.googlecode.com/svn/trunk@628 2bbb7eff-a529-9590-31e7-b0007b416f81
130 lines
3.6 KiB
C++
130 lines
3.6 KiB
C++
/*
|
|
* 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 (rc != Z_OK)
|
|
break;
|
|
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);
|
|
}
|
|
while (rc == Z_OK) {
|
|
if (compress)
|
|
rc = deflate(&flateData, Z_FINISH);
|
|
else
|
|
rc = inflate(&flateData, Z_FINISH);
|
|
if (flateData.avail_out < kBufferSize) {
|
|
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
|
|
|