diff options
Diffstat (limited to 'skia/images/SkMovie_gif.cpp')
-rw-r--r-- | skia/images/SkMovie_gif.cpp | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/skia/images/SkMovie_gif.cpp b/skia/images/SkMovie_gif.cpp deleted file mode 100644 index c7db017..0000000 --- a/skia/images/SkMovie_gif.cpp +++ /dev/null @@ -1,234 +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: - // we do NOT hold onto the stream, so it is OK if it is on the - // stack of the caller - 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_StreamFactory(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; -} - -SkMovie* SkMovie_GIF_MemoryFactory(const void* data, size_t length) { - if (length > GIF_STAMP_LEN && !memcmp(GIF_STAMP, data, GIF_STAMP_LEN)) { - SkMemoryStream stream(data, length); - 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; -} |