static void GDALPrintGifError(
#if GIFLIB_MAJOR < 5
CPL_UNUSED 
#endif
GifFileType *hGifFile, const char* pszMsg)
{
/* GIFLIB_MAJOR is only defined in libgif >= 4.2.0 */
/* libgif 4.2.0 has retired PrintGifError() and added GifErrorString() */
#if defined(GIFLIB_MAJOR) && defined(GIFLIB_MINOR) && \
        ((GIFLIB_MAJOR == 4 && GIFLIB_MINOR >= 2) || GIFLIB_MAJOR > 4)
    /* Static string actually, hence the const char* cast */

#if GIFLIB_MAJOR >= 5
    const char* pszGIFLIBError = (const char*) GifErrorString(hGifFile->Error);
#else
    const char* pszGIFLIBError = (const char*) GifErrorString();
#endif
    if (pszGIFLIBError == NULL)
        pszGIFLIBError = "Unknown error";
    CPLError( CE_Failure, CPLE_AppDefined,
              "%s. GIFLib Error : %s", pszMsg, pszGIFLIBError );
#else
    PrintGifError();
    CPLError( CE_Failure, CPLE_AppDefined, "%s", pszMsg );
#endif
}
Пример #2
0
PixRectArray::PixRectArray(const StringArray &fileNames, StringArray &errors) {
  USES_CONVERSION;
  m_updateCounter = 0;
  for(size_t i = 0; i < fileNames.size(); i++) {
    const String &name = fileNames[i];
    try {
      if(FileNameSplitter(name).getExtension().equalsIgnoreCase(_T(".gif"))) {
        int error;
        const char *namea = T2A(name.cstr());
        GifFileType *gifFile = DGifOpenFileName(namea, &error);
        if(gifFile == NULL) {
          throwException(_T("%s"), GifErrorString(error));
        }
        if(DGifSlurp(gifFile) != GIF_OK) {
          const String msg = GifErrorString(gifFile->Error);
          DGifCloseFile(gifFile, &error);
          throwException(_T("%s"), msg.cstr());
        }
        const int imageCount   = gifFile->ImageCount;

        for(int k = 0; k < imageCount; k++) {
          add(new GifPixRect(gifFile, k));
        }
        DGifCloseFile(gifFile, &error);
      } else {
        add(GifPixRect::load(name));
      }
    } catch(Exception e) {
      errors.add(e.what());
    }
  }
}
Пример #3
0
void checkGifError(const char *file, int line, int errorCode) {
  if(errorCode == GIF_OK) {
    return;
  }
  printf("Error in %s line %d:%s\n", file, line, GifErrorString(errorCode));
  exit(-1);
}
Пример #4
0
int main(int argc, char **argv) {
  argv++;
  if(!*argv) usage();

  int errorCode;
  GifFileType *gifFile = DGifOpenFileName(*argv, &errorCode);
  if(gifFile == NULL) {
    printf("Error:%s\n", GifErrorString(errorCode));
    exit(-1);
  }
  CHECKGIFOK(DGifSlurp(gifFile));

  _tprintf(_T("GifFile:Size:(%d,%d)\n"), gifFile->SWidth, gifFile->SHeight);
  _tprintf(_T("GifFile:BackgroundColor:%d, AspectByte:%d, ColorResultion:%d\n"), gifFile->SBackGroundColor, gifFile->AspectByte, gifFile->SColorResolution);
  _tprintf(_T("GifFile ")); dumpImageDesc(gifFile->Image);
  _tprintf(_T("GifFile:")); dumpColorMap(gifFile->SColorMap);
  _tprintf(_T("GifFile.ExtentionBlocks:\n"));
  dumpExtensionBlocks(gifFile->ExtensionBlocks, gifFile->ExtensionBlockCount);

  for(int i = 0; i < gifFile->ImageCount; i++) {
    dumpSavedImage(i, gifFile->SavedImages[i]);
  }

  if(DGifCloseFile(gifFile, &errorCode) != GIF_OK) {
    CHECKGIFOK(errorCode);
  }

  return 0;
}
Пример #5
0
ImageSet* process_gif(const char *buf, size_t len) {
    int error;
    GifFileType* gif = DGifOpen((char*)buf, &gif_readfunc, &error);
    if (error != GIF_OK) {
	printf("GIF reading error %d: %s\n", error, GifErrorString(error));
	return NULL;
    }
    printf("gif read, now converting\n", error);
    ImageSet* imgset = (ImageSet*)malloc(sizeof(ImageSet));
    imgset->width  = gif->SWidth;
    imgset->height = gif->SHeight;
    ColorMapObject* gif_colormap = gif->SColorMap;
    if (gif_colormap != NULL) {
	gif_colormap->ColorCount;
	imgset->palette = (Color*)calloc(256, sizeof(Color));
	int shift = 8 - gif_colormap->BitsPerPixel;
	if (shift < 1 || shift > 7) {
	    fprintf(stderr, "Error opening gif: invalid palette BPP %d\n", gif_colormap->BitsPerPixel);
	}
	for (int i=0;  i < 256;  i++) {
	    if (i <= gif_colormap->ColorCount) {
		imgset->palette[i].r = gif_colormap->Colors[i].Red   >> shift;
		imgset->palette[i].g = gif_colormap->Colors[i].Green >> shift;
		imgset->palette[i].b = gif_colormap->Colors[i].Blue  >> shift;
	    } else {
		//gset->palette[i] = Color{0,0,0};
	    }
	}
    } else {
Пример #6
0
static String gifErrorCodeToString(int errorCode) {
  const char *errorMsg = GifErrorString(errorCode);
  if(errorMsg == NULL) {
    return _T("No error");
  } else {
    return errorMsg;
  }
}
Пример #7
0
void
PrintGifError(int ErrorCode) {
    const char *Err = GifErrorString(ErrorCode);

    if (Err != NULL)
        fprintf(stderr, "GIF-LIB error: %s.\n", Err);
    else
        fprintf(stderr, "GIF-LIB undefined error %d.\n", ErrorCode);
}
Пример #8
0
static inline void
gif_error (const gchar *action, int err)
{
	const char *str = GifErrorString (err);
	if (str != NULL) {
		g_message ("%s, error: '%s'", action, str);
	} else {
		g_message ("%s, undefined error %d", action, err);
	}
}
Пример #9
0
static void GIFDisplayError(const GifFileType* const gif, int gif_error) {
  // libgif 4.2.0 has retired PrintGifError() and added GifErrorString().
#if LOCAL_GIF_PREREQ(4, 2)
#if LOCAL_GIF_PREREQ(5, 0)
  const char* error_str =
      GifErrorString((gif == NULL) ? gif_error : gif->Error);
#else
  const char* error_str = GifErrorString();
  (void)gif;
#endif
  if (error_str == NULL) error_str = "Unknown error";
  fprintf(stderr, "GIFLib Error %d: %s\n", gif_error, error_str);
#else
  (void)gif;
  fprintf(stderr, "GIFLib Error %d: ", gif_error);
  PrintGifError();
  fprintf(stderr, "\n");
#endif
}
Пример #10
0
void
GIFInput::report_last_error (void)
{
    // N.B. Only GIFLIB_MAJOR >= 5 looks properly thread-safe, in that the
    // error is guaranteed to be specific to this open file.  We use a  spin
    // mutex to prevent a thread clash for older versions, but it still
    // appears to be a global call, so we can't be absolutely sure that the
    // error was for *this* file.  So if you're using giflib prior to
    // version 5, beware.
#if GIFLIB_MAJOR >= 5
    error ("%s", GifErrorString (m_gif_file->Error));
#elif GIFLIB_MAJOR == 4 && GIFLIB_MINOR >= 2
    spin_lock lock (gif_error_mutex);
    error ("%s", GifErrorString());
#else
    spin_lock lock (gif_error_mutex);
    error ("GIF error %d", GifLastError());
#endif
}
Пример #11
0
static void DisplayGifError(const GifFileType* const gif, int gif_error) {
  // GIFLIB_MAJOR is only defined in libgif >= 4.2.0.
  // libgif 4.2.0 has retired PrintGifError() and added GifErrorString().
#if defined(GIFLIB_MAJOR) && defined(GIFLIB_MINOR) && \
        ((GIFLIB_MAJOR == 4 && GIFLIB_MINOR >= 2) || GIFLIB_MAJOR > 4)
#if GIFLIB_MAJOR >= 5
    // Static string actually, hence the const char* cast.
    const char* error_str = (const char*)GifErrorString(
        (gif == NULL) ? gif_error : gif->Error);
#else
    const char* error_str = (const char*)GifErrorString();
    (void)gif;
#endif
    if (error_str == NULL) error_str = "Unknown error";
    fprintf(stderr, "GIFLib Error %d: %s\n", gif_error, error_str);
#else
    (void)gif;
    fprintf(stderr, "GIFLib Error %d: ", gif_error);
    PrintGifError();
    fprintf(stderr, "\n");
#endif
}
Пример #12
0
/*
 * Copyright (C) 2006, Jamie McCracken <*****@*****.**>
 * Copyright (C) 2008, Nokia <*****@*****.**>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#include "config.h"

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <gif_lib.h>

#include <libtracker-common/tracker-common.h>

#include <libtracker-extract/tracker-extract.h>

#define XMP_MAGIC_TRAILER_LENGTH 256
#define EXTENSION_RECORD_COMMENT_BLOCK_CODE 0xFE

typedef struct {
	const gchar *title;
	const gchar *date;
	const gchar *artist;
} MergeData;

typedef struct {
	gchar *width;
	gchar *height;
	gchar *comment;
} GifData;

typedef struct {
	unsigned int   byteCount;
	char          *bytes;
} ExtBlock;

static int
ext_block_append(ExtBlock *extBlock,
		 unsigned int len,
		 unsigned char extData[])
{
	extBlock->bytes = realloc(extBlock->bytes,extBlock->byteCount+len);
	if (extBlock->bytes == NULL) {
		return (GIF_ERROR);
	}

	memcpy(&(extBlock->bytes[extBlock->byteCount]), &extData[0], len);
	extBlock->byteCount += len;

	return (GIF_OK);
}

#if GIFLIB_MAJOR >= 5
static inline void
gif_error (const gchar *action, int err)
{
	const char *str = GifErrorString (err);
	if (str != NULL) {
		g_message ("%s, error: '%s'", action, str);
	} else {
		g_message ("%s, undefined error %d", action, err);
	}
}
#else /* GIFLIB_MAJOR >= 5 */
static inline void print_gif_error()
{
#if defined(GIFLIB_MAJOR) && defined(GIFLIB_MINOR) && ((GIFLIB_MAJOR == 4 && GIFLIB_MINOR >= 2) || GIFLIB_MAJOR > 4)
	const char *str = GifErrorString ();
	if (str != NULL) {
		g_message ("GIF, error: '%s'", str);
	} else {
		g_message ("GIF, undefined error");
	}
#else
	PrintGifError();
#endif
}
Пример #13
0
/************************************************************************
return NULL if error
http://www.imagemagick.org/Usage/anim_basics/#dispose
http://wwwcdf.pd.infn.it/libgif/gif89.txt
http://wwwcdf.pd.infn.it/libgif/gif_lib.html
************************************************************************/
static anim_t * giflib_load(SDL_Renderer * render, const char * filename)
{
	GifFileType * gif = NULL;
	int i = 0;
	int j = 0;
	int transparent = 0;
	unsigned char transparent_color = 0;
	int disposal = 0;
	int delay = 0;
	ColorMapObject * global_pal = NULL;
	ColorMapObject * pal = NULL;
	SDL_Surface* surf = NULL;
	SDL_Surface* prev_surf = NULL;
	int x = 0;
	int y = 0;
	int col = 0;
	int pix_index = 0;
	anim_t * anim = NULL;
	int render_width;
	int render_height;
	int frame_left = 0;
	int frame_top = 0;
	int frame_width = 0;
	int frame_height = 0;
	int allow_draw = 1;
	int error = 0;
	int ret;

	gif = DGifOpenFileName(filename,&error);
	if(gif == NULL) {
#if 0
		printf("%s: %s\n", filename,GifErrorString(error));
#endif
		return NULL;
	}

	ret = DGifSlurp(gif);
	if (ret != GIF_OK) {
		DGifCloseFile(gif,&error);
		return NULL;
	}
	if ( gif->Error != D_GIF_SUCCEEDED) {
		DGifCloseFile(gif,&error);
		return NULL;
	}

	anim = malloc(sizeof(anim_t));
	memset(anim,0,sizeof(anim_t));

	anim->num_frame = gif->ImageCount;
	anim->tex = malloc(sizeof(SDL_Texture *) * anim->num_frame);
	anim->w = gif->SWidth;
	anim->h = gif->SHeight;
	anim->delay = malloc(sizeof(Uint32) * anim->num_frame);

	render_width = gif->SWidth;
	render_height = gif->SHeight;
	//bg_color = gif->SBackGroundColor;

	surf = SDL_CreateRGBSurface(0,render_width,render_height,32,0xff000000,0x00ff0000,0x0000ff00,0x000000ff);
	prev_surf = SDL_CreateRGBSurface(0,render_width,render_height,32,0xff000000,0x00ff0000,0x0000ff00,0x000000ff);

	global_pal = gif->SColorMap;
	pal = global_pal;

	/* Init with transparent background */
	memset(surf->pixels,0, render_height * render_width * 4 );

	for(i=0; i<gif->ImageCount; i++) {
		frame_left = gif->SavedImages[i].ImageDesc.Left;
		frame_top = gif->SavedImages[i].ImageDesc.Top;
		frame_width = gif->SavedImages[i].ImageDesc.Width;
		frame_height = gif->SavedImages[i].ImageDesc.Height;

		/* select palette */
		pal = global_pal;
		if( gif->SavedImages[i].ImageDesc.ColorMap ) {
			pal = gif->SavedImages[i].ImageDesc.ColorMap;
		}
		/* GCE */
		for(j=0; j<gif->SavedImages[i].ExtensionBlockCount; j++) {
			if(gif->SavedImages[i].ExtensionBlocks[j].Function == GIF_GCE) {
				transparent = gif->SavedImages[i].ExtensionBlocks[j].Bytes[0] & 0x01;
				disposal = (gif->SavedImages[i].ExtensionBlocks[j].Bytes[0] & 28)>>2;
				delay = (gif->SavedImages[i].ExtensionBlocks[j].Bytes[1] + gif->SavedImages[i].ExtensionBlocks[j].Bytes[2] * 256)*10;
				if(delay==0) {
					delay = DEFAULT_DELAY;
				}
				if(transparent) {
					transparent_color = gif->SavedImages[i].ExtensionBlocks[j].Bytes[3];
				}
			}
		}

		/* Save the current render if needed */
		if( disposal == DISPOSE_PREVIOUS ) {
			memcpy(prev_surf->pixels,surf->pixels, render_height * render_width * 4);
		}

		/* Fill surface buffer with raster bytes */
		if( allow_draw ) { // See DISPOSE_DO_NOT
			for(y=0; y<frame_height; y++) {
				for(x=0; x<frame_width; x++) {
					pix_index = ((x+frame_left) + ( (y+frame_top) *render_width))*4;
					col = gif->SavedImages[i].RasterBits[(x)+(y)*frame_width];
					if( col == transparent_color && transparent) {
						/* Transparent color means do not touch the render */
					} else {
						((char*)surf->pixels)[pix_index+3] = pal->Colors[col].Red;
						((char*)surf->pixels)[pix_index+2] = pal->Colors[col].Green;
						((char*)surf->pixels)[pix_index+1] = pal->Colors[col].Blue;
						((char*)surf->pixels)[pix_index+0] = 0xFF;
					}
				}
			}
		}

		anim->delay[i] = delay;
		anim->tex[i] = SDL_CreateTextureFromSurface(render,surf);

		/* Prepare next rendering depending of disposal */
		allow_draw = 1;
		switch( disposal ) {
		/* Do not touch render for next frame */
		case DISPOSE_DO_NOT:
			allow_draw = 0;
			break;
		case DISPOSE_BACKGROUND:
			/* Draw transparent color in frame */
			for(y=0; y<frame_height; y++) {
				for(x=0; x<frame_width; x++) {
					pix_index = ((x+frame_left)+((y+frame_top)*render_width))*4;
					((char*)surf->pixels)[pix_index+3] = 0;
					((char*)surf->pixels)[pix_index+2] = 0;
					((char*)surf->pixels)[pix_index+1] = 0;
					((char*)surf->pixels)[pix_index+0] = 0;
				}
			}
			break;
		case DISPOSE_PREVIOUS:
			/* Restore previous render in frame*/
			memcpy(surf->pixels,prev_surf->pixels, render_height * render_width * 4);
			break;
		default:
			break;
		}
	}
Пример #14
0
int FileGIF::read_frame(VFrame *output, VFrame *input)
{
	data = input->get_data();
	offset = 0;
	size = input->get_compressed_size();

	GifFileType *gif_file;
	GifRowType *gif_buffer;
	gif_file = DGifOpen(this, input_func);
	
	
	if(gif_file == 0)
	{
		printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString());
		return 1;
	}
	gif_buffer = (GifRowType*)malloc(sizeof(GifRowType) * gif_file->SHeight);
	int row_size = gif_file->SWidth * sizeof(GifPixelType);
	gif_buffer[0] = (GifRowType)malloc(row_size);

	for(int i = 0; i < gif_file->SWidth; i++)
	{
		gif_buffer[0][i] = gif_file->SBackGroundColor;
	}

	for(int i = 0; i < gif_file->SHeight; i++)
	{
		gif_buffer[i] = (GifRowType)malloc(row_size);
		memcpy(gif_buffer[i], gif_buffer[0], row_size);
	}

	GifRecordType record_type;
	do
	{
		if(DGifGetRecordType(gif_file, &record_type) == GIF_ERROR)
		{
			printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString());
			break;
		}
		
		switch(record_type)
		{
			case IMAGE_DESC_RECORD_TYPE:
			{
				if(DGifGetImageDesc(gif_file) == GIF_ERROR)
				{
					printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString());
					break;
				}

				int row = gif_file->Image.Top;
				int col = gif_file->Image.Left;
				int width = gif_file->Image.Width;
				int height = gif_file->Image.Height;
				if(gif_file->Image.Left + gif_file->Image.Width > gif_file->SWidth ||
		 		  gif_file->Image.Top + gif_file->Image.Height > gif_file->SHeight)
				{
					DGifCloseFile(gif_file);
					for(int k = 0; k < gif_file->SHeight; k++)
					{
						free(gif_buffer[k]);
					}
					free(gif_buffer);
					return 1;
				}
				
				if (gif_file->Image.Interlace) 
				{
				    static int InterlacedOffset[] = { 0, 4, 2, 1 };
				    static int InterlacedJumps[] = { 8, 8, 4, 2 };
/* Need to perform 4 passes on the images: */
		    		for (int i = 0; i < 4; i++)
					{
						for (int j = row + InterlacedOffset[i]; 
							j < row + height;
							j += InterlacedJumps[i]) 
						{
			    			if (DGifGetLine(gif_file, 
								&gif_buffer[j][col],
								width) == GIF_ERROR) 
							{
								DGifCloseFile(gif_file);
								for(int k = 0; k < gif_file->SHeight; k++)
								{
									free(gif_buffer[k]);
								}
								free(gif_buffer);
								return 1;
			    			}
						}
					}
				}
				else 
				{
		    		for (int i = 0; i < height; i++) 
					{
						if (DGifGetLine(gif_file, &gif_buffer[row++][col],
							width) == GIF_ERROR) 
						{
							DGifCloseFile(gif_file);
							for(int k = 0; k < gif_file->SHeight; k++)
							{
								free(gif_buffer[k]);
							}
							free(gif_buffer);
			    			return 1;
						}
		    		}
				}
				
				break;
			}
			
		}
		
	} while(record_type != TERMINATE_RECORD_TYPE);

	
	int background = gif_file->SBackGroundColor;
	ColorMapObject *color_map = (gif_file->Image.ColorMap
		? gif_file->Image.ColorMap
		: gif_file->SColorMap);
	if(!color_map) 
	{
		DGifCloseFile(gif_file);
		for(int k = 0; k < gif_file->SHeight; k++)
		{
			free(gif_buffer[k]);
		}
		free(gif_buffer);
		return 1;
	}

	int screen_width = gif_file->SWidth;
	int screen_height = gif_file->SHeight;
	for(int i = 0; i < screen_height; i++)
	{
		GifRowType gif_row = gif_buffer[i];
		unsigned char *out_ptr = output->get_rows()[i];
		for(int j = 0; j < screen_width; j++)
		{
			GifColorType *color_map_entry = &color_map->Colors[gif_row[j]];
			*out_ptr++ = color_map_entry->Red;
			*out_ptr++ = color_map_entry->Green;
			*out_ptr++ = color_map_entry->Blue;
		}
	}

	
	for(int k = 0; k < gif_file->SHeight; k++)
	{
		free(gif_buffer[k]);
	}
	free(gif_buffer);
	DGifCloseFile(gif_file);
	return 0;
}
Пример #15
0
static int load_image(char *filename, struct image_info *info,
                      unsigned char *buf, ssize_t *buf_size)
{
    int w, h;
    long time = 0; /* measured ticks */
    struct gif_decoder *p_decoder = &decoder;

    unsigned char *memory, *memory_max;
    size_t memory_size, img_size, disp_size;

    /* align buffer */
    memory = (unsigned char *)((intptr_t)(buf + 3) & ~3);
    memory_max = (unsigned char *)((intptr_t)(memory + *buf_size) & ~3);
    memory_size = memory_max - memory;

#ifdef DISK_SPINDOWN
        if (iv->running_slideshow && iv->immediate_ata_off) {
            /* running slideshow and time is long enough: power down disk */
            rb->storage_sleep();
        }
#endif

        /* initialize decoder context struct, set buffer decoder is free 
         * to use.
         */
        gif_decoder_init(p_decoder, memory, memory_size);

        /* populate internal data from gif file control structs */
        gif_open(filename, p_decoder);

        if (!p_decoder->error)
        {

            if (!iv->running_slideshow)
            {
                rb->lcd_putsf(0, 2, "image %dx%d",
                              p_decoder->width,
                              p_decoder->height);
                rb->lcd_putsf(0, 3, "decoding %d*%d",
                              p_decoder->width,
                              p_decoder->height);
                rb->lcd_update();
            }

            /* the actual decoding */
            time = *rb->current_tick;

#ifdef HAVE_ADJUSTABLE_CPU_FREQ
            rb->cpu_boost(true);
#endif
            gif_decode(p_decoder, iv->cb_progress);

#ifdef HAVE_ADJUSTABLE_CPU_FREQ
            rb->cpu_boost(false);
#endif
            time = *rb->current_tick - time;
        }

    if (!iv->running_slideshow && !p_decoder->error)
    {
        rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
        rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
        rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
        rb->lcd_update();
    }

    if (p_decoder->error)
    {
        rb->splashf(HZ, "%s", GifErrorString(p_decoder->error));
        return PLUGIN_ERROR;
    }

    info->x_size = p_decoder->width;
    info->y_size = p_decoder->height;
    info->frames_count = p_decoder->frames_count;
    info->delay = p_decoder->delay;

    /* check mem constraints
     * each frame can have 4 scaled versions with ds = (1,2,4,8)
     */
    img_size = (p_decoder->native_img_size*p_decoder->frames_count + 3) & ~3;
    disp_size = (sizeof(unsigned char *)*p_decoder->frames_count*4 + 3) & ~3;

    if (memory_size < img_size + disp_size)
    {
        /* No memory to allocate disp matrix */
        rb->splashf(HZ, "%s", GifErrorString(D_GIF_ERR_NOT_ENOUGH_MEM));
        return PLUGIN_ERROR;
    }

    disp = (unsigned char **)(p_decoder->mem + img_size);
    disp_buf = (unsigned char *)disp + disp_size;

    *buf_size = memory_max - disp_buf;

    /* set all pointers to NULL initially */
    memset(disp, 0, sizeof(unsigned char *)*p_decoder->frames_count*4);

    return PLUGIN_OK;
}
Пример #16
0
void EncodeToGifBufferWorker::Execute () {
    GifByteType
        * redBuff = (GifByteType *) _pixbuf,
        * greenBuff = (GifByteType *) _pixbuf + _width * _height,
        * blueBuff = (GifByteType *) _pixbuf + 2 * _width * _height,
        * alphaBuff = (GifByteType *) _pixbuf + 3 * _width * _height,
        * gifimgbuf = (GifByteType *) malloc(_width * _height * sizeof(GifByteType)); // the indexed image
    ColorMapObject *cmap;
    SavedImage * simg;

    if (NULL == gifimgbuf){
        SetErrorMessage("Out of memory");
        return;
    }

    cmap = GifMakeMapObject(_cmapSize, NULL);

    if (NULL == cmap){
        free(gifimgbuf);
        SetErrorMessage("Out of memory");
        return;
    }

    if (GIF_ERROR == GifQuantizeBuffer(
                _width, _height, &_colors,
               redBuff, greenBuff, blueBuff,
               gifimgbuf, cmap->Colors
        )){
        free(gifimgbuf);
        GifFreeMapObject(cmap);
        SetErrorMessage("Unable to quantize image");
        return;
    }

    int errcode;
    gifWriteCbData buffinf = {NULL, 0};
    GifFileType * gif;

    gif = EGifOpen((void *) &buffinf, gifWriteCB, &errcode);

    if (NULL == gif){
        free(gifimgbuf);
        GifFreeMapObject(cmap);
        SetErrorMessage(GifErrorString(errcode));
        return;
    }

    gif->SWidth = _width;
    gif->SHeight = _height;
    gif->SColorResolution = _cmapSize;

    simg = GifMakeSavedImage(gif, NULL);

    if (NULL == simg){
        free(gifimgbuf);
        EGifCloseFile(gif, &errcode); // will also free cmap
        SetErrorMessage("Out of memory");
        return;
    }

    simg->ImageDesc.Left = 0;
    simg->ImageDesc.Top = 0;
    simg->ImageDesc.Width = _width;
    simg->ImageDesc.Height = _height;
    simg->ImageDesc.Interlace = _interlaced;
    simg->ImageDesc.ColorMap = cmap;
    simg->RasterBits = gifimgbuf;

    // for some reason giflib sometimes creates an invalid file if the global
    // color table is not set as well
    gif->SColorMap = cmap;

    if (_trans){
        ExtensionBlock ext;
        // 1. assign transparent color index in color table
        GraphicsControlBlock gcb = {0, false, 0, _colors++};
        // 2. replace transparent pixels above threshold with this color
        remapTransparentPixels(gifimgbuf, alphaBuff, _width, _height, gcb.TransparentColor, _threshold);
        // 3. create a control block
        size_t extlen = EGifGCBToExtension(&gcb, (GifByteType *) &ext);
        if (GIF_ERROR == GifAddExtensionBlock(
                &(simg->ExtensionBlockCount),
                &(simg->ExtensionBlocks),
                GRAPHICS_EXT_FUNC_CODE,
                extlen,
                (unsigned char *) &ext)
            ) {
            EGifCloseFile(gif, &errcode);
            SetErrorMessage("Out of memory");
            return;
        }
    }


    if (GIF_ERROR == EGifSpew(gif)){
        EGifCloseFile(gif, &errcode);
        SetErrorMessage(GifErrorString(gif->Error));
        return;
    }

    _gifbuf = (char *) buffinf.buff;
    _gifbufsize = buffinf.buffsize;

    return;
}
Пример #17
0
pictw_t *
sgif_read(session_t *ps, const char *path) {
	assert(path);
	pictw_t *pictw = NULL;
	GifPixelType *data = NULL;
	unsigned char *tdata = NULL;

	GifRecordType rectype;
	int ret = 0, err = 0;
	const char *errstr = NULL;
#ifdef SGIF_THREADSAFE
	GifFileType *f = DGifOpenFileName(path, &err);
#else
	GifFileType *f = DGifOpenFileName(path);
#endif
	if (unlikely(!f)) {
#ifdef SGIF_HAS_ERROR
		err = GifError();
		errstr = GifErrorString();
#endif
#ifdef SGIF_THREADSAFE
		errstr = GifErrorString(err);
#endif
		printfef("(\"%s\"): Failed to open file: %d (%s)", path, err, errstr);
		goto sgif_read_end;
	}

	int width = 0, height = 0, transp = -1;
	{
		int i = 0;
		while (GIF_OK == (ret = DGifGetRecordType(f, &rectype))
				&& TERMINATE_RECORD_TYPE != rectype) {
			++i;
			switch (rectype) {
				case UNDEFINED_RECORD_TYPE:
					printfef("(\"%s\"): %d: Encountered a record of unknown type.",
							path, i);
					break;
				case SCREEN_DESC_RECORD_TYPE:
					printfef("(\"%s\"): %d: Encountered a record of "
							"ScreenDescRecordType. This shouldn't happen!",
							path, i);
					break;
				case IMAGE_DESC_RECORD_TYPE:
					if (data) {
						printfef("(\"%s\"): %d: Extra image section ignored.",
								path, i);
						break;
					}
					if (GIF_ERROR == DGifGetImageDesc(f)) {
						printfef("(\"%s\"): %d: Failed to read GIF image info.",
								path, i);
						break;
					}
					width = f->Image.Width;
					height = f->Image.Height;
					if (width <= 0 || height <= 0) {
						printfef("(\"%s\"): %d: Width/height invalid.", path, i);
						break;
					}
					assert(!data);
					data = allocchk(malloc(width * height * sizeof(GifPixelType)));
					// FIXME: Interlace images may need special treatments
					for (int j = 0; j < height; ++j)
						if (GIF_OK != DGifGetLine(f, &data[j * width], width)) {
							printfef("(\"%s\"): %d: Failed to read line %d.", path, i, j);
							goto sgif_read_end;
						}
					break;
				case EXTENSION_RECORD_TYPE:
					{
						int code = 0;
						GifByteType *pbytes = NULL;
						if (GIF_OK != DGifGetExtension(f, &code, &pbytes) || !pbytes) {
							printfef("(\"%s\"): %d: Failed to read extension block.",
									path, i);
							break;
						}
						do {
							// Transparency
							if (0xf9 == code && (pbytes[1] & 1))
								transp = pbytes[4];
						} while (GIF_OK == DGifGetExtensionNext(f, &pbytes) && pbytes);
					}
					break;
				case TERMINATE_RECORD_TYPE:
					assert(0);
					break;
			}
		}
		if (unlikely(!data)) {
			printfef("(\"%s\"): No valid data found.", path);
			goto sgif_read_end;
		}
	}

	// Colormap translation
	int depth = 32;
	{
		ColorMapObject *cmap = f->Image.ColorMap;
		if (!cmap) cmap = f->SColorMap;
		if (unlikely(!cmap)) {
			printfef("(\"%s\"): No colormap found.", path);
			goto sgif_read_end;
		}
		tdata = allocchk(malloc(width * height * depth / 8));
		{
			GifPixelType *pd = data;
			unsigned char *end = tdata + width * height * depth / 8;
			for (unsigned char *p = tdata; p < end; p += depth / 8, ++pd) {
				// When the alpha is 0, X seemingly wants all color channels
				// to be 0 as well.
				if (transp >= 0 && transp == *pd) {
					p[0] = p[1] = p[2] = 0;
					if (32 == depth) p[3] = 0;
					continue;
				}
				p[0] = cmap->Colors[*pd].Blue;
				p[1] = cmap->Colors[*pd].Green;
				p[2] = cmap->Colors[*pd].Red;
				p[3] = 0xff;
			}
		}
	}
	if (unlikely(!(pictw = simg_data_to_pictw(ps, width, height, depth,
						tdata, 0)))) {
		printfef("(\"%s\"): Failed to create Picture.", path);
		goto sgif_read_end;
	}

sgif_read_end:
	if (data)
		free(data);
	if (likely(f))
		DGifCloseFile(f);

	return pictw;
}
Пример #18
0
bool
GIFInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec)
{
    GifColorType *local_colormap = NULL;

    if (subimage < 0 || miplevel != 0)
        return false;

    if (m_subimage == subimage) {
        // We're already pointing to the right subimage
        newspec = m_spec;
        return true;
    }

    if (m_subimage > subimage) {
        // requested subimage is located before the current one
        // file needs to be reopened
        if (m_gif_file && ! close()) {
            return false;
        }
    }

    if (! m_gif_file) {

#if GIFLIB_MAJOR >= 5
        int giflib_error;
        if (! (m_gif_file = DGifOpenFileName (m_filename.c_str(),
                                              &giflib_error))) {
            error (GifErrorString (giflib_error));
            return false;
        }
#else
        if (! (m_gif_file = DGifOpenFileName (m_filename.c_str()))) {
            error ("Error trying to open the file.");
            return false;
        }
#endif

        m_subimage = -1;

        // read global color table
        if (m_gif_file->SColorMap) {
            m_global_colormap = m_gif_file->SColorMap->Colors;
        } else {
            m_global_colormap = NULL;
        }
    }

    if (m_subimage < subimage) {
        // requested subimage is located after the current one
        // skip the preceding part of current image..
        if (m_subimage != -1 && m_next_scanline < m_spec.height) {
            int remaining_size =
                m_spec.width * (m_spec.height - m_next_scanline);
            boost::scoped_array<unsigned char> buffer
            (new unsigned char[remaining_size]);
            if (DGifGetLine (m_gif_file,
                             buffer.get(),
                             remaining_size) == GIF_ERROR) {
                report_last_error ();
                return false;
            }
        }

        // ..and skip the rest of preceding subimages
        for (m_subimage += 1; m_subimage < subimage; m_subimage ++) {
            if (! read_subimage_metadata (newspec, &local_colormap)) {
                return false;
            }
            int image_size = newspec.width * newspec.height;
            boost::scoped_array<unsigned char> buffer
            (new unsigned char[image_size]);
            if (DGifGetLine (m_gif_file,
                             buffer.get(),
                             image_size) == GIF_ERROR) {
                report_last_error ();
                return false;
            }
        }
    }

    // read metadata of current subimage
    if (! read_subimage_metadata (newspec, &local_colormap)) {
        return false;
    }

    m_spec = newspec;
    m_subimage = subimage;
    m_next_scanline = 0;
    m_cached_data.clear ();
    m_local_colormap = local_colormap;

    return true;
}