aboutsummaryrefslogtreecommitdiffstats
path: root/src/images
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:36 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:36 -0800
commit6eb364108744656fcd23a96a478aa772cd4e85bc (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/images
parenta23c4e24d873b11674987f97f1946e1c4d97e782 (diff)
downloadexternal_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.zip
external_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.tar.gz
external_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'src/images')
-rw-r--r--src/images/SkBitmap_RLEPixels.h19
-rw-r--r--src/images/SkCreateRLEPixelRef.cpp120
-rw-r--r--src/images/SkFDStream.cpp85
-rw-r--r--src/images/SkFlipPixelRef.cpp127
-rw-r--r--src/images/SkImageDecoder.cpp194
-rw-r--r--src/images/SkImageDecoder_Factory.cpp56
-rw-r--r--src/images/SkImageDecoder_fpdfemb.cpp236
-rw-r--r--src/images/SkImageDecoder_libbmp.cpp149
-rw-r--r--src/images/SkImageDecoder_libgif.cpp343
-rw-r--r--src/images/SkImageDecoder_libico.cpp392
-rw-r--r--src/images/SkImageDecoder_libjpeg.cpp800
-rw-r--r--src/images/SkImageDecoder_libpng.cpp799
-rw-r--r--src/images/SkImageDecoder_libpvjpeg.cpp206
-rw-r--r--src/images/SkImageDecoder_wbmp.cpp172
-rw-r--r--src/images/SkImageEncoder.cpp48
-rw-r--r--src/images/SkImageEncoder_Factory.cpp35
-rw-r--r--src/images/SkImageRef.cpp165
-rw-r--r--src/images/SkImageRefPool.cpp186
-rw-r--r--src/images/SkImageRefPool.h43
-rw-r--r--src/images/SkImageRef_GlobalPool.cpp83
-rw-r--r--src/images/SkMovie.cpp101
-rw-r--r--src/images/SkMovie_gif.cpp224
-rw-r--r--src/images/SkPageFlipper.cpp85
-rw-r--r--src/images/SkScaledBitmapSampler.cpp338
-rw-r--r--src/images/SkScaledBitmapSampler.h55
-rw-r--r--src/images/bmpdecoderhelper.cpp376
-rw-r--r--src/images/bmpdecoderhelper.h123
-rw-r--r--src/images/fpdfemb.h1765
-rw-r--r--src/images/fpdfemb_ext.h81
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(&copyBits);
-
- 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