diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:36 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:36 -0800 |
commit | 6eb364108744656fcd23a96a478aa772cd4e85bc (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/images | |
parent | a23c4e24d873b11674987f97f1946e1c4d97e782 (diff) | |
download | external_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.zip external_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.tar.gz external_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'src/images')
29 files changed, 0 insertions, 7406 deletions
diff --git a/src/images/SkBitmap_RLEPixels.h b/src/images/SkBitmap_RLEPixels.h deleted file mode 100644 index c83bc69..0000000 --- a/src/images/SkBitmap_RLEPixels.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SkBitmap_RLEPixels_DEFINED -#define SkBitmap_RLEPixels_DEFINED - -#include "SkChunkAlloc.h" - -class SkBitmap_RLEPixels { -public: - SkBitmap_RLEPixels(int width, int height); - ~SkBitmap_RLEPixels(); - - uint8_t* yptrs() const { return fYPtrs; } - uint8_t* allocChunk(size_t chunk); - -private: - SkChunkAlloc fChunk; - uint8_t** fYPtrs; -}; - -#endif diff --git a/src/images/SkCreateRLEPixelRef.cpp b/src/images/SkCreateRLEPixelRef.cpp deleted file mode 100644 index 5756237..0000000 --- a/src/images/SkCreateRLEPixelRef.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "SkChunkAlloc.h" -#include "SkPackBits.h" -#include "SkBitmap.h" -#include "SkPixelRef.h" - -class RLEPixelRef : public SkPixelRef { -public: - RLEPixelRef(SkBitmap::RLEPixels* rlep, SkColorTable* ctable); - virtual ~RLEPixelRef(); - -protected: - // overrides from SkPixelRef - virtual void* onLockPixels(SkColorTable**); - virtual void onUnlockPixels(); - -private: - SkBitmap::RLEPixels* fRLEPixels; - SkColorTable* fCTable; -}; - -RLEPixelRef::RLEPixelRef(SkBitmap::RLEPixels* rlep, SkColorTable* ctable) - : SkPixelRef(NULL) { - fRLEPixels = rlep; // we now own this ptr - fCTable = ctable; - ctable->safeRef(); -} - -RLEPixelRef::~RLEPixelRef() { - SkDELETE(fRLEPixels); - fCTable->safeUnref(); -} - -void* RLEPixelRef::onLockPixels(SkColorTable** ct) { - *ct = fCTable; - return fRLEPixels; -} - -void RLEPixelRef::onUnlockPixels() { - // nothing to do -} - -///////////////////////////////////////////////////////////////////////////// - -class ChunkRLEPixels : public SkBitmap::RLEPixels { -public: - ChunkRLEPixels(int width, int height, size_t chunkSize) - : SkBitmap::RLEPixels(width, height), fStorage(chunkSize) { - } - - SkChunkAlloc fStorage; -}; - -SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src); -SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src) { - - if (SkBitmap::kIndex8_Config != src.config() && - SkBitmap::kA8_Config != src.config()) { - return NULL; - } - - size_t maxPacked = SkPackBits::ComputeMaxSize8(src.width()); - - // estimate the rle size based on the original size - size_t size = src.getSize() >> 3; - if (size < maxPacked) { - size = maxPacked; - } - - ChunkRLEPixels* rlePixels = SkNEW_ARGS(ChunkRLEPixels, - (src.width(), src.height(), size)); - - uint8_t* dstRow = NULL; - size_t free = 0; - size_t totalPacked = 0; - - for (int y = 0; y < src.height(); y++) { - const uint8_t* srcRow = src.getAddr8(0, y); - - if (free < maxPacked) { - dstRow = (uint8_t*)rlePixels->fStorage.allocThrow(size); - free = size; - } - size_t packedSize = SkPackBits::Pack8(srcRow, src.width(), dstRow); - SkASSERT(packedSize <= free); - rlePixels->setPackedAtY(y, dstRow); - - dstRow += packedSize; - free -= packedSize; - - totalPacked += packedSize; - } - -//#ifdef SK_DEBUG -#if 0 - // test - uint8_t* buffer = new uint8_t[src.width()]; - for (int y = 0; y < src.height(); y++) { - const uint8_t* srcRow = src.getAddr8(0, y); - SkPackBits::Unpack8(buffer, 0, src.width(), rlePixels->packedAtY(y)); - int n = memcmp(buffer, srcRow, src.width()); - if (n) { - SkDebugf("----- memcmp returned %d on line %d\n", n, y); - } - SkASSERT(n == 0); - } - delete[] buffer; - - size_t totalAlloc = src.height() * sizeof(uint8_t*) + totalPacked; - - SkDebugf("--- RLE: orig [%d %d] %d, rle %d %d savings %g\n", - src.width(), src.height(), src.getSize(), - src.height() * sizeof(uint8_t*), totalPacked, - (float)totalAlloc / src.getSize()); - -#endif - - // transfer ownership of rlePixels to our pixelref - return SkNEW_ARGS(RLEPixelRef, (rlePixels, src.getColorTable())); -} - diff --git a/src/images/SkFDStream.cpp b/src/images/SkFDStream.cpp deleted file mode 100644 index db4a51a..0000000 --- a/src/images/SkFDStream.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "SkStream.h" -#include <unistd.h> - -//#define TRACE_FDSTREAM - -SkFDStream::SkFDStream(int fileDesc, bool closeWhenDone) - : fFD(fileDesc), fCloseWhenDone(closeWhenDone) { -} - -SkFDStream::~SkFDStream() { - if (fFD >= 0 && fCloseWhenDone) { - ::close(fFD); - } -} - -bool SkFDStream::rewind() { - if (fFD >= 0) { - off_t value = ::lseek(fFD, 0, SEEK_SET); -#ifdef TRACE_FDSTREAM - if (value) { - SkDebugf("xxxxxxxxxxxxxx rewind failed %d\n", value); - } -#endif - return value == 0; - } - return false; -} - -size_t SkFDStream::read(void* buffer, size_t size) { - if (fFD >= 0) { - if (buffer == NULL && size == 0) { // request total size - off_t curr = ::lseek(fFD, 0, SEEK_CUR); - if (curr < 0) { -#ifdef TRACE_FDSTREAM - SkDebugf("xxxxxxxxxxxxx lseek failed 0 CURR\n"); -#endif - return 0; // error - } - off_t size = ::lseek(fFD, 0, SEEK_END); - if (size < 0) { -#ifdef TRACE_FDSTREAM - SkDebugf("xxxxxxxxxxxxx lseek failed 0 END\n"); -#endif - size = 0; // error - } - if (::lseek(fFD, curr, SEEK_SET) != curr) { - // can't restore, error -#ifdef TRACE_FDSTREAM - SkDebugf("xxxxxxxxxxxxx lseek failed %d SET\n", curr); -#endif - return 0; - } - return size; - } else if (NULL == buffer) { // skip - off_t oldCurr = ::lseek(fFD, 0, SEEK_CUR); - if (oldCurr < 0) { -#ifdef TRACE_FDSTREAM - SkDebugf("xxxxxxxxxxxxx lseek1 failed %d CUR\n", oldCurr); -#endif - return 0; // error; - } - off_t newCurr = ::lseek(fFD, size, SEEK_CUR); - if (newCurr < 0) { -#ifdef TRACE_FDSTREAM - SkDebugf("xxxxxxxxxxxxx lseek2 failed %d CUR\n", newCurr); -#endif - return 0; // error; - } - // return the actual amount we skipped - return newCurr - oldCurr; - } else { // read - ssize_t actual = ::read(fFD, buffer, size); - // our API can't return an error, so we return 0 - if (actual < 0) { -#ifdef TRACE_FDSTREAM - SkDebugf("xxxxxxxxxxxxx read failed %d actual %d\n", size, actual); -#endif - actual = 0; - } - return actual; - } - } - return 0; -} - diff --git a/src/images/SkFlipPixelRef.cpp b/src/images/SkFlipPixelRef.cpp deleted file mode 100644 index 95403cc..0000000 --- a/src/images/SkFlipPixelRef.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "SkFlipPixelRef.h" -#include "SkFlattenable.h" -#include "SkRegion.h" - -SkFlipPixelRef::SkFlipPixelRef(SkBitmap::Config config, int width, int height) -: fFlipper(width, height) { - fConfig = config; - fSize = SkBitmap::ComputeSize(config, width, height); - fStorage = sk_malloc_throw(fSize << 1); - fPage0 = fStorage; - fPage1 = (char*)fStorage + fSize; -} - -SkFlipPixelRef::~SkFlipPixelRef() { - sk_free(fStorage); -} - -const SkRegion& SkFlipPixelRef::beginUpdate(SkBitmap* device) { - void* writeAddr; - const void* readAddr; - this->getFrontBack(&readAddr, &writeAddr); - - device->setConfig(fConfig, fFlipper.width(), fFlipper.height()); - device->setPixels(writeAddr); - - SkRegion copyBits; - const SkRegion& dirty = fFlipper.update(©Bits); - - SkFlipPixelRef::CopyBitsFromAddr(*device, copyBits, readAddr); - return dirty; -} - -void SkFlipPixelRef::endUpdate() { - this->swapPages(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void* SkFlipPixelRef::onLockPixels(SkColorTable** ct) { - fMutex.acquire(); - *ct = NULL; - return fPage0; -} - -void SkFlipPixelRef::onUnlockPixels() { - fMutex.release(); -} - -void SkFlipPixelRef::swapPages() { - fMutex.acquire(); - SkTSwap<void*>(fPage0, fPage1); - fMutex.release(); -} - -void SkFlipPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { - this->INHERITED::flatten(buffer); - - buffer.write32(fSize); - // only need to write page0 - buffer.writePad(fPage0, fSize); -} - -SkFlipPixelRef::SkFlipPixelRef(SkFlattenableReadBuffer& buffer) - : INHERITED(buffer, NULL) { - fSize = buffer.readU32(); - fStorage = sk_malloc_throw(fSize << 1); - fPage0 = fStorage; - fPage1 = (char*)fStorage + fSize; - buffer.read(fPage0, fSize); -} - -SkPixelRef* SkFlipPixelRef::Create(SkFlattenableReadBuffer& buffer) { - return SkNEW_ARGS(SkFlipPixelRef, (buffer)); -} - -static SkPixelRef::Registrar::Registrar reg("SkFlipPixelRef", - SkFlipPixelRef::Create); - -/////////////////////////////////////////////////////////////////////////////// - -static void copyRect(const SkBitmap& dst, const SkIRect& rect, - const void* srcAddr, int shift) { - const size_t offset = rect.fTop * dst.rowBytes() + (rect.fLeft << shift); - char* dstP = static_cast<char*>(dst.getPixels()) + offset; - const char* srcP = static_cast<const char*>(srcAddr) + offset; - const size_t rb = dst.rowBytes(); - const size_t bytes = rect.width() << shift; - - int height = rect.height(); - while (--height >= 0) { - memcpy(dstP, srcP, bytes); - dstP += rb; - srcP += rb; - } -} - -static int getShift(SkBitmap::Config config) { - switch (config) { - case SkBitmap::kARGB_8888_Config: - return 2; - case SkBitmap::kRGB_565_Config: - case SkBitmap::kARGB_4444_Config: - return 1; - case SkBitmap::kIndex8_Config: - case SkBitmap::kA8_Config: - return 0; - default: - return -1; // signal not supported - } -} - -void SkFlipPixelRef::CopyBitsFromAddr(const SkBitmap& dst, const SkRegion& clip, - const void* srcAddr) { - const int shift = getShift(dst.config()); - if (shift < 0) { - return; - } - - const SkIRect bounds = {0, 0, dst.width(), dst.height()}; - SkRegion::Cliperator iter(clip, bounds); - - while (!iter.done()) { - copyRect(dst, iter.rect(), srcAddr, shift); - iter.next(); - } -} - diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp deleted file mode 100644 index f0fff1b..0000000 --- a/src/images/SkImageDecoder.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* libs/graphics/images/SkImageDecoder.cpp -** -** Copyright 2006, 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 "SkImageDecoder.h" -#include "SkBitmap.h" -#include "SkPixelRef.h" -#include "SkStream.h" -#include "SkTemplates.h" - -static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; - -SkBitmap::Config SkImageDecoder::GetDeviceConfig() -{ - return gDeviceConfig; -} - -void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) -{ - gDeviceConfig = config; -} - -/////////////////////////////////////////////////////////////////////////////// - -SkImageDecoder::SkImageDecoder() - : fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1), - fDitherImage(true) { -} - -SkImageDecoder::~SkImageDecoder() { - fPeeker->safeUnref(); - fChooser->safeUnref(); - fAllocator->safeUnref(); -} - -SkImageDecoder::Format SkImageDecoder::getFormat() const { - return kUnknown_Format; -} - -SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { - SkRefCnt_SafeAssign(fPeeker, peeker); - return peeker; -} - -SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) { - SkRefCnt_SafeAssign(fChooser, chooser); - return chooser; -} - -SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) { - SkRefCnt_SafeAssign(fAllocator, alloc); - return alloc; -} - -void SkImageDecoder::setSampleSize(int size) { - if (size < 1) { - size = 1; - } - fSampleSize = size; -} - -bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width, - int height) const { - Chooser* chooser = fChooser; - - if (NULL == chooser) { // no chooser, we just say YES to decoding :) - return true; - } - chooser->begin(1); - chooser->inspect(0, config, width, height); - return chooser->choose() == 0; -} - -bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap, - SkColorTable* ctable) const { - return bitmap->allocPixels(fAllocator, ctable); -} - -/////////////////////////////////////////////////////////////////////////////// - -/* Technically, this should be 342, since that is the cutoff point between - an index and 32bit bitmap (they take equal ram), but since 32bit is almost - always faster, I bump up the value a bit. -*/ -#define MIN_SIZE_FOR_INDEX (512) - -/* Return the "optimal" config for this bitmap. In this case, we just look to - promote index bitmaps to full-color, since those are a little faster to - draw (fewer memory lookups). - - Seems like we could expose this to the caller through some exising or new - proxy object, allowing them to decide (after sniffing some aspect of the - original bitmap) what config they really want. - */ -static SkBitmap::Config optimal_config(const SkBitmap& bm, - SkBitmap::Config pref) { - if (bm.config() != pref) { - if (bm.config() == SkBitmap::kIndex8_Config) { - Sk64 size64 = bm.getSize64(); - if (size64.is32()) { - int32_t size = size64.get32(); - if (size < MIN_SIZE_FOR_INDEX) { - return SkBitmap::kARGB_8888_Config; - } - } - } - } - return bm.config(); -} - -bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode mode) { - // pass a temporary bitmap, so that if we return false, we are assured of - // leaving the caller's bitmap untouched. - SkBitmap tmp; - - // we reset this to false before calling onDecode - fShouldCancelDecode = false; - - if (!this->onDecode(stream, &tmp, pref, mode)) { - return false; - } - - SkBitmap::Config c = optimal_config(tmp, pref); - if (c != tmp.config()) { - if (mode == kDecodeBounds_Mode) { - tmp.setConfig(c, tmp.width(), tmp.height()); - } else { - SkBitmap tmp2; - if (tmp.copyTo(&tmp2, c, this->getAllocator())) { - tmp.swap(tmp2); - } - } - } - bm->swap(tmp); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, - SkBitmap::Config pref, Mode mode) { - SkASSERT(file); - SkASSERT(bm); - - SkFILEStream stream(file); - if (stream.isValid()) { - if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode)) { - bm->pixelRef()->setURI(file); - } - return true; - } - return false; -} - -bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, - SkBitmap::Config pref, Mode mode) { - if (0 == size) { - return false; - } - SkASSERT(buffer); - - SkMemoryStream stream(buffer, size); - return SkImageDecoder::DecodeStream(&stream, bm, pref, mode); -} - -bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode mode) { - SkASSERT(stream); - SkASSERT(bm); - - bool success = false; - SkImageDecoder* codec = SkImageDecoder::Factory(stream); - - if (NULL != codec) { - success = codec->decode(stream, bm, pref, mode); - delete codec; - } - return success; -} - diff --git a/src/images/SkImageDecoder_Factory.cpp b/src/images/SkImageDecoder_Factory.cpp deleted file mode 100644 index 9dd9913..0000000 --- a/src/images/SkImageDecoder_Factory.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* libs/graphics/ports/SkImageDecoder_Factory.cpp -** -** Copyright 2006, 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 "SkImageDecoder.h" -#include "SkMovie.h" -#include "SkStream.h" -#include "SkTRegistry.h" - -typedef SkTRegistry<SkImageDecoder*, SkStream*> DecodeReg; - -template DecodeReg* DecodeReg::gHead; - -SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) { - const DecodeReg* curr = DecodeReg::Head(); - while (curr) { - SkImageDecoder* codec = curr->factory()(stream); - stream->rewind(); - if (codec) { - return codec; - } - curr = curr->next(); - } - return NULL; -} - -///////////////////////////////////////////////////////////////////////// - -typedef SkTRegistry<SkMovie*, SkStream*> MovieReg; - -SkMovie* SkMovie::DecodeStream(SkStream* stream) { - const MovieReg* curr = MovieReg::Head(); - while (curr) { - SkMovie* movie = curr->factory()(stream); - if (movie) { - return movie; - } - stream->rewind(); - curr = curr->next(); - } - return NULL; -} - diff --git a/src/images/SkImageDecoder_fpdfemb.cpp b/src/images/SkImageDecoder_fpdfemb.cpp deleted file mode 100644 index 7f37e3d..0000000 --- a/src/images/SkImageDecoder_fpdfemb.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2007, 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 "SkImageDecoder.h" -#include "SkScaledBitmapSampler.h" -#include "SkStream.h" -#include "SkColorPriv.h" -#include "SkTDArray.h" - -#include "fpdfemb.h" - -class SkFPDFEMBImageDecoder : public SkImageDecoder { -public: - SkFPDFEMBImageDecoder() {} - - virtual Format getFormat() const { - return kBMP_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode mode); - -private: - bool render(FPDFEMB_PAGE page, const FPDFEMB_RECT& bounds, SkBitmap* bm, - SkBitmap::Config prefConfig, SkImageDecoder::Mode mode); -}; - -SkImageDecoder* SkImageDecoder_FPDFEMB_Factory(SkStream*); -SkImageDecoder* SkImageDecoder_FPDFEMB_Factory(SkStream* stream) { - static const char kPDFSig[] = { '%', 'P', 'D', 'F' }; - - size_t len = stream->getLength(); - char buffer[sizeof(kPDFSig)]; - - SkDebugf("---- SkImageDecoder_FPDFEMB_Factory len=%d\n", len); - - if (len != 12683) { return NULL; } - - if (len > sizeof(kPDFSig) && - stream->read(buffer, sizeof(kPDFSig)) == sizeof(kPDFSig) && - !memcmp(buffer, kPDFSig, sizeof(kPDFSig))) { - return SkNEW(SkFPDFEMBImageDecoder); - } - return NULL; -} - -/////////////////////////////////////////////////////////////////////////////// - -extern "C" { - static void* pdf_alloc(FPDFEMB_MEMMGR* pMgr, unsigned int size) { - void* addr = sk_malloc_throw(size); - // SkDebugf("---- pdf_alloc %d %p\n", size, addr); - return addr; - } - - static void* pdf_alloc_nl(FPDFEMB_MEMMGR* pMgr, unsigned int size) { - void* addr = sk_malloc_flags(size, 0); - // SkDebugf("---- pdf_alloc_nl %d %p\n", size, addr); - return addr; - } - - static void* pdf_realloc(FPDFEMB_MEMMGR*, void* addr, unsigned int size) { - void* newaddr = sk_realloc_throw(addr, size); - // SkDebugf("---- pdf_realloc %p %d %p\n", addr, size, newaddr); - return newaddr; - } - - static void pdf_free(FPDFEMB_MEMMGR* pMgr, void* pointer) { - // SkDebugf("---- pdf_free %p\n", pointer); - sk_free(pointer); - } - - void FX_OUTPUT_LOG_FUNC(const char* format, ...) { - SkDebugf("---- LOG_FUNC %s\n", format); - } - - static unsigned int file_getsize(FPDFEMB_FILE_ACCESS* file) { - SkStream* stream = (SkStream*)file->user; - return stream->getLength(); - } - - static FPDFEMB_RESULT file_readblock(FPDFEMB_FILE_ACCESS* file, void* dst, - unsigned int offset, unsigned int size) { - SkStream* stream = (SkStream*)file->user; -// SkDebugf("---- readblock %p %p %d %d\n", stream, dst, offset, size); - if (!stream->rewind()) { - SkDebugf("---- rewind failed\n"); - return FPDFERR_ERROR; - } - if (stream->skip(offset) != offset) { - SkDebugf("---- skip failed\n"); - return FPDFERR_ERROR; - } - if (stream->read(dst, size) != size) { - SkDebugf("---- read failed\n"); - return FPDFERR_ERROR; - } - return FPDFERR_SUCCESS; - } - - static void pdf_oom_handler(void* memory, int size) { - SkDebugf("======== pdf OOM %p %d\n", memory, size); - } -} - -static inline int PDF2Pixels(int x) { return x / 100; } -static inline SkScalar PDF2Scalar(int x) { - return SkScalarMulDiv(SK_Scalar1, x, 100); -} - -bool SkFPDFEMBImageDecoder::render(FPDFEMB_PAGE page, const FPDFEMB_RECT& bounds, SkBitmap* bm, - SkBitmap::Config prefConfig, SkImageDecoder::Mode mode) { - int width = PDF2Pixels(bounds.right - bounds.left); - int height = PDF2Pixels(bounds.top - bounds.bottom); - - SkDebugf("----- bitmap size [%d %d], mode=%d\n", width, height, mode); - bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); - if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; - } - - // USE THE CODEC TO ALLOCATE THE PIXELS!!!! - if (!this->allocPixelRef(bm, NULL)) { - SkDebugf("----- failed to alloc pixels\n"); - return false; - } - - bm->eraseColor(0); - - FPDFEMB_RESULT result; - FPDFEMB_BITMAP dib; - - result = FPDFEMB_CreateDIB(width, height, FPDFDIB_BGRA, bm->getPixels(), - bm->rowBytes(), &dib); - SkDebugf("---- createdib %d\n", result); - - result = FPDFEMB_StartRender(dib, page, 0, 0, width, height, 0, 0, NULL, NULL); - SkDebugf("---- render %d\n", result); - - result = FPDFEMB_DestroyDIB(dib); - SkDebugf("---- destroydib %d\n", result); - - SkPMColor* dst = bm->getAddr32(0, 0); - const uint8_t* src = (uint8_t*)dst; - int n = bm->getSize() >> 2; - for (int i = 0; i < n; i++) { - int b = *src++; - int g = *src++; - int r = *src++; - int a = *src++; - *dst++ = SkPackARGB32(a, r, g, b); - } - - return true; -} - -#define USE_FIXED_MEM (4 * 1024 * 1024) - -bool SkFPDFEMBImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config prefConfig, Mode mode) { - - FPDFEMB_RESULT result; -#ifdef USE_FIXED_MEM - SkAutoMalloc storage(USE_FIXED_MEM); - result = FPDFEMB_InitFixedMemory(storage.get(), USE_FIXED_MEM, - pdf_oom_handler); -#else - FPDFEMB_MEMMGR memmgr; - memmgr.Alloc = pdf_alloc; - memmgr.AllocNL = pdf_alloc_nl; - memmgr.Realloc = pdf_realloc; - memmgr.Free = pdf_free; - - result = FPDFEMB_Init(&memmgr); -#endif - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory init %d, streamLen = %d\n", result, stream->getLength()); - - FPDFEMB_FILE_ACCESS file; - file.GetSize = file_getsize; - file.ReadBlock = file_readblock; - file.user = stream; - - FPDFEMB_DOCUMENT document; - result = FPDFEMB_StartLoadDocument(&file, NULL, &document, NULL); - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory open %d %p\n", result, document); - - int pageCount = FPDFEMB_GetPageCount(document); - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory pageCount %d\n", pageCount); - - if (pageCount > 0) { - FPDFEMB_PAGE page; - result = FPDFEMB_LoadPage(document, 0, &page); - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory load page %d\n", result); - - int width, height; - result = FPDFEMB_GetPageSize(page, &width, &height); - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory page size %d [%d %d]\n", result, width, height); - - FPDFEMB_RECT rect; - result = FPDFEMB_GetPageBBox(page, &rect); - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory page rect %d [%d %d %d %d]\n", result, - rect.left, rect.top, rect.right, rect.bottom); - - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory begin page parse...\n"); - result = FPDFEMB_StartParse(page, false, NULL); - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory page parse %d\n", result); - - if (0 == result) { - this->render(page, rect, bm, prefConfig, mode); - } - - result = FPDFEMB_ClosePage(page); - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory close page %d\n", result); - } - - result = FPDFEMB_CloseDocument(document); - SkDebugf("----- SkImageDecoder_FPDFEMB_Factory close %d\n", result); - - // FPDFEMB_Exit(); - - return true; -} diff --git a/src/images/SkImageDecoder_libbmp.cpp b/src/images/SkImageDecoder_libbmp.cpp deleted file mode 100644 index a4dcbf6..0000000 --- a/src/images/SkImageDecoder_libbmp.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2007, 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 "bmpdecoderhelper.h" -#include "SkImageDecoder.h" -#include "SkScaledBitmapSampler.h" -#include "SkStream.h" -#include "SkColorPriv.h" -#include "SkTDArray.h" -#include "SkTRegistry.h" - -class SkBMPImageDecoder : public SkImageDecoder { -public: - SkBMPImageDecoder() {} - - virtual Format getFormat() const { - return kBMP_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode mode); -}; - -static SkImageDecoder* Factory(SkStream* stream) { - static const char kBmpMagic[] = { 'B', 'M' }; - - size_t len = stream->getLength(); - char buffer[sizeof(kBmpMagic)]; - - if (len > sizeof(kBmpMagic) && - stream->read(buffer, sizeof(kBmpMagic)) == sizeof(kBmpMagic) && - !memcmp(buffer, kBmpMagic, sizeof(kBmpMagic))) { - return SkNEW(SkBMPImageDecoder); - } - return NULL; -} - -static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory); - -/////////////////////////////////////////////////////////////////////////////// - -class SkBmpDecoderCallback : public image_codec::BmpDecoderCallback { -public: - // we don't copy the bitmap, just remember the pointer - SkBmpDecoderCallback(bool justBounds) : fJustBounds(justBounds) {} - - // override from BmpDecoderCallback - virtual uint8* SetSize(int width, int height) { - fWidth = width; - fHeight = height; - if (fJustBounds) { - return NULL; - } - - fRGB.setCount(width * height * 3); // 3 == r, g, b - return fRGB.begin(); - } - - int width() const { return fWidth; } - int height() const { return fHeight; } - uint8_t* rgb() const { return fRGB.begin(); } - -private: - SkTDArray<uint8_t> fRGB; - int fWidth; - int fHeight; - bool fJustBounds; -}; - -bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config prefConfig, Mode mode) { - - size_t length = stream->getLength(); - SkAutoMalloc storage(length); - - if (stream->read(storage.get(), length) != length) { - return false; - } - - const bool justBounds = SkImageDecoder::kDecodeBounds_Mode == mode; - SkBmpDecoderCallback callback(justBounds); - - // Now decode the BMP into callback's rgb() array [r,g,b, r,g,b, ...] - { - image_codec::BmpDecoderHelper helper; - const int max_pixels = 16383*16383; // max width*height - if (!helper.DecodeImage((const char*)storage.get(), length, - max_pixels, &callback)) { - return false; - } - } - - // we don't need this anymore, so free it now (before we try to allocate - // the bitmap's pixels) rather than waiting for its destructor - storage.free(); - - int width = callback.width(); - int height = callback.height(); - SkBitmap::Config config = SkBitmap::kARGB_8888_Config; - - // only accept prefConfig if it makes sense for us - if (SkBitmap::kARGB_4444_Config == prefConfig || - SkBitmap::kRGB_565_Config == config) { - config = prefConfig; - } - - SkScaledBitmapSampler sampler(width, height, getSampleSize()); - - bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); - bm->setIsOpaque(true); - if (justBounds) { - return true; - } - - if (!this->allocPixelRef(bm, NULL)) { - return false; - } - - SkAutoLockPixels alp(*bm); - - if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, getDitherImage())) { - return false; - } - - const int srcRowBytes = width * 3; - const int dstHeight = sampler.scaledHeight(); - const uint8_t* srcRow = callback.rgb(); - - srcRow += sampler.srcY0() * srcRowBytes; - for (int y = 0; y < dstHeight; y++) { - sampler.next(srcRow); - srcRow += sampler.srcDY() * srcRowBytes; - } - return true; -} diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp deleted file mode 100644 index ed8817a..0000000 --- a/src/images/SkImageDecoder_libgif.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* libs/graphics/images/SkImageDecoder_libgif.cpp -** -** Copyright 2006, 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 "SkImageDecoder.h" -#include "SkColor.h" -#include "SkColorPriv.h" -#include "SkStream.h" -#include "SkTemplates.h" -#include "SkPackBits.h" - -#include "gif_lib.h" - -class SkGIFImageDecoder : public SkImageDecoder { -public: - virtual Format getFormat() const { - return kGIF_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode mode); -}; - -static const uint8_t gStartingIterlaceYValue[] = { - 0, 4, 2, 1 -}; -static const uint8_t gDeltaIterlaceYValue[] = { - 8, 8, 4, 2 -}; - -/* Implement the GIF interlace algorithm in an iterator. - 1) grab every 8th line beginning at 0 - 2) grab every 8th line beginning at 4 - 3) grab every 4th line beginning at 2 - 4) grab every 2nd line beginning at 1 -*/ -class GifInterlaceIter { -public: - GifInterlaceIter(int height) : fHeight(height) { - fStartYPtr = gStartingIterlaceYValue; - fDeltaYPtr = gDeltaIterlaceYValue; - - fCurrY = *fStartYPtr++; - fDeltaY = *fDeltaYPtr++; - } - - int currY() const { - SkASSERT(fStartYPtr); - SkASSERT(fDeltaYPtr); - return fCurrY; - } - - void next() { - SkASSERT(fStartYPtr); - SkASSERT(fDeltaYPtr); - - int y = fCurrY + fDeltaY; - // We went from an if statement to a while loop so that we iterate - // through fStartYPtr until a valid row is found. This is so that images - // that are smaller than 5x5 will not trash memory. - while (y >= fHeight) { - if (gStartingIterlaceYValue + - SK_ARRAY_COUNT(gStartingIterlaceYValue) == fStartYPtr) { - // we done - SkDEBUGCODE(fStartYPtr = NULL;) - SkDEBUGCODE(fDeltaYPtr = NULL;) - y = 0; - } else { - y = *fStartYPtr++; - fDeltaY = *fDeltaYPtr++; - } - } - fCurrY = y; - } - -private: - const int fHeight; - int fCurrY; - int fDeltaY; - const uint8_t* fStartYPtr; - const uint8_t* fDeltaYPtr; -}; - -/////////////////////////////////////////////////////////////////////////////// - -//#define GIF_STAMP "GIF" /* First chars in file - GIF stamp. */ -//#define GIF_STAMP_LEN (sizeof(GIF_STAMP) - 1) - -static int DecodeCallBackProc(GifFileType* fileType, GifByteType* out, - int size) { - SkStream* stream = (SkStream*) fileType->UserData; - return (int) stream->read(out, size); -} - -void CheckFreeExtension(SavedImage* Image) { - if (Image->ExtensionBlocks) { - FreeExtension(Image); - } -} - -// return NULL on failure -static const ColorMapObject* find_colormap(const GifFileType* gif) { - const ColorMapObject* cmap = gif->Image.ColorMap; - if (NULL == cmap) { - cmap = gif->SColorMap; - } - // some sanity checks - if ((unsigned)cmap->ColorCount > 256 || - cmap->ColorCount != (1 << cmap->BitsPerPixel)) { - cmap = NULL; - } - return cmap; -} - -// return -1 if not found (i.e. we're completely opaque) -static int find_transpIndex(const SavedImage& image, int colorCount) { - int transpIndex = -1; - for (int i = 0; i < image.ExtensionBlockCount; ++i) { - const ExtensionBlock* eb = image.ExtensionBlocks + i; - if (eb->Function == 0xF9 && eb->ByteCount == 4) { - if (eb->Bytes[0] & 1) { - transpIndex = (unsigned char)eb->Bytes[3]; - // check for valid transpIndex - if (transpIndex >= colorCount) { - transpIndex = -1; - } - break; - } - } - } - return transpIndex; -} - -static bool error_return(GifFileType* gif, const SkBitmap& bm, - const char msg[]) { -#if 0 - SkDebugf("libgif error <%s> bitmap [%d %d] pixels %p colortable %p\n", - msg, bm.width(), bm.height(), bm.getPixels(), bm.getColorTable()); -#endif - return false; -} - -bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, - SkBitmap::Config prefConfig, Mode mode) { - GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc); - if (NULL == gif) { - return error_return(gif, *bm, "DGifOpen"); - } - - SkAutoTCallIProc<GifFileType, DGifCloseFile> acp(gif); - - SavedImage temp_save; - temp_save.ExtensionBlocks=NULL; - temp_save.ExtensionBlockCount=0; - SkAutoTCallVProc<SavedImage, CheckFreeExtension> acp2(&temp_save); - - int width, height; - GifRecordType recType; - GifByteType *extData; - - do { - if (DGifGetRecordType(gif, &recType) == GIF_ERROR) { - return error_return(gif, *bm, "DGifGetRecordType"); - } - - switch (recType) { - case IMAGE_DESC_RECORD_TYPE: { - if (DGifGetImageDesc(gif) == GIF_ERROR) { - return error_return(gif, *bm, "IMAGE_DESC_RECORD_TYPE"); - } - - if (gif->ImageCount < 1) { // sanity check - return error_return(gif, *bm, "ImageCount < 1"); - } - - width = gif->SWidth; - height = gif->SHeight; - if (width <= 0 || height <= 0 || - !this->chooseFromOneChoice(SkBitmap::kIndex8_Config, - width, height)) { - return error_return(gif, *bm, "chooseFromOneChoice"); - } - - bm->setConfig(SkBitmap::kIndex8_Config, width, height); - if (SkImageDecoder::kDecodeBounds_Mode == mode) - return true; - - SavedImage* image = &gif->SavedImages[gif->ImageCount-1]; - const GifImageDesc& desc = image->ImageDesc; - - // check for valid descriptor - if ( (desc.Top | desc.Left) < 0 || - desc.Left + desc.Width > width || - desc.Top + desc.Height > height) { - return error_return(gif, *bm, "TopLeft"); - } - - // now we decode the colortable - int colorCount = 0; - { - const ColorMapObject* cmap = find_colormap(gif); - if (NULL == cmap) { - return error_return(gif, *bm, "null cmap"); - } - - colorCount = cmap->ColorCount; - SkColorTable* ctable = SkNEW_ARGS(SkColorTable, (colorCount)); - SkPMColor* colorPtr = ctable->lockColors(); - for (int index = 0; index < colorCount; index++) - colorPtr[index] = SkPackARGB32(0xFF, - cmap->Colors[index].Red, - cmap->Colors[index].Green, - cmap->Colors[index].Blue); - - int transpIndex = find_transpIndex(temp_save, colorCount); - if (transpIndex < 0) - ctable->setFlags(ctable->getFlags() | SkColorTable::kColorsAreOpaque_Flag); - else - colorPtr[transpIndex] = 0; // ram in a transparent SkPMColor - ctable->unlockColors(true); - - SkAutoUnref aurts(ctable); - if (!this->allocPixelRef(bm, ctable)) { - return error_return(gif, *bm, "allocPixelRef"); - } - } - - SkAutoLockPixels alp(*bm); - - // time to decode the scanlines - // - uint8_t* scanline = bm->getAddr8(0, 0); - const int rowBytes = bm->rowBytes(); - const int innerWidth = desc.Width; - const int innerHeight = desc.Height; - - // abort if either inner dimension is <= 0 - if (innerWidth <= 0 || innerHeight <= 0) { - return error_return(gif, *bm, "non-pos inner width/height"); - } - - // are we only a subset of the total bounds? - if ((desc.Top | desc.Left) > 0 || - innerWidth < width || innerHeight < height) - { - uint8_t fill = (uint8_t)gif->SBackGroundColor; - // check for valid fill index/color - if (fill >= (unsigned)colorCount) { - fill = 0; - } - memset(scanline, gif->SBackGroundColor, bm->getSize()); - // bump our starting address - scanline += desc.Top * rowBytes + desc.Left; - } - - // now decode each scanline - if (gif->Image.Interlace) - { - GifInterlaceIter iter(innerHeight); - for (int y = 0; y < innerHeight; y++) - { - uint8_t* row = scanline + iter.currY() * rowBytes; - if (DGifGetLine(gif, row, innerWidth) == GIF_ERROR) { - return error_return(gif, *bm, "interlace DGifGetLine"); - } - iter.next(); - } - } - else - { - // easy, non-interlace case - for (int y = 0; y < innerHeight; y++) { - if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) { - return error_return(gif, *bm, "DGifGetLine"); - } - scanline += rowBytes; - } - } - goto DONE; - } break; - - case EXTENSION_RECORD_TYPE: - if (DGifGetExtension(gif, &temp_save.Function, - &extData) == GIF_ERROR) { - return error_return(gif, *bm, "DGifGetExtension"); - } - - while (extData != NULL) { - /* Create an extension block with our data */ - if (AddExtensionBlock(&temp_save, extData[0], - &extData[1]) == GIF_ERROR) { - return error_return(gif, *bm, "AddExtensionBlock"); - } - if (DGifGetExtensionNext(gif, &extData) == GIF_ERROR) { - return error_return(gif, *bm, "DGifGetExtensionNext"); - } - temp_save.Function = 0; - } - break; - - case TERMINATE_RECORD_TYPE: - break; - - default: /* Should be trapped by DGifGetRecordType */ - break; - } - } while (recType != TERMINATE_RECORD_TYPE); - -DONE: - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkTRegistry.h" - -static SkImageDecoder* Factory(SkStream* stream) { - char buf[GIF_STAMP_LEN]; - if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) { - if (memcmp(GIF_STAMP, buf, GIF_STAMP_LEN) == 0 || - memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 || - memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) { - return SkNEW(SkGIFImageDecoder); - } - } - return NULL; -} - -static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory); diff --git a/src/images/SkImageDecoder_libico.cpp b/src/images/SkImageDecoder_libico.cpp deleted file mode 100644 index 9f21e13..0000000 --- a/src/images/SkImageDecoder_libico.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* libs/graphics/images/SkImageDecoder_libico.cpp -** -** Copyright 2006, 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 "SkImageDecoder.h" -#include "SkStream.h" -#include "SkColorPriv.h" -#include "SkTypes.h" - -class SkICOImageDecoder : public SkImageDecoder { -public: - SkICOImageDecoder(); - - virtual Format getFormat() const { - return kICO_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode); -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -//read bytes starting from the begin-th index in the buffer -//read in Intel order, and return an integer - -#define readByte(buffer,begin) buffer[begin] -#define read2Bytes(buffer,begin) buffer[begin]+(buffer[begin+1]<<8) -#define read4Bytes(buffer,begin) buffer[begin]+(buffer[begin+1]<<8)+(buffer[begin+2]<<16)+(buffer[begin+3]<<24) - -///////////////////////////////////////////////////////////////////////////////////////// - -SkICOImageDecoder::SkICOImageDecoder() -{ -} - -//helpers - my function pointer will call one of these, depending on the bitCount, each time through the inner loop -static void editPixelBit1(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors); -static void editPixelBit4(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors); -static void editPixelBit8(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors); -static void editPixelBit24(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors); -static void editPixelBit32(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors); - - -static int calculateRowBytesFor8888(int w, int bitCount) -{ - // Default rowBytes is w << 2 for kARGB_8888 - // In the case of a 4 bit image with an odd width, we need to add some - // so we can go off the end of the drawn bitmap. - // Add 4 to ensure that it is still a multiple of 4. - if (4 == bitCount && (w & 0x1)) { - return (w + 1) << 2; - } - // Otherwise return 0, which will allow it to be calculated automatically. - return 0; -} - -bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode mode) -{ - size_t length = stream->read(NULL, 0); - SkAutoMalloc autoMal(length); - unsigned char* buf = (unsigned char*)autoMal.get(); - if (stream->read((void*)buf, length) != length) { - return false; - } - - //these should always be the same - should i use for error checking? - what about files that have some - //incorrect values, but still decode properly? - int reserved = read2Bytes(buf, 0); // 0 - int type = read2Bytes(buf, 2); // 1 - if (reserved != 0 || type != 1) - return false; - int count = read2Bytes(buf, 4); - - //need to at least have enough space to hold the initial table of info - if (length < (size_t)(6 + count*16)) - return false; - - int choice; - Chooser* chooser = this->getChooser(); - //FIXME:if no chooser, consider providing the largest color image - //what are the odds that the largest image would be monochrome? - if (NULL == chooser) { - choice = 0; - } else { - chooser->begin(count); - for (int i = 0; i < count; i++) - { - //need to find out the config, width, and height from the stream - int width = readByte(buf, 6 + i*16); - int height = readByte(buf, 7 + i*16); - int offset = read4Bytes(buf, 18 + i*16); - int bitCount = read2Bytes(buf, offset+14); - SkBitmap::Config c; - //currently only provide ARGB_8888_, but maybe we want kIndex8_Config for 1 and 4, and possibly 8? - //or maybe we'll determine this based on the provided config - switch (bitCount) - { - case 1: - case 4: - // In reality, at least for the moment, these will be decoded into kARGB_8888 bitmaps. - // However, this will be used to distinguish between the lower quality 1bpp and 4 bpp - // images and the higher quality images. - c = SkBitmap::kIndex8_Config; - break; - case 8: - case 24: - case 32: - c = SkBitmap::kARGB_8888_Config; - break; - default: - SkDEBUGF(("Image with %ibpp not supported\n", bitCount)); - continue; - } - chooser->inspect(i, c, width, height); - } - choice = chooser->choose(); - } - - //you never know what the chooser is going to supply - if (choice >= count || choice < 0) - return false; - - //skip ahead to the correct header - //commented out lines are not used, but if i switch to other read method, need to know how many to skip - //otherwise, they could be used for error checking - int w = readByte(buf, 6 + choice*16); - int h = readByte(buf, 7 + choice*16); - int colorCount = readByte(buf, 8 + choice*16); - //int reservedToo = readByte(buf, 9 + choice*16); //0 - //int planes = read2Bytes(buf, 10 + choice*16); //1 - but often 0 - //int fakeBitCount = read2Bytes(buf, 12 + choice*16); //should be real - usually 0 - int size = read4Bytes(buf, 14 + choice*16); //matters? - int offset = read4Bytes(buf, 18 + choice*16); - if ((size_t)(offset + size) > length) - return false; - //int infoSize = read4Bytes(buf, offset); //40 - //int width = read4Bytes(buf, offset+4); //should == w - //int height = read4Bytes(buf, offset+8); //should == 2*h - //int planesToo = read2Bytes(buf, offset+12); //should == 1 (does it?) - int bitCount = read2Bytes(buf, offset+14); - - void (*placePixel)(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) = NULL; - switch (bitCount) - { - case 1: - placePixel = &editPixelBit1; - colorCount = 2; - break; - case 4: - placePixel = &editPixelBit4; - colorCount = 16; - break; - case 8: - placePixel = &editPixelBit8; - colorCount = 256; - break; - case 24: - placePixel = &editPixelBit24; - colorCount = 0; - break; - case 32: - placePixel = &editPixelBit32; - colorCount = 0; - break; - default: - SkDEBUGF(("Decoding %ibpp is unimplemented\n", bitCount)); - return false; - } - - //these should all be zero, but perhaps are not - need to check - //int compression = read4Bytes(buf, offset+16); //0 - //int imageSize = read4Bytes(buf, offset+20); //0 - sometimes has a value - //int xPixels = read4Bytes(buf, offset+24); //0 - //int yPixels = read4Bytes(buf, offset+28); //0 - //int colorsUsed = read4Bytes(buf, offset+32) //0 - might have an actual value though - //int colorsImportant = read4Bytes(buf, offset+36); //0 - - int begin = offset + 40; - //this array represents the colortable - //if i allow other types of bitmaps, it may actually be used as a part of the bitmap - SkPMColor* colors = NULL; - int blue, green, red; - if (colorCount) - { - colors = new SkPMColor[colorCount]; - for (int j = 0; j < colorCount; j++) - { - //should this be a function - maybe a #define? - blue = readByte(buf, begin + 4*j); - green = readByte(buf, begin + 4*j + 1); - red = readByte(buf, begin + 4*j + 2); - colors[j] = SkPackARGB32(0xFF, red & 0xFF, green & 0xFF, blue & 0xFF); - } - } - int bitWidth = w*bitCount; - int test = bitWidth & 0x1F; - int mask = -(((test >> 4) | (test >> 3) | (test >> 2) | (test >> 1) | test) & 0x1); //either 0xFFFFFFFF or 0 - int lineBitWidth = (bitWidth & 0xFFFFFFE0) + (0x20 & mask); - int lineWidth = lineBitWidth/bitCount; - - int xorOffset = begin + colorCount*4; //beginning of the color bitmap - //other read method means we will just be here already - int andOffset = xorOffset + ((lineWidth*h*bitCount) >> 3); - - /*int */test = w & 0x1F; //the low 5 bits - we are rounding up to the next 32 (2^5) - /*int */mask = -(((test >> 4) | (test >> 3) | (test >> 2) | (test >> 1) | test) & 0x1); //either 0xFFFFFFFF or 0 - int andLineWidth = (w & 0xFFFFFFE0) + (0x20 & mask); - //if we allow different Configs, everything is the same til here - //change the config, and use different address getter, and place index vs color, and add the color table - //FIXME: what is the tradeoff in size? - //if the andbitmap (mask) is all zeroes, then we can easily do an index bitmap - //however, with small images with large colortables, maybe it's better to still do argb_8888 - - bm->setConfig(SkBitmap::kARGB_8888_Config, w, h, calculateRowBytesFor8888(w, bitCount)); - - if (SkImageDecoder::kDecodeBounds_Mode == mode) { - delete[] colors; - return true; - } - - if (!this->allocPixelRef(bm, NULL)) - { - delete[] colors; - return false; - } - - SkAutoLockPixels alp(*bm); - - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - //U32* address = bm->getAddr32(x, y); - - //check the alpha bit first, but pass it along to the function to figure out how to deal with it - int andPixelNo = andLineWidth*(h-y-1)+x; - //only need to get a new alphaByte when x %8 == 0 - //but that introduces an if and a mod - probably much slower - //that's ok, it's just a read of an array, not a stream - int alphaByte = readByte(buf, andOffset + (andPixelNo >> 3)); - int shift = 7 - (andPixelNo & 0x7); - int m = 1 << shift; - - int pixelNo = lineWidth*(h-y-1)+x; - placePixel(pixelNo, buf, xorOffset, x, y, w, bm, alphaByte, m, shift, colors); - - } - } - - delete [] colors; - //ensure we haven't read off the end? - //of course this doesn't help us if the andOffset was a lie... - //return andOffset + (andLineWidth >> 3) <= length; - return true; -} //onDecode - -//function to place the pixel, determined by the bitCount -static void editPixelBit1(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) -{ - // note that this should be the same as/similar to the AND bitmap - SkPMColor* address = bm->getAddr32(x,y); - int byte = readByte(buf, xorOffset + (pixelNo >> 3)); - int colorBit; - int alphaBit; - // Read all of the bits in this byte. - int i = x + 8; - // Pin to the width so we do not write outside the bounds of - // our color table. - i = i > w ? w : i; - // While loop to check all 8 bits individually. - while (x < i) - { - - colorBit = (byte & m) >> shift; - alphaBit = (alphaByte & m) >> shift; - *address = (alphaBit-1)&(colors[colorBit]); - x++; - // setup for the next pixel - address = address + 1; - m = m >> 1; - shift -= 1; - } - x--; -} -static void editPixelBit4(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) -{ - SkPMColor* address = bm->getAddr32(x, y); - int byte = readByte(buf, xorOffset + (pixelNo >> 1)); - int pixel = (byte >> 4) & 0xF; - int alphaBit = (alphaByte & m) >> shift; - *address = (alphaBit-1)&(colors[pixel]); - x++; - //if w is odd, x may be the same as w, which means we are writing to an unused portion of the bitmap - //but that's okay, since i've added an extra rowByte for just this purpose - address = address + 1; - pixel = byte & 0xF; - m = m >> 1; - alphaBit = (alphaByte & m) >> (shift-1); - //speed up trick here - *address = (alphaBit-1)&(colors[pixel]); -} - -static void editPixelBit8(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) -{ - SkPMColor* address = bm->getAddr32(x, y); - int pixel = readByte(buf, xorOffset + pixelNo); - int alphaBit = (alphaByte & m) >> shift; - *address = (alphaBit-1)&(colors[pixel]); -} - -static void editPixelBit24(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) -{ - SkPMColor* address = bm->getAddr32(x, y); - int blue = readByte(buf, xorOffset + 3*pixelNo); - int green = readByte(buf, xorOffset + 3*pixelNo + 1); - int red = readByte(buf, xorOffset + 3*pixelNo + 2); - int alphaBit = (alphaByte & m) >> shift; - //alphaBit == 1 => alpha = 0 - int alpha = (alphaBit-1) & 0xFF; - *address = SkPackARGB32(alpha, red & alpha, green & alpha, blue & alpha); -} - -static void editPixelBit32(const int pixelNo, const unsigned char* buf, - const int xorOffset, int& x, int y, const int w, - SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) -{ - SkPMColor* address = bm->getAddr32(x, y); - int blue = readByte(buf, xorOffset + 4*pixelNo); - int green = readByte(buf, xorOffset + 4*pixelNo + 1); - int red = readByte(buf, xorOffset + 4*pixelNo + 2); - int alphaBit = (alphaByte & m) >> shift; - int alpha = readByte(buf, xorOffset + 4*pixelNo + 3) & ((alphaBit-1)&0xFF); - *address = SkPackARGB32(alpha, red & alpha, green & alpha, blue & alpha); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -#include "SkTRegistry.h" - -static SkImageDecoder* Factory(SkStream* stream) { - // Check to see if the first four bytes are 0,0,1,0 - // FIXME: Is that required and sufficient? - SkAutoMalloc autoMal(4); - unsigned char* buf = (unsigned char*)autoMal.get(); - stream->read((void*)buf, 4); - int reserved = read2Bytes(buf, 0); - int type = read2Bytes(buf, 2); - if (reserved != 0 || type != 1) { - // This stream does not represent an ICO image. - return NULL; - } - return SkNEW(SkICOImageDecoder); -} - -static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory); - diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp deleted file mode 100644 index 018c96c..0000000 --- a/src/images/SkImageDecoder_libjpeg.cpp +++ /dev/null @@ -1,800 +0,0 @@ -/* - * Copyright 2007, 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 "SkImageDecoder.h" -#include "SkImageEncoder.h" -#include "SkColorPriv.h" -#include "SkDither.h" -#include "SkScaledBitmapSampler.h" -#include "SkStream.h" -#include "SkTemplates.h" -#include "SkUtils.h" - -#include <stdio.h> -extern "C" { - #include "jpeglib.h" - #include "jerror.h" -} - -// this enables timing code to report milliseconds for an encode -//#define TIME_ENCODE -//#define TIME_DECODE - -// this enables our rgb->yuv code, which is faster than libjpeg on ARM -// disable for the moment, as we have some glitches when width != multiple of 4 -#define WE_CONVERT_TO_YUV - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -class SkJPEGImageDecoder : public SkImageDecoder { -public: - virtual Format getFormat() const { - return kJPEG_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode); -}; - -////////////////////////////////////////////////////////////////////////// - -#include "SkTime.h" - -class AutoTimeMillis { -public: - AutoTimeMillis(const char label[]) : fLabel(label) { - if (!fLabel) { - fLabel = ""; - } - fNow = SkTime::GetMSecs(); - } - ~AutoTimeMillis() { - SkDebugf("---- Time (ms): %s %d\n", fLabel, SkTime::GetMSecs() - fNow); - } -private: - const char* fLabel; - SkMSec fNow; -}; - -/* our source struct for directing jpeg to our stream object -*/ -struct sk_source_mgr : jpeg_source_mgr { - sk_source_mgr(SkStream* stream, SkImageDecoder* decoder); - - SkStream* fStream; - const void* fMemoryBase; - size_t fMemoryBaseSize; - SkImageDecoder* fDecoder; - enum { - kBufferSize = 1024 - }; - char fBuffer[kBufferSize]; -}; - -/* Automatically clean up after throwing an exception */ -class JPEGAutoClean { -public: - JPEGAutoClean(): cinfo_ptr(NULL) {} - ~JPEGAutoClean() { - if (cinfo_ptr) { - jpeg_destroy_decompress(cinfo_ptr); - } - } - void set(jpeg_decompress_struct* info) { - cinfo_ptr = info; - } -private: - jpeg_decompress_struct* cinfo_ptr; -}; - -static void sk_init_source(j_decompress_ptr cinfo) { - sk_source_mgr* src = (sk_source_mgr*)cinfo->src; - src->next_input_byte = (const JOCTET*)src->fBuffer; - src->bytes_in_buffer = 0; -} - -static boolean sk_fill_input_buffer(j_decompress_ptr cinfo) { - sk_source_mgr* src = (sk_source_mgr*)cinfo->src; - if (src->fDecoder != NULL && src->fDecoder->shouldCancelDecode()) { - return FALSE; - } - size_t bytes = src->fStream->read(src->fBuffer, sk_source_mgr::kBufferSize); - // note that JPEG is happy with less than the full read, - // as long as the result is non-zero - if (bytes == 0) { - return FALSE; - } - - src->next_input_byte = (const JOCTET*)src->fBuffer; - src->bytes_in_buffer = bytes; - return TRUE; -} - -static void sk_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { - SkASSERT(num_bytes > 0); - - sk_source_mgr* src = (sk_source_mgr*)cinfo->src; - - long bytesToSkip = num_bytes - src->bytes_in_buffer; - - // check if the skip amount exceeds the current buffer - if (bytesToSkip > 0) { - size_t bytes = src->fStream->skip(bytesToSkip); - if (bytes != (size_t)bytesToSkip) { -// SkDebugf("xxxxxxxxxxxxxx failure to skip request %d actual %d\n", bytesToSkip, bytes); - cinfo->err->error_exit((j_common_ptr)cinfo); - } - src->next_input_byte = (const JOCTET*)src->fBuffer; - src->bytes_in_buffer = 0; - } else { - src->next_input_byte += num_bytes; - src->bytes_in_buffer -= num_bytes; - } -} - -static boolean sk_resync_to_restart(j_decompress_ptr cinfo, int desired) { - sk_source_mgr* src = (sk_source_mgr*)cinfo->src; - - // what is the desired param for??? - - if (!src->fStream->rewind()) { - SkDebugf("xxxxxxxxxxxxxx failure to rewind\n"); - cinfo->err->error_exit((j_common_ptr)cinfo); - return FALSE; - } - src->next_input_byte = (const JOCTET*)src->fBuffer; - src->bytes_in_buffer = 0; - return TRUE; -} - -static void sk_term_source(j_decompress_ptr /*cinfo*/) {} - -/////////////////////////////////////////////////////////////////////////////// - -static void skmem_init_source(j_decompress_ptr cinfo) { - sk_source_mgr* src = (sk_source_mgr*)cinfo->src; - src->next_input_byte = (const JOCTET*)src->fMemoryBase; - src->bytes_in_buffer = src->fMemoryBaseSize; -} - -static boolean skmem_fill_input_buffer(j_decompress_ptr cinfo) { - SkDebugf("xxxxxxxxxxxxxx skmem_fill_input_buffer called\n"); - return FALSE; -} - -static void skmem_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { - sk_source_mgr* src = (sk_source_mgr*)cinfo->src; -// SkDebugf("xxxxxxxxxxxxxx skmem_skip_input_data called %d\n", num_bytes); - src->next_input_byte = (const JOCTET*)((const char*)src->next_input_byte + num_bytes); - src->bytes_in_buffer -= num_bytes; -} - -static boolean skmem_resync_to_restart(j_decompress_ptr cinfo, int desired) { - SkDebugf("xxxxxxxxxxxxxx skmem_resync_to_restart called\n"); - return TRUE; -} - -static void skmem_term_source(j_decompress_ptr /*cinfo*/) {} - -/////////////////////////////////////////////////////////////////////////////// - -sk_source_mgr::sk_source_mgr(SkStream* stream, SkImageDecoder* decoder) : fStream(stream) { - fDecoder = decoder; - const void* baseAddr = stream->getMemoryBase(); - if (baseAddr && false) { - fMemoryBase = baseAddr; - fMemoryBaseSize = stream->getLength(); - - init_source = skmem_init_source; - fill_input_buffer = skmem_fill_input_buffer; - skip_input_data = skmem_skip_input_data; - resync_to_restart = skmem_resync_to_restart; - term_source = skmem_term_source; - } else { - fMemoryBase = NULL; - fMemoryBaseSize = 0; - - init_source = sk_init_source; - fill_input_buffer = sk_fill_input_buffer; - skip_input_data = sk_skip_input_data; - resync_to_restart = sk_resync_to_restart; - term_source = sk_term_source; - } -// SkDebugf("**************** use memorybase %p %d\n", fMemoryBase, fMemoryBaseSize); -} - -#include <setjmp.h> - -struct sk_error_mgr : jpeg_error_mgr { - jmp_buf fJmpBuf; -}; - -static void sk_error_exit(j_common_ptr cinfo) { - sk_error_mgr* error = (sk_error_mgr*)cinfo->err; - - (*error->output_message) (cinfo); - - /* Let the memory manager delete any temp files before we die */ - jpeg_destroy(cinfo); - - longjmp(error->fJmpBuf, -1); -} - -/////////////////////////////////////////////////////////////////////////////// - -static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer, - int count) { - for (int i = 0; i < count; i++) { - JSAMPLE* rowptr = (JSAMPLE*)buffer; - int row_count = jpeg_read_scanlines(cinfo, &rowptr, 1); - if (row_count != 1) { - return false; - } - } - return true; -} - -// This guy exists just to aid in debugging, as it allows debuggers to just -// set a break-point in one place to see all error exists. -static bool return_false(const jpeg_decompress_struct& cinfo, - const SkBitmap& bm, const char msg[]) { -#if 0 - SkDebugf("libjpeg error %d <%s> from %s [%d %d]", cinfo.err->msg_code, - cinfo.err->jpeg_message_table[cinfo.err->msg_code], msg, - bm.width(), bm.height()); -#endif - return false; // must always return false -} - -bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config prefConfig, Mode mode) { -#ifdef TIME_DECODE - AutoTimeMillis atm("JPEG Decode"); -#endif - - SkAutoMalloc srcStorage; - JPEGAutoClean autoClean; - - jpeg_decompress_struct cinfo; - sk_error_mgr sk_err; - sk_source_mgr sk_stream(stream, this); - - cinfo.err = jpeg_std_error(&sk_err); - sk_err.error_exit = sk_error_exit; - - // All objects need to be instantiated before this setjmp call so that - // they will be cleaned up properly if an error occurs. - if (setjmp(sk_err.fJmpBuf)) { - return return_false(cinfo, *bm, "setjmp"); - } - - jpeg_create_decompress(&cinfo); - autoClean.set(&cinfo); - - //jpeg_stdio_src(&cinfo, file); - cinfo.src = &sk_stream; - - int status = jpeg_read_header(&cinfo, true); - if (status != JPEG_HEADER_OK) { - return return_false(cinfo, *bm, "read_header"); - } - - /* Try to fulfill the requested sampleSize. Since jpeg can do it (when it - can) much faster that we, just use their num/denom api to approximate - the size. - */ - int sampleSize = this->getSampleSize(); - - cinfo.dct_method = JDCT_IFAST; - cinfo.scale_num = 1; - cinfo.scale_denom = sampleSize; - - /* this gives about 30% performance improvement. In theory it may - reduce the visual quality, in practice I'm not seeing a difference - */ - cinfo.do_fancy_upsampling = 0; - - /* this gives another few percents */ - cinfo.do_block_smoothing = 0; - - /* default format is RGB */ - cinfo.out_color_space = JCS_RGB; - - SkBitmap::Config config = prefConfig; - // if no user preference, see what the device recommends - if (config == SkBitmap::kNo_Config) - config = SkImageDecoder::GetDeviceConfig(); - - // only these make sense for jpegs - if (config != SkBitmap::kARGB_8888_Config && - config != SkBitmap::kARGB_4444_Config && - config != SkBitmap::kRGB_565_Config) { - config = SkBitmap::kARGB_8888_Config; - } - -#ifdef ANDROID_RGB - cinfo.dither_mode = JDITHER_NONE; - if (config == SkBitmap::kARGB_8888_Config) { - cinfo.out_color_space = JCS_RGBA_8888; - } else if (config == SkBitmap::kRGB_565_Config) { - if (sampleSize == 1) { - // SkScaledBitmapSampler can't handle RGB_565 yet, - // so don't even try. - cinfo.out_color_space = JCS_RGB_565; - if (this->getDitherImage()) { - cinfo.dither_mode = JDITHER_ORDERED; - } - } - } -#endif - - /* image_width and image_height are the original dimensions, available - after jpeg_read_header(). To see the scaled dimensions, we have to call - jpeg_start_decompress(), and then read output_width and output_height. - */ - if (!jpeg_start_decompress(&cinfo)) { - return return_false(cinfo, *bm, "start_decompress"); - } - - /* If we need to better match the request, we might examine the image and - output dimensions, and determine if the downsampling jpeg provided is - not sufficient. If so, we can recompute a modified sampleSize value to - make up the difference. - - To skip this additional scaling, just set sampleSize = 1; below. - */ - sampleSize = sampleSize * cinfo.output_width / cinfo.image_width; - - - // should we allow the Chooser (if present) to pick a config for us??? - if (!this->chooseFromOneChoice(config, cinfo.output_width, - cinfo.output_height)) { - return return_false(cinfo, *bm, "chooseFromOneChoice"); - } - -#ifdef ANDROID_RGB - /* short-circuit the SkScaledBitmapSampler when possible, as this gives - a significant performance boost. - */ - if (sampleSize == 1 && - ((config == SkBitmap::kARGB_8888_Config && - cinfo.out_color_space == JCS_RGBA_8888) || - (config == SkBitmap::kRGB_565_Config && - cinfo.out_color_space == JCS_RGB_565))) - { - bm->setConfig(config, cinfo.output_width, cinfo.output_height); - bm->setIsOpaque(true); - if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; - } - if (!this->allocPixelRef(bm, NULL)) { - return return_false(cinfo, *bm, "allocPixelRef"); - } - SkAutoLockPixels alp(*bm); - JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); - INT32 const bpr = bm->rowBytes(); - - while (cinfo.output_scanline < cinfo.output_height) { - int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); - // if row_count == 0, then we didn't get a scanline, so abort. - // if we supported partial images, we might return true in this case - if (0 == row_count) { - return return_false(cinfo, *bm, "read_scanlines"); - } - if (this->shouldCancelDecode()) { - return return_false(cinfo, *bm, "shouldCancelDecode"); - } - rowptr += bpr; - } - jpeg_finish_decompress(&cinfo); - return true; - } -#endif - - // check for supported formats - SkScaledBitmapSampler::SrcConfig sc; - if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_space) { - sc = SkScaledBitmapSampler::kRGB; -#ifdef ANDROID_RGB - } else if (JCS_RGBA_8888 == cinfo.out_color_space) { - sc = SkScaledBitmapSampler::kRGBX; - //} else if (JCS_RGB_565 == cinfo.out_color_space) { - // sc = SkScaledBitmapSampler::kRGB_565; -#endif - } else if (1 == cinfo.out_color_components && - JCS_GRAYSCALE == cinfo.out_color_space) { - sc = SkScaledBitmapSampler::kGray; - } else { - return return_false(cinfo, *bm, "jpeg colorspace"); - } - - SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, - sampleSize); - - bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); - // jpegs are always opauqe (i.e. have no per-pixel alpha) - bm->setIsOpaque(true); - - if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; - } - if (!this->allocPixelRef(bm, NULL)) { - return return_false(cinfo, *bm, "allocPixelRef"); - } - - SkAutoLockPixels alp(*bm); - if (!sampler.begin(bm, sc, this->getDitherImage())) { - return return_false(cinfo, *bm, "sampler.begin"); - } - - uint8_t* srcRow = (uint8_t*)srcStorage.alloc(cinfo.output_width * 4); - - // Possibly skip initial rows [sampler.srcY0] - if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { - return return_false(cinfo, *bm, "skip rows"); - } - - // now loop through scanlines until y == bm->height() - 1 - for (int y = 0;; y++) { - JSAMPLE* rowptr = (JSAMPLE*)srcRow; - int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); - if (0 == row_count) { - return return_false(cinfo, *bm, "read_scanlines"); - } - if (this->shouldCancelDecode()) { - return return_false(cinfo, *bm, "shouldCancelDecode"); - } - - sampler.next(srcRow); - if (bm->height() - 1 == y) { - // we're done - break; - } - - if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) { - return return_false(cinfo, *bm, "skip rows"); - } - } - - // we formally skip the rest, so we don't get a complaint from libjpeg - if (!skip_src_rows(&cinfo, srcRow, - cinfo.output_height - cinfo.output_scanline)) { - return return_false(cinfo, *bm, "skip rows"); - } - jpeg_finish_decompress(&cinfo); - -// SkDebugf("------------------- bm2 size %d [%d %d] %d\n", bm->getSize(), bm->width(), bm->height(), bm->config()); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkColorPriv.h" - -// taken from jcolor.c in libjpeg -#if 0 // 16bit - precise but slow - #define CYR 19595 // 0.299 - #define CYG 38470 // 0.587 - #define CYB 7471 // 0.114 - - #define CUR -11059 // -0.16874 - #define CUG -21709 // -0.33126 - #define CUB 32768 // 0.5 - - #define CVR 32768 // 0.5 - #define CVG -27439 // -0.41869 - #define CVB -5329 // -0.08131 - - #define CSHIFT 16 -#else // 8bit - fast, slightly less precise - #define CYR 77 // 0.299 - #define CYG 150 // 0.587 - #define CYB 29 // 0.114 - - #define CUR -43 // -0.16874 - #define CUG -85 // -0.33126 - #define CUB 128 // 0.5 - - #define CVR 128 // 0.5 - #define CVG -107 // -0.41869 - #define CVB -21 // -0.08131 - - #define CSHIFT 8 -#endif - -static void rgb2yuv_32(uint8_t dst[], SkPMColor c) { - int r = SkGetPackedR32(c); - int g = SkGetPackedG32(c); - int b = SkGetPackedB32(c); - - int y = ( CYR*r + CYG*g + CYB*b ) >> CSHIFT; - int u = ( CUR*r + CUG*g + CUB*b ) >> CSHIFT; - int v = ( CVR*r + CVG*g + CVB*b ) >> CSHIFT; - - dst[0] = SkToU8(y); - dst[1] = SkToU8(u + 128); - dst[2] = SkToU8(v + 128); -} - -static void rgb2yuv_4444(uint8_t dst[], U16CPU c) { - int r = SkGetPackedR4444(c); - int g = SkGetPackedG4444(c); - int b = SkGetPackedB4444(c); - - int y = ( CYR*r + CYG*g + CYB*b ) >> (CSHIFT - 4); - int u = ( CUR*r + CUG*g + CUB*b ) >> (CSHIFT - 4); - int v = ( CVR*r + CVG*g + CVB*b ) >> (CSHIFT - 4); - - dst[0] = SkToU8(y); - dst[1] = SkToU8(u + 128); - dst[2] = SkToU8(v + 128); -} - -static void rgb2yuv_16(uint8_t dst[], U16CPU c) { - int r = SkGetPackedR16(c); - int g = SkGetPackedG16(c); - int b = SkGetPackedB16(c); - - int y = ( 2*CYR*r + CYG*g + 2*CYB*b ) >> (CSHIFT - 2); - int u = ( 2*CUR*r + CUG*g + 2*CUB*b ) >> (CSHIFT - 2); - int v = ( 2*CVR*r + CVG*g + 2*CVB*b ) >> (CSHIFT - 2); - - dst[0] = SkToU8(y); - dst[1] = SkToU8(u + 128); - dst[2] = SkToU8(v + 128); -} - -/////////////////////////////////////////////////////////////////////////////// - -typedef void (*WriteScanline)(uint8_t* SK_RESTRICT dst, - const void* SK_RESTRICT src, int width, - const SkPMColor* SK_RESTRICT ctable); - -static void Write_32_YUV(uint8_t* SK_RESTRICT dst, - const void* SK_RESTRICT srcRow, int width, - const SkPMColor*) { - const uint32_t* SK_RESTRICT src = (const uint32_t*)srcRow; - while (--width >= 0) { -#ifdef WE_CONVERT_TO_YUV - rgb2yuv_32(dst, *src++); -#else - uint32_t c = *src++; - dst[0] = SkGetPackedR32(c); - dst[1] = SkGetPackedG32(c); - dst[2] = SkGetPackedB32(c); -#endif - dst += 3; - } -} - -static void Write_4444_YUV(uint8_t* SK_RESTRICT dst, - const void* SK_RESTRICT srcRow, int width, - const SkPMColor*) { - const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)srcRow; - while (--width >= 0) { -#ifdef WE_CONVERT_TO_YUV - rgb2yuv_4444(dst, *src++); -#else - SkPMColor16 c = *src++; - dst[0] = SkPacked4444ToR32(c); - dst[1] = SkPacked4444ToG32(c); - dst[2] = SkPacked4444ToB32(c); -#endif - dst += 3; - } -} - -static void Write_16_YUV(uint8_t* SK_RESTRICT dst, - const void* SK_RESTRICT srcRow, int width, - const SkPMColor*) { - const uint16_t* SK_RESTRICT src = (const uint16_t*)srcRow; - while (--width >= 0) { -#ifdef WE_CONVERT_TO_YUV - rgb2yuv_16(dst, *src++); -#else - uint16_t c = *src++; - dst[0] = SkPacked16ToR32(c); - dst[1] = SkPacked16ToG32(c); - dst[2] = SkPacked16ToB32(c); -#endif - dst += 3; - } -} - -static void Write_Index_YUV(uint8_t* SK_RESTRICT dst, - const void* SK_RESTRICT srcRow, int width, - const SkPMColor* SK_RESTRICT ctable) { - const uint8_t* SK_RESTRICT src = (const uint8_t*)srcRow; - while (--width >= 0) { -#ifdef WE_CONVERT_TO_YUV - rgb2yuv_32(dst, ctable[*src++]); -#else - uint32_t c = ctable[*src++]; - dst[0] = SkGetPackedR32(c); - dst[1] = SkGetPackedG32(c); - dst[2] = SkGetPackedB32(c); -#endif - dst += 3; - } -} - -static WriteScanline ChooseWriter(const SkBitmap& bm) { - switch (bm.config()) { - case SkBitmap::kARGB_8888_Config: - return Write_32_YUV; - case SkBitmap::kRGB_565_Config: - return Write_16_YUV; - case SkBitmap::kARGB_4444_Config: - return Write_4444_YUV; - case SkBitmap::kIndex8_Config: - return Write_Index_YUV; - default: - return NULL; - } -} - -struct sk_destination_mgr : jpeg_destination_mgr { - sk_destination_mgr(SkWStream* stream); - - SkWStream* fStream; - - enum { - kBufferSize = 1024 - }; - uint8_t fBuffer[kBufferSize]; -}; - -static void sk_init_destination(j_compress_ptr cinfo) { - sk_destination_mgr* dest = (sk_destination_mgr*)cinfo->dest; - - dest->next_output_byte = dest->fBuffer; - dest->free_in_buffer = sk_destination_mgr::kBufferSize; -} - -static boolean sk_empty_output_buffer(j_compress_ptr cinfo) { - sk_destination_mgr* dest = (sk_destination_mgr*)cinfo->dest; - -// if (!dest->fStream->write(dest->fBuffer, sk_destination_mgr::kBufferSize - dest->free_in_buffer)) - if (!dest->fStream->write(dest->fBuffer, sk_destination_mgr::kBufferSize)) { - ERREXIT(cinfo, JERR_FILE_WRITE); - return false; - } - - dest->next_output_byte = dest->fBuffer; - dest->free_in_buffer = sk_destination_mgr::kBufferSize; - return TRUE; -} - -static void sk_term_destination (j_compress_ptr cinfo) { - sk_destination_mgr* dest = (sk_destination_mgr*)cinfo->dest; - - size_t size = sk_destination_mgr::kBufferSize - dest->free_in_buffer; - if (size > 0) { - if (!dest->fStream->write(dest->fBuffer, size)) { - ERREXIT(cinfo, JERR_FILE_WRITE); - return; - } - } - dest->fStream->flush(); -} - -sk_destination_mgr::sk_destination_mgr(SkWStream* stream) - : fStream(stream) { - this->init_destination = sk_init_destination; - this->empty_output_buffer = sk_empty_output_buffer; - this->term_destination = sk_term_destination; -} - -class SkJPEGImageEncoder : public SkImageEncoder { -protected: - virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) { -#ifdef TIME_ENCODE - AutoTimeMillis atm("JPEG Encode"); -#endif - - const WriteScanline writer = ChooseWriter(bm); - if (NULL == writer) { - return false; - } - - SkAutoLockPixels alp(bm); - if (NULL == bm.getPixels()) { - return false; - } - - jpeg_compress_struct cinfo; - sk_error_mgr sk_err; - sk_destination_mgr sk_wstream(stream); - - // allocate these before set call setjmp - SkAutoMalloc oneRow; - SkAutoLockColors ctLocker; - - cinfo.err = jpeg_std_error(&sk_err); - sk_err.error_exit = sk_error_exit; - if (setjmp(sk_err.fJmpBuf)) { - return false; - } - jpeg_create_compress(&cinfo); - - cinfo.dest = &sk_wstream; - cinfo.image_width = bm.width(); - cinfo.image_height = bm.height(); - cinfo.input_components = 3; -#ifdef WE_CONVERT_TO_YUV - cinfo.in_color_space = JCS_YCbCr; -#else - cinfo.in_color_space = JCS_RGB; -#endif - cinfo.input_gamma = 1; - - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); - cinfo.dct_method = JDCT_IFAST; - - jpeg_start_compress(&cinfo, TRUE); - - const int width = bm.width(); - uint8_t* oneRowP = (uint8_t*)oneRow.alloc(width * 3); - - const SkPMColor* colors = ctLocker.lockColors(bm); - const void* srcRow = bm.getPixels(); - - while (cinfo.next_scanline < cinfo.image_height) { - JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ - - writer(oneRowP, srcRow, width, colors); - row_pointer[0] = oneRowP; - (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); - srcRow = (const void*)((const char*)srcRow + bm.rowBytes()); - } - - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - - return true; - } -}; - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkTRegistry.h" - -static SkImageDecoder* DFactory(SkStream* stream) { - static const char gHeader[] = { 0xFF, 0xD8, 0xFF }; - static const size_t HEADER_SIZE = sizeof(gHeader); - - char buffer[HEADER_SIZE]; - size_t len = stream->read(buffer, HEADER_SIZE); - - if (len != HEADER_SIZE) { - return NULL; // can't read enough - } - if (memcmp(buffer, gHeader, HEADER_SIZE)) { - return NULL; - } - return SkNEW(SkJPEGImageDecoder); -} - -static SkImageEncoder* EFactory(SkImageEncoder::Type t) { - return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; -} - -static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(DFactory); -static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(EFactory); - diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp deleted file mode 100644 index b616eee..0000000 --- a/src/images/SkImageDecoder_libpng.cpp +++ /dev/null @@ -1,799 +0,0 @@ -/* libs/graphics/images/SkImageDecoder_libpng.cpp -** -** Copyright 2006, 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 "SkImageDecoder.h" -#include "SkImageEncoder.h" -#include "SkColor.h" -#include "SkColorPriv.h" -#include "SkDither.h" -#include "SkMath.h" -#include "SkScaledBitmapSampler.h" -#include "SkStream.h" -#include "SkTemplates.h" -#include "SkUtils.h" - -extern "C" { -#include "png.h" -} - -class SkPNGImageDecoder : public SkImageDecoder { -public: - virtual Format getFormat() const { - return kPNG_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode); -}; - -#ifndef png_jmpbuf -# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) -#endif - -#define PNG_BYTES_TO_CHECK 4 - -/* Automatically clean up after throwing an exception */ -struct PNGAutoClean { - PNGAutoClean(png_structp p, png_infop i): png_ptr(p), info_ptr(i) {} - ~PNGAutoClean() { - png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); - } -private: - png_structp png_ptr; - png_infop info_ptr; -}; - -static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) { - SkStream* sk_stream = (SkStream*) png_ptr->io_ptr; - size_t bytes = sk_stream->read(data, length); - if (bytes != length) { - png_error(png_ptr, "Read Error!"); - } -} - -static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) { - SkImageDecoder::Peeker* peeker = - (SkImageDecoder::Peeker*)png_get_user_chunk_ptr(png_ptr); - // peek() returning true means continue decoding - return peeker->peek((const char*)chunk->name, chunk->data, chunk->size) ? - 1 : -1; -} - -static void sk_error_fn(png_structp png_ptr, png_const_charp msg) { -#if 0 - SkDebugf("------ png error %s\n", msg); -#endif - longjmp(png_jmpbuf(png_ptr), 1); -} - -static void skip_src_rows(png_structp png_ptr, uint8_t storage[], int count) { - for (int i = 0; i < count; i++) { - uint8_t* tmp = storage; - png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1); - } -} - -static bool pos_le(int value, int max) { - return value > 0 && value <= max; -} - -static bool substituteTranspColor(SkBitmap* bm, SkPMColor match) { - SkASSERT(bm->config() == SkBitmap::kARGB_8888_Config); - - bool reallyHasAlpha = false; - - for (int y = bm->height() - 1; y >= 0; --y) { - SkPMColor* p = bm->getAddr32(0, y); - for (int x = bm->width() - 1; x >= 0; --x) { - if (match == *p) { - *p = 0; - reallyHasAlpha = true; - } - p += 1; - } - } - return reallyHasAlpha; -} - -bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, - SkBitmap::Config prefConfig, Mode mode) { -// SkAutoTrace apr("SkPNGImageDecoder::onDecode"); - - /* Create and initialize the png_struct with the desired error handler - * functions. If you want to use the default stderr and longjump method, - * you can supply NULL for the last three parameters. We also supply the - * the compiler header file version, so that we know if the application - * was compiled with a compatible version of the library. */ - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, - NULL, sk_error_fn, NULL); - // png_voidp user_error_ptr, user_error_fn, user_warning_fn); - if (png_ptr == NULL) { - return false; - } - - /* Allocate/initialize the memory for image information. */ - png_infop info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); - return false; - } - - PNGAutoClean autoClean(png_ptr, info_ptr); - - /* Set error handling if you are using the setjmp/longjmp method (this is - * the normal method of doing things with libpng). REQUIRED unless you - * set up your own error handlers in the png_create_read_struct() earlier. - */ - if (setjmp(png_jmpbuf(png_ptr))) { - return false; - } - - /* If you are using replacement read functions, instead of calling - * png_init_io() here you would call: - */ - png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn); - /* where user_io_ptr is a structure you want available to the callbacks */ - /* If we have already read some of the signature */ -// png_set_sig_bytes(png_ptr, 0 /* sig_read */ ); - - // hookup our peeker so we can see any user-chunks the caller may be interested in - png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0); - if (this->getPeeker()) { - png_set_read_user_chunk_fn(png_ptr, (png_voidp)this->getPeeker(), sk_read_user_chunk); - } - - /* The call to png_read_info() gives us all of the information from the - * PNG file before the first IDAT (image data chunk). */ - png_read_info(png_ptr, info_ptr); - png_uint_32 origWidth, origHeight; - int bit_depth, color_type, interlace_type; - png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth, &color_type, - &interlace_type, int_p_NULL, int_p_NULL); - - /* tell libpng to strip 16 bit/color files down to 8 bits/color */ - if (bit_depth == 16) { - png_set_strip_16(png_ptr); - } - /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single - * byte into separate bytes (useful for paletted and grayscale images). */ - if (bit_depth < 8) { - png_set_packing(png_ptr); - } - /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { - png_set_gray_1_2_4_to_8(png_ptr); - } - - /* Make a grayscale image into RGB. */ - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - png_set_gray_to_rgb(png_ptr); - } - - SkBitmap::Config config; - bool hasAlpha = false; - bool doDither = this->getDitherImage(); - SkPMColor theTranspColor = 0; // 0 tells us not to try to match - - // check for sBIT chunk data, in case we should disable dithering because - // our data is not truely 8bits per component - if (doDither) { -#if 0 - SkDebugf("----- sBIT %d %d %d %d\n", info_ptr->sig_bit.red, - info_ptr->sig_bit.green, info_ptr->sig_bit.blue, - info_ptr->sig_bit.alpha); -#endif - // 0 seems to indicate no information available - if (pos_le(info_ptr->sig_bit.red, SK_R16_BITS) && - pos_le(info_ptr->sig_bit.green, SK_G16_BITS) && - pos_le(info_ptr->sig_bit.blue, SK_B16_BITS)) { - doDither = false; - } - } - - if (color_type == PNG_COLOR_TYPE_PALETTE) { - config = SkBitmap::kIndex8_Config; // defer sniffing for hasAlpha - } else { - png_color_16p transpColor = NULL; - int numTransp = 0; - - png_get_tRNS(png_ptr, info_ptr, NULL, &numTransp, &transpColor); - - bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); - - if (valid && numTransp == 1 && transpColor != NULL) { - /* Compute our transparent color, which we'll match against later. - We don't really handle 16bit components properly here, since we - do our compare *after* the values have been knocked down to 8bit - which means we will find more matches than we should. The real - fix seems to be to see the actual 16bit components, do the - compare, and then knock it down to 8bits ourselves. - */ - if (color_type & PNG_COLOR_MASK_COLOR) { - if (16 == bit_depth) { - theTranspColor = SkPackARGB32(0xFF, transpColor->red >> 8, - transpColor->green >> 8, transpColor->blue >> 8); - } else { - theTranspColor = SkPackARGB32(0xFF, transpColor->red, - transpColor->green, transpColor->blue); - } - } else { // gray - if (16 == bit_depth) { - theTranspColor = SkPackARGB32(0xFF, transpColor->gray >> 8, - transpColor->gray >> 8, transpColor->gray >> 8); - } else { - theTranspColor = SkPackARGB32(0xFF, transpColor->gray, - transpColor->gray, transpColor->gray); - } - } - } - - if (valid || - PNG_COLOR_TYPE_RGB_ALPHA == color_type || - PNG_COLOR_TYPE_GRAY_ALPHA == color_type) { - hasAlpha = true; - config = SkBitmap::kARGB_8888_Config; - } else { // we get to choose the config - config = prefConfig; - if (config == SkBitmap::kNo_Config) { - config = SkImageDecoder::GetDeviceConfig(); - } - if (config != SkBitmap::kRGB_565_Config && - config != SkBitmap::kARGB_4444_Config) { - config = SkBitmap::kARGB_8888_Config; - } - } - } - - if (!this->chooseFromOneChoice(config, origWidth, origHeight)) { - return false; - } - - const int sampleSize = this->getSampleSize(); - SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); - - decodedBitmap->setConfig(config, sampler.scaledWidth(), - sampler.scaledHeight(), 0); - if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; - } - - // from here down we are concerned with colortables and pixels - - // we track if we actually see a non-opaque pixels, since sometimes a PNG sets its colortype - // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we - // draw lots faster if we can flag the bitmap has being opaque - bool reallyHasAlpha = false; - - SkColorTable* colorTable = NULL; - - if (color_type == PNG_COLOR_TYPE_PALETTE) { - int num_palette; - png_colorp palette; - png_bytep trans; - int num_trans; - - png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); - - /* BUGGY IMAGE WORKAROUND - - We hit some images (e.g. fruit_.png) who contain bytes that are == colortable_count - which is a problem since we use the byte as an index. To work around this we grow - the colortable by 1 (if its < 256) and duplicate the last color into that slot. - */ - int colorCount = num_palette + (num_palette < 256); - - colorTable = SkNEW_ARGS(SkColorTable, (colorCount)); - - SkPMColor* colorPtr = colorTable->lockColors(); - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); - hasAlpha = (num_trans > 0); - } else { - num_trans = 0; - colorTable->setFlags(colorTable->getFlags() | SkColorTable::kColorsAreOpaque_Flag); - } - // check for bad images that might make us crash - if (num_trans > num_palette) { - num_trans = num_palette; - } - - int index = 0; - int transLessThanFF = 0; - - for (; index < num_trans; index++) { - transLessThanFF |= (int)*trans - 0xFF; - *colorPtr++ = SkPreMultiplyARGB(*trans++, palette->red, palette->green, palette->blue); - palette++; - } - reallyHasAlpha |= (transLessThanFF < 0); - - for (; index < num_palette; index++) { - *colorPtr++ = SkPackARGB32(0xFF, palette->red, palette->green, palette->blue); - palette++; - } - - // see BUGGY IMAGE WORKAROUND comment above - if (num_palette < 256) { - *colorPtr = colorPtr[-1]; - } - colorTable->unlockColors(true); - } - - SkAutoUnref aur(colorTable); - - if (!this->allocPixelRef(decodedBitmap, colorTable)) { - return false; - } - - SkAutoLockPixels alp(*decodedBitmap); - - /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ -// if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) -// ; // png_set_swap_alpha(png_ptr); - - /* swap bytes of 16 bit files to least significant byte first */ - // png_set_swap(png_ptr); - - /* Add filler (or alpha) byte (before/after each RGB triplet) */ - if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY) { - png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); - } - - /* Turn on interlace handling. REQUIRED if you are not using - * png_read_image(). To see how to handle interlacing passes, - * see the png_read_row() method below: - */ - const int number_passes = interlace_type != PNG_INTERLACE_NONE ? - png_set_interlace_handling(png_ptr) : 1; - - /* Optional call to gamma correct and add the background to the palette - * and update info structure. REQUIRED if you are expecting libpng to - * update the palette for you (ie you selected such a transform above). - */ - png_read_update_info(png_ptr, info_ptr); - - if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) { - for (int i = 0; i < number_passes; i++) { - for (png_uint_32 y = 0; y < origHeight; y++) { - uint8_t* bmRow = decodedBitmap->getAddr8(0, y); - png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); - } - } - } else { - SkScaledBitmapSampler::SrcConfig sc; - int srcBytesPerPixel = 4; - - if (SkBitmap::kIndex8_Config == config) { - sc = SkScaledBitmapSampler::kIndex; - srcBytesPerPixel = 1; - } else if (hasAlpha) { - sc = SkScaledBitmapSampler::kRGBA; - } else { - sc = SkScaledBitmapSampler::kRGBX; - } - - SkAutoMalloc storage(origWidth * srcBytesPerPixel); - const int height = decodedBitmap->height(); - - for (int i = 0; i < number_passes; i++) { - if (!sampler.begin(decodedBitmap, sc, doDither)) { - return false; - } - - uint8_t* srcRow = (uint8_t*)storage.get(); - skip_src_rows(png_ptr, srcRow, sampler.srcY0()); - - for (int y = 0; y < height; y++) { - uint8_t* tmp = srcRow; - png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1); - reallyHasAlpha |= sampler.next(srcRow); - if (y < height - 1) { - skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1); - } - } - - // skip the rest of the rows (if any) - png_uint_32 read = (height - 1) * sampler.srcDY() + - sampler.srcY0() + 1; - SkASSERT(read <= origHeight); - skip_src_rows(png_ptr, srcRow, origHeight - read); - } - - if (hasAlpha && !reallyHasAlpha) { -#if 0 - SkDEBUGF(("Image doesn't really have alpha [%d %d]\n", - origWidth, origHeight)); -#endif - } - } - - /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ - png_read_end(png_ptr, info_ptr); - - if (0 != theTranspColor) { - reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); - } - decodedBitmap->setIsOpaque(!reallyHasAlpha); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkColorPriv.h" -#include "SkUnPreMultiply.h" - -static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) { - SkWStream* sk_stream = (SkWStream*)png_ptr->io_ptr; - if (!sk_stream->write(data, len)) { - png_error(png_ptr, "sk_write_fn Error!"); - } -} - -typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src, - int width, char* SK_RESTRICT dst); - -static void transform_scanline_565(const char* SK_RESTRICT src, int width, - char* SK_RESTRICT dst) { - const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src; - for (int i = 0; i < width; i++) { - unsigned c = *srcP++; - *dst++ = SkPacked16ToR32(c); - *dst++ = SkPacked16ToG32(c); - *dst++ = SkPacked16ToB32(c); - } -} - -static void transform_scanline_888(const char* SK_RESTRICT src, int width, - char* SK_RESTRICT dst) { - const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; - for (int i = 0; i < width; i++) { - SkPMColor c = *srcP++; - *dst++ = SkGetPackedR32(c); - *dst++ = SkGetPackedG32(c); - *dst++ = SkGetPackedB32(c); - } -} - -static void transform_scanline_444(const char* SK_RESTRICT src, int width, - char* SK_RESTRICT dst) { - const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; - for (int i = 0; i < width; i++) { - SkPMColor16 c = *srcP++; - *dst++ = SkPacked4444ToR32(c); - *dst++ = SkPacked4444ToG32(c); - *dst++ = SkPacked4444ToB32(c); - } -} - -static void transform_scanline_8888(const char* SK_RESTRICT src, int width, - char* SK_RESTRICT dst) { - const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; - const SkUnPreMultiply::Scale* SK_RESTRICT table = - SkUnPreMultiply::GetScaleTable(); - - for (int i = 0; i < width; i++) { - SkPMColor c = *srcP++; - unsigned a = SkGetPackedA32(c); - unsigned r = SkGetPackedR32(c); - unsigned g = SkGetPackedG32(c); - unsigned b = SkGetPackedB32(c); - - if (0 != a && 255 != a) { - SkUnPreMultiply::Scale scale = table[a]; - r = SkUnPreMultiply::ApplyScale(scale, r); - g = SkUnPreMultiply::ApplyScale(scale, g); - b = SkUnPreMultiply::ApplyScale(scale, b); - } - *dst++ = r; - *dst++ = g; - *dst++ = b; - *dst++ = a; - } -} - -static void transform_scanline_4444(const char* SK_RESTRICT src, int width, - char* SK_RESTRICT dst) { - const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; - const SkUnPreMultiply::Scale* SK_RESTRICT table = - SkUnPreMultiply::GetScaleTable(); - - for (int i = 0; i < width; i++) { - SkPMColor16 c = *srcP++; - unsigned a = SkPacked4444ToA32(c); - unsigned r = SkPacked4444ToR32(c); - unsigned g = SkPacked4444ToG32(c); - unsigned b = SkPacked4444ToB32(c); - - if (0 != a && 255 != a) { - SkUnPreMultiply::Scale scale = table[a]; - r = SkUnPreMultiply::ApplyScale(scale, r); - g = SkUnPreMultiply::ApplyScale(scale, g); - b = SkUnPreMultiply::ApplyScale(scale, b); - } - *dst++ = r; - *dst++ = g; - *dst++ = b; - *dst++ = a; - } -} - -static void transform_scanline_index8(const char* SK_RESTRICT src, int width, - char* SK_RESTRICT dst) { - memcpy(dst, src, width); -} - -static transform_scanline_proc choose_proc(SkBitmap::Config config, - bool hasAlpha) { - // we don't care about search on alpha if we're kIndex8, since only the - // colortable packing cares about that distinction, not the pixels - if (SkBitmap::kIndex8_Config == config) { - hasAlpha = false; // we store false in the table entries for kIndex8 - } - - static const struct { - SkBitmap::Config fConfig; - bool fHasAlpha; - transform_scanline_proc fProc; - } gMap[] = { - { SkBitmap::kRGB_565_Config, false, transform_scanline_565 }, - { SkBitmap::kARGB_8888_Config, false, transform_scanline_888 }, - { SkBitmap::kARGB_8888_Config, true, transform_scanline_8888 }, - { SkBitmap::kARGB_4444_Config, false, transform_scanline_444 }, - { SkBitmap::kARGB_4444_Config, true, transform_scanline_4444 }, - { SkBitmap::kIndex8_Config, false, transform_scanline_index8 }, - }; - - for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) { - if (gMap[i].fConfig == config && gMap[i].fHasAlpha == hasAlpha) { - return gMap[i].fProc; - } - } - sk_throw(); - return NULL; -} - -// return the minimum legal bitdepth (by png standards) for this many colortable -// entries. SkBitmap always stores in 8bits per pixel, but for colorcount <= 16, -// we can use fewer bits per in png -static int computeBitDepth(int colorCount) { -#if 0 - int bits = SkNextLog2(colorCount); - SkASSERT(bits >= 1 && bits <= 8); - // now we need bits itself to be a power of 2 (e.g. 1, 2, 4, 8) - return SkNextPow2(bits); -#else - // for the moment, we don't know how to pack bitdepth < 8 - return 8; -#endif -} - -/* Pack palette[] with the corresponding colors, and if hasAlpha is true, also - pack trans[] and return the number of trans[] entries written. If hasAlpha - is false, the return value will always be 0. - - Note: this routine takes care of unpremultiplying the RGB values when we - have alpha in the colortable, since png doesn't support premul colors -*/ -static inline int pack_palette(SkColorTable* ctable, - png_color* SK_RESTRICT palette, - png_byte* SK_RESTRICT trans, bool hasAlpha) { - SkAutoLockColors alc(ctable); - const SkPMColor* SK_RESTRICT colors = alc.colors(); - const int ctCount = ctable->count(); - int i, num_trans = 0; - - if (hasAlpha) { - /* first see if we have some number of fully opaque at the end of the - ctable. PNG allows num_trans < num_palette, but all of the trans - entries must come first in the palette. If I was smarter, I'd - reorder the indices and ctable so that all non-opaque colors came - first in the palette. But, since that would slow down the encode, - I'm leaving the indices and ctable order as is, and just looking - at the tail of the ctable for opaqueness. - */ - num_trans = ctCount; - for (i = ctCount - 1; i >= 0; --i) { - if (SkGetPackedA32(colors[i]) != 0xFF) { - break; - } - num_trans -= 1; - } - - const SkUnPreMultiply::Scale* SK_RESTRICT table = - SkUnPreMultiply::GetScaleTable(); - - for (i = 0; i < num_trans; i++) { - const SkPMColor c = *colors++; - const unsigned a = SkGetPackedA32(c); - const SkUnPreMultiply::Scale s = table[a]; - trans[i] = a; - palette[i].red = SkUnPreMultiply::ApplyScale(s, SkGetPackedR32(c)); - palette[i].green = SkUnPreMultiply::ApplyScale(s,SkGetPackedG32(c)); - palette[i].blue = SkUnPreMultiply::ApplyScale(s, SkGetPackedB32(c)); - } - // now fall out of this if-block to use common code for the trailing - // opaque entries - } - - // these (remaining) entries are opaque - for (i = num_trans; i < ctCount; i++) { - SkPMColor c = *colors++; - palette[i].red = SkGetPackedR32(c); - palette[i].green = SkGetPackedG32(c); - palette[i].blue = SkGetPackedB32(c); - } - return num_trans; -} - -class SkPNGImageEncoder : public SkImageEncoder { -protected: - virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); -}; - -bool SkPNGImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap, - int /*quality*/) { - SkBitmap::Config config = bitmap.getConfig(); - - const bool hasAlpha = !bitmap.isOpaque(); - int colorType = PNG_COLOR_MASK_COLOR; - int bitDepth = 8; // default for color - png_color_8 sig_bit; - - switch (config) { - case SkBitmap::kIndex8_Config: - colorType |= PNG_COLOR_MASK_PALETTE; - // fall through to the ARGB_8888 case - case SkBitmap::kARGB_8888_Config: - sig_bit.red = 8; - sig_bit.green = 8; - sig_bit.blue = 8; - sig_bit.alpha = 8; - break; - case SkBitmap::kARGB_4444_Config: - sig_bit.red = 4; - sig_bit.green = 4; - sig_bit.blue = 4; - sig_bit.alpha = 4; - break; - case SkBitmap::kRGB_565_Config: - sig_bit.red = 5; - sig_bit.green = 6; - sig_bit.blue = 5; - sig_bit.alpha = 0; - break; - default: - return false; - } - - if (hasAlpha) { - // don't specify alpha if we're a palette, even if our ctable has alpha - if (!(colorType & PNG_COLOR_MASK_PALETTE)) { - colorType |= PNG_COLOR_MASK_ALPHA; - } - } else { - sig_bit.alpha = 0; - } - - SkAutoLockPixels alp(bitmap); - // readyToDraw checks for pixels (and colortable if that is required) - if (!bitmap.readyToDraw()) { - return false; - } - - // we must do this after we have locked the pixels - SkColorTable* ctable = bitmap.getColorTable(); - if (NULL != ctable) { - if (ctable->count() == 0) { - return false; - } - // check if we can store in fewer than 8 bits - bitDepth = computeBitDepth(ctable->count()); - } - - png_structp png_ptr; - png_infop info_ptr; - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, sk_error_fn, - NULL); - if (NULL == png_ptr) { - return false; - } - - info_ptr = png_create_info_struct(png_ptr); - if (NULL == info_ptr) { - png_destroy_write_struct(&png_ptr, png_infopp_NULL); - return false; - } - - /* Set error handling. REQUIRED if you aren't supplying your own - * error handling functions in the png_create_write_struct() call. - */ - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - return false; - } - - png_set_write_fn(png_ptr, (void*)stream, sk_write_fn, png_flush_ptr_NULL); - - /* Set the image information here. Width and height are up to 2^31, - * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on - * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, - * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, - * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or - * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST - * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED - */ - - png_set_IHDR(png_ptr, info_ptr, bitmap.width(), bitmap.height(), - bitDepth, colorType, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, - PNG_FILTER_TYPE_BASE); - -#if 0 // need to support this some day - /* set the palette if there is one. REQUIRED for indexed-color images */ - palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH - * png_sizeof (png_color)); - /* ... set palette colors ... */ - png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); - /* You must not free palette here, because png_set_PLTE only makes a link to - the palette that you malloced. Wait until you are about to destroy - the png structure. */ -#endif - - png_set_sBIT(png_ptr, info_ptr, &sig_bit); - png_write_info(png_ptr, info_ptr); - - const char* srcImage = (const char*)bitmap.getPixels(); - SkAutoSMalloc<1024> rowStorage(bitmap.width() << 2); - char* storage = (char*)rowStorage.get(); - transform_scanline_proc proc = choose_proc(config, hasAlpha); - - for (int y = 0; y < bitmap.height(); y++) { - png_bytep row_ptr = (png_bytep)storage; - proc(srcImage, bitmap.width(), storage); - png_write_rows(png_ptr, &row_ptr, 1); - srcImage += bitmap.rowBytes(); - } - - png_write_end(png_ptr, info_ptr); - - /* clean up after the write, and free any memory allocated */ - png_destroy_write_struct(&png_ptr, &info_ptr); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkTRegistry.h" - -static SkImageDecoder* DFactory(SkStream* stream) { - char buf[PNG_BYTES_TO_CHECK]; - if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK && - !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) { - return SkNEW(SkPNGImageDecoder); - } - return NULL; -} - -static SkImageEncoder* EFactory(SkImageEncoder::Type t) { - return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; -} - -static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(EFactory); -static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(DFactory); diff --git a/src/images/SkImageDecoder_libpvjpeg.cpp b/src/images/SkImageDecoder_libpvjpeg.cpp deleted file mode 100644 index 9177741..0000000 --- a/src/images/SkImageDecoder_libpvjpeg.cpp +++ /dev/null @@ -1,206 +0,0 @@ -#include "SkImageDecoder.h" -#include "SkColor.h" -#include "SkColorPriv.h" -#include "SkDither.h" -#include "SkMath.h" -#include "SkStream.h" -#include "SkTemplates.h" -#include "SkUtils.h" - -extern void ValidateHeap(); - -class SkPVJPEGImageDecoder : public SkImageDecoder { -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode); - -private: - enum { - STORAGE_SIZE = 8 * 1024 - }; - char fStorage[STORAGE_SIZE]; -}; - -SkImageDecoder* SkImageDecoder_PVJPEG_Factory(SkStream* stream) -{ - return SkNEW(SkPVJPEGImageDecoder); -} - -#include "pvjpgdecoderinterface.h" -#include "pvjpgdecoder_factory.h" - -class AutoPVDelete { -public: - AutoPVDelete(PVJpgDecoderInterface* codec) : fCodec(codec) {} - ~AutoPVDelete() { - fCodec->Reset(); - PVJpgDecoderFactory::DeletePVJpgDecoder(fCodec); - } -private: - PVJpgDecoderInterface* fCodec; -}; - -class MyObserver : public MPVJpegDecObserver { -public: - MyObserver() : fCount(0) {} - ~MyObserver() { - if (fCount != 0) { - SkDebugf("--- pvjpeg left %d allocations\n", fCount); - } - } - - virtual void allocateBuffer(uint8* &buffer, int32 buffersize) { - ++fCount; - // we double the allocation to work around bug when height is odd - buffer = (uint8*)sk_malloc_throw(buffersize << 1); - SkDebugf("--- pvjpeg alloc [%d] %d addr=%p\n", fCount, buffersize, buffer); - } - - virtual void deallocateBuffer(uint8 *buffer) { - SkDebugf("--- pvjpeg free [%d] addr=%p\n", fCount, buffer); - --fCount; - sk_free(buffer); - } - -private: - int fCount; -}; - -static void check_status(TPvJpgDecStatus status) { - if (TPVJPGDEC_SUCCESS != status) { - SkDEBUGF(("--- pvjpeg status %d\n", status)); - } -} - -static bool getFrame(PVJpgDecoderInterface* codec, SkBitmap* bitmap, - SkBitmap::Config prefConfig, SkImageDecoder::Mode mode) { - TPvJpgDecInfo info; - TPvJpgDecStatus status = codec->GetInfo(&info); - if (status != TPVJPGDEC_SUCCESS) - return false; - - int width = info.iWidth[0]; - int height = info.iHeight[0]; - - bitmap->setConfig(SkBitmap::kRGB_565_Config, width, height); - bitmap->setIsOpaque(true); - - if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return true; - } - - SkASSERT(info.iNumComponent == 3); - - TPvJpgDecOutputFmt format; - format.iColorFormat = TPV_COLORFMT_RGB16; - format.iCropped.topLeftX = 0; - format.iCropped.topLeftY = 0; - format.iCropped.bottomRightX = width - 1; - format.iCropped.bottomRightY = height - 1; - format.iOutputPitch = bitmap->rowBytes() >> 1; - status = codec->SetOutput(&format); - if (status != TPVJPGDEC_SUCCESS) { - SkDebugf("--- PV SetOutput failed %d\n", status); - return false; - } - - TPvJpgDecFrame frame; - uint8* ptrs[3]; - int32 widths[3], heights[3]; - bzero(ptrs, sizeof(ptrs)); - frame.ptr = ptrs; - frame.iWidth = widths; - frame.iHeight = heights; - - status = codec->GetFrame(&frame); - if (status != TPVJPGDEC_SUCCESS) { - SkDebugf("--- PV GetFrame failed %d\n", status); - return false; - } - - bitmap->allocPixels(); - memcpy(bitmap->getPixels(), ptrs[0], bitmap->getSize()); - return true; -} - -class OsclCleanupper { -public: - OsclCleanupper() { - OsclBase::Init(); - OsclErrorTrap::Init(); - OsclMem::Init(); - } - ~OsclCleanupper() { - OsclMem::Cleanup(); - OsclErrorTrap::Cleanup(); - OsclBase::Cleanup(); - } -}; - -bool SkPVJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, - SkBitmap::Config prefConfig, Mode mode) -{ - // do I need this guy? - OsclCleanupper oc; - - PVJpgDecoderInterface* codec = PVJpgDecoderFactory::CreatePVJpgDecoder(); - TPvJpgDecStatus status = codec->Init(); - check_status(status); - - MyObserver observer; // must create before autopvdelete - AutoPVDelete ad(codec); - - status = codec->SetObserver(&observer); - check_status(status); - - char* storage = fStorage; - int32 bytesInStorage = 0; - for (;;) - { - int32 bytesRead = stream->read(storage + bytesInStorage, - STORAGE_SIZE - bytesInStorage); - if (bytesRead <= 0) { - SkDEBUGF(("SkPVJPEGImageDecoder: stream read returned %d\n", bytesRead)); - return false; - } - - // update bytesInStorage to account for the read() - bytesInStorage += bytesRead; - SkASSERT(bytesInStorage <= STORAGE_SIZE); - - // now call Decode to eat some of the bytes - int32 consumed = bytesInStorage; - status = codec->Decode((uint8*)storage, &consumed); - - SkASSERT(bytesInStorage >= consumed); - bytesInStorage -= consumed; - // now bytesInStorage is the remaining unread bytes - if (bytesInStorage > 0) { // slide the leftovers to the beginning - SkASSERT(storage == fStorage); - SkASSERT(consumed >= 0 && bytesInStorage >= 0); - SkASSERT((size_t)(consumed + bytesInStorage) <= sizeof(fStorage)); - SkASSERT(sizeof(fStorage) == STORAGE_SIZE); - // SkDebugf("-- memmov srcOffset=%d, numBytes=%d\n", consumed, bytesInStorage); - memmove(storage, storage + consumed, bytesInStorage); - } - - switch (status) { - case TPVJPGDEC_SUCCESS: - SkDEBUGF(("SkPVJPEGImageDecoder::Decode returned success?\n");) - return false; - case TPVJPGDEC_FRAME_READY: - case TPVJPGDEC_DONE: - return getFrame(codec, decodedBitmap, prefConfig, mode); - case TPVJPGDEC_FAIL: - case TPVJPGDEC_INVALID_MEMORY: - case TPVJPGDEC_INVALID_PARAMS: - case TPVJPGDEC_NO_IMAGE_DATA: - SkDEBUGF(("SkPVJPEGImageDecoder: failed to decode err=%d\n", status);) - return false; - case TPVJPGDEC_WAITING_FOR_INPUT: - break; // loop around and eat more from the stream - } - } - return false; -} - diff --git a/src/images/SkImageDecoder_wbmp.cpp b/src/images/SkImageDecoder_wbmp.cpp deleted file mode 100644 index ac242ea..0000000 --- a/src/images/SkImageDecoder_wbmp.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/** -** Copyright 2006, 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 "SkImageDecoder.h" -#include "SkColor.h" -#include "SkColorPriv.h" -#include "SkMath.h" -#include "SkStream.h" -#include "SkTemplates.h" -#include "SkUtils.h" - -class SkWBMPImageDecoder : public SkImageDecoder { -public: - virtual Format getFormat() const { - return kWBMP_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode); -}; - -static bool read_byte(SkStream* stream, uint8_t* data) -{ - return stream->read(data, 1) == 1; -} - -static bool read_mbf(SkStream* stream, int* value) -{ - int n = 0; - uint8_t data; - do { - if (!read_byte(stream, &data)) { - return false; - } - n = (n << 7) | (data & 0x7F); - } while (data & 0x80); - - *value = n; - return true; -} - -struct wbmp_head { - int fWidth; - int fHeight; - - bool init(SkStream* stream) - { - uint8_t data; - - if (!read_byte(stream, &data) || data != 0) { // unknown type - return false; - } - if (!read_byte(stream, &data) || (data & 0x9F)) { // skip fixed header - return false; - } - if (!read_mbf(stream, &fWidth) || (unsigned)fWidth > 0xFFFF) { - return false; - } - if (!read_mbf(stream, &fHeight) || (unsigned)fHeight > 0xFFFF) { - return false; - } - return fWidth != 0 && fHeight != 0; - } -}; - -static void expand_bits_to_bytes(uint8_t dst[], const uint8_t src[], int bits) -{ - int bytes = bits >> 3; - - for (int i = 0; i < bytes; i++) { - unsigned mask = *src++; - dst[0] = (mask >> 7) & 1; - dst[1] = (mask >> 6) & 1; - dst[2] = (mask >> 5) & 1; - dst[3] = (mask >> 4) & 1; - dst[4] = (mask >> 3) & 1; - dst[5] = (mask >> 2) & 1; - dst[6] = (mask >> 1) & 1; - dst[7] = (mask >> 0) & 1; - dst += 8; - } - - bits &= 7; - if (bits > 0) { - unsigned mask = *src; - do { - *dst++ = (mask >> 7) & 1;; - mask <<= 1; - } while (--bits != 0); - } -} - -#define SkAlign8(x) (((x) + 7) & ~7) - -bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, - SkBitmap::Config prefConfig, Mode mode) -{ - wbmp_head head; - - if (!head.init(stream)) { - return false; - } - - int width = head.fWidth; - int height = head.fHeight; - - // assign these directly, in case we return kDimensions_Result - decodedBitmap->setConfig(SkBitmap::kIndex8_Config, width, height); - decodedBitmap->setIsOpaque(true); - - if (SkImageDecoder::kDecodeBounds_Mode == mode) - return true; - - const SkPMColor colors[] = { SK_ColorBLACK, SK_ColorWHITE }; - SkColorTable* ct = SkNEW_ARGS(SkColorTable, (colors, 2)); - SkAutoUnref aur(ct); - - if (!this->allocPixelRef(decodedBitmap, ct)) { - return false; - } - - SkAutoLockPixels alp(*decodedBitmap); - - uint8_t* dst = decodedBitmap->getAddr8(0, 0); - // store the 1-bit valuess at the end of our pixels, so we won't stomp - // on them before we're read them. Just trying to avoid a temp allocation - size_t srcRB = SkAlign8(width) >> 3; - size_t srcSize = height * srcRB; - uint8_t* src = dst + decodedBitmap->getSize() - srcSize; - if (stream->read(src, srcSize) != srcSize) { - return false; - } - - for (int y = 0; y < height; y++) - { - expand_bits_to_bytes(dst, src, width); - dst += decodedBitmap->rowBytes(); - src += srcRB; - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkTRegistry.h" - -static SkImageDecoder* Factory(SkStream* stream) { - wbmp_head head; - - if (head.init(stream)) { - return SkNEW(SkWBMPImageDecoder); - } - return NULL; -} - -static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory); - diff --git a/src/images/SkImageEncoder.cpp b/src/images/SkImageEncoder.cpp deleted file mode 100644 index d359905..0000000 --- a/src/images/SkImageEncoder.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2009, 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 "SkImageEncoder.h" -#include "SkBitmap.h" -#include "SkStream.h" -#include "SkTemplates.h" - -SkImageEncoder::~SkImageEncoder() {} - -bool SkImageEncoder::encodeStream(SkWStream* stream, const SkBitmap& bm, - int quality) { - quality = SkMin32(100, SkMax32(0, quality)); - return this->onEncode(stream, bm, quality); -} - -bool SkImageEncoder::encodeFile(const char file[], const SkBitmap& bm, - int quality) { - quality = SkMin32(100, SkMax32(0, quality)); - SkFILEWStream stream(file); - return this->onEncode(&stream, bm, quality); -} - -bool SkImageEncoder::EncodeFile(const char file[], const SkBitmap& bm, Type t, - int quality) { - SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t)); - return enc.get() && enc.get()->encodeFile(file, bm, quality); -} - -bool SkImageEncoder::EncodeStream(SkWStream* stream, const SkBitmap& bm, Type t, - int quality) { - SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t)); - return enc.get() && enc.get()->encodeStream(stream, bm, quality); -} - diff --git a/src/images/SkImageEncoder_Factory.cpp b/src/images/SkImageEncoder_Factory.cpp deleted file mode 100644 index d673167..0000000 --- a/src/images/SkImageEncoder_Factory.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2009, 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 "SkImageEncoder.h" -#include "SkTRegistry.h" - -typedef SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> EncodeReg; - -template EncodeReg* EncodeReg::gHead; - -SkImageEncoder* SkImageEncoder::Create(Type t) { - const EncodeReg* curr = EncodeReg::Head(); - while (curr) { - SkImageEncoder* codec = curr->factory()(t); - if (codec) { - return codec; - } - curr = curr->next(); - } - return NULL; -} - diff --git a/src/images/SkImageRef.cpp b/src/images/SkImageRef.cpp deleted file mode 100644 index 90c37b6..0000000 --- a/src/images/SkImageRef.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "SkImageRef.h" -#include "SkBitmap.h" -#include "SkFlattenable.h" -#include "SkImageDecoder.h" -#include "SkStream.h" -#include "SkTemplates.h" -#include "SkThread.h" - -// can't be static, as SkImageRef_Pool needs to see it -SkMutex gImageRefMutex; - -/////////////////////////////////////////////////////////////////////////////// - -SkImageRef::SkImageRef(SkStream* stream, SkBitmap::Config config, - int sampleSize) - : SkPixelRef(&gImageRefMutex), fErrorInDecoding(false) { - SkASSERT(stream); - SkASSERT(1 == stream->getRefCnt()); - - fStream = stream; - fConfig = config; - fSampleSize = sampleSize; - fPrev = fNext = NULL; - -#ifdef DUMP_IMAGEREF_LIFECYCLE - SkDebugf("add ImageRef %p [%d] data=%d\n", - this, config, (int)stream->getLength()); -#endif -} - -SkImageRef::~SkImageRef() { - SkASSERT(&gImageRefMutex == this->mutex()); - -#ifdef DUMP_IMAGEREF_LIFECYCLE - SkDebugf("delete ImageRef %p [%d] data=%d\n", - this, fConfig, (int)fStream->getLength()); -#endif - - delete fStream; -} - -bool SkImageRef::getInfo(SkBitmap* bitmap) { - SkAutoMutexAcquire ac(gImageRefMutex); - - if (!this->prepareBitmap(SkImageDecoder::kDecodeBounds_Mode)) { - return false; - } - - SkASSERT(SkBitmap::kNo_Config != fBitmap.config()); - if (bitmap) { - bitmap->setConfig(fBitmap.config(), fBitmap.width(), fBitmap.height()); - } - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -bool SkImageRef::onDecode(SkImageDecoder* codec, SkStream* stream, - SkBitmap* bitmap, SkBitmap::Config config, - SkImageDecoder::Mode mode) { - return codec->decode(stream, bitmap, config, mode); -} - -bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) { - SkASSERT(&gImageRefMutex == this->mutex()); - - if (fErrorInDecoding) { - return false; - } - - /* As soon as we really know our config, we record it, so that on - subsequent calls to the codec, we are sure we will always get the same - result. - */ - if (SkBitmap::kNo_Config != fBitmap.config()) { - fConfig = fBitmap.config(); - } - - if (NULL != fBitmap.getPixels() || - (SkBitmap::kNo_Config != fBitmap.config() && - SkImageDecoder::kDecodeBounds_Mode == mode)) { - return true; - } - - SkASSERT(fBitmap.getPixels() == NULL); - - fStream->rewind(); - - SkImageDecoder* codec = SkImageDecoder::Factory(fStream); - if (codec) { - SkAutoTDelete<SkImageDecoder> ad(codec); - - codec->setSampleSize(fSampleSize); - if (this->onDecode(codec, fStream, &fBitmap, fConfig, mode)) { - return true; - } - } - -#ifdef DUMP_IMAGEREF_LIFECYCLE - if (NULL == codec) { - SkDebugf("--- ImageRef: <%s> failed to find codec\n", this->getURI()); - } else { - SkDebugf("--- ImageRef: <%s> failed in codec for %d mode\n", - this->getURI(), mode); - } -#endif - fErrorInDecoding = true; - fBitmap.reset(); - return false; -} - -void* SkImageRef::onLockPixels(SkColorTable** ct) { - SkASSERT(&gImageRefMutex == this->mutex()); - - if (NULL == fBitmap.getPixels()) { - (void)this->prepareBitmap(SkImageDecoder::kDecodePixels_Mode); - } - - if (ct) { - *ct = fBitmap.getColorTable(); - } - return fBitmap.getPixels(); -} - -void SkImageRef::onUnlockPixels() { - // we're already have the mutex locked - SkASSERT(&gImageRefMutex == this->mutex()); -} - -size_t SkImageRef::ramUsed() const { - size_t size = 0; - - if (fBitmap.getPixels()) { - size = fBitmap.getSize(); - if (fBitmap.getColorTable()) { - size += fBitmap.getColorTable()->count() * sizeof(SkPMColor); - } - } - return size; -} - -/////////////////////////////////////////////////////////////////////////////// - -SkImageRef::SkImageRef(SkFlattenableReadBuffer& buffer) - : INHERITED(buffer, &gImageRefMutex), fErrorInDecoding(false) { - fConfig = (SkBitmap::Config)buffer.readU8(); - fSampleSize = buffer.readU8(); - size_t length = buffer.readU32(); - fStream = SkNEW_ARGS(SkMemoryStream, (length)); - buffer.read((void*)fStream->getMemoryBase(), length); - - fPrev = fNext = NULL; -} - -void SkImageRef::flatten(SkFlattenableWriteBuffer& buffer) const { - this->INHERITED::flatten(buffer); - - buffer.write8(fConfig); - buffer.write8(fSampleSize); - size_t length = fStream->getLength(); - buffer.write32(length); - fStream->rewind(); - buffer.readFromStream(fStream, length); -} - diff --git a/src/images/SkImageRefPool.cpp b/src/images/SkImageRefPool.cpp deleted file mode 100644 index e322507..0000000 --- a/src/images/SkImageRefPool.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "SkImageRefPool.h" -#include "SkImageRef.h" -#include "SkThread.h" - -SkImageRefPool::SkImageRefPool() { - fRAMBudget = 0; // means no explicit limit - fRAMUsed = 0; - fCount = 0; - fHead = fTail = NULL; -} - -SkImageRefPool::~SkImageRefPool() { - // SkASSERT(NULL == fHead); -} - -void SkImageRefPool::setRAMBudget(size_t size) { - if (fRAMBudget != size) { - fRAMBudget = size; - this->purgeIfNeeded(); - } -} - -void SkImageRefPool::justAddedPixels(SkImageRef* ref) { -#ifdef DUMP_IMAGEREF_LIFECYCLE - SkDebugf("=== ImagePool: add pixels %s [%d %d %d] bytes=%d heap=%d\n", - ref->getURI(), - ref->fBitmap.width(), ref->fBitmap.height(), - ref->fBitmap.bytesPerPixel(), - ref->fBitmap.getSize(), (int)fRAMUsed); -#endif - fRAMUsed += ref->ramUsed(); - this->purgeIfNeeded(); -} - -void SkImageRefPool::canLosePixels(SkImageRef* ref) { - // the refs near fHead have recently been released (used) - // if we purge, we purge from the tail - this->detach(ref); - this->addToHead(ref); - this->purgeIfNeeded(); -} - -void SkImageRefPool::purgeIfNeeded() { - // do nothing if we have a zero-budget (i.e. unlimited) - if (fRAMBudget != 0) { - this->setRAMUsed(fRAMBudget); - } -} - -void SkImageRefPool::setRAMUsed(size_t limit) { - SkImageRef* ref = fTail; - - while (NULL != ref && fRAMUsed > limit) { - // only purge it if its pixels are unlocked - if (0 == ref->getLockCount() && ref->fBitmap.getPixels()) { - size_t size = ref->ramUsed(); - SkASSERT(size <= fRAMUsed); - fRAMUsed -= size; - -#ifdef DUMP_IMAGEREF_LIFECYCLE - SkDebugf("=== ImagePool: purge %s [%d %d %d] bytes=%d heap=%d\n", - ref->getURI(), - ref->fBitmap.width(), ref->fBitmap.height(), - ref->fBitmap.bytesPerPixel(), - (int)size, (int)fRAMUsed); -#endif - - // remember the bitmap config (don't call reset), - // just clear the pixel memory - ref->fBitmap.setPixels(NULL); - SkASSERT(NULL == ref->fBitmap.getPixels()); - } - ref = ref->fPrev; - } -} - -/////////////////////////////////////////////////////////////////////////////// - -void SkImageRefPool::addToHead(SkImageRef* ref) { - ref->fNext = fHead; - ref->fPrev = NULL; - - if (fHead) { - SkASSERT(NULL == fHead->fPrev); - fHead->fPrev = ref; - } - fHead = ref; - - if (NULL == fTail) { - fTail = ref; - } - fCount += 1; - SkASSERT(computeCount() == fCount); - - fRAMUsed += ref->ramUsed(); -} - -void SkImageRefPool::addToTail(SkImageRef* ref) { - ref->fNext = NULL; - ref->fPrev = fTail; - - if (fTail) { - SkASSERT(NULL == fTail->fNext); - fTail->fNext = ref; - } - fTail = ref; - - if (NULL == fHead) { - fHead = ref; - } - fCount += 1; - SkASSERT(computeCount() == fCount); - - fRAMUsed += ref->ramUsed(); -} - -void SkImageRefPool::detach(SkImageRef* ref) { - SkASSERT(fCount > 0); - - if (fHead == ref) { - fHead = ref->fNext; - } - if (fTail == ref) { - fTail = ref->fPrev; - } - if (ref->fPrev) { - ref->fPrev->fNext = ref->fNext; - } - if (ref->fNext) { - ref->fNext->fPrev = ref->fPrev; - } - - ref->fNext = ref->fPrev = NULL; - - fCount -= 1; - SkASSERT(computeCount() == fCount); - - SkASSERT(fRAMUsed >= ref->ramUsed()); - fRAMUsed -= ref->ramUsed(); -} - -int SkImageRefPool::computeCount() const { - SkImageRef* ref = fHead; - int count = 0; - - while (ref != NULL) { - count += 1; - ref = ref->fNext; - } - -#ifdef SK_DEBUG - ref = fTail; - int count2 = 0; - - while (ref != NULL) { - count2 += 1; - ref = ref->fPrev; - } - SkASSERT(count2 == count); -#endif - - return count; -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkStream.h" - -void SkImageRefPool::dump() const { -#if defined(SK_DEBUG) || defined(DUMP_IMAGEREF_LIFECYCLE) - SkDebugf("ImagePool dump: bugdet: %d used: %d count: %d\n", - (int)fRAMBudget, (int)fRAMUsed, fCount); - - SkImageRef* ref = fHead; - - while (ref != NULL) { - SkDebugf(" [%3d %3d %d] ram=%d data=%d locks=%d %s\n", ref->fBitmap.width(), - ref->fBitmap.height(), ref->fBitmap.config(), - ref->ramUsed(), (int)ref->fStream->getLength(), - ref->getLockCount(), ref->getURI()); - - ref = ref->fNext; - } -#endif -} - diff --git a/src/images/SkImageRefPool.h b/src/images/SkImageRefPool.h deleted file mode 100644 index b2eb7b3..0000000 --- a/src/images/SkImageRefPool.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef SkImageRefPool_DEFINED -#define SkImageRefPool_DEFINED - -#include "SkTypes.h" - -class SkImageRef; -class SkImageRef_GlobalPool; - -class SkImageRefPool { -public: - SkImageRefPool(); - ~SkImageRefPool(); - - size_t getRAMBudget() const { return fRAMBudget; } - void setRAMBudget(size_t); - - size_t getRAMUsed() const { return fRAMUsed; } - void setRAMUsed(size_t limit); - - void addToHead(SkImageRef*); - void addToTail(SkImageRef*); - void detach(SkImageRef*); - - void dump() const; - -private: - size_t fRAMBudget; - size_t fRAMUsed; - - int fCount; - SkImageRef* fHead, *fTail; - - int computeCount() const; - - friend class SkImageRef_GlobalPool; - - void justAddedPixels(SkImageRef*); - void canLosePixels(SkImageRef*); - void purgeIfNeeded(); -}; - -#endif - diff --git a/src/images/SkImageRef_GlobalPool.cpp b/src/images/SkImageRef_GlobalPool.cpp deleted file mode 100644 index 1f0bc43..0000000 --- a/src/images/SkImageRef_GlobalPool.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "SkImageRef_GlobalPool.h" -#include "SkImageRefPool.h" -#include "SkThread.h" - -extern SkMutex gImageRefMutex; - -static SkImageRefPool gGlobalImageRefPool; - -SkImageRef_GlobalPool::SkImageRef_GlobalPool(SkStream* stream, - SkBitmap::Config config, - int sampleSize) - : SkImageRef(stream, config, sampleSize) { - this->mutex()->acquire(); - gGlobalImageRefPool.addToHead(this); - this->mutex()->release(); -} - -SkImageRef_GlobalPool::~SkImageRef_GlobalPool() { - this->mutex()->acquire(); - gGlobalImageRefPool.detach(this); - this->mutex()->release(); -} - -bool SkImageRef_GlobalPool::onDecode(SkImageDecoder* codec, SkStream* stream, - SkBitmap* bitmap, SkBitmap::Config config, - SkImageDecoder::Mode mode) { - if (!this->INHERITED::onDecode(codec, stream, bitmap, config, mode)) { - return false; - } - if (mode == SkImageDecoder::kDecodePixels_Mode) { - gGlobalImageRefPool.justAddedPixels(this); - } - return true; -} - -void SkImageRef_GlobalPool::onUnlockPixels() { - this->INHERITED::onUnlockPixels(); - - gGlobalImageRefPool.canLosePixels(this); -} - -SkImageRef_GlobalPool::SkImageRef_GlobalPool(SkFlattenableReadBuffer& buffer) - : INHERITED(buffer) { - this->mutex()->acquire(); - gGlobalImageRefPool.addToHead(this); - this->mutex()->release(); -} - -SkPixelRef* SkImageRef_GlobalPool::Create(SkFlattenableReadBuffer& buffer) { - return SkNEW_ARGS(SkImageRef_GlobalPool, (buffer)); -} - -static SkPixelRef::Registrar::Registrar reg("SkImageRef_GlobalPool", - SkImageRef_GlobalPool::Create); - -/////////////////////////////////////////////////////////////////////////////// -// global imagerefpool wrappers - -size_t SkImageRef_GlobalPool::GetRAMBudget() { - SkAutoMutexAcquire ac(gImageRefMutex); - return gGlobalImageRefPool.getRAMBudget(); -} - -void SkImageRef_GlobalPool::SetRAMBudget(size_t size) { - SkAutoMutexAcquire ac(gImageRefMutex); - gGlobalImageRefPool.setRAMBudget(size); -} - -size_t SkImageRef_GlobalPool::GetRAMUsed() { - SkAutoMutexAcquire ac(gImageRefMutex); - return gGlobalImageRefPool.getRAMUsed(); -} - -void SkImageRef_GlobalPool::SetRAMUsed(size_t usage) { - SkAutoMutexAcquire ac(gImageRefMutex); - gGlobalImageRefPool.setRAMUsed(usage); -} - -void SkImageRef_GlobalPool::DumpPool() { - SkAutoMutexAcquire ac(gImageRefMutex); - gGlobalImageRefPool.dump(); -} - diff --git a/src/images/SkMovie.cpp b/src/images/SkMovie.cpp deleted file mode 100644 index 7186ed5..0000000 --- a/src/images/SkMovie.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "SkMovie.h" -#include "SkCanvas.h" -#include "SkPaint.h" - -// We should never see this in normal operation since our time values are -// 0-based. So we use it as a sentinal. -#define UNINITIALIZED_MSEC ((SkMSec)-1) - -SkMovie::SkMovie() -{ - fInfo.fDuration = UNINITIALIZED_MSEC; // uninitialized - fCurrTime = UNINITIALIZED_MSEC; // uninitialized - fNeedBitmap = true; -} - -void SkMovie::ensureInfo() -{ - if (fInfo.fDuration == UNINITIALIZED_MSEC && !this->onGetInfo(&fInfo)) - memset(&fInfo, 0, sizeof(fInfo)); // failure -} - -SkMSec SkMovie::duration() -{ - this->ensureInfo(); - return fInfo.fDuration; -} - -int SkMovie::width() -{ - this->ensureInfo(); - return fInfo.fWidth; -} - -int SkMovie::height() -{ - this->ensureInfo(); - return fInfo.fHeight; -} - -int SkMovie::isOpaque() -{ - this->ensureInfo(); - return fInfo.fIsOpaque; -} - -bool SkMovie::setTime(SkMSec time) -{ - SkMSec dur = this->duration(); - if (time > dur) - time = dur; - - bool changed = false; - if (time != fCurrTime) - { - fCurrTime = time; - changed = this->onSetTime(time); - fNeedBitmap |= changed; - } - return changed; -} - -const SkBitmap& SkMovie::bitmap() -{ - if (fCurrTime == UNINITIALIZED_MSEC) // uninitialized - this->setTime(0); - - if (fNeedBitmap) - { - if (!this->onGetBitmap(&fBitmap)) // failure - fBitmap.reset(); - fNeedBitmap = false; - } - return fBitmap; -} - -//////////////////////////////////////////////////////////////////// - -#include "SkStream.h" - -SkMovie* SkMovie::DecodeMemory(const void* data, size_t length) { - SkMemoryStream stream(data, length, false); - return SkMovie::DecodeStream(&stream); -} - -SkMovie* SkMovie::DecodeFile(const char path[]) -{ - SkMovie* movie = NULL; - - SkFILEStream stream(path); - if (stream.isValid()) { - movie = SkMovie::DecodeStream(&stream); - } -#ifdef SK_DEBUG - else { - SkDebugf("Movie file not found <%s>\n", path); - } -#endif - - return movie; -} - diff --git a/src/images/SkMovie_gif.cpp b/src/images/SkMovie_gif.cpp deleted file mode 100644 index ca9c812..0000000 --- a/src/images/SkMovie_gif.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* libs/graphics/images/SkImageDecoder_libgif.cpp -** -** Copyright 2006, 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 "SkMovie.h" -#include "SkColor.h" -#include "SkColorPriv.h" -#include "SkStream.h" -#include "SkTemplates.h" - -#include "gif_lib.h" - -class SkGIFMovie : public SkMovie { -public: - SkGIFMovie(SkStream* stream); - virtual ~SkGIFMovie(); - -protected: - virtual bool onGetInfo(Info*); - virtual bool onSetTime(SkMSec); - virtual bool onGetBitmap(SkBitmap*); - -private: - GifFileType* fGIF; - SavedImage* fCurrSavedImage; -}; - -SkMovie* SkMovie_GIF_Factory(SkStream* stream) { - char buf[GIF_STAMP_LEN]; - if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) { - if (memcmp(GIF_STAMP, buf, GIF_STAMP_LEN) == 0 || - memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 || - memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) { - stream->rewind(); - return SkNEW_ARGS(SkGIFMovie, (stream)); - } - } - return NULL; -} - -static int Decode(GifFileType* fileType, GifByteType* out, int size) { - SkStream* stream = (SkStream*) fileType->UserData; - return (int) stream->read(out, size); -} - -SkGIFMovie::SkGIFMovie(SkStream* stream) -{ - fGIF = DGifOpen( stream, Decode ); - if (NULL == fGIF) - return; - - if (DGifSlurp(fGIF) != GIF_OK) - { - DGifCloseFile(fGIF); - fGIF = NULL; - } - fCurrSavedImage = NULL; -} - -SkGIFMovie::~SkGIFMovie() -{ - if (fGIF) - DGifCloseFile(fGIF); -} - -static SkMSec savedimage_duration(const SavedImage* image) -{ - for (int j = 0; j < image->ExtensionBlockCount; j++) - { - if (image->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE) - { - int size = image->ExtensionBlocks[j].ByteCount; - SkASSERT(size >= 4); - const uint8_t* b = (const uint8_t*)image->ExtensionBlocks[j].Bytes; - return ((b[2] << 8) | b[1]) * 10; - } - } - return 0; -} - -bool SkGIFMovie::onGetInfo(Info* info) -{ - if (NULL == fGIF) - return false; - - SkMSec dur = 0; - for (int i = 0; i < fGIF->ImageCount; i++) - dur += savedimage_duration(&fGIF->SavedImages[i]); - - info->fDuration = dur; - info->fWidth = fGIF->SWidth; - info->fHeight = fGIF->SHeight; - info->fIsOpaque = false; // how to compute? - return true; -} - -bool SkGIFMovie::onSetTime(SkMSec time) -{ - if (NULL == fGIF) - return false; - - SkMSec dur = 0; - for (int i = 0; i < fGIF->ImageCount; i++) - { - dur += savedimage_duration(&fGIF->SavedImages[i]); - if (dur >= time) - { - SavedImage* prev = fCurrSavedImage; - fCurrSavedImage = &fGIF->SavedImages[i]; - return prev != fCurrSavedImage; - } - } - fCurrSavedImage = &fGIF->SavedImages[fGIF->ImageCount - 1]; - return true; -} - -bool SkGIFMovie::onGetBitmap(SkBitmap* bm) -{ - GifFileType* gif = fGIF; - if (NULL == gif) - return false; - - // should we check for the Image cmap or the global (SColorMap) first? - ColorMapObject* cmap = gif->SColorMap; - if (cmap == NULL) - cmap = gif->Image.ColorMap; - - if (cmap == NULL || gif->ImageCount < 1 || cmap->ColorCount != (1 << cmap->BitsPerPixel)) - { - SkASSERT(!"bad colortable setup"); - return false; - } - - const int width = gif->SWidth; - const int height = gif->SHeight; - if (width <= 0 || height <= 0) { - return false; - } - - SavedImage* gif_image = fCurrSavedImage; - SkBitmap::Config config = SkBitmap::kIndex8_Config; - - SkColorTable* colorTable = SkNEW_ARGS(SkColorTable, (cmap->ColorCount)); - SkAutoUnref aur(colorTable); - - bm->setConfig(config, width, height, 0); - if (!bm->allocPixels(colorTable)) { - return false; - } - - int transparent = -1; - for (int i = 0; i < gif_image->ExtensionBlockCount; ++i) { - ExtensionBlock* eb = gif_image->ExtensionBlocks + i; - if (eb->Function == 0xF9 && - eb->ByteCount == 4) { - bool has_transparency = ((eb->Bytes[0] & 1) == 1); - if (has_transparency) { - transparent = (unsigned char)eb->Bytes[3]; - } - } - } - - SkPMColor* colorPtr = colorTable->lockColors(); - - if (transparent >= 0) - memset(colorPtr, 0, cmap->ColorCount * 4); - else - colorTable->setFlags(colorTable->getFlags() | SkColorTable::kColorsAreOpaque_Flag); - - for (int index = 0; index < cmap->ColorCount; index++) - { - if (transparent != index) - colorPtr[index] = SkPackARGB32(0xFF, cmap->Colors[index].Red, - cmap->Colors[index].Green, cmap->Colors[index].Blue); - } - colorTable->unlockColors(true); - - unsigned char* in = (unsigned char*)gif_image->RasterBits; - unsigned char* out = bm->getAddr8(0, 0); - if (gif->Image.Interlace) { - - // deinterlace - int row; - // group 1 - every 8th row, starting with row 0 - for (row = 0; row < height; row += 8) { - memcpy(out + width * row, in, width); - in += width; - } - - // group 2 - every 8th row, starting with row 4 - for (row = 4; row < height; row += 8) { - memcpy(out + width * row, in, width); - in += width; - } - - // group 3 - every 4th row, starting with row 2 - for (row = 2; row < height; row += 4) { - memcpy(out + width * row, in, width); - in += width; - } - - for (row = 1; row < height; row += 2) { - memcpy(out + width * row, in, width); - in += width; - } - - } else { - memcpy(out, in, width * height); - } - return true; -} diff --git a/src/images/SkPageFlipper.cpp b/src/images/SkPageFlipper.cpp deleted file mode 100644 index 526ba09..0000000 --- a/src/images/SkPageFlipper.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2008 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 "SkPageFlipper.h" - -SkPageFlipper::SkPageFlipper() { - fWidth = 0; - fHeight = 0; - fDirty0 = &fDirty0Storage; - fDirty1 = &fDirty1Storage; - - fDirty0->setEmpty(); - fDirty1->setEmpty(); -} - -SkPageFlipper::SkPageFlipper(int width, int height) { - fWidth = width; - fHeight = height; - fDirty0 = &fDirty0Storage; - fDirty1 = &fDirty1Storage; - - fDirty0->setRect(0, 0, width, height); - fDirty1->setEmpty(); -} - -void SkPageFlipper::resize(int width, int height) { - fWidth = width; - fHeight = height; - - // this is the opposite of the constructors - fDirty1->setRect(0, 0, width, height); - fDirty0->setEmpty(); -} - -void SkPageFlipper::inval() { - fDirty1->setRect(0, 0, fWidth, fHeight); -} - -void SkPageFlipper::inval(const SkIRect& rect) { - SkIRect r; - r.set(0, 0, fWidth, fHeight); - if (r.intersect(rect)) { - fDirty1->op(r, SkRegion::kUnion_Op); - } -} - -void SkPageFlipper::inval(const SkRegion& rgn) { - SkRegion r; - r.setRect(0, 0, fWidth, fHeight); - if (r.op(rgn, SkRegion::kIntersect_Op)) { - fDirty1->op(r, SkRegion::kUnion_Op); - } -} - -void SkPageFlipper::inval(const SkRect& rect, bool antialias) { - SkIRect r; - rect.round(&r); - if (antialias) { - r.inset(-1, -1); - } - this->inval(r); -} - -const SkRegion& SkPageFlipper::update(SkRegion* copyBits) { - // Copy over anything new from page0 that isn't dirty in page1 - copyBits->op(*fDirty0, *fDirty1, SkRegion::kDifference_Op); - SkTSwap<SkRegion*>(fDirty0, fDirty1); - fDirty1->setEmpty(); - return *fDirty0; -} - - diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp deleted file mode 100644 index 15f4432..0000000 --- a/src/images/SkScaledBitmapSampler.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2007, 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 "SkScaledBitmapSampler.h" -#include "SkBitmap.h" -#include "SkColorPriv.h" -#include "SkDither.h" - -// 8888 - -static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; - for (int x = 0; x < width; x++) { - dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]); - src += deltaSrc; - } - return false; -} - -static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; - for (int x = 0; x < width; x++) { - dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); - src += deltaSrc; - } - return false; -} - -static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; - unsigned alphaMask = 0xFF; - for (int x = 0; x < width; x++) { - unsigned alpha = src[3]; - dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); - src += deltaSrc; - alphaMask &= alpha; - } - return alphaMask != 0xFF; -} - -// 565 - -static bool Sample_Gray_D565(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; - for (int x = 0; x < width; x++) { - dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); - src += deltaSrc; - } - return false; -} - -static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int y) { - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; - DITHER_565_SCAN(y); - for (int x = 0; x < width; x++) { - dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x)); - src += deltaSrc; - } - return false; -} - -static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; - for (int x = 0; x < width; x++) { - dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); - src += deltaSrc; - } - return false; -} - -static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int y) { - uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; - DITHER_565_SCAN(y); - for (int x = 0; x < width; x++) { - dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x)); - src += deltaSrc; - } - return false; -} - -// 4444 - -static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; - for (int x = 0; x < width; x++) { - unsigned gray = src[0] >> 4; - dst[x] = SkPackARGB4444(0xF, gray, gray, gray); - src += deltaSrc; - } - return false; -} - -static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int y) { - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; - DITHER_4444_SCAN(y); - for (int x = 0; x < width; x++) { - dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0], - DITHER_VALUE(x)); - src += deltaSrc; - } - return false; -} - -static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; - for (int x = 0; x < width; x++) { - dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4); - src += deltaSrc; - } - return false; -} - -static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int y) { - SkPMColor16* dst = (SkPMColor16*)dstRow; - DITHER_4444_SCAN(y); - - for (int x = 0; x < width; x++) { - dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2], - DITHER_VALUE(x)); - src += deltaSrc; - } - return false; -} - -static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; - unsigned alphaMask = 0xFF; - - for (int x = 0; x < width; x++) { - unsigned alpha = src[3]; - SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); - dst[x] = SkPixel32ToPixel4444(c); - src += deltaSrc; - alphaMask &= alpha; - } - return alphaMask != 0xFF; -} - -static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int y) { - SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; - unsigned alphaMask = 0xFF; - DITHER_4444_SCAN(y); - - for (int x = 0; x < width; x++) { - unsigned alpha = src[3]; - SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); - dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); - src += deltaSrc; - alphaMask &= alpha; - } - return alphaMask != 0xFF; -} - -// Index - -static bool Sample_Index_DI(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int) { - if (1 == deltaSrc) { - memcpy(dstRow, src, width); - } else { - uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow; - for (int x = 0; x < width; x++) { - dst[x] = src[0]; - src += deltaSrc; - } - } - return false; -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkScaledBitmapSampler.h" - -SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height, - int sampleSize) { - if (width <= 0 || height <= 0) { - sk_throw(); - } - - if (sampleSize <= 1) { - fScaledWidth = width; - fScaledHeight = height; - fX0 = fY0 = 0; - fDX = fDY = 1; - return; - } - - int dx = SkMin32(sampleSize, width); - int dy = SkMin32(sampleSize, height); - - fScaledWidth = width / dx; - fScaledHeight = height / dy; - - SkASSERT(fScaledWidth > 0); - SkASSERT(fScaledHeight > 0); - - fX0 = dx >> 1; - fY0 = dy >> 1; - - SkASSERT(fX0 >= 0 && fX0 < width); - SkASSERT(fY0 >= 0 && fY0 < height); - - fDX = dx; - fDY = dy; - - SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width); - SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height); - - fRowProc = NULL; -} - -bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither) { - static const RowProc gProcs[] = { - // 8888 (no dither distinction) - Sample_Gray_D8888, Sample_Gray_D8888, - Sample_RGBx_D8888, Sample_RGBx_D8888, - Sample_RGBA_D8888, Sample_RGBA_D8888, - NULL, NULL, - // 565 (no alpha distinction) - Sample_Gray_D565, Sample_Gray_D565_D, - Sample_RGBx_D565, Sample_RGBx_D565_D, - Sample_RGBx_D565, Sample_RGBx_D565_D, - NULL, NULL, - // 4444 - Sample_Gray_D4444, Sample_Gray_D4444_D, - Sample_RGBx_D4444, Sample_RGBx_D4444_D, - Sample_RGBA_D4444, Sample_RGBA_D4444_D, - NULL, NULL, - // Index8 - NULL, NULL, - NULL, NULL, - NULL, NULL, - Sample_Index_DI, Sample_Index_DI, - }; - - - int index = 0; - if (dither) { - index += 1; - } - switch (sc) { - case SkScaledBitmapSampler::kGray: - fSrcPixelSize = 1; - index += 0; - break; - case SkScaledBitmapSampler::kRGB: - fSrcPixelSize = 3; - index += 2; - break; - case SkScaledBitmapSampler::kRGBX: - fSrcPixelSize = 4; - index += 2; - break; - case SkScaledBitmapSampler::kRGBA: - fSrcPixelSize = 4; - index += 4; - break; - case SkScaledBitmapSampler::kIndex: - fSrcPixelSize = 1; - index += 6; - break; - default: - return false; - } - - switch (dst->config()) { - case SkBitmap::kARGB_8888_Config: - index += 0; - break; - case SkBitmap::kRGB_565_Config: - index += 8; - break; - case SkBitmap::kARGB_4444_Config: - index += 16; - break; - case SkBitmap::kIndex8_Config: - index += 24; - break; - default: - return false; - } - - fRowProc = gProcs[index]; - fDstRow = (char*)dst->getPixels(); - fDstRowBytes = dst->rowBytes(); - fCurrY = 0; - return fRowProc != NULL; -} - -bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) { - SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight); - - bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth, - fDX * fSrcPixelSize, fCurrY); - fDstRow += fDstRowBytes; - fCurrY += 1; - return hadAlpha; -} diff --git a/src/images/SkScaledBitmapSampler.h b/src/images/SkScaledBitmapSampler.h deleted file mode 100644 index 0bb9924..0000000 --- a/src/images/SkScaledBitmapSampler.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef SkScaledBitmapSampler_DEFINED -#define SkScaledBitmapSampler_DEFINED - -#include "SkTypes.h" - -class SkBitmap; - -class SkScaledBitmapSampler { -public: - SkScaledBitmapSampler(int origWidth, int origHeight, int cellSize); - - int scaledWidth() const { return fScaledWidth; } - int scaledHeight() const { return fScaledHeight; } - - int srcY0() const { return fY0; } - int srcDY() const { return fDY; } - - enum SrcConfig { - kGray, // 1 byte per pixel - kIndex, // 1 byte per pixel - kRGB, // 3 bytes per pixel - kRGBX, // 4 byes per pixel (ignore 4th) - kRGBA // 4 bytes per pixel - }; - - // Given a dst bitmap (with pixels already allocated) and a src-config, - // prepares iterator to process the src colors and write them into dst. - // Returns false if the request cannot be fulfulled. - bool begin(SkBitmap* dst, SrcConfig sc, bool doDither); - // call with row of src pixels, for y = 0...scaledHeight-1. - // returns true if the row had non-opaque alpha in it - bool next(const uint8_t* SK_RESTRICT src); - -private: - int fScaledWidth; - int fScaledHeight; - - int fX0; // first X coord to sample - int fY0; // first Y coord (scanline) to sample - int fDX; // step between X samples - int fDY; // step between Y samples - - typedef bool (*RowProc)(void* SK_RESTRICT dstRow, - const uint8_t* SK_RESTRICT src, - int width, int deltaSrc, int y); - - // setup state - char* fDstRow; // points into bitmap's pixels - int fDstRowBytes; - int fCurrY; // used for dithering - int fSrcPixelSize; // 1, 3, 4 - RowProc fRowProc; -}; - -#endif diff --git a/src/images/bmpdecoderhelper.cpp b/src/images/bmpdecoderhelper.cpp deleted file mode 100644 index acabf44..0000000 --- a/src/images/bmpdecoderhelper.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright 2007, 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. - */ -// Author: cevans@google.com (Chris Evans) - -#include "bmpdecoderhelper.h" - -namespace image_codec { - -static const int kBmpHeaderSize = 14; -static const int kBmpInfoSize = 40; -static const int kBmpOS2InfoSize = 12; -static const int kMaxDim = SHRT_MAX / 2; - -bool BmpDecoderHelper::DecodeImage(const char* p, - int len, - int max_pixels, - BmpDecoderCallback* callback) { - data_ = reinterpret_cast<const uint8*>(p); - pos_ = 0; - len_ = len; - inverted_ = true; - // Parse the header structure. - if (len < kBmpHeaderSize + 4) { - return false; - } - GetShort(); // Signature. - GetInt(); // Size. - GetInt(); // Reserved. - int offset = GetInt(); - // Parse the info structure. - int infoSize = GetInt(); - if (infoSize != kBmpOS2InfoSize && infoSize < kBmpInfoSize) { - return false; - } - int cols = 0; - int comp = 0; - int colLen = 4; - if (infoSize >= kBmpInfoSize) { - if (len < kBmpHeaderSize + kBmpInfoSize) { - return false; - } - width_ = GetInt(); - height_ = GetInt(); - GetShort(); // Planes. - bpp_ = GetShort(); - comp = GetInt(); - GetInt(); // Size. - GetInt(); // XPPM. - GetInt(); // YPPM. - cols = GetInt(); - GetInt(); // Important colours. - } else { - if (len < kBmpHeaderSize + kBmpOS2InfoSize) { - return false; - } - colLen = 3; - width_ = GetShort(); - height_ = GetShort(); - GetShort(); // Planes. - bpp_ = GetShort(); - } - if (height_ < 0) { - height_ = -height_; - inverted_ = false; - } - if (width_ <= 0 || width_ > kMaxDim || height_ <= 0 || height_ > kMaxDim) { - return false; - } - if (width_ * height_ > max_pixels) { - return false; - } - if (cols < 0 || cols > 256) { - return false; - } - // Allocate then read in the colour map. - if (cols == 0 && bpp_ <= 8) { - cols = 1 << bpp_; - } - if (bpp_ <= 8 || cols > 0) { - uint8* colBuf = new uint8[256 * 3]; - memset(colBuf, '\0', 256 * 3); - colTab_.reset(colBuf); - } - if (cols > 0) { - if (pos_ + (cols * colLen) > len_) { - return false; - } - for (int i = 0; i < cols; ++i) { - int base = i * 3; - colTab_[base + 2] = GetByte(); - colTab_[base + 1] = GetByte(); - colTab_[base] = GetByte(); - if (colLen == 4) { - GetByte(); - } - } - } - // Read in the compression data if necessary. - redBits_ = 0x7c00; - greenBits_ = 0x03e0; - blueBits_ = 0x001f; - bool rle = false; - if (comp == 1 || comp == 2) { - rle = true; - } else if (comp == 3) { - if (pos_ + 12 > len_) { - return false; - } - redBits_ = GetInt() & 0xffff; - greenBits_ = GetInt() & 0xffff; - blueBits_ = GetInt() & 0xffff; - } - redShiftRight_ = CalcShiftRight(redBits_); - greenShiftRight_ = CalcShiftRight(greenBits_); - blueShiftRight_ = CalcShiftRight(blueBits_); - redShiftLeft_ = CalcShiftLeft(redBits_); - greenShiftLeft_ = CalcShiftLeft(greenBits_); - blueShiftLeft_ = CalcShiftLeft(blueBits_); - rowPad_ = 0; - pixelPad_ = 0; - int rowLen; - if (bpp_ == 32) { - rowLen = width_ * 4; - pixelPad_ = 1; - } else if (bpp_ == 24) { - rowLen = width_ * 3; - } else if (bpp_ == 16) { - rowLen = width_ * 2; - } else if (bpp_ == 8) { - rowLen = width_; - } else if (bpp_ == 4) { - rowLen = width_ / 2; - if (width_ & 1) { - rowLen++; - } - } else if (bpp_ == 1) { - rowLen = width_ / 8; - if (width_ & 7) { - rowLen++; - } - } else { - return false; - } - // Round the rowLen up to a multiple of 4. - if (rowLen % 4 != 0) { - rowPad_ = 4 - (rowLen % 4); - rowLen += rowPad_; - } - - if (offset > 0 && offset > pos_ && offset < len_) { - pos_ = offset; - } - // Deliberately off-by-one; a load of BMPs seem to have their last byte - // missing. - if (!rle && (pos_ + (rowLen * height_) > len_ + 1)) { - return false; - } - - output_ = callback->SetSize(width_, height_); - if (NULL == output_) { - return true; // meaning we succeeded, but they want us to stop now - } - - if (rle && (bpp_ == 4 || bpp_ == 8)) { - DoRLEDecode(); - } else { - DoStandardDecode(); - } - return true; -} - -void BmpDecoderHelper::DoRLEDecode() { - static const uint8 RLE_ESCAPE = 0; - static const uint8 RLE_EOL = 0; - static const uint8 RLE_EOF = 1; - static const uint8 RLE_DELTA = 2; - int x = 0; - int y = height_ - 1; - while (pos_ < len_ - 1) { - uint8 cmd = GetByte(); - if (cmd != RLE_ESCAPE) { - uint8 pixels = GetByte(); - int num = 0; - uint8 col = pixels; - while (cmd-- && x < width_) { - if (bpp_ == 4) { - if (num & 1) { - col = pixels & 0xf; - } else { - col = pixels >> 4; - } - } - PutPixel(x++, y, col); - num++; - } - } else { - cmd = GetByte(); - if (cmd == RLE_EOF) { - return; - } else if (cmd == RLE_EOL) { - x = 0; - y--; - if (y < 0) { - return; - } - } else if (cmd == RLE_DELTA) { - if (pos_ < len_ - 1) { - uint8 dx = GetByte(); - uint8 dy = GetByte(); - x += dx; - if (x > width_) { - x = width_; - } - y -= dy; - if (y < 0) { - return; - } - } - } else { - int num = 0; - int bytesRead = 0; - uint8 val = 0; - while (cmd-- && pos_ < len_) { - if (bpp_ == 8 || !(num & 1)) { - val = GetByte(); - bytesRead++; - } - uint8 col = val; - if (bpp_ == 4) { - if (num & 1) { - col = col & 0xf; - } else { - col >>= 4; - } - } - if (x < width_) { - PutPixel(x++, y, col); - } - num++; - } - // All pixel runs must be an even number of bytes - skip a byte if we - // read an odd number. - if ((bytesRead & 1) && pos_ < len_) { - GetByte(); - } - } - } - } -} - -void BmpDecoderHelper::PutPixel(int x, int y, uint8 col) { - CHECK(x >= 0 && x < width_); - CHECK(y >= 0 && y < height_); - if (!inverted_) { - y = height_ - (y + 1); - } - - int base = ((y * width_) + x) * 3; - int colBase = col * 3; - output_[base] = colTab_[colBase]; - output_[base + 1] = colTab_[colBase + 1]; - output_[base + 2] = colTab_[colBase + 2]; -} - -void BmpDecoderHelper::DoStandardDecode() { - int row = 0; - uint8 currVal = 0; - for (int h = height_ - 1; h >= 0; h--, row++) { - int realH = h; - if (!inverted_) { - realH = height_ - (h + 1); - } - uint8* line = output_ + (3 * width_ * realH); - for (int w = 0; w < width_; w++) { - if (bpp_ >= 24) { - line[2] = GetByte(); - line[1] = GetByte(); - line[0] = GetByte(); - } else if (bpp_ == 16) { - uint32 val = GetShort(); - line[0] = ((val & redBits_) >> redShiftRight_) << redShiftLeft_; - line[1] = ((val & greenBits_) >> greenShiftRight_) << greenShiftLeft_; - line[2] = ((val & blueBits_) >> blueShiftRight_) << blueShiftLeft_; - } else if (bpp_ <= 8) { - uint8 col; - if (bpp_ == 8) { - col = GetByte(); - } else if (bpp_ == 4) { - if ((w % 2) == 0) { - currVal = GetByte(); - col = currVal >> 4; - } else { - col = currVal & 0xf; - } - } else { - if ((w % 8) == 0) { - currVal = GetByte(); - } - int bit = w & 7; - col = ((currVal >> (7 - bit)) & 1); - } - int base = col * 3; - line[0] = colTab_[base]; - line[1] = colTab_[base + 1]; - line[2] = colTab_[base + 2]; - } - line += 3; - for (int i = 0; i < pixelPad_; ++i) { - GetByte(); - } - } - for (int i = 0; i < rowPad_; ++i) { - GetByte(); - } - } -} - -int BmpDecoderHelper::GetInt() { - uint8 b1 = GetByte(); - uint8 b2 = GetByte(); - uint8 b3 = GetByte(); - uint8 b4 = GetByte(); - return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24); -} - -int BmpDecoderHelper::GetShort() { - uint8 b1 = GetByte(); - uint8 b2 = GetByte(); - return b1 | (b2 << 8); -} - -uint8 BmpDecoderHelper::GetByte() { - CHECK(pos_ >= 0 && pos_ <= len_); - // We deliberately allow this off-by-one access to cater for BMPs with their - // last byte missing. - if (pos_ == len_) { - return 0; - } - return data_[pos_++]; -} - -int BmpDecoderHelper::CalcShiftRight(uint32 mask) { - int ret = 0; - while (mask != 0 && !(mask & 1)) { - mask >>= 1; - ret++; - } - return ret; -} - -int BmpDecoderHelper::CalcShiftLeft(uint32 mask) { - int ret = 0; - while (mask != 0 && !(mask & 1)) { - mask >>= 1; - } - while (mask != 0 && !(mask & 0x80)) { - mask <<= 1; - ret++; - } - return ret; -} - -} // namespace image_codec diff --git a/src/images/bmpdecoderhelper.h b/src/images/bmpdecoderhelper.h deleted file mode 100644 index 07f0ae5..0000000 --- a/src/images/bmpdecoderhelper.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2007, 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. - */ - -#ifndef IMAGE_CODEC_BMPDECODERHELPER_H__ -#define IMAGE_CODEC_BMPDECODERHELPER_H__ - -/////////////////////////////////////////////////////////////////////////////// -// this section is my current "glue" between google3 code and android. -// will be fixed soon - -#include "SkTypes.h" -#include <limits.h> -#define DISALLOW_EVIL_CONSTRUCTORS(name) -#define CHECK(predicate) SkASSERT(predicate) -typedef uint8_t uint8; -typedef uint32_t uint32; - -template <typename T> class scoped_array { -private: - T* ptr_; - scoped_array(scoped_array const&); - scoped_array& operator=(const scoped_array&); - -public: - explicit scoped_array(T* p = 0) : ptr_(p) {} - ~scoped_array() { - delete[] ptr_; - } - - void reset(T* p = 0) { - if (p != ptr_) { - delete[] ptr_; - ptr_ = p; - } - } - - T& operator[](int i) const { - return ptr_[i]; - } -}; - -/////////////////////////////////////////////////////////////////////////////// - -namespace image_codec { - -class BmpDecoderCallback { - public: - BmpDecoderCallback() { } - virtual ~BmpDecoderCallback() {} - - /** - * This is called once for an image. It is passed the width and height and - * should return the address of a buffer that is large enough to store - * all of the resulting pixels (widht * height * 3 bytes). If it returns NULL, - * then the decoder will abort, but return true, as the caller has received - * valid dimensions. - */ - virtual uint8* SetSize(int width, int height) = 0; - - private: - DISALLOW_EVIL_CONSTRUCTORS(BmpDecoderCallback); -}; - -class BmpDecoderHelper { - public: - BmpDecoderHelper() { } - ~BmpDecoderHelper() { } - bool DecodeImage(const char* data, - int len, - int max_pixels, - BmpDecoderCallback* callback); - - private: - DISALLOW_EVIL_CONSTRUCTORS(BmpDecoderHelper); - - void DoRLEDecode(); - void DoStandardDecode(); - void PutPixel(int x, int y, uint8 col); - - int GetInt(); - int GetShort(); - uint8 GetByte(); - int CalcShiftRight(uint32 mask); - int CalcShiftLeft(uint32 mask); - - const uint8* data_; - int pos_; - int len_; - int width_; - int height_; - int bpp_; - int pixelPad_; - int rowPad_; - scoped_array<uint8> colTab_; - uint32 redBits_; - uint32 greenBits_; - uint32 blueBits_; - int redShiftRight_; - int greenShiftRight_; - int blueShiftRight_; - int redShiftLeft_; - int greenShiftLeft_; - int blueShiftLeft_; - uint8* output_; - bool inverted_; -}; - -} // namespace - -#endif diff --git a/src/images/fpdfemb.h b/src/images/fpdfemb.h deleted file mode 100644 index 3c77116..0000000 --- a/src/images/fpdfemb.h +++ /dev/null @@ -1,1765 +0,0 @@ -// FPDFEMB.H - Header file for FPDFEMB SDK -// Copyright (c) 2007-2008 Foxit Software Company, All Right Reserved. - -// Date: 2008-04-07 - -// Embedded platforms have many different aspects from desktop platforms, -// among them, the followings are most important for PDF processing: -// -// 1. Embedded platforms have only limited memory, and there is no virtual memory. -// PDF is a very complicated format, processing PDF may consumes quite -// large amount of memory, even for some smaller PDFs. And, in order to -// increase the performance of PDF parsing and rendering, cache memory -// is often used. For some big PDFs with many pages, the cache may grow -// while user browing through pages, eventually, for some PDFs, the memory -// on the device may run out. -// -// FPDFEMB SDK allows graceful out-of-memory (OOM) handling by returning -// OOM error code for all functions that may involve memory allocation. -// When an application detects OOM situation, it can do one of the followings: -// -// a) Give user some prompt and quit the application or close the document; -// b) Or better, try to recover from the error. Sometimes OOM can be caused -// by ever-growing cache. For example, when user browses a 1000-page -// document, let's say OOM happen at page #300. In this case, the -// application might close the whole document (cache will be gone with -// it), reopen the document, then go directly to page #300. It's likely -// the process will go through this time. This is called "OOM recovery". -// If OOM happens again during a recovery, then, it's not possible to finish -// the process, the application must quit of close the document. -// -// 2. Embedded platforms has only limited computing power. Since some PDFs -// can be very complicated and require a lot of processing to be displayed, -// it may take a lot of time for the process to finish. This may cause -// some problem with user experience, especially for devices like mobile -// phones, when an application may need to be put on hold any time. Therefore, -// it's important to break lengthy process into small steps which can be -// stopped or resumed at any time. We call this kind of process as -// "progressive process". -// -// FPDFEMB SDK allows progressive page parsing and rendering, the most time- -// consuming part of PDF processing. -// -// IMPORTANT: -// FPDFEMB module is not intended to run in multi-threaded environment. - -// Components inside FPDFEMB: -// * Library Memory Management -// * Document Operations -// * Page Basic Operations -// * Page Parsing -// * Page Rendering -// * Coordination Conversion -// * Text Search -// * Text Information -// * Device Independant Bitmap -// * Custom Font Handler and CJK Support -// * Bookmark Information -// * Hyperlink Information -// * Graphic Output - -#ifndef _FPDFEMB_H_ -#define _FPDFEMB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// Standard return type for many FPDFEMB functions: FPDFERR_SUCCESS for success, otherwise error code -typedef int FPDFEMB_RESULT; - -// Standard boolean type: 0 for false, non-zero for true -typedef int FPDFEMB_BOOL; - -// Unicode character. FPDFEMB uses UTF16LE format for unicode string. -typedef unsigned short FPDFEMB_WCHAR; - -// Error codes -#define FPDFERR_SUCCESS 0 -#define FPDFERR_MEMORY 1 // Out of memory -#define FPDFERR_ERROR 2 // Error of any kind, without specific reason -#define FPDFERR_PASSWORD 3 // Incorrect password -#define FPDFERR_FORMAT 4 // Not PDF format -#define FPDFERR_FILE 5 // File access error -#define FPDFERR_PARAM 6 // Parameter error -#define FPDFERR_STATUS 7 // Not in correct status -#define FPDFERR_TOBECONTINUED 8 // To be continued -#define FPDFERR_NOTFOUND 9 // Search result not found - -/******************************************************************************************** -**** -**** Library Memory Management -**** -********************************************************************************************/ - -// Structure: FPDFEMB_MEMMGR -// Including interfaces implemented by host application, providing memory allocation -// facilities. All members are required. -// A memory manager structure is required to be valid during the entire period -// when an application using FPDFEMB module. -// -// IMPORTANT NOTE: using of this interface is strongly not recommended, because -// FPDFEMB now internally use FPDFEMB_MEMMGR_EX interface, which allows more -// advanced memory management. This interface is retained for backward compatibility -// only, and maybe discontinued in the future. -// -struct FPDFEMB_MEMMGR { - // Interface: Alloc - // Allocate a memory block - // Parameters: - // pMgr - Pointer to the memory manager. - // size - Number of bytes for the memory block. - // Return Value: - // The pointer to allocated memory block. NULL if no memory available. - // Comments: - // In order to handle OOM situation, application can use longjmp() inside - // implementation of this function. If underlying memory manager fails to - // allocate enough memory, then application can use longjmp() to jump to - // OOM handling codes. - // - void* (*Alloc)(struct FPDFEMB_MEMMGR* pMgr, unsigned int size); - - // Interface: AllocNL - // Allocate a memory block, without leaving - // Parameters: - // pMgr - Pointer to the memory manager. - // size - Number of bytes for the memory block. - // Return Value: - // The pointer to allocated memory block. NULL if no memory available. - // Comments: - // Implementation MUST return NULL if no memory available, no exception - // or longjmp() can be used. - // - void* (*AllocNL)(struct FPDFEMB_MEMMGR* pMgr, unsigned int size); - - // Interfce: Realloc - // Reallocate a memory block - // Parameters: - // pMgr - Pointer to the memory manager. - // pointer - An existing memory block, or NULL. - // new_size - New size (number of bytes) of the memory block. Can be zero. - // Return value: - // The pointer of reallocated memory block, it could be a new block, or just - // the previous block with size modified. - // Comments: - // If an existing memory block specified, the data in the memory block will - // be copied to the new block, if reallocated. - // - // In order to handle OOM situation, application can use longjmp() inside - // implementation of this function. If underlying memory manager fails to - // allocate enough memory, then application can use longjmp() to jump to - // OOM handling codes. - // - void* (*Realloc)(struct FPDFEMB_MEMMGR* pMgr, void* pointer, unsigned int new_size); - - // Interface: Free - // Free a memory block - // Parameters: - // pMgr - Pointer to the memory manager. - // pointer - An existing memory block. - // Return Value: - // None. - // - void (*Free)(struct FPDFEMB_MEMMGR* pMgr, void* pointer); -}; - -// Function: FPDFEMB_Init -// Initialize the FPDFEMB module -// Parameters: -// mem_mgr - Pointer to memory manager structure -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// This function will allocate necessary internal data structure for -// the whole module to operate. -FPDFEMB_RESULT FPDFEMB_Init(FPDFEMB_MEMMGR* mem_mgr); - -typedef void (*FPDFEMB_FIXED_OOM_HANDLER)(void* memory, int size); - -// Function: FPDFEMB_InitFixedMemory -// Initialize the FPDFEMB module, providing a fixed memory heap -// Parameters: -// memory - Pointer to a pre-allocated memory block -// size - Number of bytes in the memory block -// oom_handler - Pointer to a function which will be called when OOM happens. Can be -// NULL if application doesn't want to be notified om OOM. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// In many embedded system, memory usage are predetermined. The application -// is assigned with fixed size of available memory, then it can pre-allocate -// a memory block with maximum size and pass to this function to initialize -// FPDFEMB module. In this case, FPDFEMB won't need any additional memory -// allocation. -// -// In case the pre-allocated memory has run out, the "oom_proc" callback -// function will be called to notify the application that an OOM recovery -// procedure needs to be performed. -// -FPDFEMB_RESULT FPDFEMB_InitFixedMemory(void* memory, int size, FPDFEMB_FIXED_OOM_HANDLER oom_handler); - -// Memory Management Flags -#define FPDFEMB_NONLEAVE 1 -#define FPDFEMB_MOVABLE 2 -#define FPDFEMB_DISCARDABLE 4 - -// Structure: FPDFEMB_MEMMGR_EX -// This is an extended version of memory manager interface, allowing advanced -// memory management, including movable and discardable memory blocks. -// -// Use this interface with FPDFEMB_InitExt function. -// -struct FPDFEMB_MEMMGR_EX { - // Interface: Alloc - // Allocate a memory block - // Parameters: - // pMgr - Pointer to the memory manager. - // size - Number of bytes for the memory block. - // flags - A combination of flags defined above. - // Return Value: - // The pointer to allocated memory block. NULL if no memory available. - // If FPDFEMB_MOVABLE flag is used, implementation should return a handle - // to the memory block, if it supports movable block allocation. - // Comments: - // The implementation should not do any action if no memory available, - // just return NULL. OOM handling can be done in OOM_Handler interface. - // - void* (*Alloc)(struct FPDFEMB_MEMMGR_EX* pMgr, unsigned int size, int flags); - - // Interface: OOM_Handler - // OOM (out-of-memory) situation handler - // Parameters: - // pMgr - Pointer to the memory manager. - // Return Value: - // None. - // Comments: - // In order to handle OOM situation, application can use longjmp() inside - // implementation of this function. - // - void (*OOM_Handler)(struct FPDFEMB_MEMMGR_EX* pMgr); - - // Interfce: Realloc - // Reallocate a memory block - // Parameters: - // pMgr - Pointer to the memory manager. - // pointer - Pointer to an existing memory block, or handle to a movable - // block. Can not be NULL. - // new_size - New size (number of bytes) of the memory block. Can not be zero. - // Return value: - // The pointer of reallocated memory block, it could be a new block, or just - // the previous block with size modified. - // If FPDFEMB_MOVABLE flag is used, implementation should return a handle - // to the memory block, if it supports movable block allocation. - // Comments: - // If an existing memory block specified, the data in the memory block should - // be copied to the new block, if reallocated. - // - // The implementation should not do any action if no memory available, - // just return NULL. OOM handling can be done in OOM_Handler interface. - // - void* (*Realloc)(struct FPDFEMB_MEMMGR_EX* pMgr, void* pointer, unsigned int new_size, int flags); - - // Interface: Lock - // Lock a movable memory block - // Parameters: - // pMgr - Pointer to the memory manager. - // handle - Handle to movable memory block, returned by Alloc or Realloc. - // Return Value: - // The pointer of the memory block. NULL if the block was discarded. - // Comments: - // This interface is optional, if implementation doesn't support movable memory - // block, then this interface can be set to NULL. - // - void* (*Lock)(struct FPDFEMB_MEMMGR_EX* pMgr, void* handle); - - // Interface: Unlock - // Unlock a locked movable memory block - // Parameters: - // pMgr - Pointer to the memory manager. - // handle - Handle to movable memory block, returned by Alloc or Realloc. - // Return Value: - // None. - // Comments: - // This interface is optional, if implementation doesn't support movable memory - // block, then this interface can be set to NULL. - // - void (*Unlock)(struct FPDFEMB_MEMMGR_EX* pMgr, void* handle); - - // Interface: Free - // Free a memory block - // Parameters: - // pMgr - Pointer to the memory manager. - // pointer - Pointer to an existing memory block, or handle to a movable block. - // Return Value: - // None. - // - void (*Free)(struct FPDFEMB_MEMMGR_EX* pMgr, void* pointer, int flags); - - void* user; // A user pointer, used by the application -}; - -// Function: FPDFEMB_LoadJbig2Decoder -// Function: FPDFEMB_LoadJpeg2000Decoder -// Enable JBIG2 or JPEG2000 image decoder -// Parameters: -// None. -// Return Value: -// None. -// Comments: -// If you want to display JBIG2 or JPEG2000 encoded images, you need to call -// these functions after FPDFEMB initialized. -// -// Calling these functions will increase code size by about 200K-400K bytes. -// Also JPEG2000 decoder may not be available on some platforms. -// -void FPDFEMB_LoadJbig2Decoder(); -void FPDFEMB_LoadJpeg2000Decoder(); - -// Function: FPDFEMB_InitEx -// Initialize the FPDFEMB module with the extended memory manager -// Parameters: -// mem_mgr - Pointer to memory manager structure -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// This function will allocate necessary internal data structure for -// the whole module to operate. -FPDFEMB_RESULT FPDFEMB_InitEx(FPDFEMB_MEMMGR_EX* mem_mgr); - -// Function: FPDFEMB_Exit -// Stop using FPDFEMB module and release all resources -// Parameters: -// None. -// Return Value: -// None. -// Comments: -// All loaded documents and pages will become invalid after this call. -// -// This function is useful for OOM recovery: when your application hits -// an OOM situation, calling this function will clear all memory allocated -// by FPDFEMB module, then you can call one of the initialization functions, -// reopen the document and recovery from OOM. -// -void FPDFEMB_Exit(); - -// Function: FPDFEMB_AllocMemory -// Allocate memory -// Parameters: -// size - Number of bytes -// Return Value: -// The allocated buffer pointer. NULL for out of memory. -// -void* FPDFEMB_AllocMemory(unsigned int size); - -// Function: FPDFEMB_FreeMemory -// Free allocated memory -// Parameters: -// pointer - Pointer returned by FPDFEMB_AllocMemory -// Return Value: -// None. -// -void FPDFEMB_FreeMemory(void* pointer); - -// Function: FPDFEMB_FreeCaches -// Free all expendable caches used by FPDFEMB in order to save memory -// Parameters: -// None. -// Return Value: -// None. -// Comments: -// When an application memory manager runs out of memory, before an OOM situation -// is raised, the application can try this -// -void FPDFEMB_FreeCaches(); - -/******************************************************************************************** -**** -**** Document Operations -**** -********************************************************************************************/ - -// Structure: FPDFEMB_FILE_ACCESS -// Describe the way to access a file (readonly). -struct FPDFEMB_FILE_ACCESS { - // Inteface: GetSize - // Get total size of the file - // Parameters: - // file - Pointer to this file access structure - // Return Value: - // File size, in bytes. Implementation can return 0 for any error. - // - unsigned int (*GetSize)(struct FPDFEMB_FILE_ACCESS* file); - - // Interface: ReadBlock - // Read a data block from the file - // Parameters: - // file - Pointer to this file access structure - // buffer - Pointer to a buffer receiving read data - // offset - Byte offset for the block, from beginning of the file - // size - Number of bytes for the block. - // Return Value: - // Error code, or FPDFERR_SUCCESS for success. - // - FPDFEMB_RESULT (*ReadBlock)(struct FPDFEMB_FILE_ACCESS* file, void* buffer, - unsigned int offset, unsigned int size); - - void* user; // A user pointer, used by the application -}; - -// Structure: FPDFEMB_PAUSE -// An interface for pausing a progressive process. -struct FPDFEMB_PAUSE { - // Interface: NeedPauseNow - // Check if we need to pause a progressive proccess now - // Parameters: - // pause - Pointer to the pause structure - // Return Value: - // Non-zero for pause now, 0 for continue. - // Comments: - // Typically implementation of this interface compares the current system tick - // with the previous one, if the time elapsed exceeds certain threshold, then - // the implementation returns TRUE, indicating a pause is needed. - // - FPDFEMB_BOOL (*NeedPauseNow)(struct FPDFEMB_PAUSE* pause); - - void* user; // A user pointer, used by the application -}; - -typedef void* FPDFEMB_DOCUMENT; - -// Function: FPDFEMB_StartLoadDocument -// Start loading a PDF document -// Parameters: -// file - Pointer to file access structure. -// This structure must be kept valid as long as the document is open. -// password - Pointer to a zero-terminated byte string, for the password. -// Or NULL for no password. -// document - Receiving the document handle -// pause - A callback mechanism allowing the document loading process -// to be paused before it's finished. This can be NULL if you -// don't want to pause. -// Return Value: -// FPDFERR_SUCCESS: document successfully loaded. -// FPDFERR_TOBECONTINUED: The document loading can't be finished now. -// See comments below. -// FPDFERR_PASSWORD: incorrect password. -// FPDFERR_FORMAT: not a PDF or corrupted PDF. -// FPDFERR_FILE: file access error. -// FPDFERR_MEMORY: out of memory. -// Comments: -// Document loading is a progressive process. It might take a long time to -// load a document, especiall when a file is corrupted, FPDFEMB will try to -// recover the document contents by scanning the whole file. If "pause" parameter -// is provided, this function may return FPDFERR_TOBECONTINUED any time during -// the document loading. -// -// When FPDFERR_TOBECONTINUED is returned, the "document" parameter will -// still receive a valid document handle, however, no further operations can -// be performed on the document, except the "FPDFEMB_ContineLoadDocument" function -// call, which resume the document loading. -// -FPDFEMB_RESULT FPDFEMB_StartLoadDocument(FPDFEMB_FILE_ACCESS* file, const char* password, - FPDFEMB_DOCUMENT* document, FPDFEMB_PAUSE* pause); - -// Function: FPDFEMB_ContinueLoadDocument -// Continue loading a PDF document -// Parameters: -// document - Document handle returned by FPDFEMB_StartLoadDocument function -// pause - A callback mechanism allowing the document loading process -// to be paused before it's finished. This can be NULL if you -// don't want to pause. -// Return Value: -// FPDFERR_SUCCESS: document successfully loaded. -// FPDFERR_TOBECONTINUED: The document loading can't be finished now. -// Further call to this function is needed. -// FPDFERR_PASSWORD: incorrect password. -// FPDFERR_FORMAT: not a PDF or corrupted PDF. -// FPDFERR_FILE: file access error. -// FPDFERR_MEMORY: out of memory. -// FPDFERR_STATUS: document already loaded. -// FPDFERR_PARAM: invalid parameter (like NULL document handle) -// -FPDFEMB_RESULT FPDFEMB_ContinueLoadDocument(FPDFEMB_DOCUMENT document, FPDFEMB_PAUSE* pause); - -// Function: FPDFEMB_CloseDocument -// Close a PDF document and free all associated resources -// Parameters: -// document - Document handle -// Return Value: -// Error code. FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_CloseDocument(FPDFEMB_DOCUMENT document); - -// Function: Get page count -// Get number of pages in the document -// Parameters: -// document - Document handle -// Return Value: -// Number of pages. -// -int FPDFEMB_GetPageCount(FPDFEMB_DOCUMENT document); - -// Function: FPDFEMB_SetFileBufferSize -// Set size of internal buffer used to read from source file. -// Parameters: -// size - Number of bytes -// Return Value: -// None. -// Comments: -// Currently FPDFEMB uses 512 bytes as default buffer size. The new buffer size -// takes effect next time you call FPDFEMB_StartLoadDocument. -// -void FPDFEMB_SetFileBufferSize(int size); - -/******************************************************************************************** -**** -**** Page Basic Operations -**** -********************************************************************************************/ - -typedef void* FPDFEMB_PAGE; - -// Function: FPDFEMB_LoadPage -// Load a page -// Parameters: -// document - Document handle -// index - Page index, starting from zero -// page - Receiving the loaded page handler -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_LoadPage(FPDFEMB_DOCUMENT document, int index, FPDFEMB_PAGE* page); - -// Function: FPDFEMB_ClosePage -// Close a page and release all related resources -// Parameters: -// page - Page handle -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_ClosePage(FPDFEMB_PAGE page); - -// Function: FPDFEMB_GetPageSize -// Get size of a page -// Parameters: -// page - Page handle -// width - Receiving page width, in hundredth of points -// height - Receiving page height, in hundredth of points -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// -FPDFEMB_RESULT FPDFEMB_GetPageSize(FPDFEMB_PAGE page, int* width, int* height); - -// Structure: FPDFEMB_RECT -// Rectangle area in device or page coordination system -// -struct FPDFEMB_RECT -{ - // For device system, coordinations are measured in pixels; - // For page system, coordinations are measured in hundredth of points. - int left; - int top; - int right; - int bottom; -}; - -// Function: FPDFEMB_GetPageBBox -// Get displayable area (bounding box) of a page -// Parameters: -// page - Page handle -// rect - Pointer to a structure receiving the rectangle -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// -FPDFEMB_RESULT FPDFEMB_GetPageBBox(FPDFEMB_PAGE page, FPDFEMB_RECT* rect); - -/******************************************************************************************** -**** -**** Page Parsing -**** -********************************************************************************************/ - -// Function: FPDFEMB_StartParse -// Start parsing a page, so it can get rendered or searched -// Parameters: -// page - Page handle -// text_only - flag for parsing texts only (used for searching) -// pause - A structure that can pause the parsing process. -// Or NULL if you don't want to pause the process. -// Return Value: -// FPDFERR_SUCCESS: parsing successfully finished; -// FPDFERR_TOBECONTINUED: parsing started successfully, but not finished; -// FPDFERR_STATUS: page already parsed, or parsing already started. -// Other return value: error code. -// Comments: -// Parsing is a progressive process. This function starts the parsing process, -// and may return before parsing is finished, if a pause structure is provided. -// -// Application should call FPDFEMB_ContinueParse repeatedly to finish the parsing -// when return value is FPDFERR_TOBECONTINUED. -// -// There can be only one parsing procedure active for a page, and if a page -// has already been parsed, you can't start a parsing again. -// -FPDFEMB_RESULT FPDFEMB_StartParse(FPDFEMB_PAGE page, FPDFEMB_BOOL text_only, - FPDFEMB_PAUSE* pause); - -// Function: FPDFEMB_ContinueParse -// Continue the page parsing -// Parameters: -// page - Page handle -// pause - A structure that can pause the parsing process. -// Or NULL if you don't want to pause the process. -// Return Value: -// FPDFERR_SUCCESS: parsing successfully finished; -// FPDFERR_TOBECONTINUED: parsing performed successfully, but not finished; -// FPDFERR_STATUS: page already parsed (or parsing not started). -// Other return value: error code. -// Comments: -// FPDFEMB_StartParse should be called before on the page. -// -// Application should call FPDFEMB_ContinueParse repeatedly to finish the parsing -// when return value is FPDFERR_TOBECONTINUED. -// -FPDFEMB_RESULT FPDFEMB_ContinueParse(FPDFEMB_PAGE page, FPDFEMB_PAUSE* pause); - -// Function: FPDFEMB_GetParseProgress -// Get an estimated parsing progress in percentage -// Parameters: -// page - Page handle -// Return Value: -// An integer between 0 and 100 (inclusive) indicating the parsing progress. -// The result is just a rough estimation. -// -int FPDFEMB_GetParseProgress(FPDFEMB_PAGE page); - -/******************************************************************************************** -**** -**** Page Rendering -**** -********************************************************************************************/ - -typedef void* FPDFEMB_BITMAP; - -// Function: FPDFEMB_StartQuickDraw -// Start drawing a quick preview of a page -// Parameters: -// dib - DIB handle, as the rendering device -// page - Page handle. The page has to be parsed first. -// start_x - Left pixel position of the display area in the device coordination -// start_y - Top pixel position of the display area in the device coordination -// size_x - Horizontal size (in pixels) for displaying the page -// size_y - Vertical size (in pixels) for displaying the page -// rotate - Page orientation: 0 (normal), 1 (rotated 90 degrees clockwise), -// 2 (rotated 180 degrees), 3 (rotated 90 degrees counter-clockwise). -// flags - Reserved, must be zero. -// pause - Pointer to a structure that can pause the rendering process. -// Can be NULL if no pausing is needed. -// Return Value: -// FPDFERR_SUCCESS: quickdraw successly finished; -// FPDFERR_TOBECONTINUED: quickdraw started successfully, but not finished. -// FPDFEMB_ContinueQuickDraw needs to be called to finish the quickdraw; -// FPDFERR_STATUS: quickdraw already in progress, or page not parsed; -// Other return value: error code. -// Comments: -// It's often useful to present user a quick preview of a page, right after the -// page is parsed. This preview renders only a limited set of easy features in the -// page, so it'll be rather quick to finish this process. -// -FPDFEMB_RESULT FPDFEMB_StartQuickDraw(FPDFEMB_BITMAP dib, FPDFEMB_PAGE page, - int start_x, int start_y, int size_x, int size_y, int rotate, - int flags, FPDFEMB_PAUSE* pause); - -// Function: FPDFEMB_ContinueQuickDraw -// Continue a quick draw processing -// Parameters: -// page - Page handle. The page has to be parsed first. -// pause - Pointer to a structure that can pause the rendering process. -// Can be NULL if no pausing is needed. -// Return Value: -// FPDFERR_SUCCESS: quickdraw successly finished; -// FPDFERR_TOBECONTINUED: quickdraw started successfully, but not finished. -// more calls to this function needed to finish the quickdraw; -// FPDFERR_STATUS: quickdraw not started yet; -// Other return value: error code. -// -FPDFEMB_RESULT FPDFEMB_ContinueQuickDraw(FPDFEMB_PAGE page, FPDFEMB_PAUSE* pause); - -#define FPDFEMB_ANNOT 0x01 // Set if annotations are to be rendered -#define FPDFEMB_LCD_TEXT 0x02 // Set if using text rendering optimized for LCD display -#define FPDFEMB_BGR_STRIPE 0x04 // Set if the device is using BGR LCD stripe - -// Function: FPDFEMB_StartRender -// Start rendering of a page. -// Parameter: -// dib - DIB handle, as the rendering device -// page - Page handle. The page has to be parsed first. -// start_x - Left pixel position of the display area in the device coordination -// start_y - Top pixel position of the display area in the device coordination -// size_x - Horizontal size (in pixels) for displaying the page -// size_y - Vertical size (in pixels) for displaying the page -// rotate - Page orientation: 0 (normal), 1 (rotated 90 degrees clockwise), -// 2 (rotated 180 degrees), 3 (rotated 90 degrees counter-clockwise). -// flags - 0 for normal display, or combination of flags defined above -// clip - Pointer to clip rectangle (in DIB device coordinations), -// or NULL if no clipping needed. -// pause - Pointer to a structure that can pause the rendering process. -// Can be NULL if no pausing is needed. -// Return Value: -// FPDFERR_SUCCESS: rendering successfully finished; -// FPDFERR_TOBECONTINUED: rendering started successfully, but not finished; -// Other return value: error code. -// Comments: -// Rendering is a progressive process. This function starts the rendering process, -// and may return before rendering is finished, if a pause structure is provided. -// -// Application should call FPDFEMB_ContinueRender repeatedly to finish the rendering -// when return value is FPDFERR_TOBECONTINUED. -// -// There can be only one rendering procedure for a page at any time. And rendering -// can be started over and over again for the same page. If a page rendering is already -// active, starting another one will cancel the previous rendering. -// -// Rendering of a page doesn't draw the page background, therefore, you usually need -// to draw the background in the DIB yourself. -// -FPDFEMB_RESULT FPDFEMB_StartRender(FPDFEMB_BITMAP dib, FPDFEMB_PAGE page, - int start_x, int start_y, int size_x, int size_y, int rotate, int flags, - FPDFEMB_RECT* clip, FPDFEMB_PAUSE* pause); - -// Function: FPDFEMB_ContinueRender -// Continue the page rendering -// Parameters: -// page - Page handle -// pause - Pointer to a structure that can pause the rendering process. -// Can be NULL if no pausing is needed. -// Return Value: -// FPDFERR_SUCCESS: rendering successfully finished. -// FPDFERR_TOBECONTINUED: rendering needs to be continued; -// Other return value: error code. -// Comments: -// This function may return any time when the pause interface indicates -// a pause is needed. Application can call FPDFEMB_ContinueRender any number -// of times, until FPDFERR_TOBECONTINUED is not returned. -// -FPDFEMB_RESULT FPDFEMB_ContinueRender(FPDFEMB_PAGE page, FPDFEMB_PAUSE* pause); - -// Function: FPDFEMB_GetRenderProgress -// Get an estimated rendering progress in percentage -// Parameters: -// page - Page handle -// Return Value: -// An integer between 0 and 100 (inclusive) indicating the rendering progress. -// The result is just a rough estimation. -// If the rendering just finished, this function will return 0. -// -int FPDFEMB_GetRenderProgress(FPDFEMB_PAGE page); - -// Function: FPDFEMB_SetHalftoneLimit -// Set pixel count limit for using halftone when display image -// Parameter: -// limit - Number of pixels for the limit -// Return Value: -// None. -// Comments: -// By default, FPDFEMB displays all bitmaps using downsamping, which means -// if the image is shrinked onto screen, only part of pixels will be picked -// and displayed. This saves a lot of calculation, especially for big images -// with millions of pixels. However the display quality can be bad. In order to -// reach a balance between performance and quality, application can use this -// function to set a limit, if number of pixels in an image is more than this -// limit, then FPDFEMB will use downsampling for quick drawing, otherwise, if -// the image has less pixels, FPDFEMB will use halftoning for better quality. -// -void FPDFEMB_SetHalftoneLimit(int limit); - -/******************************************************************************************** -**** -**** Coordination Conversion -**** -********************************************************************************************/ - -// Structure: FPDFEMB_POINT -// A point in device or page coordination system -// -struct FPDFEMB_POINT -{ - // For device system, coordinations are measured in pixels; - // For page system, coordinations are measured hundredth of points. - int x; - int y; -}; - -// Function: FPDFEMB_DeviceToPagePoint, FPDFEMB_DeviceToPageRect -// Convert the device coordinations of a point or a rectangle to page coordinations. -// Parameters: -// page - Handle to the page. Returned by FPDFEMB_LoadPage function. -// start_x - Left pixel position of the display area in the device coordination -// start_y - Top pixel position of the display area in the device coordination -// size_x - Horizontal size (in pixels) for displaying the page -// size_y - Vertical size (in pixels) for displaying the page -// rotate - Page orientation: 0 (normal), 1 (rotated 90 degrees clockwise), -// 2 (rotated 180 degrees), 3 (rotated 90 degrees counter-clockwise). -// point - A point structure with device coordinations upon the call, -// also receiving the result page coordinations. -// rect - A rectangle structure with device coordinations upon the call, -// also receiving the result page coordinations. -// Return value: -// None. -// Comments: -// The page coordination system has its origin at left-bottom corner of the page, -// with X axis goes along the bottom side to the right, and Y axis goes along the -// left side upward. No matter how you zoom, scroll, or rotate a page, a particular -// element (like text or image) on the page should always have the same coordination -// values in the page coordination system. -// -// The device coordination system is device dependant. For bitmap device, its origin -// is at left-top corner of the window. You must make sure the start_x, start_y, size_x, -// size_y and rotate parameters have exactly same values as you used in -// FPDFEMB_StartRender() function call. -// -// For rectangle conversion, the result rectangle is always "normalized", meaning for -// page coordinations, left is always smaller than right, bottom is smaller than top. -// -void FPDFEMB_DeviceToPagePoint(FPDFEMB_PAGE page, - int start_x, int start_y, int size_x, int size_y, int rotate, - FPDFEMB_POINT* point); - -void FPDFEMB_DeviceToPageRect(FPDFEMB_PAGE page, - int start_x, int start_y, int size_x, int size_y, int rotate, - FPDFEMB_RECT* rect); - -// Function: FPDFEMB_PageToDevicePoint, FPDFEMB_PageToDeviceRect -// Convert the page coordinations of a point or a rectangle to device coordinations. -// Parameters: -// page - Handle to the page. Returned by FPDFEMB_LoadPage function. -// start_x - Left pixel position of the display area in the device coordination -// start_y - Top pixel position of the display area in the device coordination -// size_x - Horizontal size (in pixels) for displaying the page -// size_y - Vertical size (in pixels) for displaying the page -// rotate - Page orientation: 0 (normal), 1 (rotated 90 degrees clockwise), -// 2 (rotated 180 degrees), 3 (rotated 90 degrees counter-clockwise). -// point - A point structure with page coordinations upon the call, -// also receiving the result device coordinations. -// rect - A rectangle structure with page coordinations upon the call, -// also receiving the result device coordinations. -// Return value: -// None -// Comments: -// For rectangle conversion, the result rectangle is always "normalized", meaning for -// device coordinations, left is always smaller than right, top is smaller than bottom. -// -void FPDFEMB_PageToDevicePoint(FPDFEMB_PAGE page, - int start_x, int start_y, int size_x, int size_y, int rotate, - FPDFEMB_POINT* point); - -void FPDFEMB_PageToDeviceRect(FPDFEMB_PAGE page, - int start_x, int start_y, int size_x, int size_y, int rotate, - FPDFEMB_RECT* rect); - -/******************************************************************************************** -**** -**** Text Search -**** -********************************************************************************************/ - -// Search flags for FPDFEMB_FindFirst function -#define FPDFEMB_MATCHCASE 1 // whether matching case -#define FPDFEMB_MATCHWHOLEWORD 2 // whether matching whole word -#define FPDFEMB_CONSECUTIVE 4 // whether matching consecutively (for example, "CC" will - // match twice in "CCC"). - -// Function: FPDFEMB_FindFirst -// Find first occurance of a pattern string in a page -// Parameters: -// page - Page handle. -// pattern - A zero-terminated unicode string to be found. -// from_last - Whether we start from the end of page -// flags - Search flags, see above defined constants -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Is not found, FPDFERR_NOTFOUND is returned. -// Comments: -// A page must be parsed first before it can be searched. -// There can be only one search in progress for a page. A new search will -// cancel the previous one. -// -// IMPORTANT: this function is now obsolete and kept for back compatibility -// only, please use FPDFEMB_FindFrom function below. -// -FPDFEMB_RESULT FPDFEMB_FindFirst(FPDFEMB_PAGE page, const FPDFEMB_WCHAR* pattern, - FPDFEMB_BOOL from_last, unsigned int flags); - -// Function: FPDFEMB_FindFrom -// Find first occurance of a pattern string in a page, from a particular position -// Parameters: -// page - Page handle. -// pattern - A zero-terminated unicode string to be found. -// pos - The position, returned from FPDFEMB_GetSearchPos. -// Or 0 from the beginning of page, -1 from the end of page. -// flags - Search flags, see above defined constants -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Is not found, FPDFERR_NOTFOUND is returned. -// Comments: -// A page must be parsed first before it can be searched. -// There can be only one search in progress for a page. A new search will -// cancel the previous one. -// -FPDFEMB_RESULT FPDFEMB_FindFrom(FPDFEMB_PAGE page, const FPDFEMB_WCHAR* pattern, - int pos, unsigned int flags); - -// Function: FPDFEMB_FindNext -// Find next occurance of a search -// Parameters: -// page - Page handle. -// FPDFEMB_FindFirst must be called for this page first. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Is not found, FPDFERR_NOTFOUND is returned. -// -FPDFEMB_RESULT FPDFEMB_FindNext(FPDFEMB_PAGE page); - -// Function: FPDFEMB_FindPrev -// Find previous occurance of a search -// Parameters: -// page - Page handle. -// FPDFEMB_FindFirst must be called for this page first. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Is not found, FPDFERR_NOTFOUND is returned. -// -FPDFEMB_RESULT FPDFEMB_FindPrev(FPDFEMB_PAGE page); - -// Function: FPDFEMB_CountFoundRects -// Get number of rectangles for last found result -// Parameters: -// page - Page handle. -// Return Value: -// Number of rectangles for last found result. 0 for not found or failure. -// -int FPDFEMB_CountFoundRects(FPDFEMB_PAGE page); - -// Function: FPDFEMB_GetFoundRect -// Get a particular found rectangle -// Parameters: -// page - Page handle. -// index - Zero-based index for the rectangle. -// rect - Receiving the result rectangle, in hundredth of points -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// Application should always call FPDFEMB_CountFoundRects first to get -// number of rectangles, then use this function to get each rectangle. -// -// The returned rectangle uses page coordination system. -// -FPDFEMB_RESULT FPDFEMB_GetFoundRect(FPDFEMB_PAGE page, int index, FPDFEMB_RECT* rect); - -// Function: FPDFEMB_GetSearchPos -// Return position of current search result -// Parameters: -// page - Page handle. -// Return Value: -// Zero based character index for the current search result. -1 if not found. -// -int FPDFEMB_GetSearchPos(FPDFEMB_PAGE page); - -// Function: FPDFEMB_QuickSearch -// Search a pattern in a page quickly, without the page to be parsed -// Parameters: -// document - Document handle returned by FPDFEMB_StartLoadDocument function -// page_index - Zero-based index of the page -// pattern - A zero-terminated unicode string to be found. -// case_sensitive - Non-zero for case-sensitive searching, zero for case-insensitive -// Return Value: -// FPDFERR_SUCCESS if pattern found, FPDFERR_NOTFOUND if pattern not found. -// Otherwise error code is returned. -// Comments: -// This function does a rough and quick search in a page, before the page is loaded. -// The quick search will not generate an exact result saying where the pattern is -// found, and, it might be possible if a quick search result is "pattern found", and -// a real search for the same pattern, in the same page, will result in "not found". -// -// However, if quick search doesn't find a pattern in a page, then we can be sure the -// pattern won't be found in this page when we do a real search. So, this function is -// very useful when we search in a multiple-page document, and we want to quickly skip -// those pages in which the pattern can't possibly be found. -// -FPDFEMB_RESULT FPDFEMB_QuickSearch(FPDFEMB_DOCUMENT document, int page_index, - const FPDFEMB_WCHAR* pattern, int case_sensitive); - -/******************************************************************************************** -**** -**** Text Information -**** -********************************************************************************************/ - -// Function: FPDFEMB_GetCharCount -// Get number of characters in the page -// Parameters: -// page - Page handle -// count - Receiving number of characters -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_GetCharCount(FPDFEMB_PAGE page, int* count); - -// Structure: FPDFEMB_CHAR_INFO -// Character information. -struct FPDFEMB_CHAR_INFO { - int unicode; // Unicode for the character. 0 if not available. - // Space and new line charcters (U+0020 and U+000A) may be generated - // according to the text formatting. - FPDFEMB_POINT origin; // X/Y position for the character origin, in hundredth of points - FPDFEMB_RECT bbox; // Bounding box of the character, in hundredth of points - // Maybe an empty box (left == right or top == bottom). -}; - -// Function: FPDFEMB_GetCharInfo -// Get character information -// Parameters: -// page - Page handle -// index - Character index, starting from zero -// char_info - Receiving the character info -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// Application must call FPDFEMB_GetCharCount first before it can call this function -// for any particular characters. -// -FPDFEMB_RESULT FPDFEMB_GetCharInfo(FPDFEMB_PAGE page, int index, FPDFEMB_CHAR_INFO* char_info); - -// Function: FPDFEMB_GetCharIndexAtPos() -// Get index of character nearest to a certain position on the page -// Parameters: -// page - Page handle -// x - X position in PDF page coordination system -// y - Y position in PDF page coordination system -// index - Pointer to an integer receiving zero-based character index. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// This function finds the character that's nearest to the particular page position. -// If there is no character, the output index will be -1. -// -FPDFEMB_RESULT FPDFEMB_GetCharIndexAtPos(FPDFEMB_PAGE page, double x, double y, int* index); - -/******************************************************************************************** -**** -**** Device Independant Bitmap -**** -********************************************************************************************/ - -#define FPDFDIB_BGR 1 // 3 bytes per pixel, byte order: Blue, Green, Red -#define FPDFDIB_BGRx 2 // 4 bytes per pixel, byte order: Blue, Green, Red, not used -#define FPDFDIB_BGRA 3 // 4 bytes per pixel, byte order: Blue, Green, Red, Alpha -#define FPDFDIB_GRAY 4 // 1 byte per pixel (grayscale) - -// Function: FPDFEMB_CreateDIB -// Create a DIB (Device Independant Bitmap) -// Parameters: -// width - Width pixels; -// height - Height pixels; -// format - Format type. See FPDFDIB_xxx constants -// buffer - External buffer provided for the DIB, -// or NULL if new buffer is to be allocated. -// stride - Number of bytes for each scan line, for external buffer only. -// If not specified, 4-byte alignment assumed. -// dib - Receiving the created DIB handle -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// If "buffer" parameter is not NULL, then the provided buffer must conform -// to standard DIB format (see comments of FPDFEMB_GetDIBData function below). -// -// This function doesn't initialize the pixels inside the DIB buffer. So if you -// want to use the DIB to display a PDF page, you usually need to initialize -// the DIB to white background by youself. -// -FPDFEMB_RESULT FPDFEMB_CreateDIB(int width, int height, int format, - void* buffer, int stride, FPDFEMB_BITMAP* dib); - -// Function: FPDFEMB_DestroyDIB -// Destroy a DIB -// Parameters: -// dib - DIB handle -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// If external buffer is used (specified in "buffer" parameter when calling -// FPDFEMB_CreateDIB), the buffer will not be destroyed. -// -FPDFEMB_RESULT FPDFEMB_DestroyDIB(FPDFEMB_BITMAP dib); - -// Function: FPDFEMB_GetDIBWidth -// Get width (in pixels) of a DIB -// Parameters: -// dib - DIB handle -// Return Value: -// DIB width in pixels. -// -int FPDFEMB_GetDIBWidth(FPDFEMB_BITMAP dib); - -// Function: FPDFEMB_GetDIBHeight -// Get height (in pixels) of a DIB -// Parameters: -// dib - DIB handle -// Return Value: -// DIB height in pixels. -// -int FPDFEMB_GetDIBHeight(FPDFEMB_BITMAP dib); - -// Function: FPDFEMB_GetDIBData -// Get data pointer to a DIB -// Parameters: -// dib - DIB handle -// Return Value: -// Pointer to the DIB data. -// Comments: -// DIB data are organized in scanlines, from top down. -// -void* FPDFEMB_GetDIBData(FPDFEMB_BITMAP dib); - -// Function: FPDFEMB_GetDIBStride -// Get scan line stride of a DIB -// Parameters: -// dib - DIB handle -// Return Value: -// Number of bytes occupied by a scanline -// -int FPDFEMB_GetDIBStride(FPDFEMB_BITMAP dib); - -// Function: FPDFEMB_GetRotatedDIB -// Swap X/Y dimensions of a DIB to generate a rotated new DIB -// Parameters: -// dib - DIB handle -// flip_x - Whether flip pixels on the destination X dimension (left/right) -// flip_y - Whether flip pixels on the destination Y dimension (up/down) -// result_dib - Receiving the result DIB handle -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// -FPDFEMB_RESULT FPDFEMB_GetRotatedDIB(FPDFEMB_BITMAP dib, - FPDFEMB_BOOL bFlipX, FPDFEMB_BOOL bFlipY, - FPDFEMB_BITMAP* result_dib); - -// Function: FPDFEMB_StretchDIB -// Stretch a source DIB into another destination DIB -// Parameters: -// dest_dib - The destination DIB handle -// dest_left - Left position in the destination DIB -// dest_top - Top position in the destination DIB -// dest_width - Destination width, in pixels. Can be negative for horizontal flipping -// dest_height - Destination height, in pixels. Can be negative for vertical flipping -// clip - Destination clipping rectangle, or NULL for no clipping. -// The coordinations are measured in destination bitmap. -// src_dib - Source DIB handle. -// interpol - Whether we use interpolation to improve the result quality -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// -FPDFEMB_RESULT FPDFEMB_StretchDIB(FPDFEMB_BITMAP dest_dib, int dest_left, int dest_top, - int dest_width, int dest_height, FPDFEMB_RECT* clip_rect, - FPDFEMB_BITMAP src_dib, FPDFEMB_BOOL interpol); - -// Function: FPDFEMB_TransformDIB -// Transform a source DIB into another destination DIB -// Parameters: -// dest_dib - The destination DIB handle -// clip - Destination clipping rectangle, or NULL for no clipping. -// The coordinations are measured in destination bitmap. -// src_dib - Source DIB handle. -// x - X coordination of the dest origin -// y - Y coordination of the dest origin -// xx - X distance of the dest X vector -// yx - Y distance of the dest X vector -// xy - X distance of the dest Y vector -// yy - Y distance of the dest Y vector -// interpol - Whether we use interpolation to improve the result quality -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// All coordinations and distances are measured in destination bitmap system. -// -// This function places the bottom-left pixel of the image at the destination -// origin, then the bottom sideline along the destination X vector, and left -// sideline along the destination Y vector. -// -FPDFEMB_RESULT FPDFEMB_TransformDIB(FPDFEMB_BITMAP dest_dib, FPDFEMB_RECT* clip_rect, - FPDFEMB_BITMAP src_dib, int x, int y, int xx, int yx, - int xy, int yy, FPDFEMB_BOOL interpol); - -/******************************************************************************************** -**** -**** Custom Font Handler and CJK Support -**** -********************************************************************************************/ - -// FPDFEMB comes with standard fonts for Latin characters. If your device is targeted to -// Eastern Asian markets, then system fonts must be provided and registered with FPDFEMB. -// Depending on your device configuration, those system fonts might be in TrueType or Type1 -// format, or some other non-standard compact format. For the first case, you should register -// a font mapper so FPDFEMB can pick the right font file, and for the second case, you -// should register a glyph provider so FPDFEMB can get glyph bitmap for each character. - -#define FPDFEMB_CHARSET_DEFAULT 0 -#define FPDFEMB_CHARSET_GB 936 -#define FPDFEMB_CHARSET_BIG5 950 -#define FPDFEMB_CHARSET_JIS 932 -#define FPDFEMB_CHARSET_KOREA 949 -#define FPDFEMB_CHARSET_UNICODE 1200 - -#define FPDFEMB_FONT_FIXEDPITCH 1 -#define FPDFEMB_FONT_SERIF 2 -#define FPDFEMB_FONT_SYMBOLIC 4 -#define FPDFEMB_FONT_SCRIPT 8 -#define FPDFEMB_FONT_NONSYMBOLIC 32 -#define FPDFEMB_FONT_ITALIC 64 -#define FPDFEMB_FONT_ALLCAP 0x10000 -#define FPDFEMB_FONT_SMALLCAP 0x20000 -#define FPDFEMB_FONT_FORCEBOLD 0x40000 - -// Structure: FPDFEMB_FONT_MAPPER -// Defines interface for system font mapper. -// -struct FPDFEMB_FONT_MAPPER -{ - // Interface: MapFont - // Find font file path for a particular PDF font - // Parameters: - // mapper - Pointer to the FPDFEMB_FONT_MAPPER structure - // name - Font name - // charset - Charset ID (see above FPDFEMB_CHARSET_xxx constants) - // flags - Font flags (see above FPDFEMB_FONT_xxx constants) - // weight - Weight of the font. Range from 100 to 900. 400 is normal, - // 700 is bold. - // path - Receiving the full file path. The buffer size is 512 bytes. - // face_index - Receiving an zero-based index value for the font face, if the - // mapped font file is a "collection" (meaning a number of faces - // are stored in the same file). If the font file is not a - // collection, the index value should be zero. - // Return Value: - // Non-zero for success, 0 for failure. - // - FPDFEMB_BOOL (*MapFont)(struct FPDFEMB_FONT_MAPPER* mapper, const char* name, int charset, - unsigned int flags, int weight, - char* path, int* face_index); - - void* user; // A user pointer, used by the application -}; - -// Function: FPDFEMB_SetFontMapper -// Use a system font mapper (typically for Chinese/Japanese/Korean charsets) -// Parameters: -// mapper - Pointer to FPDFEMB_FONT_MAPPER structure. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// This function is used with devices that come with one or more system fonts, -// and those fonts are in standard TT or T1 format. -// -FPDFEMB_RESULT FPDFEMB_SetFontMapper(FPDFEMB_FONT_MAPPER* mapper); - -// Structure: FPDFEMB_GLYPH_PROVIDER -// Interface for providing glyph bitmap of non-latin characters. -// This is usually used for embedded devices with Chinese/Japanese/Korean -// fonts installed, but those fonts are not in TrueType or Type1 format. -// -struct FPDFEMB_GLYPH_PROVIDER -{ - // Interface: MapFont - // Return an internal handle for a font - // Parameters: - // provider - Pointer to this structure - // name - Font name - // charset - Charset ID (see above FPDFEMB_CHARSET_xxx constants) - // flags - Font flags (see above FPDFEMB_FONT_xxx constants) - // weight - Weight of the font. Range from 100 to 900. 400 is normal, - // 700 is bold. - // Return Value: - // An internal handle to the mapped font. If the embedded device supports - // multiple fonts, then this value can serve as an identifier to differentiate - // among them. If the device supports only one font, then implementation of - // this function can simply return NULL. - // - void* (*MapFont)(struct FPDFEMB_GLYPH_PROVIDER* provider, const char* name, int charset, - unsigned int flags, int weight); - // Interface: GetGlyphBBox - // Get glyph bounding box - // Parameters: - // provider - Pointer to this structure - // font - Internal handle to the font. Returned by MapFont interface. - // unicode - Unicode of the character - // CID - Adobe CID for this character. Or zero if not available. - // bbox - Receiving the result bounding box. See comments below. - // Return Value: - // None. - // Comments: - // The bounding box is measure in a glyph coordination system, in which the - // origin is set to character origin, and unit is set to one-thousandth of - // "em size" (representing the font size). - // - // In most CJK fonts, all CJK characters (except some symbols or western - // characters) have same glyph bounding box: - // left = 0, right = 1000, bottom = -220, top = 780. - // - // It's OK to return a box that's larger than the actual glyph box. - // - void (*GetGlyphBBox)(struct FPDFEMB_GLYPH_PROVIDER* provider, void* font, - FPDFEMB_WCHAR unicode, unsigned short CID, - FPDFEMB_RECT* bbox); - - // Interface: GetGlyphBitmap - // Get bitmap of a glyph - // Parameters: - // provider - Pointer to this structure - // font - Internal handle to the font. Returned by MapFont interface. - // unicode - Unicode of the character - // CID - Adobe CID for this character. Or zero if not available. - // font_width - Width of the font em square, measured in device units. - // font_height - Height of the font em square, measured in device units. - // left - Receiving the left offset, from the character origin, of the - // result glyph bitmap. Positive value will move the bitmap to - // the right side, negative to the left. - // top - Receiving the top offset, from the character origin, of the - // result glyph bitmap. Positive value will move the bitmap upward, - // negative downward. - // bitmap_width - Receiving number of width pixels in the result bitmap - // bitmap_height - Receiving number of height pixels in the result bitmap - // buffer - Receiving a data buffer pointer, allocated by the implementation. - // See comments below. - // stride - Receiving number of bytes per scanline, in the data buffer. - // pdf_width - Width of the character specified in PDF. It is measured in one- - // thousandth of the font width. It can be 0 if width not specified - // in PDF. See comments below. - // Return Value: - // Non-zero for success. 0 for failure. In this case the glyph can not be displayed. - // Comments: - // The buffer should be allocated by implemenation. And it must be allocated - // using FPDFEMB_AllocMemory function. The result buffer will be destroyed by - // FPDFEMB SDK, so implementation should not destroy it. - // - // The implementation should write "coverage" data into allocated buffer, one byte - // for each pixel, from top scanline to bottom scanline, within each scan line, - // from left pixel to right. Coverage 0 means the pixel is outside the glyph, - // coverage 255 means the pixel is inside the glyph. - // - // The "pdf_width" parameter can be used to scale the character in system font - // horizontally to match the font width specified in PDF. For example, if we have - // a PDF file which requires a character in half-width (pdf_width is 500), but - // in the system font the character has full-width (1000), then the glyph provider - // implementation should scale the font horizontally to half of its original width. - // - FPDFEMB_BOOL (*GetGlyphBitmap)(struct FPDFEMB_GLYPH_PROVIDER* provider, void* font, - FPDFEMB_WCHAR unicode, unsigned short CID, - double font_width, double font_height, int* left, int* top, - int* bitmap_width, int* bitmap_height, - void** buffer, int* stride, int pdf_width); - - void* user; // A user pointer, used by the application -}; - -// Function: FPDFEMB_SetGlyphProvider -// Make use of a glyph provider: generating glyph bitmap for non-Latin characters -// Parameters: -// provider - Pointer to the glyph provider structure. -// This structure must stay valid throughout usage of FPDFEMB module. -// Return Value: -// None. -// Comments: -// FPDFEMB embeds some standard fonts for Latin characters and symbols, like -// Times, Courier and Helvetica (Arial). For non-Latin characters, however, -// FPDFEMB has to ask glyph provide for help. -// -// If an embedded device carries fonts for non-Latin character sets, especially -// those for CJK markets, then the application can implement a glyph provider, -// allowing PDFs using non-embedded CJK fonts to be properly displayed. -// -void FPDFEMB_SetGlyphProvider(FPDFEMB_GLYPH_PROVIDER* provider); - -// Function: FPDFEMB_LoadCMap_GB -// Function: FPDFEMB_LoadCMap_GB_Ext -// Function: FPDFEMB_LoadCMap_CNS -// Function: FPDFEMB_LoadCMap_Korean -// Function: FPDFEMB_LoadCMap_Japan -// Function: FPDFEMB_LoadCMap_Japan_Ext -// Make use of character encoding maps embedded with FPDFEMB -// Parameters: -// None. -// Return Value: -// None. -// Comments: -// These functions add character encoding data to your application. Each call -// will increase the code size of your application. Total data size for all -// character sets is 151K bytes. -void FPDFEMB_LoadCMap_GB(); -void FPDFEMB_LoadCMap_GB_Ext(); // Load full code table for GB -void FPDFEMB_LoadCMap_CNS(); -void FPDFEMB_LoadCMap_Korea(); -void FPDFEMB_LoadCMap_Japan(); -void FPDFEMB_LoadCMap_Japan_Ext(); // Load full code table for Japan - -/******************************************************************************************** -**** -**** Document Information -**** -********************************************************************************************/ - -// Function: PDFEMB_GetDocInfoString -// Get information string about the document, like creator, modifcation date, etc. -// Parameters: -// document - Handle to the document -// key - A byte string for the information key. Currently can be one of the followings: -// "Title", "Author", "Subject", "Keywords", "Creator", "Producer", "CreationDate", -// "ModDate", or some custom information key, if supported by the PDF file. -// buffer - A buffer allocated by the application, or NULL. -// bufsize - [IN/OUT] A pointer to a number indicating the buffer size (number of bytes), -// before this function call. After return, this place will store -// number of bytes used by the output (including terminator). -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// The string is output in Unicode, using UTF-16LE format. It's terminated by -// two consecutive zero bytes. -// -// If the "buffer" parameter is NULL, then the "bufsize" parameter will receive -// number of bytes required to store the string (including the two-byte terminator). -// -FPDFEMB_RESULT FPDFEMB_GetDocInfoString(FPDFEMB_DOCUMENT document, const char* key, void* buffer, unsigned int* bufsize); - -/******************************************************************************************** -**** -**** Action (Destination) Information -**** -********************************************************************************************/ - -typedef void* FPDFEMB_ACTION; - -// Action types supported by FPDFEMB -#define FPDFEMB_DEST_NONE 0 // No or unsupported destination -#define FPDFEMB_DEST_PAGE 1 // A page inside the same document -#define FPDFEMB_DEST_DOC 2 // An external PDF document -#define FPDFEMB_DEST_URL 3 // An external URL -#define FPDFEMB_ACTION_LAUNCH 4 // Launch an external file or command - -// Zoom mode for destination -#define FPDFEMB_ZOOM_NONE 0 // Zoom mode not specified -#define FPDFEMB_ZOOM_FACTOR 1 // Specific zoom factor is used -#define FPDFEMB_ZOOM_FITPAGE 2 // Fit the whole page on screen -#define FPDFEMB_ZOOM_FITWIDTH 3 // Fit width of the page on screen -#define FPDFEMB_ZOOM_FITHEIGHT 4 // Fit height of the page on screen -#define FPDFEMB_ZOOM_FITRECT 5 // Fit a particular rectangle on screen -#define FPDFEMB_ZOOM_FITCONTENT 6 // Fit whole content of page on screen -#define FPDFEMB_ZOOM_FITCONTENTW 7 // Fit content width of page on screen -#define FPDFEMB_ZOOM_FITCONTENTH 8 // Fit content height of page on screen - -// Data structure for page destination -struct FPDFEMB_PAGEDEST -{ - int page_index; // Zero based index for the page - int zoom_mode; // See FPDFEMB_ZOOM_xxx definition above - int zoom_factor; // For FPDFEMB_ZOOM_FACTOR only: the zoom factor (in percentage) - FPDFEMB_RECT position; // Specify position inside the page. Depends on the zoom mode, - // different members of the rectangle are used: - // FPDFEMB_ZOOM_NONE: left, top - // FPDFEMB_ZOOM_FACTOR: left, top - // FPDFEMB_ZOOM_FITPAGE: none - // FPDFEMB_ZOOM_FITWIDTH: top - // FPDFEMB_ZOOM_FITHEIGHT: left - // FPDFEMB_ZOOM_FITRECT: left, top, bottom, right - // FPDFEMB_ZOOM_FITCONTENT: none - // FPDFEMB_ZOOM_FITCONTENTW: top - // FPDFEMB_ZOOM_FITCONTENTH: left -}; - -// Data structure for document destination -struct FPDFEMB_DOCDEST -{ - FPDFEMB_PAGEDEST page_data; // page data - char* file_name; // The file name, encoded in original charset (maybe MBCS) -}; - -// Data structure for URL destination -struct FPDFEMB_URLDEST -{ - char* url; // URL encoded in 7-bit ASCII -}; - -// Data structure for Launch action -struct FPDFEMB_LAUNCHACTION -{ - int new_window; // Whether a new window should be opened - char* file_name; // The file name, encoded in original charset (maybe MBCS) -}; - -// Function: FPDFEMB_Action_GetType -// Get type of an action -// Parameters: -// document - Handle to the document -// action - Handle to the action -// dest_type - Pointer to an integer receiving type of the destination. See the above -// FPDFEMB_DEST_xxx definitions -// data_size - Pointer to an integer receiving data block size for the destination. -// If this parameter is NULL, then data size won't be retrieved. -// Comments: -// Each different type of destination has different data structure. The "data_size" result -// indicates how many bytes is required to hold the destination data structure. The application -// can then allocate sufficient buffer and then call FPDFEMB_Bookmark_GetDest function to -// get the real data. -// -FPDFEMB_RESULT FPDFEMB_Action_GetType(FPDFEMB_DOCUMENT document, FPDFEMB_ACTION action, int* dest_type, int* data_size); - -// Function: FPDFEMB_Action_GetData -// Get detailed data of a particular action -// Parameters: -// document - Handle to the document -// action - Handle to the action -// buffer - Application allocated buffer receiving the destination data -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// See data structure definition for different action type above. Please note -// the actual action data might use more space than the structure definition -// shows, to store things like file name or URL. So you should always call -// FPDFEMB_Action_GetType first to get data size then allocate enough buffer -// for this call. -// -FPDFEMB_RESULT FPDFEMB_Action_GetData(FPDFEMB_DOCUMENT document, FPDFEMB_ACTION action, void* buffer); - -// Function: FPDFEMB_Action_GetNext -// Get next action in an action chain -// Parameters: -// document - Handle to the document -// action - Handle to current action -// next - Receiving handle to next action. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// If there is no next action, the "next" parameter will be set to NULL after the function returns. -// -FPDFEMB_RESULT FPDFEMB_Action_GetNext(FPDFEMB_ACTION action, FPDFEMB_ACTION* next); - -/******************************************************************************************** -**** -**** Bookmark Information -**** -********************************************************************************************/ - -typedef void* FPDFEMB_BOOKMARK; - -// Function: FPDFEMB_Bookmark_GetFirstChild -// Get first child of a bookmark item, or first top level bookmark item -// Parameters: -// document - Handle to the document -// parent - Handle to the parent bookmark. -// Can be NULL if you want to get the first top level item. -// bookmark - Receiving handle to the first child or top level bookmark item. -// If result is NULL, then bookmark not found. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// -FPDFEMB_RESULT FPDFEMB_Bookmark_GetFirstChild(FPDFEMB_DOCUMENT document, FPDFEMB_BOOKMARK parent, - FPDFEMB_BOOKMARK* bookmark); - -// Function: FPDFEMB_Bookmark_GetFirstChild -// Get next sibling of a bookmark item -// Parameters: -// document - Handle to the document -// bookmark - Handle to the bookmark -// sibling - Receiving the handle of next sibling. -// If result is NULL, then this is the last bookmark in this level. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// -FPDFEMB_RESULT FPDFEMB_Bookmark_GetNextSibling(FPDFEMB_DOCUMENT document, FPDFEMB_BOOKMARK bookmark, - FPDFEMB_BOOKMARK* sibling); - -// Function: FPDFEMB_Bookmark_GetTitle -// Get title of a bookmark -// Parameters: -// bookmark - Handle to the bookmark -// buffer - A buffer allocated by the application, or NULL. -// bufsize - [IN/OUT] A pointer to a number indicating the buffer size, -// before this function call. After return, this place will store -// number of bytes used by the output (including terminator). -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// The title is output in Unicode, using UTF-16LE format. It's terminated by -// two consecutive zero bytes. -// -// If the "buffer" parameter is NULL, then the "bufsize" parameter will receive -// number of bytes required to store the bookmark title (including the two- -// byte terminator). -// -// If the buffer provided is smaller than the required size, then this function -// will not copy any data, return FPDFEMB_PARAM, and the required buffer size will -// also be put in "bufsize" parameter. -// -FPDFEMB_RESULT FPDFEMB_Bookmark_GetTitle(FPDFEMB_BOOKMARK bookmark, void* buffer, unsigned int* bufsize); - -// Function: FPDFEMB_Bookmark_GetPage -// Get page number of a bookmark pointing to -// Parameters: -// document - Handle to the document -// bookmark - Handle to the bookmark -// page - Receiving the page number. -1 if this bookmark doesn't actually -// point to a page inside the document. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success -// Comments: -// Some bookmark might not point to a page, some bookmark might have more than one destination -// (action), for detailed information about a bookmark, you should call FPDFEMB_Bookmark_GetAction. -// -FPDFEMB_RESULT FPDFEMB_Bookmark_GetPage(FPDFEMB_DOCUMENT document, FPDFEMB_BOOKMARK bookmark, int* page); - -// Function: FPDFEMB_Bookmark_GetAction -// Get action(s) associated with a particular bookmark -// Parameters: -// document - Handle to the document -// bookmark - Handle to the bookmark -// action - Receiving handle of first action -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_Bookmark_GetAction(FPDFEMB_DOCUMENT document, FPDFEMB_BOOKMARK bookmark, FPDFEMB_ACTION* action); - -/******************************************************************************************** -**** -**** Hyperlink Information -**** -********************************************************************************************/ - -// Function: FPDFEMB_Link_GetCount -// Get number of hyperlinks inside a page -// Parameters: -// page - Page handle. -// link_count - Pointer to an integer receiving the number of links -// reserved - Must be zero now. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// This function must be called before any other link related function can -// be called for the page. -// -FPDFEMB_RESULT FPDFEMB_Link_GetCount(FPDFEMB_PAGE page, int* link_count, int reserved); - -// Function: FPDFEMB_Link_GetAction -// Get action(s) associated with a particular hyperlink -// Parameters: -// page - Page handle -// link_index - Zero-based index for the link -// action - Receiving handle of first action -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_Link_GetAction(FPDFEMB_PAGE page, int link_index, FPDFEMB_ACTION* action); - -// Function: FPDFEMB_Link_GetAreaCount -// Get number of area (quadrilaterals) for a link -// Parameters: -// page - Page handle -// link_index - Zero-based index for the link -// count - Pointer to an integer receiving number of quadrilaterals -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_Link_GetAreaCount(FPDFEMB_PAGE page, int link_index, int* count); - -// Function: FPDFEMB_Link_GetArea -// Get a particular quadrilateral for a link -// Parameters: -// page - Page handle -// link_index - Zero-based index for the link -// area_index - Zero-based index for the quadrilateral -// points - Pointer to an array consists 4 points, receiving coordinations -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// The result in "points" array are the X/Y coordinations for the four vertices -// of the quadrilateral. Vertices are in the following order: lower left, lower -// right, upper right, upper left. -// -FPDFEMB_RESULT FPDFEMB_Link_GetArea(FPDFEMB_PAGE page, int link_index, int area_index, - FPDFEMB_POINT* points); - -/******************************************************************************************** -**** -**** Graphic Output (onto DIB) -**** -********************************************************************************************/ - -typedef void* FPDFEMB_FONT; - -// Function: FPDFEMB_OpenStandardFont -// Get ready to use a standard PDF font -// Parameters: -// font_name - Name of the font. See a list of supported fonts below. -// font_handle - Receiving the font handle. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// Currently supported standard fonts: -// Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique, -// Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique, -// Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic, -// Symbol, ZapfDingbats. -// -FPDFEMB_RESULT FPDFEMB_OpenStandardFont(const char* font_name, FPDFEMB_FONT* font_handle); - -// Function: FPDFEMB_OpenSystemFont -// Get ready to use a system font -// Parameters: -// font_name - Font name -// charset - Charset ID (see above FPDFEMB_CHARSET_xxx constants) -// flags - Font flags (see above FPDFEMB_FONT_xxx constants) -// weight - Weight of the font. Range from 100 to 900. 400 is normal, -// 700 is bold. -// font_handle - Receiving the font handle. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// Comments: -// System font is supported only if either FPDFEMB_SetFontMapper or -// FPDFEMB_SetGlyphProvider is called. -// Font attributes (name, charset, flags and weight) can be all optional, if the -// font mapper or glyph provider doesn't make use of them. -// -FPDFEMB_RESULT FPDFEMB_OpenSystemFont(const char* font_name, int charset, unsigned int flags, int weight, - FPDFEMB_FONT* font_handle); - -// Function: FPDFEMB_CloseFont -// Close a font handle. -// Parameters: -// font_handle - Handle to the font. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_CloseFont(FPDFEMB_FONT font_handle); - -struct FPDFEMB_TEXTMATRIX -{ - double a, b, c, d; -}; - -// Function: FPDFEMB_OutputText -// Output text string onto a DIB device. -// Parameters: -// dib - DIB handle, as the output device -// x, y - DIB coordinations for the origin point of the first character. -// font_handle - Handle to the font -// font_size - Font size in pixels -// matrix - Matrix for the text output. Can be NULL. -// text - Zero-terminated unicode text string -// argb - Color of the text, in 0xaarrggbb format. -// Return Value: -// Error code, or FPDFERR_SUCCESS for success. -// -FPDFEMB_RESULT FPDFEMB_OutputText(FPDFEMB_BITMAP dib, int x, int y, FPDFEMB_FONT font_handle, double font_size, - FPDFEMB_TEXTMATRIX* matrix, const FPDFEMB_WCHAR* text, unsigned long argb); - -#ifdef __cplusplus -}; -#endif - -#endif // #ifdef _FPDFEMB_H_ diff --git a/src/images/fpdfemb_ext.h b/src/images/fpdfemb_ext.h deleted file mode 100644 index d82c4df..0000000 --- a/src/images/fpdfemb_ext.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -/** Extended interfaces for JPEG, JPEG2000 and JBIG2 decoders **/ -typedef struct -{ - /** Initialize the decoding context, with memory allocator provided by FPDFEMB. - Implementation should return a pointer to the decoding context. - */ - void* (*Init)(void* (*alloc_func)(unsigned int), void (*free_func)(void*)); - - /** Finish with the decoding. */ - void (*Finish)(void* pContext); - - /** Input JPEG encoded data from the source. - This function may be called multiple times during decoding progress. - */ - void (*Input)(void* pContext, const unsigned char* src_buf, unsigned long src_size); - - /** Read the header information. Return non-zero for success, 0 for failure */ - int (*ReadHeader)(void* pContext); - - /** Get info from the decoder, including image width, height and number of components */ - void (*GetInfo)(void* pContext, int* width, int* height, int* nComps); - - /** Read one scanline from decoded image */ - int (*ReadScanline)(void* pContext, unsigned char* dest_buf); - - /** Get number of available source bytes left in the input stream */ - unsigned long (*GetAvailInput)(void* pContext); -} FPDFEMB_JPEG_DECODER; - -void FPDFEMB_SetJpegDecoder(FPDFEMB_JPEG_DECODER* pDecoder); - -typedef struct -{ - /** Initialize the decoder with the full source data. - Implementation should return a pointer to the context. - */ - void* (*Init)(const unsigned char* src_buf, unsigned long src_size); - - /** Destroy the context */ - void (*Finish)(void* context); - - /** Get image info from the context, including width, height, number of components - in original codestream, and number of components in output image. For some - particular type of encoded image, like paletted image, these two numbers of - components may vary. - */ - void (*GetInfo)(void* context, unsigned long* width, unsigned long* height, - unsigned long* codestream_nComps, unsigned long* output_nComps); - - /** Do the real data decoding, output to a pre-allocated buffer. - bTranslateColor indicates whether the decoder should use JPEG2000 embedded - color space info to translate image into sRGB color space. - "offsets" array describes the byte order of all components. For example, - {2,1,0} means the first components is output to last byte. - */ - void (*Decode)(void* context, unsigned char* dest_buf, int pitch, - int bTranslateColor, unsigned char* offsets); -} FPDFEMB_JPEG2000_DECODER; - -void FPDFEMB_SetJpeg2000Decoder(FPDFEMB_JPEG2000_DECODER* pDecoder); - -typedef struct -{ - /** Do the whole decoding process. Supplied parameters include width, height, source image - data and size, global data and size (can be shared among different images), destination - buffer and scanline pitch in dest buffer. - */ - void (*Decode)(unsigned long width, unsigned long height, const unsigned char* src_buf, - unsigned long src_size, const unsigned char* global_buf, unsigned long global_size, - unsigned char* dest_buf, int dest_pitch); -} FPDFEMB_JBIG2_DECODER; - -void FPDFEMB_SetJbig2Decoder(FPDFEMB_JBIG2_DECODER* pDecoder); - -#ifdef __cplusplus -}; -#endif |