示例#1
0
文件: ungif.c 项目: hoangduit/reactos
/******************************************************************************
 * This routine should be called last, to close the GIF file.
 *****************************************************************************/
int
DGifCloseFile(GifFileType * GifFile) {

    GifFilePrivateType *Private;

    if (GifFile == NULL)
        return GIF_ERROR;

    Private = GifFile->Private;

    if (GifFile->Image.ColorMap) {
        FreeMapObject(GifFile->Image.ColorMap);
        GifFile->Image.ColorMap = NULL;
    }

    if (GifFile->SColorMap) {
        FreeMapObject(GifFile->SColorMap);
        GifFile->SColorMap = NULL;
    }

    ungif_free(Private);
    Private = NULL;

    if (GifFile->SavedImages) {
        FreeSavedImages(GifFile);
        GifFile->SavedImages = NULL;
    }

    FreeExtension(&GifFile->Extensions);

    ungif_free(GifFile);

    return GIF_OK;
}
示例#2
0
/******************************************************************************
*   This routine should be called last, to close the GIF file.		      *
******************************************************************************/
int DGifCloseFile(GifFileType *GifFile)
{
    GifFilePrivateType *Private;
    FILE *File;

    if (GifFile == NULL) return GIF_ERROR;

    Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
	/* This file was NOT open for reading: */
	_GifError = D_GIF_ERR_NOT_READABLE;
	return GIF_ERROR;
    }

    File = Private->File;

    if (GifFile->Image.ColorMap)
	FreeMapObject(GifFile->Image.ColorMap);
    if (GifFile->SColorMap)
	FreeMapObject(GifFile->SColorMap);
    if (Private)
	free((char *) Private);
    if (GifFile->SavedImages)
	FreeSavedImages(GifFile);
    free(GifFile);

    if ( File && (fclose(File) != 0)) {
	  _GifError = D_GIF_ERR_CLOSE_FAILED;
	  return GIF_ERROR;
    }
    return GIF_OK;
}
示例#3
0
static int DGifCloseFile(GifFileType * GifFile)
{
	GifFilePrivateType *Private;
	FILE *File;

	if (GifFile == NULL)
		return GIF_ERROR;

	Private = (GifFilePrivateType *) GifFile->Private;

	if (!IS_READABLE(Private))
	{
		_GifError = D_GIF_ERR_NOT_READABLE;
		return GIF_ERROR;
	}

	File = Private->File;

	if (GifFile->Image.ColorMap)
	{
		FreeMapObject(GifFile->Image.ColorMap);
		GifFile->Image.ColorMap = NULL;
	}

	if (GifFile->SColorMap)
	{
		FreeMapObject(GifFile->SColorMap);
		GifFile->SColorMap = NULL;
	}

	if (Private)
	{
		gif_free((char *) Private);
		Private = NULL;
	}

	if (GifFile->SavedImages)
	{
		FreeSavedImages(GifFile);
		GifFile->SavedImages = NULL;
	}

	gif_free(GifFile);

	if (File && (fclose(File) != 0))
	{
		_GifError = D_GIF_ERR_CLOSE_FAILED;
		return GIF_ERROR;
	}
	return GIF_OK;
}
示例#4
0
文件: dgif_lib.c 项目: 0x0all/ROOT
/******************************************************************************
*   This routine should be called last, to close the GIF file.		      *
******************************************************************************/
int DGifCloseFile(GifFileType *GifFile)
{
    GifFilePrivateType *Private;
    FILE *File;
	int ret = GIF_OK;

    if (GifFile == NULL) return GIF_ERROR;

    Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
		/* This file was NOT open for reading: */
		_GifError = D_GIF_ERR_NOT_READABLE;
		ret = GIF_ERROR; /* we have to free everything regardless */
    }

    File = Private->File;

    if (GifFile->Image.ColorMap)
    {
		FreeMapObject(GifFile->Image.ColorMap);
        GifFile->Image.ColorMap = NULL;
    }

    if (GifFile->SColorMap)
    {
		FreeMapObject(GifFile->SColorMap);
		GifFile->SColorMap = NULL;
    }

    if (Private)
    {
		free((char *) Private);
		GifFile->Private = NULL;
    }

    if (GifFile->SavedImages)
    {
		FreeSavedImages(GifFile);
		GifFile->SavedImages = NULL;
    }

    free(GifFile);

    if ( File && (fclose(File) != 0)) 
	{
	  	_GifError = D_GIF_ERR_CLOSE_FAILED;
		ret = GIF_ERROR;
    }
    return ret;
}
示例#5
0
static void FreeSavedImages(GifFileType * GifFile)
{
	SavedImage *sp;

	if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
	{
		return;
	}
	for (sp = GifFile->SavedImages; sp < GifFile->SavedImages + GifFile->ImageCount; sp++)
	{
		if (sp->ImageDesc.ColorMap)
		{
			FreeMapObject(sp->ImageDesc.ColorMap);
			sp->ImageDesc.ColorMap = NULL;
		}

		if (sp->RasterBits)
			gif_free((char *) sp->RasterBits);

		if (sp->ExtensionBlocks)
			FreeExtension(sp);
	}
	gif_free((char *) GifFile->SavedImages);
	GifFile->SavedImages = NULL;
}
示例#6
0
文件: gifalloc.c 项目: drons/gdal
/* Private Function:
 * Frees the last image in the GifFile->SavedImages array
 */
static void
FreeLastSavedImage(GifFileType *GifFile) {

    SavedImage *sp;

    if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
        return;

    /* Remove one SavedImage from the GifFile */
    GifFile->ImageCount--;
    sp = &GifFile->SavedImages[GifFile->ImageCount];

    /* Deallocate its Colormap */
    if (sp->ImageDesc.ColorMap) {
        FreeMapObject(sp->ImageDesc.ColorMap);
        sp->ImageDesc.ColorMap = NULL;
    }

    /* Deallocate the image data */
    if (sp->RasterBits)
        free((char *)sp->RasterBits);

    /* Deallocate any extensions */
    if (sp->ExtensionBlocks)
        FreeExtension(sp);

    /*** FIXME: We could realloc the GifFile->SavedImages structure but is
     * there a point to it? Saves some memory but we'd have to do it every
     * time.  If this is used in FreeSavedImages then it would be inefficient
     * (The whole array is going to be deallocated.)  If we just use it when
     * we want to free the last Image it's convenient to do it here.
     */
}
示例#7
0
static int DGifGetScreenDesc(GifFileType * GifFile)
{
	int i, BitsPerPixel;
	GifByteType Buf[3];
	GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

	if (!IS_READABLE(Private))
	{
		_GifError = D_GIF_ERR_NOT_READABLE;
		return GIF_ERROR;
	}

	if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR || DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
		return GIF_ERROR;

	if (READ(GifFile, Buf, 3) != 3)
	{
		_GifError = D_GIF_ERR_READ_FAILED;
		return GIF_ERROR;
	}
	GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
	BitsPerPixel = (Buf[0] & 0x07) + 1;
	GifFile->SBackGroundColor = Buf[1];
	if (Buf[0] & 0x80)
	{

		GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
		if (GifFile->SColorMap == NULL)
		{
			_GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
			return GIF_ERROR;
		}

		for (i = 0; i < GifFile->SColorMap->ColorCount; i++)
		{
			if (READ(GifFile, Buf, 3) != 3)
			{
				FreeMapObject(GifFile->SColorMap);
				GifFile->SColorMap = NULL;
				_GifError = D_GIF_ERR_READ_FAILED;
				return GIF_ERROR;
			}
			GifFile->SColorMap->Colors[i].Red = Buf[0];
			GifFile->SColorMap->Colors[i].Green = Buf[1];
			GifFile->SColorMap->Colors[i].Blue = Buf[2];
		}
	}
	else
	{
		GifFile->SColorMap = NULL;
	}

	return GIF_OK;
}
示例#8
0
/******************************************************************************
 * This routine should be called before any other DGif calls. Note that
 * this routine is called automatically from DGif file open routines.
 *****************************************************************************/
int
DGifGetScreenDesc(GifFileType * GifFile) {

    int BitsPerPixel;
    GifByteType Buf[3];
    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;

    if (!IS_READABLE(Private)) {
        /* This file was NOT open for reading: */
        _GifError = D_GIF_ERR_NOT_READABLE;
        return GIF_ERROR;
    }

    /* Put the screen descriptor into the file: */
    if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
        DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
        return GIF_ERROR;

    if (READ(GifFile, Buf, 3) != 3) {
        _GifError = D_GIF_ERR_READ_FAILED;
        return GIF_ERROR;
    }
    GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
    BitsPerPixel = (Buf[0] & 0x07) + 1;
    GifFile->SBackGroundColor = Buf[1];
    if (Buf[0] & 0x80) {    /* Do we have global color map? */
	int i;

        GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
        if (GifFile->SColorMap == NULL) {
            _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
            return GIF_ERROR;
        }

        /* Get the global color map: */
        for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
            if (READ(GifFile, Buf, 3) != 3) {
                FreeMapObject(GifFile->SColorMap);
                GifFile->SColorMap = NULL;
                _GifError = D_GIF_ERR_READ_FAILED;
                return GIF_ERROR;
            }
            GifFile->SColorMap->Colors[i].Red = Buf[0];
            GifFile->SColorMap->Colors[i].Green = Buf[1];
            GifFile->SColorMap->Colors[i].Blue = Buf[2];
        }
    } else {
        GifFile->SColorMap = NULL;
    }

    return GIF_OK;
}
示例#9
0
void GifFree(GifFileType * GifFile)
{
    GifFilePrivateType *Private;

    if (GifFile == NULL)
        return;

    Private = (GifFilePrivateType *) GifFile->Private;

    if (GifFile->SavedImages)
        FreeSavedImages(GifFile);
    if (GifFile->Image.ColorMap)
        FreeMapObject(GifFile->Image.ColorMap);
    if (GifFile->SColorMap)
        FreeMapObject(GifFile->SColorMap);
    if (Private) {
        free(Private);
    }
    if (GifFile->GifIO)
        free(GifFile->GifIO);
    free(GifFile);
}
示例#10
0
文件: gif.c 项目: scanlime/picogui
/******************************************************************************
*   This routine should be called before any attemp to read an image.         *
*   Note it is assumed the Image desc. header (',') has been read.	      *
******************************************************************************/
int DGifGetImageDesc(GifFileType *GifFile)
{
    int i, BitsPerPixel;
    GifByteType Buf[3];
    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
	/* This file was NOT open for reading: */
	_GifError = D_GIF_ERR_NOT_READABLE;
	return GIF_ERROR;
    }

    if (DGifGetWord(Private, &GifFile->Image.Left) == GIF_ERROR ||
	DGifGetWord(Private, &GifFile->Image.Top) == GIF_ERROR ||
	DGifGetWord(Private, &GifFile->Image.Width) == GIF_ERROR ||
	DGifGetWord(Private, &GifFile->Image.Height) == GIF_ERROR)
	return GIF_ERROR;
    if (my_fread(Buf, 1, 1, Private) != 1) {
	_GifError = D_GIF_ERR_READ_FAILED;
	return GIF_ERROR;
    }
    BitsPerPixel = (Buf[0] & 0x07) + 1;
    GifFile->Image.Interlace = (Buf[0] & 0x40);
    if (Buf[0] & 0x80) {	    /* Does this image have local color map? */

	if (GifFile->Image.ColorMap)
	    FreeMapObject(GifFile->Image.ColorMap);

	GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
    
	/* Get the image local color map: */
	for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
	    if (my_fread(Buf, 1, 3, Private) != 3) {
		_GifError = D_GIF_ERR_READ_FAILED;
		return GIF_ERROR;
	    }
	    GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
	    GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
	    GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
	}
    }

    GifFile->ImageCount++;

    Private->PixelCount = (s32) GifFile->Image.Width *
			    (s32) GifFile->Image.Height;

    DGifSetupDecompress(GifFile);  /* Reset decompress algorithm parameters. */

    return GIF_OK;
}
示例#11
0
文件: gif.c 项目: scanlime/picogui
/******************************************************************************
*   This routine should be called last, to close the GIF file.		      *
******************************************************************************/
int DGifCloseFile(GifFileType *GifFile)
{
    GifFilePrivateType *Private;

    if (GifFile == NULL) return GIF_ERROR;

    Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
	/* This file was NOT open for reading: */
	_GifError = D_GIF_ERR_NOT_READABLE;
	return GIF_ERROR;
    }

    if (GifFile->Image.ColorMap)
	FreeMapObject(GifFile->Image.ColorMap);
    if (GifFile->SColorMap)
	FreeMapObject(GifFile->SColorMap);
    if (Private)
	free((char *) Private);
    free(GifFile);

    return GIF_OK;
}
示例#12
0
文件: ungif.c 项目: Remmy/afterstep
void
free_gif_saved_image( SavedImage *sp, Bool reusable )
{
	if( sp )
	{
		if (sp->ImageDesc.ColorMap)
	    	FreeMapObject(sp->ImageDesc.ColorMap);

		if (sp->RasterBits)
		    free((char *)sp->RasterBits);

		if (sp->ExtensionBlocks)
		    FreeExtension(sp);

		if( !reusable )
			free( sp );
	}
}
示例#13
0
文件: ungif.c 项目: hoangduit/reactos
/******************************************************************************
 * This routine should be called before any other DGif calls. Note that
 * this routine is called automatically from DGif file open routines.
 *****************************************************************************/
static int
DGifGetScreenDesc(GifFileType * GifFile) {

    int i, BitsPerPixel, SortFlag;
    GifByteType Buf[3];

    /* Put the screen descriptor into the file: */
    if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
        DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
        return GIF_ERROR;

    if (READ(GifFile, Buf, 3) != 3) {
        return GIF_ERROR;
    }
    GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
    SortFlag = (Buf[0] & 0x08) != 0;
    BitsPerPixel = (Buf[0] & 0x07) + 1;
    GifFile->SBackGroundColor = Buf[1];
    GifFile->SAspectRatio = Buf[2];
    if (Buf[0] & 0x80) {    /* Do we have global color map? */

        GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
        if (GifFile->SColorMap == NULL) {
            return GIF_ERROR;
        }

        /* Get the global color map: */
        GifFile->SColorMap->SortFlag = SortFlag;
        for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
            if (READ(GifFile, Buf, 3) != 3) {
                FreeMapObject(GifFile->SColorMap);
                GifFile->SColorMap = NULL;
                return GIF_ERROR;
            }
            GifFile->SColorMap->Colors[i].Red = Buf[0];
            GifFile->SColorMap->Colors[i].Green = Buf[1];
            GifFile->SColorMap->Colors[i].Blue = Buf[2];
        }
    } else {
        GifFile->SColorMap = NULL;
    }

    return GIF_OK;
}
示例#14
0
void FreeSavedImages(GifFileType *GifFile)
{
    SavedImage	*sp;

    for (sp = GifFile->SavedImages;
	 sp < GifFile->SavedImages + GifFile->ImageCount;
	 sp++)
    {
	if (sp->ImageDesc.ColorMap)
	    FreeMapObject(sp->ImageDesc.ColorMap);

	if (sp->RasterBits)
	    free((char *)sp->RasterBits);

	if (sp->ExtensionBlocks)
	    FreeExtension(sp);
    }
    free((char *) GifFile->SavedImages);
}
示例#15
0
文件: gifalloc.c 项目: drons/gdal
/*
 * Compute the union of two given color maps and return it.  If result can't
 * fit into 256 colors, NULL is returned, the allocated union otherwise.
 * ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
 * copied iff they didn't exist before.  ColorTransIn2 maps the old
 * ColorIn2 into ColorUnion color map table.
 */
ColorMapObject *
UnionColorMap(const ColorMapObject * ColorIn1,
              const ColorMapObject * ColorIn2,
              GifPixelType ColorTransIn2[]) {

    int i, j, CrntSlot, RoundUpTo, NewBitSize;
    ColorMapObject *ColorUnion;

    /*
     * Allocate table which will hold the result for sure.
     */
    ColorUnion = MakeMapObject(MAX(ColorIn1->ColorCount,
                                   ColorIn2->ColorCount) * 2, NULL);

    if (ColorUnion == NULL)
        return (NULL);

    /* Copy ColorIn1 to ColorUnionSize; */
    /*** FIXME: What if there are duplicate entries into the colormap to begin
     * with? */
    for (i = 0; i < ColorIn1->ColorCount; i++)
        ColorUnion->Colors[i] = ColorIn1->Colors[i];
    CrntSlot = ColorIn1->ColorCount;

    /*
     * Potentially obnoxious hack:
     *
     * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
     * of table 1.  This is very useful if your display is limited to
     * 16 colors.
     */
    while (ColorIn1->Colors[CrntSlot - 1].Red == 0
            && ColorIn1->Colors[CrntSlot - 1].Green == 0
            && ColorIn1->Colors[CrntSlot - 1].Blue == 0)
        CrntSlot--;

    /* Copy ColorIn2 to ColorUnionSize (use old colors if they exist): */
    for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
        /* Let's see if this color already exists: */
        /*** FIXME: Will it ever occur that ColorIn2 will contain duplicate
         * entries?  So we should search from 0 to CrntSlot rather than
         * ColorIn1->ColorCount?
         */
        for (j = 0; j < ColorIn1->ColorCount; j++)
            if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i],
                        sizeof(GifColorType)) == 0)
                break;

        if (j < ColorIn1->ColorCount)
            ColorTransIn2[i] = j;    /* color exists in Color1 */
        else {
            /* Color is new - copy it to a new slot: */
            ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
            ColorTransIn2[i] = CrntSlot++;
        }
    }

    if (CrntSlot > 256) {
        FreeMapObject(ColorUnion);
        return ((ColorMapObject *) NULL);
    }

    NewBitSize = BitSize(CrntSlot);
    RoundUpTo = (1 << NewBitSize);

    if (RoundUpTo > 0 && RoundUpTo != ColorUnion->ColorCount) {
        register GifColorType *Map = ColorUnion->Colors;

        /*
         * Zero out slots up to next power of 2.
         * We know these slots exist because of the way ColorUnion's
         * start dimension was computed.
         */
        for (j = CrntSlot; j < RoundUpTo; j++)
            Map[j].Red = Map[j].Green = Map[j].Blue = 0;

        /* perhaps we can shrink the map? */
        if (RoundUpTo < ColorUnion->ColorCount) {
            GifColorType *new_map = (GifColorType *)realloc(Map,
                                    RoundUpTo * sizeof(GifColorType));
            if( new_map == NULL ) {
                FreeMapObject(ColorUnion);
                return ((ColorMapObject *) NULL);
            }
            ColorUnion->Colors = new_map;
        }
    }

    ColorUnion->ColorCount = RoundUpTo;
    ColorUnion->BitsPerPixel = NewBitSize;

    return (ColorUnion);
}
示例#16
0
static int encode_gif_data(psx_image_header* header, psx_image_frame* frame, int idx, const ps_byte* buffer, size_t buffer_len, int* ret)
{
    int x, y;
    ColorMapObject *output_map = NULL;
    int map_size = 256;

    struct gif_image_ctx* ctx = (struct gif_image_ctx*)header->priv;

    if ((output_map = MakeMapObject(map_size, NULL)) == NULL) {
        if (ret) *ret = S_FAILURE;
        return -1;
    }

    for (y = 0; y < header->height; y++) {
        ps_byte* row = (ps_byte*)(buffer + header->pitch * y);
        for (x = 0; x < header->width; x++) {
            uint32_t rgba[4] = {0}; // r, g, b, a 
            gif_get_pixel_rgba_premultiply(header->format, row, x, rgba);
            ctx->red_buf[header->width * y + x] = rgba[0];
            ctx->green_buf[header->width * y + x] = rgba[1];
            ctx->blue_buf[header->width * y + x] = rgba[2];
        }
    }
    
    if (QuantizeBuffer(header->width, header->height, &map_size,
		ctx->red_buf, ctx->green_buf, ctx->blue_buf, ctx->output_buffer, output_map->Colors) == GIF_ERROR) {
        FreeMapObject(output_map);
        if (ret) *ret = S_FAILURE;
        return -1;
    }

    if (frame->duration > 0) {
        GifByteType extension[4];
#if GIFLIB_MAJOR >= 5
        GraphicsControlBlock gcb;
        gcb.DisposalMode = DISPOSAL_UNSPECIFIED; // FIXME: need specified ?
        gcb.UserInputFlag = false;
        gcb.DelayTime = frame->duration / 10;
        gcb.TransparentColor = -1; // FIXME: need specified ?

        EGifGCBToExtension(&gcb, extension);
#else
        int delay = frame->duration / 10;
        extension[0] = 0;
        extension[1] = LOBYTE(delay);
        extension[2] = HIBYTE(delay);
        extension[3] = (char)-1;
#endif
        if (EGifPutExtension(ctx->gif, GRAPHICS_EXT_FUNC_CODE, 4, extension) == GIF_ERROR) {
            FreeMapObject(output_map);
            if (ret) *ret = S_FAILURE;
            return -1;
        }
    }

    if (EGifPutImageDesc(ctx->gif, 0, 0, header->width, header->height, FALSE, output_map) == GIF_ERROR) {
        FreeMapObject(output_map);
        if (ret) *ret = S_FAILURE;
        return -1;
    }

    for (y = 0; y < header->height; y++) {
        EGifPutLine(ctx->gif, ctx->output_buffer + y * header->width, header->width);
    }
    FreeMapObject(output_map);
    return 0;
}
示例#17
0
/******************************************************************************
*   This routine should be called before any attemp to read an image.         *
*   Note it is assumed the Image desc. header (',') has been read.	      *
******************************************************************************/
int DGifGetImageDesc(GifFileType *GifFile)
{
    int i, BitsPerPixel;
    GifByteType Buf[3];
    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
	SavedImage	*sp;

    if (!IS_READABLE(Private)) {
	/* This file was NOT open for reading: */
	_GifError = D_GIF_ERR_NOT_READABLE;
	return GIF_ERROR;
    }

    if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
	DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
	DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
	DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
	return GIF_ERROR;
    if (READ(GifFile,Buf, 1) != 1) {
	_GifError = D_GIF_ERR_READ_FAILED;
	return GIF_ERROR;
    }
    BitsPerPixel = (Buf[0] & 0x07) + 1;
    GifFile->Image.Interlace = (Buf[0] & 0x40);
    if (Buf[0] & 0x80) {	    /* Does this image have local color map? */

	if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)
	    FreeMapObject(GifFile->Image.ColorMap);

	GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
    
	/* Get the image local color map: */
	for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
	    if (READ(GifFile,Buf, 3) != 3) {
		_GifError = D_GIF_ERR_READ_FAILED;
		return GIF_ERROR;
	    }
	    GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
	    GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
	    GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
	}
    }

    if (GifFile->SavedImages) {
	    if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
		     sizeof(SavedImage) * (GifFile->ImageCount + 1))) == NULL) {
	        _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
	        return GIF_ERROR;
	    }
    } else {
        if ((GifFile->SavedImages =
             (SavedImage *)malloc(sizeof(SavedImage))) == NULL) {
            _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
            return GIF_ERROR;
        }
    }

	sp = &GifFile->SavedImages[GifFile->ImageCount];
	memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
    if (GifFile->Image.ColorMap != NULL) {
        sp->ImageDesc.ColorMap = MakeMapObject(
                GifFile->Image.ColorMap->ColorCount,
                GifFile->Image.ColorMap->Colors);
    }
	sp->RasterBits = (char *)NULL;
	sp->ExtensionBlockCount = 0;
	sp->ExtensionBlocks = (ExtensionBlock *)NULL;

    GifFile->ImageCount++;

    Private->PixelCount = (long) GifFile->Image.Width *
			    (long) GifFile->Image.Height;

    DGifSetupDecompress(GifFile);  /* Reset decompress algorithm parameters. */

    return GIF_OK;
}
示例#18
0
bool CxImageGIF::Encode(CxFile * fp)
{
	if (EncodeSafeCheck(fp)) return false;

	GifFileType *GifFile = NULL;
	ColorMapObject *OutputColorMap = NULL;
	int i, ColorMapSize;

	if(head.biBitCount != 8)
	{
		if(head.biBitCount < 8)IncreaseBpp(8);
		else DecreaseBpp(8, true);
	}

	try
	{
		GifFile = EGifOpen(fp, writeCxFile);

		ColorMapSize = head.biClrUsed;
		OutputColorMap = MakeMapObject(ColorMapSize, NULL);

		RGBQUAD* pPal = GetPalette();
		for(i=0; i<ColorMapSize; ++i) 
		{
			OutputColorMap->Colors[i].Red = pPal[i].rgbRed;
			OutputColorMap->Colors[i].Green = pPal[i].rgbGreen;
			OutputColorMap->Colors[i].Blue = pPal[i].rgbBlue;
		}

		EGifPutScreenDesc(GifFile, head.biWidth, head.biHeight, OutputColorMap->ColorCount, info.nBkgndIndex== -1 ? 0 : info.nBkgndIndex, OutputColorMap);

		FreeMapObject(OutputColorMap);
		OutputColorMap = NULL;

		if(info.nBkgndIndex != -1)
		{
			unsigned char ExtStr[4] = { 1, 0, 0, info.nBkgndIndex };
			EGifPutExtension(GifFile, GRAPHICS_EXT_FUNC_CODE, 4, ExtStr);
		}

		EGifPutImageDesc(GifFile, 0, 0, head.biWidth, head.biHeight, FALSE, NULL);

		for (i = 0; i < head.biHeight; i++)
			EGifPutLine(GifFile, GetBits(head.biHeight - i - 1), head.biWidth);

		EGifCloseFile(GifFile);
		GifFile = NULL;
	} catch (int errid) {
		strncpy(info.szLastError,GifGetErrorMessage(errid),255);
		if(OutputColorMap)
		{
			FreeMapObject(OutputColorMap);
			OutputColorMap = NULL;
		}
		if(GifFile)
		{
			EGifCloseFile(GifFile);
			GifFile = NULL;
		}
		return false;
	} catch (char *message) {
		strncpy(info.szLastError,message,255);
		if(OutputColorMap)
		{
			FreeMapObject(OutputColorMap);
			OutputColorMap = NULL;
		}
		if(GifFile)
		{
			EGifCloseFile(GifFile);
			GifFile = NULL;
		}
		return false;
	}

	return true;
}
示例#19
0
static int DGifGetImageDesc(GifFileType * GifFile)
{
	int i, BitsPerPixel;
	GifByteType Buf[3];
	GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
	SavedImage *sp;

	if (!IS_READABLE(Private))
	{
		_GifError = D_GIF_ERR_NOT_READABLE;
		return GIF_ERROR;
	}

	if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR || DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR || DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR
			|| DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
		return GIF_ERROR;
	if (READ(GifFile, Buf, 1) != 1)
	{
		_GifError = D_GIF_ERR_READ_FAILED;
		return GIF_ERROR;
	}
	BitsPerPixel = (Buf[0] & 0x07) + 1;
	GifFile->Image.Interlace = (Buf[0] & 0x40);
	if (Buf[0] & 0x80)
	{
		if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)
			FreeMapObject(GifFile->Image.ColorMap);

		GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
		if (GifFile->Image.ColorMap == NULL)
		{
			_GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
			return GIF_ERROR;
		}

		for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++)
		{
			if (READ(GifFile, Buf, 3) != 3)
			{
				FreeMapObject(GifFile->Image.ColorMap);
				_GifError = D_GIF_ERR_READ_FAILED;
				GifFile->Image.ColorMap = NULL;
				return GIF_ERROR;
			}
			GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
			GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
			GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
		}
	}
	else if (GifFile->Image.ColorMap)
	{
		FreeMapObject(GifFile->Image.ColorMap);
		GifFile->Image.ColorMap = NULL;
	}

	if (GifFile->SavedImages)
	{
		if ((GifFile->SavedImages = (SavedImage *) realloc(GifFile->SavedImages, sizeof(SavedImage) * (GifFile->ImageCount + 1))) == NULL)
		{
			_GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
			return GIF_ERROR;
		}
	}
	else
	{
		if ((GifFile->SavedImages = (SavedImage *) gif_malloc(sizeof(SavedImage))) == NULL)
		{
			_GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
			return GIF_ERROR;
		}
	}

	sp = &GifFile->SavedImages[GifFile->ImageCount];
	memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
	if (GifFile->Image.ColorMap != NULL)
	{
		sp->ImageDesc.ColorMap = MakeMapObject(GifFile->Image.ColorMap->ColorCount, GifFile->Image.ColorMap->Colors);
		if (sp->ImageDesc.ColorMap == NULL)
		{
			_GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
			return GIF_ERROR;
		}
	}
	sp->RasterBits = (unsigned char *) NULL;
	sp->ExtensionBlockCount = 0;
	sp->ExtensionBlocks = (ExtensionBlock *) NULL;

	GifFile->ImageCount++;

	Private->PixelCount = (long) GifFile->Image.Width * (long) GifFile->Image.Height;

	DGifSetupDecompress(GifFile);

	return GIF_OK;
}
示例#20
0
void *
gif_encode(Image *image, int single, int *size)
{
    int width = image->columns;
    int height = image->rows;
    int total = width * height;
    GifByteType output[total];
    GifByteType red[total];
    GifByteType green[total];
    GifByteType blue[total];

    // Quantize the images using IM/GM first, to reduce
    // their number of colors to 256.
    int count = GetImageListLength(image);
    QuantizeInfo info;
    GetQuantizeInfo(&info);
    info.dither = 1;
    info.number_colors = NCOLORS;
    QuantizeImage(&info, image);
    if (count > 1) {
#ifdef _MAGICK_USES_IM
        RemapImages(&info, image->next, image);
#else
        MapImages(image->next, image, 0);
#endif
    }

    if (!acquire_image_pixels(image, red, green, blue)) {
        return NULL;
    }

    Frame *frames = calloc(count, sizeof(*frames));

    ColorMapObject *palette = MakeMapObject(NCOLORS, NULL);
    int palette_size = NCOLORS;

    // Quantize again using giflib, since it yields a palette which produces
    // better compression, reducing the file size by 20%. Note that this second
    // quantization is very fast, because the image already has 256 colors, so
    // its effect on performance is negligible.
    if (QuantizeBuffer(width, height, &palette_size, red, green, blue, output, palette->Colors) == GIF_ERROR) {
        FreeMapObject(palette);
        gif_frames_free(frames, count);
        return NULL;
    }

    frames[0].data = malloc(total);
    memcpy(frames[0].data, output, total);
    frames[0].width = width;
    frames[0].height = height;
    frames[0].duration = image->delay;
    GifColorType *colors = palette->Colors;

    Image *cur = image->next;
    PixelCache *cache = pixel_cache_new();
    int ii;
    for (ii = 1; ii < count; ii++, cur = cur->next) {
        frames[ii].width = width;
        frames[ii].height = height;
        frames[ii].duration = cur->delay;
        GifPixelType *data = malloc(total);
        frames[ii].data = data;
        
        if (!aprox_image_pixels(cur, colors, palette_size, cache, data)) {
            FreeMapObject(palette);
            gif_frames_free(frames, count);
            pixel_cache_free(cache);
            return NULL;
        }
    }
    pixel_cache_free(cache);
    void *ret = gif_save(image, palette, frames, count, size);
    FreeMapObject(palette);
    gif_frames_free(frames, count);
    return ret;
}
示例#21
0
/*!
 *  pixWriteStreamGif()
 *
 *      Input:  stream
 *              pix (1, 2, 4, 8, 16 or 32 bpp)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) All output gif have colormaps.  If the pix is 32 bpp rgb,
 *          this quantizes the colors and writes out 8 bpp.
 *          If the pix is 16 bpp grayscale, it converts to 8 bpp first.
 *      (2) We can't write to memory using open_memstream() because
 *          the gif functions write through a file descriptor, not a
 *          file stream.
 */
l_int32
pixWriteStreamGif(FILE  *fp,
                  PIX   *pix)
{
char            *text;
l_int32          fd, wpl, i, j, w, h, d, ncolor, rval, gval, bval;
l_int32          gif_ncolor = 0;
l_uint32        *data, *line;
PIX             *pixd;
PIXCMAP         *cmap;
GifFileType     *gif;
ColorMapObject  *gif_cmap;
GifByteType     *gif_line;

    PROCNAME("pixWriteStreamGif");

    if (!fp)
        return ERROR_INT("stream not open", procName, 1);
    if (!pix)
        return ERROR_INT("pix not defined", procName, 1);
    rewind(fp);

    if ((fd = fileno(fp)) < 0)
        return ERROR_INT("invalid file descriptor", procName, 1);

    d = pixGetDepth(pix);
    if (d == 32) {
        pixd = pixConvertRGBToColormap(pix, 1);
    }
    else if (d > 1) {
        pixd = pixConvertTo8(pix, TRUE);
    }
    else {  /* d == 1; make sure there's a colormap */
        pixd = pixClone(pix);
        if (!pixGetColormap(pixd)) {
            cmap = pixcmapCreate(1);
            pixcmapAddColor(cmap, 255, 255, 255);
            pixcmapAddColor(cmap, 0, 0, 0);
            pixSetColormap(pixd, cmap);
        }
    }

    if (!pixd)
        return ERROR_INT("failed to convert image to indexed", procName, 1);
    d = pixGetDepth(pixd);

    if ((cmap = pixGetColormap(pixd)) == NULL) {
        pixDestroy(&pixd);
        return ERROR_INT("cmap is missing", procName, 1);
    }

        /* 'Round' the number of gif colors up to a power of 2 */
    ncolor = pixcmapGetCount(cmap);
    for (i = 0; i <= 8; i++) {
        if ((1 << i) >= ncolor) {
            gif_ncolor = (1 << i);
            break;
        }
    }
    if (gif_ncolor < 1) {
        pixDestroy(&pixd);
        return ERROR_INT("number of colors is invalid", procName, 1);
    }

        /* Save the cmap colors in a gif_cmap */
    if ((gif_cmap = MakeMapObject(gif_ncolor, NULL)) == NULL) {
        pixDestroy(&pixd);
        return ERROR_INT("failed to create GIF color map", procName, 1);
    }
    for (i = 0; i < gif_ncolor; i++) {
        rval = gval = bval = 0;
        if (ncolor > 0) {
            if (pixcmapGetColor(cmap, i, &rval, &gval, &bval) != 0) {
                pixDestroy(&pixd);
                FreeMapObject(gif_cmap);
                return ERROR_INT("failed to get color from color map",
                                 procName, 1);
            }
            ncolor--;
        }
        gif_cmap->Colors[i].Red = rval;
        gif_cmap->Colors[i].Green = gval;
        gif_cmap->Colors[i].Blue = bval;
    }

        /* Get the gif file handle */
    if ((gif = EGifOpenFileHandle(fd)) == NULL) {
        pixDestroy(&pixd);
        FreeMapObject(gif_cmap);
        return ERROR_INT("failed to create GIF image handle", procName, 1);
    }

    pixGetDimensions(pixd, &w, &h, NULL);
    if (EGifPutScreenDesc(gif, w, h, gif_cmap->BitsPerPixel, 0, gif_cmap)
        != GIF_OK) {
        pixDestroy(&pixd);
        FreeMapObject(gif_cmap);
        EGifCloseFile(gif);
        return ERROR_INT("failed to write screen description", procName, 1);
    }
    FreeMapObject(gif_cmap); /* not needed after this point */

    if (EGifPutImageDesc(gif, 0, 0, w, h, FALSE, NULL) != GIF_OK) {
        pixDestroy(&pixd);
        EGifCloseFile(gif);
        return ERROR_INT("failed to image screen description", procName, 1);
    }

    data = pixGetData(pixd);	
    wpl = pixGetWpl(pixd);
    if (d != 1 && d != 2 && d != 4 && d != 8) {
        pixDestroy(&pixd);
        EGifCloseFile(gif);
        return ERROR_INT("image depth is not in {1, 2, 4, 8}", procName, 1);
    }

    if ((gif_line = (GifByteType *)CALLOC(sizeof(GifByteType), w)) == NULL) {
        pixDestroy(&pixd);
        EGifCloseFile(gif);
        return ERROR_INT("mem alloc fail for data line", procName, 1);
    }

    for (i = 0; i < h; i++) {
        line = data + i * wpl;
            /* Gif's way of setting the raster line up for compression */
        for (j = 0; j < w; j++) {
            switch(d)
            {
            case 8:
                gif_line[j] = GET_DATA_BYTE(line, j);
                break;
            case 4:
                gif_line[j] = GET_DATA_QBIT(line, j);
                break;
            case 2:
                gif_line[j] = GET_DATA_DIBIT(line, j);
                break;
            case 1:
                gif_line[j] = GET_DATA_BIT(line, j);
                break;
            }
        }

            /* Compress and save the line */
        if (EGifPutLine(gif, gif_line, w) != GIF_OK) {
            FREE(gif_line);
            pixDestroy(&pixd);
            EGifCloseFile(gif);
            return ERROR_INT("failed to write data line into GIF", procName, 1);
        }
    }

        /* Write a text comment.  This must be placed after writing the
         * data (!!)  Note that because libgif does not provide a function
         * for reading comments from file, you will need another way
         * to read comments. */
    if ((text = pixGetText(pix)) != NULL) {
        if (EGifPutComment(gif, text) != GIF_OK)
            L_WARNING("gif comment not written", procName);
    }

    FREE(gif_line);
    pixDestroy(&pixd);
    EGifCloseFile(gif);
    return 0;
}
示例#22
0
ColorMapObject *UnionColorMap(
			 ColorMapObject *ColorIn1,
			 ColorMapObject *ColorIn2,
			 GifPixelType ColorTransIn2[])
/*
 * Compute the union of two given color maps and return it.  If result can't 
 * fit into 256 colors, NULL is returned, the allocated union otherwise.
 * ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
 * copied iff they didn't exist before.  ColorTransIn2 maps the old
 * ColorIn2 into ColorUnion color map table.
 */
{
    int i, j, CrntSlot, RoundUpTo, NewBitSize;
    ColorMapObject *ColorUnion;

    /*
     * Allocate table which will hold the result for sure.
     */
    ColorUnion
	= MakeMapObject(MAX(ColorIn1->ColorCount,ColorIn2->ColorCount)*2,NULL);

    if (ColorUnion == NULL)
	return(NULL);

    /* Copy ColorIn1 to ColorUnionSize; */
    for (i = 0; i < ColorIn1->ColorCount; i++)
	ColorUnion->Colors[i] = ColorIn1->Colors[i];
    CrntSlot = ColorIn1->ColorCount;

    /*
     * Potentially obnoxious hack:
     *
     * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
     * of table 1.  This is very useful if your display is limited to
     * 16 colors.
     */
    while (ColorIn1->Colors[CrntSlot-1].Red == 0
	   && ColorIn1->Colors[CrntSlot-1].Green == 0
	   && ColorIn1->Colors[CrntSlot-1].Red == 0)
	CrntSlot--;

    /* Copy ColorIn2 to ColorUnionSize (use old colors if they exist): */
    for (i = 0; i < ColorIn2->ColorCount && CrntSlot<=256; i++)
    {
	/* Let's see if this color already exists: */
	for (j = 0; j < ColorIn1->ColorCount; j++)
	    if (memcmp(&ColorIn1->Colors[j], &ColorIn2->Colors[i], sizeof(GifColorType)) == 0)
		break;

	if (j < ColorIn1->ColorCount)
	    ColorTransIn2[i] = j;	/* color exists in Color1 */
	else
	{
	    /* Color is new - copy it to a new slot: */
	    ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
	    ColorTransIn2[i] = CrntSlot++;
	}
    }

    if (CrntSlot > 256)
    {
	FreeMapObject(ColorUnion);
	return((ColorMapObject *)NULL);
    }

    NewBitSize = BitSize(CrntSlot);
    RoundUpTo = (1 << NewBitSize);

    if (RoundUpTo != ColorUnion->ColorCount)
    {
	register GifColorType	*Map = ColorUnion->Colors;

	/*
	 * Zero out slots up to next power of 2.
	 * We know these slots exist because of the way ColorUnion's
	 * start dimension was computed.
	 */
	for (j = CrntSlot; j < RoundUpTo; j++)
	    Map[j].Red = Map[j].Green = Map[j].Blue = 0;

	/* perhaps we can shrink the map? */
	if (RoundUpTo < ColorUnion->ColorCount)
	    ColorUnion->Colors 
		= (GifColorType *)realloc(Map, sizeof(GifColorType)*RoundUpTo);
    }

    ColorUnion->ColorCount = RoundUpTo;
    ColorUnion->BitsPerPixel = NewBitSize;

    return(ColorUnion);
}
示例#23
0
static void Icon2Gif(char *FileName, FILE *txtin, int fdout)
{
    unsigned int	ExtCode, ColorMapSize = 0;
    GifColorType GlobalColorMap[256], LocalColorMap[256],
	*ColorMap = GlobalColorMap;
    char GlobalColorKeys[PRINTABLES], LocalColorKeys[PRINTABLES],
	*KeyTable = GlobalColorKeys;
    int red, green, blue;

    char buf[BUFSIZ * 2], InclusionFile[64];
    GifFileType *GifFileOut;
    SavedImage *NewImage = NULL;
    int n, LineNum = 0;

    if ((GifFileOut = EGifOpenFileHandle(fdout)) == NULL) {
	(void) HandleGifError(GifFileOut);
    }

    /* OK, interpret directives */
    while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
    {
	char	*cp;

	++LineNum;

	/*
	 * Skip lines consisting only of whitespace and comments
	 */
	for (cp = buf; isspace((int)(*cp)); cp++)
	    continue;
	if (*cp == '#' || *cp == '\0')
	    continue;

	/*
	 * If there's a trailing comment, nuke it and all preceding whitespace.
	 * But preserve the EOL.
	 */
	if ((cp = strchr(buf, '#')) && (cp == strrchr(cp, '#')))
	{
	    while (isspace((int)(*--cp)))
		continue;
	    *++cp = '\n';
	    *++cp = '\0';
	}

	/*
	 * Explicit header declarations
	 */

	if (sscanf(buf, "screen width %d\n", &GifFileOut->SWidth) == 1)
	    continue;

	else if (sscanf(buf, "screen height %d\n", &GifFileOut->SHeight) == 1)
	    continue;

	else if (sscanf(buf, "screen colors %d\n", &n) == 1)
	{
	    int	ResBits = BitSize(n);

	    if (n > 256 || n < 0 || n != (1 << ResBits))
	    {
		PARSE_ERROR("Invalid color resolution value.");
		exit(EXIT_FAILURE);
	    }

	    GifFileOut->SColorResolution = ResBits;
	    continue;
	}

	else if (sscanf(buf,
			"screen background %d\n",
			&GifFileOut->SBackGroundColor) == 1)
	    continue;

	/*
	 * Color table parsing
	 */

	else if (strcmp(buf, "screen map\n") == 0)
	{
	    if (GifFileOut->SColorMap != NULL)
	    {
		PARSE_ERROR("You've already declared a global color map.");
		exit(EXIT_FAILURE);
	    }

	    ColorMapSize = 0;
	    ColorMap = GlobalColorMap;
	    KeyTable = GlobalColorKeys;
	    memset(GlobalColorKeys, '\0', sizeof(GlobalColorKeys));
	}

	else if (strcmp(buf, "image map\n") == 0)
	{
	    if (NewImage == NULL)
	    {
		PARSE_ERROR("No previous image declaration.");
		exit(EXIT_FAILURE);
	    }

	    ColorMapSize = 0;
	    ColorMap = LocalColorMap;
	    KeyTable = LocalColorKeys;
	    memset(LocalColorKeys, '\0', sizeof(LocalColorKeys));
	}

	else if (sscanf(buf, "	rgb %d %d %d is %c",
		   &red, &green, &blue, &KeyTable[ColorMapSize]) == 4)
	{
	    ColorMap[ColorMapSize].Red = red;
	    ColorMap[ColorMapSize].Green = green;
	    ColorMap[ColorMapSize].Blue = blue;
	    ColorMapSize++;
	}

	else if (strcmp(buf, "end\n") == 0)
	{
	    ColorMapObject	*NewMap;


	    NewMap = MakeMapObject(1 << BitSize(ColorMapSize), ColorMap);
	    if (NewMap == (ColorMapObject *)NULL)
	    {
		PARSE_ERROR("Out of memory while allocating new color map.");
		exit(EXIT_FAILURE);
	    }

	    if (NewImage)
		NewImage->ImageDesc.ColorMap = NewMap;
	    else
		GifFileOut->SColorMap = NewMap;
	}

	/* GIF inclusion */
	else if (sscanf(buf, "include %s", InclusionFile) == 1)
	{
	    GifBooleanType	DoTranslation;
	    GifPixelType	Translation[256];

	    GifFileType	*Inclusion;
	    SavedImage	*NewImage, *CopyFrom;

	    if ((Inclusion = DGifOpenFileName(InclusionFile)) == NULL
		|| DGifSlurp(Inclusion) == GIF_ERROR)
	    {
		PARSE_ERROR("Inclusion read failed.");
        QuitGifError(Inclusion, GifFileOut);
	    }

	    if ((DoTranslation = (GifFileOut->SColorMap!=(ColorMapObject*)NULL)))
	    {
		ColorMapObject	*UnionMap;

		UnionMap = UnionColorMap(GifFileOut->SColorMap,
					 Inclusion->SColorMap, Translation);

		if (UnionMap == NULL)
		{
		    PARSE_ERROR("Inclusion failed --- global map conflict.");
            QuitGifError(Inclusion, GifFileOut);
		}

		FreeMapObject(GifFileOut->SColorMap);
		GifFileOut->SColorMap = UnionMap;
	    }

	    for (CopyFrom = Inclusion->SavedImages;
		 CopyFrom < Inclusion->SavedImages + Inclusion->ImageCount;
		 CopyFrom++)
	    {
		if ((NewImage = MakeSavedImage(GifFileOut, CopyFrom)) == NULL)
		{
		    PARSE_ERROR("Inclusion failed --- out of memory.");
            QuitGifError(Inclusion, GifFileOut);
		}
		else if (DoTranslation)
		    ApplyTranslation(NewImage, Translation);

		GifQprintf(
		        "%s: Image %d at (%d, %d) [%dx%d]: from %s\n",
			PROGRAM_NAME, GifFileOut->ImageCount,
			NewImage->ImageDesc.Left, NewImage->ImageDesc.Top,
			NewImage->ImageDesc.Width, NewImage->ImageDesc.Height,
			InclusionFile);
	    }

	    (void) DGifCloseFile(Inclusion);
	}

	/*
	 * Explicit image declarations 
	 */

	else if (strcmp(buf, "image\n") == 0)
	{
	    if ((NewImage = MakeSavedImage(GifFileOut, NULL)) == (SavedImage *)NULL)
	    {
		PARSE_ERROR("Out of memory while allocating image block.");
		exit(EXIT_FAILURE);
	    }

	    /* use global table unless user specifies a local one */
	    ColorMap = GlobalColorMap;
	    KeyTable = GlobalColorKeys;
	}

	/*
	 * Nothing past this point is valid unless we've seen a previous
	 * image declaration.
	 */
	else if (NewImage == (SavedImage *)NULL)
	{
	    (void) fputs(buf, stderr);
	    PARSE_ERROR("Syntax error in header block.");
	    exit(EXIT_FAILURE);
	}

	/*
	 * Accept image attributes
	 */
	else if (sscanf(buf, "image top %d\n", &NewImage->ImageDesc.Top) == 1)
	    continue;

	else if (sscanf(buf, "image left %d\n", &NewImage->ImageDesc.Left)== 1)
	    continue;

	else if (strcmp(buf, "image interlaced\n") == 0)
	{
	    NewImage->ImageDesc.Interlace = TRUE;
	    continue;
	}

	else if (sscanf(buf,
			"image bits %d by %d\n",
			&NewImage->ImageDesc.Width,
			&NewImage->ImageDesc.Height) == 2)
	{
	    int i, j;
	    static GifPixelType *Raster, *cp;
	    int c;

	    if ((Raster = (GifPixelType *) malloc(sizeof(GifPixelType) * NewImage->ImageDesc.Width * NewImage->ImageDesc.Height))
		== NULL) {
		PARSE_ERROR("Failed to allocate raster block, aborted.");
		exit(EXIT_FAILURE);
	    }

	    if (!GifQuietPrint)
		fprintf(stderr, "%s: Image %d at (%d, %d) [%dx%d]:     ",
		    PROGRAM_NAME, GifFileOut->ImageCount,
		    NewImage->ImageDesc.Left, NewImage->ImageDesc.Top,
		    NewImage->ImageDesc.Width, NewImage->ImageDesc.Height);

	    cp = Raster;
	    for (i = 0; i < NewImage->ImageDesc.Height; i++) {

		char	*dp;

		for (j = 0; j < NewImage->ImageDesc.Width; j++)
		    if ((c = fgetc(txtin)) == EOF) {
			PARSE_ERROR("input file ended prematurely.");
			exit(EXIT_FAILURE);
		    }
		    else if (c == '\n')
		    {
			--j;
			++LineNum;
		    }
		    else if (isspace(c))
			--j;
		    else if ((dp = strchr(KeyTable, c)))
			*cp++ = (dp - KeyTable);
		    else {
			PARSE_ERROR("Invalid pixel value.");
			exit(EXIT_FAILURE);
		    }

		if (!GifQuietPrint)
		    fprintf(stderr, "\b\b\b\b%-4d", i);
	    }

	    if (!GifQuietPrint)
		putc('\n', stderr);

	    NewImage->RasterBits = (unsigned char *) Raster;
	}
	else if (sscanf(buf, "comment"))
	{
	    MakeExtension(NewImage, COMMENT_EXT_FUNC_CODE);
	    while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
		if (strcmp(buf, "end\n") == 0)
		    break;
	        else
		{
		    int Len;

		    buf[strlen(buf) - 1] = '\0';
		    Len = EscapeString(buf, buf);
		    if (AddExtensionBlock(NewImage, Len, (unsigned char *)buf) == GIF_ERROR) {
			PARSE_ERROR("out of memory while adding comment block.");
			exit(EXIT_FAILURE);
		    }
		}
	}
	else if (sscanf(buf, "plaintext"))
	{
	    MakeExtension(NewImage, PLAINTEXT_EXT_FUNC_CODE);
	    while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
		if (strcmp(buf, "end\n") == 0)
		    break;
	        else
		{
		    int Len;

		    buf[strlen(buf) - 1] = '\0';
		    Len = EscapeString(buf, buf);
		    if (AddExtensionBlock(NewImage, Len, (unsigned char *)buf) == GIF_ERROR) {
			PARSE_ERROR("out of memory while adding plaintext block.");
			exit(EXIT_FAILURE);
		    }
		}
	}
	else if (sscanf(buf, "extension %02x", &ExtCode))
	{
	    MakeExtension(NewImage, ExtCode);
	    while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
		if (strcmp(buf, "end\n") == 0)
		    break;
	        else
		{
		    int Len;

		    buf[strlen(buf) - 1] = '\0';
		    Len = EscapeString(buf, buf);
		    if (AddExtensionBlock(NewImage, Len, (unsigned char *)buf) == GIF_ERROR) {
			PARSE_ERROR("out of memory while adding extension block.");
			exit(EXIT_FAILURE);
		    }
		}
	}
	else
	{
	    (void) fputs(buf, stderr);
	    PARSE_ERROR("Syntax error in image description.");
	    exit(EXIT_FAILURE);
	}
    }

    if (EGifSpew(GifFileOut) == GIF_ERROR)
	HandleGifError(GifFileOut);
}
示例#24
0
文件: ungif.c 项目: hoangduit/reactos
/******************************************************************************
 * This routine should be called before any attempt to read an image.
 * Note it is assumed the Image desc. header (',') has been read.
 *****************************************************************************/
static int
DGifGetImageDesc(GifFileType * GifFile) {

    int i, BitsPerPixel, SortFlag;
    GifByteType Buf[3];
    GifFilePrivateType *Private = GifFile->Private;
    SavedImage *sp;

    if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
        DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
        DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
        DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
        return GIF_ERROR;
    if (READ(GifFile, Buf, 1) != 1) {
        return GIF_ERROR;
    }
    BitsPerPixel = (Buf[0] & 0x07) + 1;
    SortFlag = (Buf[0] & 0x20) != 0;
    GifFile->Image.Interlace = (Buf[0] & 0x40);
    if (Buf[0] & 0x80) {    /* Does this image have local color map? */

        FreeMapObject(GifFile->Image.ColorMap);

        GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
        if (GifFile->Image.ColorMap == NULL) {
            return GIF_ERROR;
        }

        /* Get the image local color map: */
        GifFile->Image.ColorMap->SortFlag = SortFlag;
        for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
            if (READ(GifFile, Buf, 3) != 3) {
                FreeMapObject(GifFile->Image.ColorMap);
                GifFile->Image.ColorMap = NULL;
                return GIF_ERROR;
            }
            GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
            GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
            GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
        }
    } else if (GifFile->Image.ColorMap) {
        FreeMapObject(GifFile->Image.ColorMap);
        GifFile->Image.ColorMap = NULL;
    }

    if (GifFile->SavedImages) {
        if ((GifFile->SavedImages = ungif_realloc(GifFile->SavedImages,
                                      sizeof(SavedImage) *
                                      (GifFile->ImageCount + 1))) == NULL) {
            return GIF_ERROR;
        }
    } else {
        if ((GifFile->SavedImages = ungif_alloc(sizeof(SavedImage))) == NULL) {
            return GIF_ERROR;
        }
    }

    sp = &GifFile->SavedImages[GifFile->ImageCount];
    sp->ImageDesc = GifFile->Image;
    if (GifFile->Image.ColorMap != NULL) {
        sp->ImageDesc.ColorMap = MakeMapObject(
                                 GifFile->Image.ColorMap->ColorCount,
                                 GifFile->Image.ColorMap->Colors);
        if (sp->ImageDesc.ColorMap == NULL) {
            return GIF_ERROR;
        }
        sp->ImageDesc.ColorMap->SortFlag = GifFile->Image.ColorMap->SortFlag;
    }
    sp->RasterBits = NULL;
    sp->Extensions.ExtensionBlockCount = 0;
    sp->Extensions.ExtensionBlocks = NULL;

    GifFile->ImageCount++;

    Private->PixelCount = (long)GifFile->Image.Width *
       (long)GifFile->Image.Height;

    DGifSetupDecompress(GifFile);  /* Reset decompress algorithm parameters. */

    return GIF_OK;
}
示例#25
0
GDALDataset *
GIFDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
               int bStrict, char ** papszOptions, 
               GDALProgressFunc pfnProgress, void * pProgressData )

{
    int  nBands = poSrcDS->GetRasterCount();
    int  nXSize = poSrcDS->GetRasterXSize();
    int  nYSize = poSrcDS->GetRasterYSize();
    int	 bInterlace = FALSE;

/* -------------------------------------------------------------------- */
/*      Check for interlaced option.                                    */
/* -------------------------------------------------------------------- */
    bInterlace = CSLFetchBoolean(papszOptions, "INTERLACING", FALSE);

/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    if( nBands != 1 )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GIF driver only supports one band images.\n" );

        return NULL;
    }

    if (nXSize > 65535 || nYSize > 65535)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GIF driver only supports datasets up to 65535x65535 size.\n" );

        return NULL;
    }

    if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
        && bStrict )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GIF driver doesn't support data type %s. "
                  "Only eight bit bands supported.\n", 
                  GDALGetDataTypeName( 
                      poSrcDS->GetRasterBand(1)->GetRasterDataType()) );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Open the output file.                                           */
/* -------------------------------------------------------------------- */
    GifFileType *hGifFile;
    VSILFILE *fp;

    fp = VSIFOpenL( pszFilename, "wb" );
    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to create %s:\n%s", 
                  pszFilename, VSIStrerror( errno ) );
        return NULL;
    }

    hGifFile = EGifOpen( fp, VSIGIFWriteFunc );
    if( hGifFile == NULL )
    {
        VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "EGifOpenFilename(%s) failed.  Does file already exist?",
                  pszFilename );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Prepare colortable.                                             */
/* -------------------------------------------------------------------- */
    GDALRasterBand	*poBand = poSrcDS->GetRasterBand(1);
    ColorMapObject	*psGifCT;
    int			iColor;

    if( poBand->GetColorTable() == NULL )
    {
        psGifCT = MakeMapObject( 256, NULL );
        for( iColor = 0; iColor < 256; iColor++ )
        {
            psGifCT->Colors[iColor].Red = (GifByteType) iColor;
            psGifCT->Colors[iColor].Green = (GifByteType) iColor;
            psGifCT->Colors[iColor].Blue = (GifByteType) iColor;
        }
    }
    else
    {
        GDALColorTable	*poCT = poBand->GetColorTable();
        int nFullCount = 1;

        while( nFullCount < poCT->GetColorEntryCount() )
            nFullCount = nFullCount * 2;

        psGifCT = MakeMapObject( nFullCount, NULL );
        for( iColor = 0; iColor < poCT->GetColorEntryCount(); iColor++ )
        {
            GDALColorEntry	sEntry;

            poCT->GetColorEntryAsRGB( iColor, &sEntry );
            psGifCT->Colors[iColor].Red = (GifByteType) sEntry.c1;
            psGifCT->Colors[iColor].Green = (GifByteType) sEntry.c2;
            psGifCT->Colors[iColor].Blue = (GifByteType) sEntry.c3;
        }
        for( ; iColor < nFullCount; iColor++ )
        {
            psGifCT->Colors[iColor].Red = 0;
            psGifCT->Colors[iColor].Green = 0;
            psGifCT->Colors[iColor].Blue = 0;
        }
    }

/* -------------------------------------------------------------------- */
/*      Setup parameters.                                               */
/* -------------------------------------------------------------------- */
    if (EGifPutScreenDesc(hGifFile, nXSize, nYSize, 
                          psGifCT->ColorCount, 255, psGifCT) == GIF_ERROR)
    {
        FreeMapObject(psGifCT);
        PrintGifError();
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Error writing gif file." );
        EGifCloseFile(hGifFile);
        VSIFCloseL( fp );
        return NULL;
    }
    
    FreeMapObject(psGifCT);
    psGifCT = NULL;

    /* Support for transparency */
    int bNoDataValue;
    double noDataValue = poBand->GetNoDataValue(&bNoDataValue);
    if (bNoDataValue && noDataValue >= 0 && noDataValue <= 255)
    {
        unsigned char extensionData[4];
        extensionData[0] = 1; /*  Transparent Color Flag */
        extensionData[1] = 0;
        extensionData[2] = 0;
        extensionData[3] = (unsigned char)noDataValue;
        EGifPutExtension(hGifFile, 0xf9, 4, extensionData);
    }

    if (EGifPutImageDesc(hGifFile, 0, 0, nXSize, nYSize, bInterlace, NULL) == GIF_ERROR )
    {
        PrintGifError();
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Error writing gif file." );
        EGifCloseFile(hGifFile);
        VSIFCloseL( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Loop over image, copying image data.                            */
/* -------------------------------------------------------------------- */
    CPLErr      eErr;
    GDALPamDataset *poDS;
    GByte      *pabyScanline;

    pabyScanline = (GByte *) CPLMalloc( nXSize );

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
        eErr = CE_Failure;

    if( !bInterlace )
    {
        for( int iLine = 0; iLine < nYSize; iLine++ )
        {
            eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
                                     pabyScanline, nXSize, 1, GDT_Byte,
                                     nBands, nBands * nXSize );

            if( eErr != CE_None || EGifPutLine( hGifFile, pabyScanline, nXSize ) == GIF_ERROR )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Error writing gif file." );
                goto error;
            }

            if( !pfnProgress( (iLine + 1) * 1.0 / nYSize, NULL, pProgressData ) )
            {
                goto error;
            }

        }
    }
    else
    {
        int 	i, j;
        int nLinesRead = 0;
        int nLinesToRead = 0;
        for ( i = 0; i < 4; i++)
        {
            for (j = InterlacedOffset[i]; j < nYSize; j += InterlacedJumps[i]) 
            {
                nLinesToRead ++;
            }
        }

        /* Need to perform 4 passes on the images: */
        for ( i = 0; i < 4; i++)
        {
            for (j = InterlacedOffset[i]; j < nYSize; j += InterlacedJumps[i]) 
            {
                eErr= poBand->RasterIO( GF_Read, 0, j, nXSize, 1, 
                                        pabyScanline, nXSize, 1, GDT_Byte,
                                        1, nXSize );

                if (eErr != CE_None || EGifPutLine(hGifFile, pabyScanline, nXSize) == GIF_ERROR)
                {
                    CPLError( CE_Failure, CPLE_AppDefined, 
                            "Error writing gif file." );
                    goto error;
                }

                nLinesRead ++;
                if( !pfnProgress( nLinesRead * 1.0 / nYSize, NULL, pProgressData ) )
                {
                    goto error;
                }
            }
        }
    }

    CPLFree( pabyScanline );
    pabyScanline = NULL;

/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    if (EGifCloseFile(hGifFile) == GIF_ERROR)
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "EGifCloseFile() failed.\n" );
        hGifFile = NULL;
        goto error;
    }
    hGifFile = NULL;

    VSIFCloseL( fp );
    fp = NULL;

/* -------------------------------------------------------------------- */
/*      Do we need a world file?                                          */
/* -------------------------------------------------------------------- */
    if( CSLFetchBoolean( papszOptions, "WORLDFILE", FALSE ) )
    {
    	double      adfGeoTransform[6];
	
	if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None )
            GDALWriteWorldFile( pszFilename, "wld", adfGeoTransform );
    }

/* -------------------------------------------------------------------- */
/*      Re-open dataset, and copy any auxilary pam information.         */
/* -------------------------------------------------------------------- */

    /* If outputing to stdout, we can't reopen it, so we'll return */
    /* a fake dataset to make the caller happy */
    CPLPushErrorHandler(CPLQuietErrorHandler);
    poDS = (GDALPamDataset*) GDALOpen(pszFilename, GA_ReadOnly);
    CPLPopErrorHandler();
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
        return poDS;
    }
    else
    {
        CPLErrorReset();

        GIFDataset* poGIF_DS = new GIFDataset();
        poGIF_DS->nRasterXSize = nXSize;
        poGIF_DS->nRasterYSize = nYSize;
        for(int i=0;i<nBands;i++)
            poGIF_DS->SetBand( i+1, new GIFRasterBand( poGIF_DS, i+1, NULL, 0 ) );
        return poGIF_DS;
    }

error:
    if (hGifFile)
        EGifCloseFile(hGifFile);
    if (fp)
        VSIFCloseL( fp );
    if (pabyScanline)
        CPLFree( pabyScanline );
    return NULL;
}