X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=platform-abstractions%2Ftizen%2Fimage-loaders%2Floader-gif.cpp;h=9bcd17b764c30038d801783f706b93ce6011147d;hb=refs%2Fchanges%2F41%2F166141%2F1;hp=6d9ed0e79517dddabb894d08b1150873fe0fab63;hpb=43d62b88c530b72d2d419da81beffbdb13ec25fc;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/platform-abstractions/tizen/image-loaders/loader-gif.cpp b/platform-abstractions/tizen/image-loaders/loader-gif.cpp index 6d9ed0e..9bcd17b 100644 --- a/platform-abstractions/tizen/image-loaders/loader-gif.cpp +++ b/platform-abstractions/tizen/image-loaders/loader-gif.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,16 +18,18 @@ #include "loader-gif.h" #include -#include #include -#include -#include +#include +#include + +// We need to check if giflib has the new open and close API (including error parameter). +#ifdef GIFLIB_MAJOR +#define LIBGIF_VERSION_5_1_OR_ABOVE +#endif namespace Dali { -using Integration::Bitmap; -using Dali::Integration::PixelBuffer; namespace TizenPlatform { @@ -48,29 +50,23 @@ struct AutoCleanupGif if(NULL != gifInfo) { // clean up GIF resources - DGifCloseFile(gifInfo); +#ifdef LIBGIF_VERSION_5_1_OR_ABOVE + int errorCode = 0; //D_GIF_SUCCEEDED is 0 + DGifCloseFile( gifInfo, &errorCode ); + + if( errorCode ) + { + DALI_LOG_ERROR( "GIF Loader: DGifCloseFile Error. Code: %d\n", errorCode ); + } +#else + DGifCloseFile( gifInfo ); +#endif } } GifFileType*& gifInfo; }; -// Simple class to enforce clean-up of PixelBuffer -struct AutoDeleteBuffer -{ - AutoDeleteBuffer( PixelBuffer* _buffer ) - : buffer( _buffer ) - { - } - - ~AutoDeleteBuffer() - { - delete []buffer; - } - - PixelBuffer* buffer; -}; - // Used in the GIF interlace algorithm to determine the starting byte and the increment required // for each pass. struct InterlacePair @@ -99,10 +95,17 @@ int ReadDataFromGif(GifFileType *gifInfo, GifByteType *data, int length) /// Loads the GIF Header. bool LoadGifHeader(FILE *fp, unsigned int &width, unsigned int &height, GifFileType** gifInfo) { - *gifInfo = DGifOpen(reinterpret_cast(fp), ReadDataFromGif); + int errorCode = 0; //D_GIF_SUCCEEDED is 0 + +#ifdef LIBGIF_VERSION_5_1_OR_ABOVE + *gifInfo = DGifOpen( reinterpret_cast(fp), ReadDataFromGif, &errorCode ); +#else + *gifInfo = DGifOpen( reinterpret_cast(fp), ReadDataFromGif ); +#endif - if ( !(*gifInfo) ) + if ( !(*gifInfo) || errorCode ) { + DALI_LOG_ERROR( "GIF Loader: DGifOpen Error. Code: %d\n", errorCode ); return false; } @@ -119,7 +122,7 @@ bool LoadGifHeader(FILE *fp, unsigned int &width, unsigned int &height, GifFileT } /// Decode the GIF image. -bool DecodeImage( GifFileType* gifInfo, PixelBuffer* decodedData, const unsigned int width, const unsigned int height, const unsigned int bytesPerRow ) +bool DecodeImage( GifFileType* gifInfo, unsigned char* decodedData, const unsigned int width, const unsigned int height, const unsigned int bytesPerRow ) { if ( gifInfo->Image.Interlace ) { @@ -130,7 +133,7 @@ bool DecodeImage( GifFileType* gifInfo, PixelBuffer* decodedData, const unsigned { for( unsigned int currentByte = interlacePairPtr->startingByte; currentByte < height; currentByte += interlacePairPtr->incrementalByte ) { - PixelBuffer* row = decodedData + currentByte * bytesPerRow; + unsigned char* row = decodedData + currentByte * bytesPerRow; if ( DGifGetLine( gifInfo, row, width ) == GIF_ERROR ) { DALI_LOG_ERROR( "GIF Loader: Error reading Interlaced GIF\n" ); @@ -142,7 +145,7 @@ bool DecodeImage( GifFileType* gifInfo, PixelBuffer* decodedData, const unsigned else { // Non-interlace does not require any erratic reading / jumping. - PixelBuffer* decodedDataPtr( decodedData ); + unsigned char* decodedDataPtr( decodedData ); for ( unsigned int row = 0; row < height; ++row ) { @@ -174,7 +177,7 @@ GifColorType* GetImageColors( SavedImage* image, GifFileType* gifInfo ) } /// Called when we want to handle IMAGE_DESC_RECORD_TYPE -bool HandleImageDescriptionRecordType( Bitmap& bitmap, ImageAttributes& attributes, GifFileType* gifInfo, unsigned int width, unsigned int height, bool& finished ) +bool HandleImageDescriptionRecordType( Dali::Devel::PixelBuffer& bitmap, GifFileType* gifInfo, unsigned int width, unsigned int height, bool& finished ) { if ( DGifGetImageDesc( gifInfo ) == GIF_ERROR ) { @@ -189,35 +192,35 @@ bool HandleImageDescriptionRecordType( Bitmap& bitmap, ImageAttributes& attribut return false; } + Pixel::Format pixelFormat( Pixel::RGB888 ); + SavedImage* image( &gifInfo->SavedImages[ gifInfo->ImageCount - 1 ] ); const GifImageDesc& desc( image->ImageDesc ); - // Create a buffer to store the decoded data. - PixelBuffer* decodedData( new PixelBuffer[ width * height * sizeof( GifPixelType ) ] ); - AutoDeleteBuffer autoDeleteBuffer( decodedData ); + auto decodedData = new unsigned char[ width * height * sizeof( GifPixelType ) ]; + + std::unique_ptr ptr{ decodedData }; const unsigned int bytesPerRow( width * sizeof( GifPixelType ) ); const unsigned int actualWidth( desc.Width ); const unsigned int actualHeight( desc.Height ); + // Create a buffer to store the decoded data. + bitmap = Dali::Devel::PixelBuffer::New( actualWidth, actualHeight, pixelFormat ); + // Decode the GIF Image if ( !DecodeImage( gifInfo, decodedData, actualWidth, actualHeight, bytesPerRow ) ) { return false; } - // TODO: Add scaling support - // Get the colormap for the GIF GifColorType* color( GetImageColors( image, gifInfo ) ); // If it's an animated GIF, we still only read the first image // Create and populate pixel buffer. - - Pixel::Format pixelFormat( Pixel::RGB888 ); - PixelBuffer *pixels = bitmap.GetPackedPixelsProfile()->ReserveBuffer( pixelFormat, actualWidth, actualHeight ); - + auto pixels = bitmap.GetBuffer(); for (unsigned int row = 0; row < actualHeight; ++row) { for (unsigned int column = 0; column < actualWidth; ++column) @@ -230,11 +233,7 @@ bool HandleImageDescriptionRecordType( Bitmap& bitmap, ImageAttributes& attribut pixels += 3; } } - - attributes.SetSize( actualWidth, actualHeight ); - finished = true; - return true; } @@ -242,12 +241,21 @@ bool HandleImageDescriptionRecordType( Bitmap& bitmap, ImageAttributes& attribut bool HandleExtensionRecordType( GifFileType* gifInfo ) { SavedImage image; + GifByteType *extensionByte( NULL ); + +#ifdef LIBGIF_VERSION_5_1_OR_ABOVE + ExtensionBlock extensionBlocks; + image.ExtensionBlocks = &extensionBlocks; + image.ExtensionBlockCount = 1; + int *extensionBlockTypePointer = &image.ExtensionBlocks->Function; +#else image.ExtensionBlocks = NULL; image.ExtensionBlockCount = 0; - GifByteType *extensionByte( NULL ); + int *extensionBlockTypePointer = &image.Function; +#endif // Not really interested in the extensions so just skip them unless there is an error. - for ( int extRetCode = DGifGetExtension( gifInfo, &image.Function, &extensionByte ); + for ( int extRetCode = DGifGetExtension( gifInfo, extensionBlockTypePointer, &extensionByte ); extensionByte != NULL; extRetCode = DGifGetExtensionNext( gifInfo, &extensionByte ) ) { @@ -263,16 +271,18 @@ bool HandleExtensionRecordType( GifFileType* gifInfo ) } // unnamed namespace -bool LoadGifHeader(FILE *fp, const ImageAttributes& attributes, unsigned int &width, unsigned int &height ) +bool LoadGifHeader( const ImageLoader::Input& input, unsigned int& width, unsigned int& height ) { GifFileType* gifInfo = NULL; AutoCleanupGif autoCleanupGif(gifInfo); + FILE* const fp = input.file; return LoadGifHeader(fp, width, height, &gifInfo); } -bool LoadBitmapFromGif(FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, const ResourceLoadingClient& client ) +bool LoadBitmapFromGif( const ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap ) { + FILE* const fp = input.file; // Load the GIF Header file. GifFileType* gifInfo( NULL ); @@ -300,7 +310,7 @@ bool LoadBitmapFromGif(FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, co if( IMAGE_DESC_RECORD_TYPE == recordType ) { - if ( !HandleImageDescriptionRecordType( bitmap, attributes, gifInfo, width, height, finished ) ) + if ( !HandleImageDescriptionRecordType( bitmap, gifInfo, width, height, finished ) ) { return false; }