Exemplo n.º 1
0
Arquivo: ipas.cpp Projeto: macx0r/ipas
void save_image (image* img, char* file, image_format fmt) {
  if (fmt == imgIRMID) {
    FILE* fp;
    fp = fopen (file, "w");
    fwrite (img, img->size, 1, fp);
    fclose (fp);
  } else if (fmt == imgGIF) {
    GifFileType* GifFileOut = (GifFileType *)NULL;
    GifFileOut = EGifOpenFileName (file, 0);

    GifColorType* color_map = new GifColorType[0x100 * 3];
    for (uint n = 0; n < 0x100 ; ++n) {
      color_map[n].Red = n;
      color_map[n].Green = n;
      color_map[n].Blue = n;
    }
    ColorMapObject* map_object = MakeMapObject (0x100, color_map);

    GifRowType pixels = (GifRowType) new GifPixelType[img->xy];
    for (uint n = 0; n < img->xy; ++n)
      pixels[n] = (GifPixelType)data(img)[n];

    EGifPutScreenDesc (GifFileOut, img->dimx, img->dimy, 0x100, 0x100, map_object);
    EGifPutImageDesc (GifFileOut, 0, 0, img->dimx, img->dimy, 0, map_object);
    EGifPutLine (GifFileOut, pixels, img->xy);
    EGifCloseFile (GifFileOut);
  }
}
Exemplo n.º 2
0
int
get_gif_image_desc( GifFileType *gif, SavedImage *im )
{
	long start_pos, end_pos ;
	int status;

	start_pos = ftell(gif->UserData);
	status = DGifGetImageDesc( gif );
	end_pos = ftell(gif->UserData);
	if( status == GIF_OK )
	{
		int ext_count = im->ExtensionBlockCount ;
		ExtensionBlock	*ext_ptr = im->ExtensionBlocks ;

		im->ExtensionBlocks = NULL ;
		im->ExtensionBlockCount = 0 ;

		free_gif_saved_image( im, True );
		memset( im, 0x00, sizeof(SavedImage));

		im->ExtensionBlocks = ext_ptr ;
		im->ExtensionBlockCount = ext_count ;

		memcpy( &(im->ImageDesc), &(gif->Image), sizeof(GifImageDesc));
		if( gif->Image.ColorMap )
		{
			im->ImageDesc.ColorMap = MakeMapObject(gif->Image.ColorMap->ColorCount, NULL);
			fseek( gif->UserData, start_pos+9, SEEK_SET ); 
			fread( im->ImageDesc.ColorMap->Colors, 1, gif->Image.ColorMap->ColorCount*3, gif->UserData);
			fseek( gif->UserData, end_pos, SEEK_SET );
			gif->Image.ColorMap = NULL ;
 		}
	}
	return status;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, Error, NumFiles, Width, Height;
    char **FileName = NULL;
    GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL,
        *OutputBuffer = NULL;
    ColorMapObject *OutputColorMap = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint,
		&ColorFlag, &ExpNumOfColors, &HelpFlag,
		&NumFiles, &FileName)) != FALSE ||
		(NumFiles > 1 && !HelpFlag)) {
	if (Error)
	    GAPrintErrMsg(Error);
	else if (NumFiles > 1)
	    GIF_MESSAGE("Error in command line parsing - one GIF file please.");
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

    if (HelpFlag) {
	fprintf(stderr, VersionStr);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    ColorMapSize = 1 << ExpNumOfColors;

    if (NumFiles == 1) {
	LoadRle(*FileName,
		&RedBuffer, &GreenBuffer, &BlueBuffer, &Width, &Height);
    }
    else {
	LoadRle(NULL,
		&RedBuffer, &GreenBuffer, &BlueBuffer, &Width, &Height);
    }
    if ((OutputColorMap = MakeMapObject(ColorMapSize, NULL)) == NULL ||
	    (OutputBuffer = (GifByteType *) malloc(Width * Height *
					    sizeof(GifByteType))) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    if (QuantizeBuffer(Width, Height, &ColorMapSize,
		       RedBuffer, GreenBuffer, BlueBuffer,
		       OutputBuffer, OutputColorMap->Colors) == GIF_ERROR)
	QuitGifError(NULL);
    free((char *) RedBuffer);
    free((char *) GreenBuffer);
    free((char *) BlueBuffer);

    SaveGif(OutputBuffer, OutputColorMap, ExpNumOfColors, Width, Height);

    return 0;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;

    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;
}
Exemplo n.º 7
0
/******************************************************************************
 * 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;
}
Exemplo n.º 8
0
void init_gifs(char *fileName, int sizex, int sizey)
{
  if(gifFileIn==NULL) {
    gifFileIn = DGifOpenFileName("kaavyhdi.gif");
    if(gifFileIn==NULL) {failExit;}
    printf("%i,%i: %i\n", gifFileIn->SWidth, gifFileIn->SHeight, gifFileIn->SColorResolution);
    if(DGifSlurp(gifFileIn) == GIF_ERROR) failExit;
    printf("slurp done\n");
  }
  gifFileOut = EGifOpenFileName(fileName, FALSE);
  if(gifFileOut==NULL) failExit;

  printf("making output...\n");
  if(EGifPutScreenDesc(gifFileOut, sizex, sizey, gifFileIn->SColorResolution,
                       gifFileIn->SBackGroundColor, 
                       MakeMapObject(gifFileIn->SColorMap->ColorCount,
                                     gifFileIn->SColorMap->Colors)) == GIF_ERROR) failExit;
  if(EGifPutImageDesc(gifFileOut, 0, 0, sizex, sizey, FALSE, NULL) == GIF_ERROR) failExit;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
/******************************************************************************
* Image block allocation functions					      *
******************************************************************************/
SavedImage *MakeSavedImage(GifFileType *GifFile, SavedImage *CopyFrom)
/*
 * Append an image block to the SavedImages array  
 */
{
    SavedImage	*sp;

    if (GifFile->SavedImages == NULL)
	GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
    else
	GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
				sizeof(SavedImage) * (GifFile->ImageCount+1));

    if (GifFile->SavedImages == NULL)
	return((SavedImage *)NULL);
    else
    {
	sp = &GifFile->SavedImages[GifFile->ImageCount++];
	memset((char *)sp, '\0', sizeof(SavedImage));

	if (CopyFrom)
	{
	    memcpy((char *)sp, CopyFrom, sizeof(SavedImage));

	    /*
	     * Make our own allocated copies of the heap fields in the
	     * copied record.  This guards against potential aliasing
	     * problems.
	     */

	    /* first, the local color map */
	    if (sp->ImageDesc.ColorMap)
		sp->ImageDesc.ColorMap =
		    MakeMapObject(CopyFrom->ImageDesc.ColorMap->ColorCount,
				  CopyFrom->ImageDesc.ColorMap->Colors);

	    /* next, the raster */
	    sp->RasterBits = (char *)malloc(sizeof(GifPixelType)
				* CopyFrom->ImageDesc.Height
				* CopyFrom->ImageDesc.Width);
	    memcpy(sp->RasterBits,
		   CopyFrom->RasterBits,
		   sizeof(GifPixelType)
			* CopyFrom->ImageDesc.Height
			* CopyFrom->ImageDesc.Width);

	    /* finally, the extension blocks */
	    if (sp->ExtensionBlocks)
	    {
		sp->ExtensionBlocks
		    = (ExtensionBlock*)malloc(sizeof(ExtensionBlock)
					      * CopyFrom->ExtensionBlockCount);
		memcpy(sp->ExtensionBlocks,
		   CopyFrom->ExtensionBlocks,
		   sizeof(ExtensionBlock)
		   	* CopyFrom->ExtensionBlockCount);

		/*
		 * For the moment, the actual blocks can take their
		 * chances with free().  We'll fix this later. 
		 */
	    }
	}

	return(sp);
    }
}
Exemplo n.º 12
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);
}
Exemplo n.º 13
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    unsigned int Ratio;
    int	i, j, l, LevelHeight, LevelWidth, Error, LogNumLevels, FlipDir,
	Accumulator, StartX, StepX, Count = 0, DoAllMaximum = FALSE,
	DirectionFlag = FALSE, LevelsFlag = FALSE, ColorFlag = FALSE,
	MinFlag = FALSE, MaxFlag = FALSE, SizeFlag = FALSE, HelpFlag = FALSE;
    GifPixelType Color;
    char *DirectionStr = DEFAULT_DIR;
    GifRowType Line;
    ColorMapObject *ColorMap;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint,
		&DirectionFlag, &DirectionStr, &LevelsFlag, &NumLevels,
		&ColorFlag, &RedColor, &GreenColor, &BlueColor,
		&MinFlag, &MinimumIntensity, &MaxFlag, &MaximumIntensity,
		&SizeFlag, &ImageWidth, &ImageHeight,
		&HelpFlag)) != FALSE) {
	GAPrintErrMsg(Error);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

    if (HelpFlag) {
	fprintf(stderr, VersionStr);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    /* Make sure intensities are in the right range: */
    if (MinimumIntensity < 0 || MinimumIntensity > 100 ||
	MaximumIntensity < 0 || MaximumIntensity > 100)
	GIF_EXIT("Intensities (-m or -M options) are not in [0..100] range (percent).");

    /* Convert DirectionStr to our local representation: */
    Direction = DIR_NONE;
    FlipDir = FALSE;
    for (i = 0; i < (int)strlen(DirectionStr);  i++) /* Make sure its upper case. */
	if (islower(DirectionStr[i]))
	    DirectionStr[i] = toupper(DirectionStr[i]);

    switch(DirectionStr[0]) {
	case 'T': /* Top or North */
	case 'N':
	    if (strlen(DirectionStr) < 2)
		Direction = DIR_TOP;
	    else
		switch(DirectionStr[1]) {
		    case 'R':
		    case 'E':
			Direction = DIR_TOP_RIGHT;
			break;
		    case 'L':
		    case 'W':
			Direction = DIR_TOP_LEFT;
			FlipDir = TRUE;
			break;
		}
	    break;
	case 'R': /* Right or East */
	case 'E':
	    Direction = DIR_RIGHT;
	    break;
	case 'B': /* Bottom or South */
	case 'S':
	    if (strlen(DirectionStr) < 2) {
		Direction = DIR_BOT;
		FlipDir = TRUE;
	    }
	    else
		switch(DirectionStr[1]) {
		    case 'R':
		    case 'E':
			Direction = DIR_BOT_RIGHT;
			break;
		    case 'L':
		    case 'W':
			Direction = DIR_BOT_LEFT;
			FlipDir = TRUE;
			break;
		}
	    break;
	case 'L': /* Left or West */
	case 'W':
	    Direction = DIR_LEFT;
	    FlipDir = TRUE;
	    break;
    }
    if (Direction == DIR_NONE)
	GIF_EXIT("Direction requested (-d option) is wierd!");

    /* We are going to handle only TOP, TOP_RIGHT, RIGHT, BOT_RIGHT  so flip */
    /* the complement cases (TOP <-> BOT for example) by flipping the	     */
    /* Color i with color (NumLevels - i - 1).				     */
    if (FlipDir) {
	switch (Direction) {
	    case DIR_BOT:
		Direction = DIR_TOP;
		break;
	    case DIR_BOT_LEFT:
		Direction = DIR_TOP_RIGHT;
		break;
	    case DIR_LEFT:
		Direction = DIR_RIGHT;
		break;
	    case DIR_TOP_LEFT:
		Direction = DIR_BOT_RIGHT;
		break;
	}
    }

    /* If binary mask is requested (special case): */
    if (MinimumIntensity == 100 && MaximumIntensity == 100 && NumLevels == 2) {
	MinimumIntensity = 0;
	DoAllMaximum = TRUE;
	Direction = DIR_RIGHT;
    }

    /* Make sure colors are in the right range: */
    if (RedColor > 255 || GreenColor > 255 || BlueColor > 255)
	GIF_EXIT("Colors are not in the ragne [0..255].");

    /* Make sure number of levels is power of 2 (up to 8 bits per pixel).    */
    for (i = 1; i < 8; i++) if (NumLevels == (1 << i)) break;
    if (i == 8) GIF_EXIT("#Lvls (-l option) is not power of 2.");
    LogNumLevels = i;

    /* Open stdout for the output file: */
    if ((GifFile = EGifOpenFileHandle(1)) == NULL)
	QuitGifError(GifFile);

    /* Dump out screen description with given size and generated color map:  */
    if ((ColorMap = MakeMapObject(NumLevels, NULL)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    for (i = 1; i <= NumLevels; i++) {
	/* Ratio will be in the range of 0..100 for required intensity: */
	Ratio = (MaximumIntensity * (i * (256 / NumLevels)) +
		 MinimumIntensity * ((NumLevels - i) * (256 / NumLevels))) /
		 256;
	ColorMap->Colors[i-1].Red   = (RedColor * Ratio) / 100;
	ColorMap->Colors[i-1].Green = (GreenColor * Ratio) / 100;
	ColorMap->Colors[i-1].Blue  = (BlueColor * Ratio) / 100;
    }
    if (EGifPutScreenDesc(GifFile,
	ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap)
	== GIF_ERROR)
	QuitGifError(GifFile);

    /* Dump out the image descriptor: */
    if (EGifPutImageDesc(GifFile,
	0, 0, ImageWidth, ImageHeight, FALSE, NULL) == GIF_ERROR)
	QuitGifError(GifFile);

    GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]:     ",
	       PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top,
	       GifFile->Image.Width, GifFile->Image.Height);

    /* Allocate one scan line twice as big as image is as we are going to    */
    /* shift along it, while we dump the scan lines:			     */
    if ((Line = (GifRowType) malloc(sizeof(GifPixelType) * ImageWidth * 2)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    if (Direction == DIR_TOP) {
	/* We must evaluate the line each time level is changing: */
	LevelHeight = ImageHeight / NumLevels;
	for (Color = NumLevels, i = l = 0; i < ImageHeight; i++) {
	    if (i == l) {
		/* Time to update the line to next color level: */
		if (Color != 0) Color--;
		for (j = 0; j < ImageWidth; j++)
		    Line[j] = (FlipDir ? NumLevels - Color - 1 : Color);
		l += LevelHeight;
	    }
	    if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR)
		QuitGifError(GifFile);
	    GifQprintf("\b\b\b\b%-4d", Count++);
	}
    }
    else if (Direction == DIR_RIGHT) {
	/* We pre-prepare the scan lines as going from color zero to maximum */
	/* color and dump the same scan line Height times:		     */
	/* Note this case should handle the Boolean Mask special case.	     */
	LevelWidth = ImageWidth / NumLevels;
	if (DoAllMaximum) {
	    /* Special case - do all in maximum color: */
	    for (i = 0; i < ImageWidth; i++) Line[i] = 1;
	}
	else {
	    for (Color = i = 0, l = LevelWidth; i < ImageWidth; i++, l--) {
		if (l == 0) {
		    l = LevelWidth;
		    if (Color < NumLevels - 1) Color++;
		}
		Line[i] = (FlipDir ? NumLevels - Color - 1 : Color);
	    }
	}

	for (i = 0; i < ImageHeight; i++) {
	    if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR)
		QuitGifError(GifFile);
	    GifQprintf("\b\b\b\b%-4d", Count++);
	}
    }
    else {
	/* We are in one of the TOP_RIGHT, BOT_RIGHT cases: we will          */
	/* initialize the Line with its double ImageWidth length from the    */
	/* minimum intensity to the maximum intensity and shift along it     */
	/* while we go along the image height.				     */
	LevelWidth = ImageWidth * 2 / NumLevels;
	for (Color = i = 0, l = LevelWidth; i < ImageWidth * 2; i++, l--) {
	    if (l == 0) {
		l = LevelWidth;
		if (Color < NumLevels - 1) Color++;
	    }
	    Line[i] = (FlipDir ? NumLevels - Color - 1 : Color);
	}
	/* We need to implement a DDA to know how much to shift Line while   */
	/* we go down along image height. we set the parameters for it now:  */
	Accumulator = 0;
	switch(Direction) {
	    case DIR_TOP_RIGHT:
		StartX = ImageWidth;
		StepX = -1;
		break;
	    case DIR_BOT_RIGHT:
	    default:
		StartX = 0;
		StepX = 1;
		break;
	}

	/* Time to dump information out: */
	for (i = 0; i < ImageHeight; i++) {
	    if (EGifPutLine(GifFile, &Line[StartX], ImageWidth) == GIF_ERROR)
		QuitGifError(GifFile);
	    GifQprintf("\b\b\b\b%-4d", Count++);
	    if ((Accumulator += ImageWidth) > ImageHeight) {
		while (Accumulator > ImageHeight) {
		    Accumulator -= ImageHeight;
		    StartX += StepX;
		}
		if (Direction < 0) Direction = 0;
		if (Direction > ImageWidth) Direction = ImageWidth;
	    }
	}
    }

    if (EGifCloseFile(GifFile) == GIF_ERROR)
	QuitGifError(GifFile);

    return 0;
}
Exemplo n.º 14
0
/*
 *	Updates the background objects as necessary. Removes existing ones,
 *	and then looks at the interface and builds new ones.
 */
void
UpdateBackgroundObjects ( WindowObjectType *wo, int potIndex )
{

	MetObjectType		*mot, *mlist[MAXMETOBJS];
	int			i, count, nmaps;
	char			mapfile[GEMPAKSTRING];
	char			mapname[GEMPAKSTRING];
	char			*latinc, *loninc, *lblinc;
	char			line_color[GEMPAKSTRING];
	char			line_type[GEMPAKSTRING];
	char			line_width[GEMPAKSTRING];
	char			sysM [] = "M";
	float			lat1, lat2, lon1, lon2, latdiff;
	double			fminscale, fmaxscale;
	char			*minscale, *maxscale;
	Widget			stateW;
	BooleanType		stateChanged;
	GuiMapBackgroundDialogType *mbg;
	GuiLatLonGridDialogType	*llg;
	PixmapObjectType	*po, *ppo;


	llg = GetGuiLatLonGridDialog();
	mbg = GetGuiMapBackgroundDialog();
	po = wo->pixmapObjects[potIndex];

/*
 *	First, decide if we need to rebuild the background objects. If there
 *	are no MAP class objects, or if the backgrounds
 *	dialog info has changed, then we will build new ones.
 */
	nmaps = 0;
	for ( i = 0; i < po->numMetObjects; i++ ) {
	    mot = po->metObjects [i];
	    if ( GetMetObjectClass ( mot->type ) == MAP ) nmaps++;
	} 

	stateChanged =( GetLatLonGridChangeState (llg) || 
			GetMapListChangeState (mbg) );

	if ( nmaps == 0 || stateChanged ) 
		RemoveBackgroundObjects( po );
	else
	   	return;


/*
 *	Get the latitude range of the current window
 */
	if ( (getbounds ( sysM, &lat1, &lon1, &lat2, &lon2 )) == 0 )
	    latdiff = -9999;
	else
	    latdiff = (float) fabs (lat2 - lat1);


 	count = 0;

/*
 *	Loop over all the map objects. See if any are turned on. If so,
 *	check the scale range and add them if they are in the right scale.
 */
	for ( i = 0; i < mbg->nmaps; i++ ) {

	    if ( XmToggleButtonGetState ( GetMapListOnToggleW(mbg,i)) ) {
	    
	    	maxscale = XmTextGetString( GetMapListMaxScaleW(mbg,i));
	    	minscale = XmTextGetString( GetMapListMinScaleW(mbg,i));

		fmaxscale = atof ( maxscale);
		fminscale = atof ( minscale);
	        XtFree (  maxscale);
	        XtFree (  minscale);
		
		if ( ( fmaxscale <= 0.0 ) ||
		     ( latdiff >= fminscale && latdiff <= fmaxscale) ) {
		
		    strcpy ( mapfile, mbg->path[i] );
		    strcpy ( mapname, mbg->name[i].string );
		    sprintf ( line_color, "%d", GetMapListLineColor(mbg,i));
		    sprintf ( line_type,  "%d", GetMapListLineType(mbg,i));
		    sprintf ( line_width, "%d", GetMapListLineWidth(mbg,i));
				
		    mlist[count] = (MetObjectType *) MakeMapObject( 
						mapname,
						mapfile,
						line_color,
						line_type,
						line_width);
		    count++;
		}

	    }

	}

/*
 *	Add a lat/lon grid 
 */
	if ( XmToggleButtonGetState ( GetLatLonGridStateW (llg) )) {

	    latinc = XmTextGetString ( GetLatIncrementW (llg) );
	    loninc = XmTextGetString ( GetLonIncrementW (llg) );
	    lblinc = XmTextGetString ( GetLatLonGridLabelIncW(llg) );
	    
	    sprintf ( line_color, "%d", GetLatLonGridColor (llg));
	    sprintf ( line_type, "%d", GetLatLonGridType (llg));
	    sprintf ( line_width,  "%d", GetLatLonGridWidth (llg));

	    mlist[count] = (MetObjectType *) MakeLatLonGridObject( 
						latinc,
						loninc,
						lblinc,
						line_color,
						line_type,
						line_width);
	    XtFree ( latinc );
	    XtFree ( loninc );
	    XtFree ( lblinc );

	    count++;
	}


/*
 *	Add all the created objects in as background objects
 */
	AddMapBackgroundObjects ( po, count, mlist );

/*
 *	Since we have new maps, set all the drawn flags of all the metObjects
 *	in this pixmapObject false so that they will be redrawn.
 */
	SetPixmapObjectDrawnFlag ( po, False );
 
/*
 *	Reset the change state of the map and lat/lon dialogs for the last
 *	pixmap
 */
	if ( potIndex == wo->numPixmapObjects - 1 ) {
 	    SetLatLonGridChangeState ( llg, False);
  	    SetMapListChangeState ( mbg, False);
	}

}
Exemplo n.º 15
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;
}
Exemplo n.º 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;
}
Exemplo n.º 17
0
Arquivo: gif.c Projeto: McNeight/GLsat
int 
write_gif(const char *filename, int width, int height, char *rgb)
{
    int i;
    int colormap_size = 256;
    GifByteType *red, *green, *blue, *buffer, *ptr;
    GifFileType *outfile;
    ColorMapObject *colormap;

    red = malloc(width * height * sizeof(GifByteType));
    green = malloc(width * height * sizeof(GifByteType));
    blue = malloc(width * height * sizeof(GifByteType));
    buffer = malloc(width * height * sizeof(GifByteType));

    if (red == NULL || green == NULL || blue == NULL || buffer == NULL)
    {
        fprintf(stderr, "Can't allocate memory for GIF file.\n");
        return(0);
    }

    colormap = MakeMapObject(colormap_size, NULL);

    for (i = 0; i < width * height; i++)
    {
        red[i]   = (GifByteType) rgb[3*i  ];
        green[i] = (GifByteType) rgb[3*i+1];
        blue[i]  = (GifByteType) rgb[3*i+2];
    }
  
    if (QuantizeBuffer(width, height, &colormap_size, red, green, blue,   
                       buffer, colormap->Colors) == GIF_ERROR)
    {
        PrintGifError();
        return(0);
    }

    free(red);
    free(green);
    free(blue);

    outfile = EGifOpenFileName((char *) filename, FALSE);
    if (outfile == NULL)
    {
        PrintGifError();
        return(0);
    }

    if (EGifPutScreenDesc(outfile, width, height, colormap_size, 0, colormap)
        == GIF_ERROR)
    {
        PrintGifError();
        return(0);
    }

    if (EGifPutImageDesc(outfile, 0, 0, width, height, FALSE, NULL)
        == GIF_ERROR)
    {
        PrintGifError();
        return(0);
    }

    ptr = buffer;
    for (i = 0; i < height; i++)
    {
        if (EGifPutLine(outfile, ptr, width) == GIF_ERROR)
        {
            PrintGifError();
            return(0);
        }
        ptr += width;
    }

    EGifSpew(outfile);

    if (EGifCloseFile(outfile) == GIF_ERROR) 
        PrintGifError();

    free(buffer);

    return(1);
}
Exemplo n.º 18
0
int main(int argc, char **argv)
{
 int i,j,k,l,c,h;
 char fname[16]="test.gif";
 unsigned char img[64];

 GifColorType ScratchMap2[2];
 GifColorType ScratchMap4[4];
 GifColorType ScratchMap[16];
#define SETCOL(x,y) {\
   ScratchMap[x].Red   = (y>>16)&0xFF;\
   ScratchMap[x].Green = (y>>8)&0xFF;\
   ScratchMap[x].Blue  = y&0xFF;\
   }

 SETCOL( 0,0x000000);
 SETCOL( 1,0x0000AA);
 SETCOL( 2,0x00AA00);
 SETCOL( 3,0x00AAAA);
 SETCOL( 4,0xAA0000);
 SETCOL( 5,0xAA00AA);
 SETCOL( 6,0xAA5500);
 SETCOL( 7,0xAAAAAA);
 SETCOL( 8,0x555555);
 SETCOL( 9,0x5555FF);
 SETCOL(10,0x55FF55);
 SETCOL(11,0x55FFFF);
 SETCOL(12,0xFF5555);
 SETCOL(13,0xFF55FF);
 SETCOL(14,0xFFFF55);
 SETCOL(15,0xFFFFFF);

 for(h=0;h<5;h++)
 {
  ScratchMap2[0] = ScratchMap[0];
  switch(h)
  {
    case 0: ScratchMap2[1] = ScratchMap[2]; break;
    case 1: ScratchMap2[1] = ScratchMap[7]; break;
    case 2: ScratchMap2[1] = ScratchMap[12]; break;
    case 3: ScratchMap2[1] = ScratchMap[11]; break;
    case 4: ScratchMap2[1] = ScratchMap[0];
            ScratchMap2[0] = ScratchMap[2]; break;
  }

  colormap = MakeMapObject(2,ScratchMap2);
  if(colormap==NULL) return -1;

  for(k=0;k<FONT8X8_CHARS;k++)
  {
   sprintf(fname,"0%i%2.2x.gif",h,k+FONT8X8_FIRST);
   l = 0;
   for(j=0;j<8;j++)
   {
     c = font8x8[k][j];
     for(i=0;i<8;i++)
     {
        if(c&0x80)
             img[l] = 1;
        else img[l] = 0;
        l++;c<<=1;
     }
   }
   SaveGif(fname,img,colormap,2,8,8);
  }
 }

#if 1 /* special PCB characters */

for(h=0;h<5;h++)
{
 if(h==0)
 {
   ScratchMap4[0] = ScratchMap[0];
   ScratchMap4[1] = ScratchMap[1];
   ScratchMap4[2] = ScratchMap[2];
   ScratchMap4[3] = ScratchMap[4];

   colormap = MakeMapObject(4,ScratchMap4);
   if(colormap==NULL) return -2;
 }
 if(h==1)
 {
   ScratchMap4[0] = ScratchMap[0];
   ScratchMap4[1] = ScratchMap[7];
   ScratchMap4[2] = ScratchMap[12];
   ScratchMap4[3] = ScratchMap[11];

   colormap = MakeMapObject(4,ScratchMap4);
   if(colormap==NULL) return -3;
 }
 if(h==4)
 {
   ScratchMap4[0] = ScratchMap[2];
   ScratchMap4[1] = ScratchMap[0];
   ScratchMap4[2] = ScratchMap[0];
   ScratchMap4[3] = ScratchMap[0];

   colormap = MakeMapObject(4,ScratchMap4);
   if(colormap==NULL) return -3;
 }

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[63]=2;
 }
 else
 {
  img[63]=h;
 }
 sprintf(fname,"0%i00.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  for(i=0;i<64;i++) img[i]=1;
  img[18]=2;img[19]=2;img[20]=2;img[21]=2;
  img[26]=2;img[27]=0;img[28]=0;img[29]=2;
  img[34]=2;img[35]=0;img[36]=0;img[37]=2;
  img[42]=2;img[43]=2;img[44]=2;img[45]=2;
  img[24]=3;img[25]=3;
  img[32]=3;img[33]=3;
 }
 else
 {
  for(i=0;i<64;i++) img[i]=h;
  img[18]=h;img[19]=h;img[20]=h;img[21]=h;
  img[26]=h;img[27]=0;img[28]=0;img[29]=h;
  img[34]=h;img[35]=0;img[36]=0;img[37]=h;
  img[42]=h;img[43]=h;img[44]=h;img[45]=h;
  img[24]=h;img[25]=h;
  img[32]=h;img[33]=h;
 }
 sprintf(fname,"0%i01.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  img[30]=3;img[31]=3;
  img[38]=3;img[39]=3;
 }
 else
 {
  img[30]=h;img[31]=h;
  img[38]=h;img[39]=h;
 }
 sprintf(fname,"0%i03.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  img[24]=1;img[25]=1;
  img[32]=1;img[33]=1;
 }
 else
 {
  img[24]=h;img[25]=h;
  img[32]=h;img[33]=h;
 }
 sprintf(fname,"0%i02.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  for(i=0;i<64;i++) img[i]=1;
  for(i=0;i<8;i++){img[24+i]=3;img[32+i]=3;}
 }
 else
 {
  for(i=0;i<64;i++) img[i]=h;
 }
 sprintf(fname,"0%i04.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[18]=2;img[19]=2;img[20]=2;img[21]=2;
  img[26]=2;img[27]=0;img[28]=0;img[29]=2;
  img[34]=2;img[35]=0;img[36]=0;img[37]=2;
  img[42]=2;img[43]=2;img[44]=2;img[45]=2;
  img[ 3]=1;img[ 4]=1;
  img[11]=1;img[12]=1;
  img[24]=3;img[25]=3;
  img[32]=3;img[33]=3;
 }
 else
 {
  img[18]=h;img[19]=h;img[20]=h;img[21]=h;
  img[26]=h;img[27]=0;img[28]=0;img[29]=h;
  img[34]=h;img[35]=0;img[36]=0;img[37]=h;
  img[42]=h;img[43]=h;img[44]=h;img[45]=h;
  img[ 3]=h;img[ 4]=h;
  img[11]=h;img[12]=h;
  img[24]=h;img[25]=h;
  img[32]=h;img[33]=h;
 }
 sprintf(fname,"0%i05.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  img[30]=3;img[31]=3;
  img[38]=3;img[39]=3;
 }
 else
 {
  img[30]=h;img[31]=h;
  img[38]=h;img[39]=h;
 }
 sprintf(fname,"0%i07.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 img[24]=0;img[25]=0;
 img[32]=0;img[33]=0;
 sprintf(fname,"0%i06.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[24]=1;img[32]=1;img[40]=1;
  img[33]=1;img[41]=1;img[49]=1;
  img[42]=1;img[50]=1;img[58]=1;
  img[51]=1;img[59]=1;
  img[60]=1;
 }
 else
 {
  img[24]=h;img[32]=h;img[40]=h;
  img[33]=h;img[41]=h;img[49]=h;
  img[42]=h;img[50]=h;img[58]=h;
  img[51]=h;img[59]=h;
  img[60]=h;
 }
 sprintf(fname,"0%i08.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[18]=2;img[19]=2;img[20]=2;img[21]=2;
  img[26]=2;img[27]=0;img[28]=0;img[29]=2;
  img[34]=2;img[35]=0;img[36]=0;img[37]=2;
  img[42]=2;img[43]=2;img[44]=2;img[45]=2;
  img[51]=1;img[52]=1;
  img[59]=1;img[60]=1;
  img[24]=3;img[25]=3;
  img[32]=3;img[33]=3;
 }
 else
 {
  img[18]=h;img[19]=h;img[20]=h;img[21]=h;
  img[26]=h;img[27]=0;img[28]=0;img[29]=h;
  img[34]=h;img[35]=0;img[36]=0;img[37]=h;
  img[42]=h;img[43]=h;img[44]=h;img[45]=h;
  img[51]=h;img[52]=h;
  img[59]=h;img[60]=h;
  img[24]=h;img[25]=h;
  img[32]=h;img[33]=h;
 }
 sprintf(fname,"0%i09.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  img[30]=3;img[31]=3;
  img[38]=3;img[39]=3;
 }
 else
 {
  img[30]=h;img[31]=h;
  img[38]=h;img[39]=h;
 }
 sprintf(fname,"0%i0b.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 img[24]=0;img[25]=0;
 img[32]=0;img[33]=0;
 sprintf(fname,"0%i0a.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[3]=1;img[4]=1;img[5]=1;
  img[12]=1;img[13]=1;img[14]=1;
  img[21]=1;img[22]=1;img[23]=1;
  img[30]=1;img[31]=1;
  img[39]=1;
 }
 else
 {
  img[3]=h;img[4]=h;img[5]=h;
  img[12]=h;img[13]=h;img[14]=h;
  img[21]=h;img[22]=h;img[23]=h;
  img[30]=h;img[31]=h;
  img[39]=h;
 }
 sprintf(fname,"0%i0c.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[18]=2;img[19]=2;img[20]=2;img[21]=2;
  img[26]=2;img[27]=0;img[28]=0;img[29]=2;
  img[34]=2;img[35]=0;img[36]=0;img[37]=2;
  img[42]=2;img[43]=2;img[44]=2;img[45]=2;
  img[ 3]=1;img[ 4]=1;
  img[11]=1;img[12]=1;
  img[24]=3;img[25]=3;
  img[32]=3;img[33]=3;
  img[51]=1;img[52]=1;
  img[59]=1;img[60]=1;
 }
 else
 {
  img[18]=h;img[19]=h;img[20]=h;img[21]=h;
  img[26]=h;img[27]=0;img[28]=0;img[29]=h;
  img[34]=h;img[35]=0;img[36]=0;img[37]=h;
  img[42]=h;img[43]=h;img[44]=h;img[45]=h;
  img[ 3]=h;img[ 4]=h;
  img[11]=h;img[12]=h;
  img[24]=h;img[25]=h;
  img[32]=h;img[33]=h;
  img[51]=h;img[52]=h;
  img[59]=h;img[60]=h;
 }
 sprintf(fname,"0%i0d.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  img[30]=3;img[31]=3;
  img[38]=3;img[39]=3;
 }
 else
 {
  img[30]=h;img[31]=h;
  img[38]=h;img[39]=h;
 }
 sprintf(fname,"0%i0f.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 img[24]=0;img[25]=0;
 img[32]=0;img[33]=0;
 sprintf(fname,"0%i0e.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  for(i=0;i<64;i++) img[i]=1;
 }
 else
 {
  for(i=0;i<64;i++) img[i]=h;
 }
 sprintf(fname,"0%i10.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  for(i=0;i<8;i++){img[24+i]=3;img[32+i]=3;}
 }
 else
 {
  for(i=0;i<8;i++){img[24+i]=h;img[32+i]=h;}
 }
 sprintf(fname,"0%i11.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  for(i=0;i<8;i++){img[3+i*8]=1;img[4+i*8]=1;}
 }
 else
 {
  for(i=0;i<8;i++){img[3+i*8]=h;img[4+i*8]=h;}
 }
 sprintf(fname,"0%i12.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  for(i=0;i<8;i++) img[24+i]=3;
  for(i=0;i<8;i++) img[32+i]=3;
  img[18]=0;img[19]=1;img[20]=1;img[21]=0;
  img[42]=0;img[43]=1;img[44]=1;img[45]=0;
 }
 else
 {
  for(i=0;i<8;i++) img[24+i]=h;
  for(i=0;i<8;i++) img[32+i]=h;
  img[18]=0;img[19]=h;img[20]=h;img[21]=0;
  img[42]=0;img[43]=h;img[44]=h;img[45]=0;
 }
 sprintf(fname,"0%i13.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  for(i=0;i<8;i++){img[6+i*8]=2;img[7+i*8]=2;}
  for(i=1;i<7;i++){img[4+i*8]=2;img[5+i*8]=2;}
  for(i=2;i<6;i++) img[3+i*8]=2;
 }
 else
 {
  for(i=0;i<8;i++){img[6+i*8]=h;img[7+i*8]=h;}
  for(i=1;i<7;i++){img[4+i*8]=h;img[5+i*8]=h;}
  for(i=2;i<6;i++) img[3+i*8]=h;
 }
 sprintf(fname,"0%i14.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  img[24]=3;img[25]=3;img[26]=3;
  img[32]=3;img[33]=3;img[34]=3;
 }
 else
 {
  img[24]=h;img[25]=h;img[26]=h;
  img[32]=h;img[33]=h;img[34]=h;
 }
 sprintf(fname,"0%i15.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  for(i=0;i<8;i++){img[i*8]=2;img[1+i*8]=2;}
  for(i=1;i<7;i++){img[2+i*8]=2;img[3+i*8]=2;}
  for(i=2;i<6;i++) img[4+i*8]=2;
 }
 else
 {
  for(i=0;i<8;i++){img[i*8]=h;img[1+i*8]=h;}
  for(i=1;i<7;i++){img[2+i*8]=h;img[3+i*8]=h;}
  for(i=2;i<6;i++) img[4+i*8]=h;
 }
 sprintf(fname,"0%i16.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  img[29]=3;img[30]=3;img[31]=3;
  img[37]=3;img[38]=3;img[39]=3;
 }
 else
 {
  img[29]=h;img[30]=h;img[31]=h;
  img[37]=h;img[38]=h;img[39]=h;
 }
 sprintf(fname,"0%i17.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  for(i=0;i<64;i++) img[i]=2;
 }
 else
 {
  for(i=0;i<64;i++) img[i]=h;
 }
 img[19]=0;img[20]=0;
 img[26]=0;img[27]=0;img[28]=0;img[29]=0;
 img[34]=0;img[35]=0;img[36]=0;img[37]=0;
 img[43]=0;img[44]=0;
 sprintf(fname,"0%i18.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 img[0]=0;img[1]=0;img[8]=0;
 img[6]=0;img[7]=0;img[15]=0;
 img[56]=0;img[57]=0;img[48]=0;
 img[62]=0;img[63]=0;img[55]=0;
 sprintf(fname,"0%i19.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  for(i=0;i<64;i++)
  {
   if(i>=16 && i<48) img[i]=3;
   else img[i]=0;
  }
 }
 else
 {
  for(i=0;i<64;i++)
  {
   if(i>=16 && i<48) img[i]=h;
   else img[i]=0;
  }
 }
 sprintf(fname,"0%i1a.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 if(h==0||h==4)
 {
  for(i=0;i<64;i++) img[i]=3;
 }
 else
 {
  for(i=0;i<64;i++) img[i]=h;
 }
 sprintf(fname,"0%i1b.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[16]=3;img[24]=3;img[32]=3;
  img[9]=3;img[17]=3;img[25]=3;
  img[2]=3;img[10]=3;img[18]=3;
  img[3]=3;img[11]=3;
  img[4]=3;
 }
 else
 {
  img[16]=h;img[24]=h;img[32]=h;
  img[9]=h;img[17]=h;img[25]=h;
  img[2]=h;img[10]=h;img[18]=h;
  img[3]=h;img[11]=h;
  img[4]=h;
 }
 sprintf(fname,"0%i1c.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[31]=3;img[39]=3;img[47]=3;
  img[38]=3;img[46]=3;img[54]=3;
  img[45]=3;img[53]=3;img[61]=3;
  img[52]=3;img[60]=3;
  img[59]=3;
 }
 else
 {
  img[31]=h;img[39]=h;img[47]=h;
  img[38]=h;img[46]=h;img[54]=h;
  img[45]=h;img[53]=h;img[61]=h;
  img[52]=h;img[60]=h;
  img[59]=h;
 }
 sprintf(fname,"0%i1d.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[4]=2;
  img[12]=2;
  img[19]=2;img[20]=2;img[21]=2;
  img[27]=2;img[28]=2;img[29]=2;
  img[34]=2;img[35]=2;img[36]=2;img[37]=2;img[38]=2;
  img[42]=2;img[43]=2;img[44]=2;img[45]=2;img[46]=2;
  img[49]=2;img[50]=2;img[52]=2;img[54]=2;img[55]=2;
  img[57]=2;img[60]=2;img[63]=2;
 }
 else
 {
  img[4]=h;
  img[12]=h;
  img[19]=h;img[20]=h;img[21]=h;
  img[27]=h;img[28]=h;img[29]=h;
  img[34]=h;img[35]=h;img[36]=h;img[37]=h;img[38]=h;
  img[42]=h;img[43]=h;img[44]=h;img[45]=h;img[46]=h;
  img[49]=h;img[50]=h;img[52]=h;img[54]=h;img[55]=h;
  img[57]=h;img[60]=h;img[63]=h;
 }
 sprintf(fname,"0%i1e.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

 for(i=0;i<64;i++) img[i]=0;
 if(h==0||h==4)
 {
  img[60]=2;
  img[52]=2;
  img[43]=2;img[44]=2;img[45]=2;
  img[35]=2;img[36]=2;img[37]=2;
  img[26]=2;img[27]=2;img[28]=2;img[29]=2;img[30]=2;
  img[18]=2;img[19]=2;img[20]=2;img[21]=2;img[22]=2;
  img[9]=2;img[10]=2;img[12]=2;img[14]=2;img[15]=2;
  img[1]=2;img[4]=2;img[7]=2;
 }
 else
 {
  img[60]=h;
  img[52]=h;
  img[43]=h;img[44]=h;img[45]=h;
  img[35]=h;img[36]=h;img[37]=h;
  img[26]=h;img[27]=h;img[28]=h;img[29]=h;img[30]=h;
  img[18]=h;img[19]=h;img[20]=h;img[21]=h;img[22]=h;
  img[9]=h;img[10]=h;img[12]=h;img[14]=h;img[15]=h;
  img[1]=h;img[4]=h;img[7]=h;
 }
 sprintf(fname,"0%i1f.gif",h);
 SaveGif(fname,img,colormap,4,8,8);

}

#endif

return 0;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
0
unsigned char *
gifconv_lossless2gif(void *image_data,
                     unsigned short width, unsigned short height,
                     void *index_data,
                     unsigned short index_data_count,
                     int tag_no, int format,
                     unsigned long *length) {
    GifFileType *GifFile = NULL;
    GifColorType *Colors = NULL;
    int ColorCount;
    my_gif_buffer gif_buff;
    gif_uint_32 gif_width = 0, gif_height = 0;
    int bpp;
    gif_bytep gif_image_data = NULL;
    gif_uint_32 x, y;
    gif_colorp gif_palette = NULL;
//    int trans_index = -1;
    int i;
    if (format != 3) {
        fprintf(stderr, "jpegconv_lossless2gif: format=%d not implemented yes.\n", format);
        return NULL;
    }
    bpp = 8;
    gif_width = width;
    gif_height = height;
    ColorCount = 256;
    Colors = calloc(sizeof(GifColorType), ColorCount);

    gif_buff.data = NULL;
    gif_buff.data_len = 0;
    gif_buff.data_offset = 0;
#if GIFLIB_MAJOR >= 5
    GifFile = EGifOpen(& gif_buff, gif_data_write_func, NULL);
#else
    GifFile = EGifOpen(& gif_buff, gif_data_write_func);
#endif
    if (GifFile == NULL) {
        fprintf(stderr, "gifconv_lossless2gif: can't open GIFFile\n");
        return NULL;
    }
    GifFile->SWidth  = gif_width;
    GifFile->SHeight = gif_height;
    GifFile->SColorResolution = bpp;

    gif_palette = (gif_colorp) malloc(sizeof(gif_color)*index_data_count);

    if (tag_no == 20) {
        swf_rgb_t *rgb_list  = index_data;
        for (i=0 ; i < index_data_count ; i++) {
            Colors[i].Red   = rgb_list[i].red;
            Colors[i].Green = rgb_list[i].green;
            Colors[i].Blue  = rgb_list[i].blue;
        }
    } else {
        swf_rgba_t *rgba_list  = index_data;
        for (i=0 ; i < index_data_count ; i++) {
//            if (rgba_list[i].alpha)
            Colors[i].Red   = rgba_list[i].red;
            Colors[i].Green = rgba_list[i].green;
            Colors[i].Blue  = rgba_list[i].blue;
//                gif_palette[i].alpha = ;
        }
    }
    GifFile->SBackGroundColor = 0; // XXX
    gif_image_data = (gif_bytep) calloc(sizeof(unsigned char), gif_width * gif_height);
    i = 0;
    for (y=0 ; y < gif_height ; y++) {
        for (x=0 ; x < gif_width ; x++) {
            unsigned char *data = image_data;
            gif_image_data[i] = data[x + y*((gif_width +3) & -4)];
            i++;
        }
    }

    GifFile->SavedImages[0].RasterBits = gif_image_data;
#if GIFLIB_MAJOR >= 5
    GifFile->SColorMap = GifMakeMapObject(ColorCount, Colors);
#else
    GifFile->SColorMap = MakeMapObject(ColorCount, Colors);
#endif
    EGifSpew(GifFile); // XXX

    free(gif_image_data);

    if (GifFile) {
#if GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1 || GIFLIB_MAJOR > 5
        EGifCloseFile(GifFile, NULL);
#else
        EGifCloseFile(GifFile);
#endif
    }
    *length = gif_buff.data_offset;
    return gif_buff.data;
}
Exemplo n.º 21
0
/******************************************************************************
* Modify the given colormap according to global variables setting.	      *
******************************************************************************/
static ColorMapObject *ModifyColorMap(ColorMapObject *ColorMap)
{
    int i, Dummy, Red, Green, Blue, Max = 0;
    double Gamma1;

    if (SaveFlag) {
	/* Save this color map to ColorFile: */
	for (i = 0; i < ColorMap->ColorCount; i++)
	    fprintf(ColorFile, "%3d %3d %3d %3d\n", i,
		    ColorMap->Colors[i].Red,
		    ColorMap->Colors[i].Green,
		    ColorMap->Colors[i].Blue);
	return(ColorMap);
    }
    else if (LoadFlag) {
	/* Read the color map in ColorFile into this color map: */
	for (i = 0; i < ColorMap->ColorCount; i++) {
	    if (feof(ColorFile))
		GIF_EXIT("Color file to load color map from, too small.");
	    fscanf(ColorFile, "%3d %3d %3d %3d\n", &Dummy, &Red, &Green, &Blue);
	    ColorMap->Colors[i].Red = Red;
	    ColorMap->Colors[i].Green = Green;
	    ColorMap->Colors[i].Blue = Blue;
	}
	return(ColorMap);
    }
    else if (GammaFlag) {
	/* Apply gamma correction to this color map: */
	Gamma1 = 1.0 / Gamma;
	for (i = 0; i < ColorMap->ColorCount; i++) {
	    ColorMap->Colors[i].Red =
		((int) (255 * pow(ColorMap->Colors[i].Red / 255.0, Gamma1)));
	    ColorMap->Colors[i].Green =
		((int) (255 * pow(ColorMap->Colors[i].Green / 255.0, Gamma1)));
	    ColorMap->Colors[i].Blue =
		((int) (255 * pow(ColorMap->Colors[i].Blue / 255.0, Gamma1)));
	}
	return(ColorMap);
    }
    else if (TranslateFlag) {
	ColorMapObject *NewMap;

	/* Read the translation table in TranslateFile: */
	for (i = 0; i < ColorMap->ColorCount; i++) {
	    int tmp;
	    if (feof(TranslateFile))
		GIF_EXIT("Color file to load color map from, too small.");
	    fscanf(TranslateFile, "%3d %3d\n", &Dummy, &tmp);
	    Translation[i] = tmp;
	    if (Translation[i] > Max)
		Max = Translation[i];
	}

	if ((NewMap = MakeMapObject(1 << BitSize(Max+1), NULL)) == NULL)
	    GIF_EXIT("Out of memory while allocating color map!");

	/* Apply the translation; we'll do it to the pixels, too */
	for (i = 0; i < ColorMap->ColorCount; i++) {
	    NewMap->Colors[i] = ColorMap->Colors[Translation[i]];
	}
	
	return(NewMap);
    }
    else
    {
	GIF_EXIT("Nothing to do!");
	return(ColorMap);
    }
}
Exemplo n.º 22
0
/*
 * 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);
}
Exemplo n.º 23
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);
}
Exemplo n.º 24
0
int main(int argc, char **argv) {
   FILE *input_file;
   float arg,size,rx,ry,rz;
   float f,fmin=1e10,fmax=-1e10;
   uint16_t i;
   uint64_t count;
   int xi,yi,zi,xo,yo,zo,nx,ny,nz,dx,dy,dz,x0,y0,z0,h;
   int **image;
   char format,type,comment[256];
   GifFileType *GIFfile;
   ColorMapObject *GIFcmap;
   GifPixelType *GIFline;
   //
   // command line args
   //
   if (!((argc == 6) || (argc == 7)  || (argc == 8) || (argc == 9) || (argc == 10) || (argc == 13) || (argc == 16) || (argc == 19))) {
      printf("command line: vol_gif in.vol out.gif nx ny nz [format [type [arg [size [dx dy dz [x0 y0 z0 [rx ry rz]]]]]]]\n");
      printf("   in.vol = input volume file\n");
      printf("   out.gif = output GIF file\n");
      printf("   nx,ny,nz = x,y,z input voxel number\n");
      printf("   format = 'f' for float 32, 'i' for uint16_t (default 'f')\n");
      printf("   type = 's' for section, 'h' for height (default 's')\n");
      printf("   arg = gamma for 's', threshold for 'h' (default 1)\n");
      printf("   size = mm per voxel (default 1)\n");
      printf("   dx,dy,dz = x,y,z output voxel number (default all)\n");
      printf("   x0,y0,z0 = x,y,z output voxel origin (default 0)\n");
      printf("   to be implemented: rx,ry,rz = view rotation angles (degrees; default 0)\n");
      exit(-1);
      }
   format = 'f';
   type = 's';
   arg = 1;
   size = 1.0;
   rx = ry = rz = 0;
   sscanf(argv[3],"%d",&nx);
   sscanf(argv[4],"%d",&ny);
   sscanf(argv[5],"%d",&nz);
   dx = nx; dy = ny; dz = nz;
   x0 = y0 = z0 = 0;
   if (argc >= 7) {
      sscanf(argv[6],"%c",&format);
      if (!((format == 'f') || (format == 'i'))) {
         printf("vol_gif: oops -- format must be 'f' or 'i'\n");
         exit(-1);
         }
      }
   if (argc >= 8) {
      sscanf(argv[7],"%c",&type);
      if (!((type == 's') || (type == 'h'))) {
         printf("vol_gif: oops -- type must be 's' or 'h'\n");
         exit(-1);
         }
      }
   if (argc >= 9) {
      sscanf(argv[8],"%f",&arg);
      }
   if (argc >= 10) {
      sscanf(argv[9],"%f",&size);
      }
   if (argc >= 13) {
      sscanf(argv[10],"%d",&x0);
      sscanf(argv[11],"%d",&y0);
      sscanf(argv[12],"%d",&z0);
      }
   if (argc >= 16) {
      sscanf(argv[13],"%d",&dx);
      sscanf(argv[14],"%d",&dy);
      sscanf(argv[15],"%d",&dz);
      }
   if (argc >= 19) {
      sscanf(argv[16],"%f",&rx);
      sscanf(argv[17],"%f",&ry);
      sscanf(argv[18],"%f",&rz);
      }
   //
   // check and find limits
   //
   input_file = fopen(argv[1],"rb");
   if (input_file == NULL) {
      printf("vol_gif: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   if (((x0 + dx) > nx) || ((y0 + dy) > ny) || ((z0 + dz) > nz)) {
      printf("vol_gif: oops -- region too large\n");
      exit(-1);
      }
   printf("read %s\n",argv[1]);
   if (format == 'f') {
      count = 0;
      while (fread(&f,sizeof(f),1,input_file) != 0) {
         if (f > fmax) fmax = f;
         if (f < fmin) fmin = f;
         count += 1;
         }
      }
   else if (format == 'i') {
      count = 0;
      while (fread(&i,sizeof(i),1,input_file) != 0) {
         if (i > fmax) fmax = i;
         if (i < fmin) fmin = i;
         count += 1;
         }
      }
   printf("   %" PRIu64 " points, min %f, max %f\n",count,fmin,fmax);
   printf("   nx ny nz: %d %d %d\n",nx,ny,nz);
   rewind(input_file);
   //
   // set up color map
   //
#if GIFLIB_MAJOR >= 5
   GIFcmap = GifMakeMapObject(256, NULL);
#else
   GIFcmap = MakeMapObject(256, NULL);
#endif
   for (i = 0; i < 256; i++) {
      GIFcmap->Colors[i].Red = i;
      GIFcmap->Colors[i].Green = i;
      GIFcmap->Colors[i].Blue = i;
      }
   //
   // open GIF file
   //
   printf("write %s\n",argv[2]);

   EGifPutScreenDesc(GIFfile,dx,dy,8,0,GIFcmap);
   unsigned char loop_count[] = {1,0,0};
#if GIFLIB_MAJOR >= 5
   GIFfile = EGifOpenFileName(argv[2], 0, NULL);
   EGifPutExtension(GIFfile, APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0");
   EGifPutExtension(GIFfile, APPLICATION_EXT_FUNC_CODE, 3, loop_count);
#else
   GIFfile = EGifOpenFileName(argv[2], 0);
   EGifPutExtensionFirst(GIFfile, APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0");
   EGifPutExtensionLast(GIFfile, APPLICATION_EXT_FUNC_CODE, 3, loop_count);
#endif


   unsigned char delay_count[5] = { 
      0, // no transparency
      0, // delay time
      0, // delay time
      0 // transparent index not used
      };
   //
   // allocate image
   //
   image = malloc(dy*sizeof(int *));
   for (yo = 0; yo < dy; ++yo) {
      image[yo] = malloc(dx*sizeof(int));
      for (xo = 0; xo < dx; ++xo)
         image[yo][xo] = 0;
      }
   GIFline = malloc(dx*sizeof(GifPixelType));
   //
   // scan file
   //
   xi = yi = zi = 0;
   for (zo = 0; zo < dz; ++zo) {
      printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b   layer = %d",zo);
      EGifPutExtension(GIFfile,GRAPHICS_EXT_FUNC_CODE,4,delay_count);
      EGifPutImageDesc(GIFfile,0,0,dx,dy,0,NULL);
      //
      // read layer
      //
      for (yo = 0; yo < dy; ++yo) {
         for (xo = 0; xo < dx; ++xo) {
            if (format == 'f') {
               read_voxel_f(input_file,&f,xo+x0,yo+y0,zo+z0,&xi,&yi,&zi,nx,ny,nz);
               if (type == 'h') {
                  h = 255*zo/(nz-1.0);
                  if ((h > image[yo][xo]) && (f > arg))
                     image[yo][xo] = h;
                  GIFline[xo] = image[yo][xo]*(nz-1.0)/zo;
                  }
               else if (type == 's') {
                  GIFline[xo] = 255*pow((f-fmin)/(fmax-fmin),arg);
                  }
               }
            else if (format == 'i') {
               read_voxel_i(input_file,&i,xo+x0,yo+y0,zo+z0,&xi,&yi,&zi,nx,ny,nz);
               if (type == 'h') {
                  h = 255*zo/(nz-1.0);
                  if ((h > image[yo][xo]) && (i > arg))
                     image[yo][xo] = h;
                  GIFline[xo] = image[yo][xo]*(nz-1.0)/zo;
                  }
               else if (type == 's') {
                  GIFline[xo] = 255*pow((i-fmin)/(fmax-fmin),arg);
                  }
               }
            }
         EGifPutLine(GIFfile,GIFline,dx);
         }
      }
   printf("\n");
   //
   // put mm per pixel in comment
   //
   sprintf(comment,"mm per pixel: %f;",size);
   EGifPutComment(GIFfile,comment);
   //
   // exit
   //
   fclose(input_file);
   EGifCloseFile(GIFfile);
   exit(0);
   }
Exemplo n.º 25
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;
}
Exemplo n.º 26
0
/*
 * Append an image block to the SavedImages array
 */
SavedImage *
MakeSavedImage(GifFileType * GifFile,
               const SavedImage * CopyFrom) {

    SavedImage *sp;

    if (GifFile->SavedImages == NULL)
        GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
    else
        GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
                               sizeof(SavedImage) * (GifFile->ImageCount + 1));

    if (GifFile->SavedImages == NULL)
        return ((SavedImage *)NULL);
    else {
        sp = &GifFile->SavedImages[GifFile->ImageCount++];
        memset((char *)sp, '\0', sizeof(SavedImage));

        if (CopyFrom) {
            memcpy((char *)sp, CopyFrom, sizeof(SavedImage));

            /*
             * Make our own allocated copies of the heap fields in the
             * copied record.  This guards against potential aliasing
             * problems.
             */

            /* first, the local color map */
            if (CopyFrom->ImageDesc.ColorMap) {
                sp->ImageDesc.ColorMap = MakeMapObject(
                                             CopyFrom->ImageDesc.ColorMap->ColorCount,
                                             CopyFrom->ImageDesc.ColorMap->Colors);
                if (sp->ImageDesc.ColorMap == NULL) {
                    FreeLastSavedImage(GifFile);
                    return (SavedImage *)(NULL);
                }
            }

            /* next, the raster */
            sp->RasterBits = (unsigned char *)malloc(sizeof(GifPixelType) *
                             CopyFrom->ImageDesc.Height *
                             CopyFrom->ImageDesc.Width);
            if (sp->RasterBits == NULL) {
                FreeLastSavedImage(GifFile);
                return (SavedImage *)(NULL);
            }
            memcpy(sp->RasterBits, CopyFrom->RasterBits,
                   sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
                   CopyFrom->ImageDesc.Width);

            /* finally, the extension blocks */
            if (CopyFrom->ExtensionBlocks) {
                sp->ExtensionBlocks = (ExtensionBlock *)malloc(
                                          sizeof(ExtensionBlock) *
                                          CopyFrom->ExtensionBlockCount);
                if (sp->ExtensionBlocks == NULL) {
                    FreeLastSavedImage(GifFile);
                    return (SavedImage *)(NULL);
                }
                memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
                       sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);

                /*
                 * For the moment, the actual blocks can take their
                 * chances with free().  We'll fix this later.
                 *** FIXME: [Better check this out... Toshio]
                 * 2004 May 27: Looks like this was an ESR note.
                 * It means the blocks are shallow copied from InFile to
                 * OutFile.  However, I don't see that in this code....
                 * Did ESR fix it but never remove this note (And other notes
                 * in gifspnge?)
                 */
            }
        }

        return (sp);
    }
}
Exemplo n.º 27
0
/******************************************************************************
 * 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;
}
Exemplo n.º 28
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;
}
Exemplo n.º 29
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, Size, Error, NumFiles, ExtCode, CodeSize, NumColors = 2, Color,
	Count, ImageNum = 0, TextFlag = FALSE, SizeFlag = FALSE,
	ImageNFlag = FALSE, BackGroundFlag = FALSE, HelpFlag = FALSE;
    long Scaler, Histogram[256];
    GifRecordType RecordType;
    GifByteType *Extension, *CodeBlock;
    char **FileName = NULL;
    GifRowType Line;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    /* Same image dimension vars for both Image & ImageN as only one allowed */
    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint,
		&TextFlag, &SizeFlag, &ImageWidth, &ImageHeight,
		&ImageNFlag, &ImageN, &BackGroundFlag,
		&HelpFlag, &NumFiles, &FileName)) != FALSE ||
		(NumFiles > 1 && !HelpFlag)) {
	if (Error)
	    GAPrintErrMsg(Error);
	else if (NumFiles > 1)
	    GIF_MESSAGE("Error in command line parsing - one GIF file please.");
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

    if (HelpFlag) {
	fprintf(stderr, VersionStr);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    if (NumFiles == 1) {
	if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }
    else {
	/* Use the stdin instead: */
	if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    for (i = 0; i < 256; i++) Histogram[i] = 0;		  /* Reset counters. */

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		if (GifFileIn->Image.ColorMap)
		    NumColors = GifFileIn->Image.ColorMap->ColorCount;
		else if (GifFileIn->SColorMap)
		    NumColors = GifFileIn->SColorMap->ColorCount;
		else
		    GIF_EXIT("Neither Screen nor Image color map exists.");

		if ((ImageHeight / NumColors) * NumColors != ImageHeight)
		    GIF_EXIT("Image height specified not dividable by #colors.");

		if (++ImageNum == ImageN) {
		    /* This is the image we should make histogram for:       */
		    Line = (GifRowType) malloc(GifFileIn->Image.Width *
							sizeof(GifPixelType));
		    GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
			PROGRAM_NAME, ImageNum,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height);

		    for (i = 0; i < GifFileIn->Image.Height; i++) {
			if (DGifGetLine(GifFileIn, Line, GifFileIn->Image.Width)
			    == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
			for (j = 0; j < GifFileIn->Image.Width; j++)
			    Histogram[Line[j]]++;
			GifQprintf("\b\b\b\b%-4d", i);
		    }

		    free((char *) Line);
		}
		else {
		    /* Skip the image: */
		    /* Now read image itself in decoded form as we dont      */
		    /* really care what is there, and this is much faster.   */
		    if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL)
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    /* We we requested to kill back ground count: */
    if (BackGroundFlag) Histogram[GifFileIn->SBackGroundColor] = 0;

    if (DGifCloseFile(GifFileIn) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);


    /* We may required to dump out the histogram as text file: */
    if (TextFlag) {
	for (i = 0; i < NumColors; i++)
	    printf("%12ld  %3d\n", Histogram[i], i);
    }
    else {
	/* Open stdout for the histogram output file: */
	if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);

	/* Dump out screen descriptor to fit histogram dimensions: */
	if (EGifPutScreenDesc(GifFileOut,
	    ImageWidth, ImageHeight, HISTO_BITS_PER_PIXEL, 0,
	    MakeMapObject(4, HistoColorMap)) == GIF_ERROR)
		QuitGifError(GifFileIn, GifFileOut);

	/* Dump out image descriptor to fit histogram dimensions: */
	if (EGifPutImageDesc(GifFileOut,
			     0, 0, ImageWidth, ImageHeight, FALSE, NULL) == GIF_ERROR)
		QuitGifError(GifFileIn, GifFileOut);

	/* Prepare scan line for histogram file, and find scaler to scale    */
	/* histogram to be between 0 and ImageWidth:			     */
	Line = (GifRowType) malloc(ImageWidth * sizeof(GifPixelType));
	for (Scaler = 0, i = 0; i < NumColors; i++) if (Histogram[i] > Scaler)
	    Scaler = Histogram[i];
	Scaler /= ImageWidth;
	if (Scaler == 0) Scaler = 1;  /* In case maximum is less than width. */

	/* Dump out the image itself: */
	for (Count = ImageHeight, i = 0, Color = 1; i < NumColors; i++) {
	    if ((Size = Histogram[i] / Scaler) > ImageWidth) Size = ImageWidth;
	    for (j = 0; j < Size; j++)
		Line[j] = Color;
	    for (j = Size; j < ImageWidth; j++)
		Line[j] = GifFileOut->SBackGroundColor;

	    /* Move to next color: */
	    if (++Color >= (1 << HISTO_BITS_PER_PIXEL)) Color = 1;

	    /* Dump this histogram entry as many times as required: */
	    for (j = 0; j < ImageHeight / NumColors; j++) {
		if (EGifPutLine(GifFileOut, Line, ImageWidth) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		GifQprintf("\b\b\b\b%-4d", Count--);
	    }
	}

	if (EGifCloseFile(GifFileOut) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    return 0;
}