// gifimage.cpp -- image data from gif file // // Written by Frederic Bouvier, started November 2004. // // Copyright (C) 2004 Frederic Bouvier - fredb@users.sourceforge.net // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // $Id: gifimage.cpp,v 1.2 2005/05/09 07:01:52 fredb Exp $ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_GIF_LIB_H #include "gifimage.hpp" #include #include #ifdef HAVE_UNISTD_H #include #endif #include extern "C" { # include "gif_lib.h" } FGSD_GIFImage::FGSD_GIFImage( bool __reverted ) : _reverted( __reverted ) { } FGSD_GIFImage::~FGSD_GIFImage () { } bool FGSD_GIFImage::load (const char *__fileName) { bool ret = false; GifFileType *gif = DGifOpenFileName( __fileName ); if ( gif != 0 ) { int res = DGifSlurp( gif ); if ( res == GIF_OK && gif->ImageCount >= 1 ) { SavedImage *image = gif->SavedImages; allocImage( gif->SWidth, gif->SHeight ); for ( int i = 0; i < gif->SHeight; i++ ) { int r = _reverted ? gif->SHeight - ( i + 1 ) : i; unsigned char *buf = buffer( r ); for ( int j = 0; j < gif->SWidth; j++ ) { char index = image->RasterBits[ i * gif->SWidth + j ]; GifByteType red = 0; GifByteType green = 0; GifByteType blue = 0; if ( index < gif->SColorMap->ColorCount ) { red = gif->SColorMap->Colors[ index ].Red; green = gif->SColorMap->Colors[ index ].Green; blue = gif->SColorMap->Colors[ index ].Blue; } buf[ j * 3 + 0 ] = red; buf[ j * 3 + 1 ] = green; buf[ j * 3 + 2 ] = blue; } } ret = true; } DGifCloseFile( gif ); } return ret; } int FGSD_GIFImage::readData_cb(void *g,unsigned char* b,int l) { #ifdef HAVE_DGIFOPEN GifFileType *gif = static_cast( g ); return static_cast( gif->UserData )->readData( b, l ); #else return 0; #endif } int FGSD_GIFImage::readData(unsigned char *b,int l) { int nb = l; if ( nb + _sent > (int)_len ) { nb = _len - _sent; } ::memcpy( b, _buffer + _sent, nb ); _sent += nb; return nb; } bool FGSD_GIFImage::loadFromBuffer( const unsigned char *__buffer, size_t __len ) { bool ret = false; #ifdef HAVE_DGIFOPEN _sent = 0; _buffer = __buffer; _len = __len; GifFileType *gif = DGifOpen(this,(InputFunc)readData_cb); #else #ifdef HAVE_MKSTEMP char *templ = 0; char *tmp = getenv("TMP"); if ( tmp == 0 ) { templ = new char[ 17 ]; strcpy( templ, "/tmp/fgsd$XXXXXX" ); } else { templ = new char[ strlen( tmp ) + 13 ]; strcpy( templ, tmp ); strcat( templ, "/fgsd$XXXXXX" ); } int fd = mkstemp( templ ); if ( fd == -1 ) { delete[] templ; return false; } write( fd, (char *)__buffer, __len ); lseek( fd, 0, SEEK_SET ); GifFileType *gif = DGifOpenFileHandle( fd ); #else char *fn = tempnam( 0, "fgsd$" ); if ( fn ) { std::ofstream fstr( fn, std::ios::trunc | std::ios::binary ); fstr.write( (char *)__buffer, __len ); } GifFileType *gif = DGifOpenFileName( fn ); #endif #endif if ( gif != 0 ) { int res = DGifSlurp( gif ); if ( res == GIF_OK && gif->ImageCount >= 1 ) { SavedImage *image = gif->SavedImages; allocImage( gif->SWidth, gif->SHeight ); for ( int i = 0; i < gif->SHeight; i++ ) { int r = _reverted ? gif->SHeight - ( i + 1 ) : i; unsigned char *buf = buffer( r ); for ( int j = 0; j < gif->SWidth; j++ ) { char index = image->RasterBits[ i * gif->SWidth + j ]; GifByteType red = 0; GifByteType green = 0; GifByteType blue = 0; if ( index < gif->SColorMap->ColorCount ) { red = gif->SColorMap->Colors[ index ].Red; green = gif->SColorMap->Colors[ index ].Green; blue = gif->SColorMap->Colors[ index ].Blue; } buf[ j * 3 + 0 ] = red; buf[ j * 3 + 1 ] = green; buf[ j * 3 + 2 ] = blue; } } ret = true; } DGifCloseFile( gif ); } #ifndef HAVE_DGIFOPEN #ifdef HAVE_MKSTEMP close( fd ); unlink( templ ); delete[] templ; #else unlink( fn ); #endif #endif return ret; } #endif