/*
- * 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.
#include "loader-gif.h"
#include <gif_lib.h>
-#include <cstdlib>
#include <dali/integration-api/debug.h>
-#include <dali/integration-api/bitmap.h>
+#include <adaptors/devel-api/adaptor-framework/pixel-buffer.h>
+#include <memory>
+
+// 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
{
if(NULL != gifInfo)
{
// clean up GIF resources
+#ifdef LIBGIF_VERSION_5_1_OR_ABOVE
int errorCode = 0; //D_GIF_SUCCEEDED is 0
- DGifCloseFile(gifInfo, &errorCode);
+ DGifCloseFile( gifInfo, &errorCode );
if( errorCode )
{
- DALI_LOG_ERROR( "GIF Loader: DGifCloseFile Error. Code: %d\n", 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;
+ GifFileType*& gifInfo;
};
// Used in the GIF interlace algorithm to determine the starting byte and the increment required
bool LoadGifHeader(FILE *fp, unsigned int &width, unsigned int &height, GifFileType** gifInfo)
{
int errorCode = 0; //D_GIF_SUCCEEDED is 0
- *gifInfo = DGifOpen(reinterpret_cast<void*>(fp), ReadDataFromGif, &errorCode);
+
+#ifdef LIBGIF_VERSION_5_1_OR_ABOVE
+ *gifInfo = DGifOpen( reinterpret_cast<void*>(fp), ReadDataFromGif, &errorCode );
+#else
+ *gifInfo = DGifOpen( reinterpret_cast<void*>(fp), ReadDataFromGif );
+#endif
if ( !(*gifInfo) || errorCode )
{
- DALI_LOG_ERROR( "GIF Loader: DGifOpen Error. Code: %d\n", errorCode);
+ DALI_LOG_ERROR( "GIF Loader: DGifOpen Error. Code: %d\n", errorCode );
return false;
}
}
/// 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 )
{
{
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" );
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 )
{
}
/// Called when we want to handle IMAGE_DESC_RECORD_TYPE
-bool HandleImageDescriptionRecordType( Bitmap& bitmap, 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 )
{
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<unsigned char[]> 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 ) )
{
// 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)
pixels += 3;
}
}
-
finished = true;
-
return true;
}
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.ExtensionBlocks->Function, &extensionByte );
+ for ( int extRetCode = DGifGetExtension( gifInfo, extensionBlockTypePointer, &extensionByte );
extensionByte != NULL;
extRetCode = DGifGetExtensionNext( gifInfo, &extensionByte ) )
{
return LoadGifHeader(fp, width, height, &gifInfo);
}
-bool LoadBitmapFromGif( const ResourceLoadingClient& client, const ImageLoader::Input& input, Integration::Bitmap& bitmap )
+bool LoadBitmapFromGif( const ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap )
{
FILE* const fp = input.file;
// Load the GIF Header file.