Ejemplo n.º 1
0
/******************************************************************************
 Interpret the command line and scan the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
    int i, j, ExtCode, ErrorCode, CodeSize, NumFiles, Len, ImageNum = 1;
    bool Error,
	ColorMapFlag = false, EncodedFlag = false, LZCodesFlag = false,
	PixelFlag = false, HelpFlag = false, RawFlag = false; 
    char *GifFileName, **FileName = NULL;
    GifPixelType *Line;
    GifRecordType RecordType;
    GifByteType *CodeBlock, *Extension;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifNoisyPrint, &ColorMapFlag, &EncodedFlag,
		&LZCodesFlag, &PixelFlag, &RawFlag, &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) {
	(void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    if (NumFiles == 1) {
	GifFileName = *FileName;
	if ((GifFile = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) {
	    PrintGifError(ErrorCode);
	    exit(EXIT_FAILURE);
	}
    }
    else {
	/* Use stdin instead: */
	GifFileName = "Stdin";
	if ((GifFile = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
	    PrintGifError(ErrorCode);
	    exit(EXIT_FAILURE);
	}
    }

    /* Because we write binary data - make sure no text will be written. */
    if (RawFlag) {
	ColorMapFlag = EncodedFlag = LZCodesFlag = PixelFlag = false;
#ifdef _WIN32
	_setmode(1, O_BINARY);             /* Make sure it is in binary mode. */
#endif /* _WIN32 */
    }
    else {
	printf("\n%s:\n\n\tScreen Size - Width = %d, Height = %d.\n",
	       GifFileName, GifFile->SWidth, GifFile->SHeight);
	printf("\tColorResolution = %d, BitsPerPixel = %d, BackGround = %d, Aspect = %d.\n",
	       GifFile->SColorResolution,
	       GifFile->SColorMap ? GifFile->SColorMap->BitsPerPixel : 0,
	       GifFile->SBackGroundColor,
	       GifFile->AspectByte);
	if (GifFile->SColorMap)
	    printf("\tHas Global Color Map.\n\n");
	else
	    printf("\tNo Global Color Map.\n\n");
	if (ColorMapFlag && GifFile->SColorMap) {
	    printf("\tGlobal Color Map:\n");
	    Len = GifFile->SColorMap->ColorCount;
	    printf("\tSort Flag: %s\n", 
		   GifFile->SColorMap->SortFlag ? "on":"off");
	    for (i = 0; i < Len; i+=4) {
		for (j = 0; j < 4 && j < Len; j++) {
		    printf("%3d: %02xh %02xh %02xh   ", i + j,
			   GifFile->SColorMap->Colors[i + j].Red,
			   GifFile->SColorMap->Colors[i + j].Green,
			   GifFile->SColorMap->Colors[i + j].Blue);
		}
		printf("\n");
	    }
	}
    }

    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
	    PrintGifError(GifFile->Error);
	    exit(EXIT_FAILURE);
	}
	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
		    PrintGifError(GifFile->Error);
		    exit(EXIT_FAILURE);
		}
		if (!RawFlag) {
		    printf("\nImage #%d:\n\n\tImage Size - Left = %d, Top = %d, Width = %d, Height = %d.\n",
			   ImageNum++, GifFile->Image.Left, GifFile->Image.Top,
			   GifFile->Image.Width, GifFile->Image.Height);
		    printf("\tImage is %s",
			   GifFile->Image.Interlace ? "Interlaced" :
						    "Non Interlaced");
		    if (GifFile->Image.ColorMap != NULL)
			printf(", BitsPerPixel = %d.\n",
				GifFile->Image.ColorMap->BitsPerPixel);
		    else
			printf(".\n");
		    if (GifFile->Image.ColorMap)
			printf("\tImage Has Color Map.\n");
		    else
			printf("\tNo Image Color Map.\n");
		    if (ColorMapFlag && GifFile->Image.ColorMap) {
			printf("\tSort Flag: %s\n", 
			       GifFile->Image.ColorMap->SortFlag ? "on":"off");
			Len = 1 << GifFile->Image.ColorMap->BitsPerPixel;
			for (i = 0; i < Len; i+=4) {
			    for (j = 0; j < 4 && j < Len; j++) {
				printf("%3d: %02xh %02xh %02xh   ", i + j,
				       GifFile->Image.ColorMap->Colors[i + j].Red,
				       GifFile->Image.ColorMap->Colors[i + j].Green,
				       GifFile->Image.ColorMap->Colors[i + j].Blue);
			    }
			    printf("\n");
			}
		    }
		}

		if (EncodedFlag) {
		    if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
			PrintGifError(GifFile->Error);
			exit(EXIT_FAILURE);
		    }
		    printf("\nImage LZ compressed Codes (Code Size = %d):\n",
			   CodeSize);
		    PrintCodeBlock(GifFile, CodeBlock, true);
		    while (CodeBlock != NULL) {
			if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
			PrintCodeBlock(GifFile, CodeBlock, false);
		    }
		}
		else if (LZCodesFlag) {
		    PrintLZCodes(GifFile);
		}
		else if (PixelFlag) {
		    Line = (GifPixelType *) malloc(GifFile->Image.Width *
						sizeof(GifPixelType));
		    for (i = 0; i < GifFile->Image.Height; i++) {
			if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
			    == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
			PrintPixelBlock(Line, GifFile->Image.Width, i == 0);
		    }
		    PrintPixelBlock(NULL, GifFile->Image.Width, false);
		    free((char *) Line);
		}
		else if (RawFlag) {
		    Line = (GifPixelType *) malloc(GifFile->Image.Width *
						sizeof(GifPixelType));
		    for (i = 0; i < GifFile->Image.Height; i++) {
			if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
			    == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
			fwrite(Line, 1, GifFile->Image.Width, stdout);
		    }
		    free((char *) Line);
		}
		else {
		    /* Skip the image: */
		    if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
			PrintGifError(GifFile->Error);
			exit(EXIT_FAILURE);
		    }
		    while (CodeBlock != NULL) {
			if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
		    }

		}
		break;
	    case EXTENSION_RECORD_TYPE:
		if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
		    PrintGifError(GifFile->Error);
		    exit(EXIT_FAILURE);
		}
		if (!RawFlag) {
		    putchar('\n');
		    switch (ExtCode)
		    {
		    case COMMENT_EXT_FUNC_CODE:
			printf("GIF89 comment");
			break;
		    case GRAPHICS_EXT_FUNC_CODE:
			printf("GIF89 graphics control");
			break;
		    case PLAINTEXT_EXT_FUNC_CODE:
			printf("GIF89 plaintext");
			break;
		    case APPLICATION_EXT_FUNC_CODE:
			printf("GIF89 application block");
			break;
		    default:
			printf("Extension record of unknown type");
			break;
		    }
		    printf(" (Ext Code = %d [%c]):\n",
			   ExtCode, MAKE_PRINTABLE(ExtCode));
		    PrintExtBlock(Extension, true);

		    if (ExtCode == GRAPHICS_EXT_FUNC_CODE) {
			GraphicsControlBlock gcb;
			if (DGifExtensionToGCB(Extension[0], Extension+1, &gcb) == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
			printf("\tDisposal Mode: %d\n", gcb.DisposalMode);
			printf("\tUser Input Flag: %d\n", gcb.UserInputFlag);
			printf("\tTransparency on: %s\n",
			       gcb.TransparentColor != -1 ? "yes" : "no");
			printf("\tDelayTime: %d\n", gcb.DelayTime);
			printf("\tTransparent Index: %d\n", gcb.TransparentColor);
		    }
		}
		for (;;) {
		    if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
			PrintGifError(GifFile->Error);
			exit(EXIT_FAILURE);
		    }
		    if (Extension == NULL)
			break;
		    PrintExtBlock(Extension, false);
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:	     /* Should be trapped by DGifGetRecordType */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    if (!RawFlag) printf("\nGIF file terminated normally.\n");

    return 0;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
int main(int argc, char **argv) {
   //
   // local vars
   //
   GifFileType *GIFfile;
   GifRecordType GIFtype;
   GifByteType *GIFextension;
   GifPixelType *GIFline;
   uint32_t **lower_array,**upper_array;
   double **image_array;
   double f,fmin,fmax;
   int x,y,z,h,i,j,k,n,p;
   int image_width,image_height,image_count,color_resolution,GIFcode,ret;
   float pixel_size,arg,rx,ry,rz;
   char type,comment[256];
   struct fab_vars v;
   init_vars(&v);
   //
   // command line args
   //
   if (!((argc == 3) || (argc == 4) || (argc == 5) || (argc == 6) || (argc == 7) || (argc == 10))) {
      printf("command line: gif_png in.gif out.png [type [arg [points [size [rx ry rz]]]]]\n");
      printf("   in.gif = input gif file\n");
      printf("   out.png = output PNG file\n");
      printf("   type = 'z' of density, 'h' for height (default z)\n");
      printf("   arg = gamma for 'z', threshold for 'h' (default 1)\n");
      printf("   points = points to interpolate per point (linear, default 0)\n");
      printf("   size = voxel size (mm, default from file))\n");
      printf("   to be implemented: rx,ry,rz = x,y,z rotation angles (degrees; default 0)\n");
      exit(-1);
      }
   type = 'z';
   p = 0;
   arg = 1;
   rx = ry = rz = 0;
   pixel_size = -1;
   image_width = -1;
   image_height = -1;
   if (argc >= 4) {
      sscanf(argv[3],"%c",&type);
      if (!((type == 'z') || (type == 'h'))) {
         printf("gif_png: oops -- type must be 'z' or 'h'\n");
         exit(-1);
         }
   if (argc >= 5)
      sscanf(argv[4],"%f",&arg);
      }
   if (argc >= 6)
      sscanf(argv[5],"%d",&p);
   if (argc >= 7)
      sscanf(argv[6],"%f",&pixel_size);
   if (argc >= 10) {
      sscanf(argv[7],"%f",&rx);
      sscanf(argv[8],"%f",&ry);
      sscanf(argv[9],"%f",&rz);
      }
   //
   // scan the file 
   //
   printf("read %s\n",argv[1]);
   color_resolution = -1;
   GIFfile = DGifOpenFileName(argv[1]);
   if (GIFfile == NULL) {
      printf("gif_png: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   GIFline = malloc(MAX_LINE*sizeof(GifPixelType));
   do {
      DGifGetRecordType(GIFfile,&GIFtype);
      switch (GIFtype) {
         case IMAGE_DESC_RECORD_TYPE:
            DGifGetImageDesc(GIFfile);
            image_width = GIFfile->SWidth;
            image_height = GIFfile->SHeight;
            image_count = GIFfile->ImageCount;
            color_resolution = GIFfile->SColorResolution;
            for (y = 0; y < GIFfile->SHeight; ++y) {
               ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth);
               if (ret != GIF_OK) {
                  printf("gif_png: oops -- error reading line\n");
                  exit(-1);
                  }
               }
            break;
         case EXTENSION_RECORD_TYPE:
            DGifGetExtension(GIFfile,&GIFcode,&GIFextension);
            if (GIFcode == COMMENT_EXT_FUNC_CODE) {
               n = GIFextension[0];
               for (i = 1; i <= n; ++i)
                  comment[i-1] = GIFextension[i];
               comment[n] = 0;
               if (pixel_size == -1)
                  sscanf(comment,"mm per pixel: %f;",&pixel_size);
               }
            while (GIFextension != NULL)
               DGifGetExtensionNext(GIFfile,&GIFextension);
            break;
         case SCREEN_DESC_RECORD_TYPE:
            DGifGetScreenDesc(GIFfile);
            break;
         case TERMINATE_RECORD_TYPE:
            break;
         case UNDEFINED_RECORD_TYPE:
            printf("gif_png: oops -- undefined GIF record type\n");
            exit(-1);
            break;
         }
      } while (GIFtype != TERMINATE_RECORD_TYPE);
   if (GIFfile == NULL) {
      printf("gif_png: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   if (pixel_size == -1) {
      pixel_size = 1.0;
      printf("   no pixel size found, assuming 1 mm\n");
      }
   printf("   pixel size (mm): %f, color resolution (bits): %d\n",pixel_size,color_resolution);
   printf("   number of images: %d, image width %d, image height %d\n",image_count,image_width,image_height);
   //
   // check and set limits
   //
   v.nx = image_width + (image_width-1)*p;
   v.ny = image_height + (image_height-1)*p;
   v.nz = image_count + (image_count-1)*p;
   v.dx = v.nx*pixel_size;
   v.dy = v.ny*pixel_size;
   v.dz = v.nz*pixel_size;
   v.xmin = 0;
   v.ymin = 0;
   v.zmin = 0;
   //
   // allocate arrays
   //
   lower_array = malloc(image_height*sizeof(uint32_t *));
   for (y = 0; y < image_height; ++y) {
      lower_array[y] = malloc(image_width*sizeof(uint32_t));
      for (x = 0; x < image_width; ++x)
         lower_array[y][x] = 0;
      }
   upper_array = malloc(image_height*sizeof(uint32_t *));
   for (y = 0; y < image_height; ++y) {
      upper_array[y] = malloc(image_width*sizeof(uint32_t));
      for (x = 0; x < image_width; ++x)
         upper_array[y][x] = 0;
      }
   image_array = malloc(v.ny*sizeof(double *));
   for (y = 0; y < v.ny; ++y) {
      image_array[y] = malloc(v.nx*sizeof(double));
      for (x = 0; x < v.nx; ++x)
         image_array[y][x] = 0;
      }
   v.array = malloc(v.ny*sizeof(uint32_t *));
   for (y = 0; y < v.ny; ++y) {
      v.array[y] = malloc(v.nx*sizeof(uint32_t));
      for (x = 0; x < v.nx; ++x)
         v.array[y][x] = 0;
      }
   //
   // read the file
   //
   DGifCloseFile(GIFfile);
   GIFfile = DGifOpenFileName(argv[1]);
   if (GIFfile == NULL) {
      printf("gif_png: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   z = 0;
   do {
      DGifGetRecordType(GIFfile,&GIFtype);
      switch (GIFtype) {
         case IMAGE_DESC_RECORD_TYPE:
            //
            // read image
            //
            DGifGetImageDesc(GIFfile);
            printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b   layer = %d",z);
            if (z == 0) {
               //
               // read first layer
               //
               for (y = 0; y < image_height; ++y) {
                  ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth);
                  if (ret != GIF_OK) {
                     printf("gif_png: oops -- error reading first line\n");
                     exit(-1);
                     }
                  for (x = 0; x < image_width; ++x)
                     upper_array[y][x] = GIFline[x];
                  }
               }
            else {
               //
               // read next layer
               //
               for (y = 0; y < image_height; ++y) {
                  ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth);
                  if (ret != GIF_OK) {
                     printf("gif_png: oops -- error reading line\n");
                     exit(-1);
                     }
                  for (x = 0; x < image_width; ++x) {
                     lower_array[y][x] = upper_array[y][x];
                     upper_array[y][x] = GIFline[x];
                     }
                  }
               //
               // interpolate layer image
               //
               for (x = 0; x < (image_width-1); ++x) {
                  for (y = 0; y < (image_height-1); ++y) {
                     for (i = 0; i <= p; ++i) {
                        for (j = 0; j <= p; ++j) {
                           for (k = 0; k <= p; ++k) {
                              f = lower_array[y][x]*((p+1.0-i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((p+1.0-k)/(p+1.0))
                                + lower_array[y][x+1]*((i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((p+1.0-k)/(p+1.0))
                                + lower_array[y+1][x]*((p+1.0-i)/(p+1.0))*((j)/(p+1.0))*((p+1.0-k)/(p+1.0))
                                + lower_array[y+1][x+1]*((i)/(p+1.0))*((j)/(p+1.0))*((p+1.0-k)/(p+1.0))
                                + upper_array[y][x]*((p+1.0-i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((k)/(p+1.0))
                                + upper_array[y][x+1]*((i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((k)/(p+1.0))
                                + upper_array[y+1][x]*((p+1.0-i)/(p+1.0))*((j)/(p+1.0))*((k)/(p+1.0))
                                + upper_array[y+1][x+1]*((i)/(p+1.0))*((j)/(p+1.0))*((k)/(p+1.0));
                              if (type == 'z') {
                                 image_array[(1+p)*y+j][(1+p)*x+i] += f;
                                 }
                              else if (type == 'h') {
                                 h = (1+p)*z+k;
                                 if ((f > arg) && (h > image_array[(1+p)*y+j][(1+p)*x+i]))
                                    image_array[(1+p)*y+j][(1+p)*x+i] = h;
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            z += 1;
            break;
         case EXTENSION_RECORD_TYPE:
            DGifGetExtension(GIFfile,&GIFcode,&GIFextension);
            while (GIFextension != NULL)
               DGifGetExtensionNext(GIFfile,&GIFextension);
            break;
         case SCREEN_DESC_RECORD_TYPE:
            DGifGetScreenDesc(GIFfile);
            break;
         case TERMINATE_RECORD_TYPE:
            break;
         case UNDEFINED_RECORD_TYPE:
            printf("gif_png: oops -- undefined GIF record type\n");
            exit(-1);
            break;
         }
      } while (GIFtype != TERMINATE_RECORD_TYPE);
   printf("\n");
   //
   // scale image and copy to PNG array
   //
   if (type == 'z') {
      fmin = BIG;
      fmax = 0;
      for (x = 0; x < v.nx; ++x) {
         for (y = 0; y < v.ny; ++y) {
            if (image_array[y][x] > fmax) fmax = image_array[y][x];
            if (image_array[y][x] < fmin) fmin = image_array[y][x];
            }
         }
      if (arg == 1) {
         for (x = 0; x < v.nx; ++x)
            for (y = 0; y < v.ny; ++y)
               v.array[y][x] = 65536*(image_array[y][x]-fmin)/(fmax-fmin);
         }
      else {
         for (x = 0; x < v.nx; ++x)
            for (y = 0; y < v.ny; ++y)
               v.array[y][x] = 65536*pow((image_array[y][x]-fmin)/(fmax-fmin),arg);
         }
      }
   else if (type == 'h') {
      for (x = 0; x < v.nx; ++x)
         for (y = 0; y < v.ny; ++y)
            v.array[y][x] = 65536*image_array[y][x]/(v.nz-1.0);
      }
   //
   // write PNG
   //
   v.bit_depth = 16;
   fab_write_png_K(&v,argv[2]);
   //
   // exit
   //
   DGifCloseFile(GIFfile);
   exit(0);
   }
Ejemplo n.º 4
0
static void GIF2RGB(int NumFiles, char *FileName, 
            bool OneFileFlag, 
            char *OutFileName)
{
    int	i, j, Size, Row, Col, Width, Height, ExtCode, Count;
    GifRecordType RecordType;
    GifByteType *Extension;
    GifRowType *ScreenBuffer;
    GifFileType *GifFile;
    int
    InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
    InterlacedJumps[] = { 8, 8, 4, 2 };    /* be read - offsets and jumps... */
    int ImageNum = 0;
    ColorMapObject *ColorMap;
    int Error;

    if (NumFiles == 1) {
    int Error;
    if ((GifFile = DGifOpenFileName(FileName, &Error)) == NULL) {
        PrintGifError(Error);
        exit(EXIT_FAILURE);
    }
    }
    else {
    int Error;
    /* Use stdin instead: */
    if ((GifFile = DGifOpenFileHandle(0, &Error)) == NULL) {
        PrintGifError(Error);
        exit(EXIT_FAILURE);
    }
    }

    /* 
     * Allocate the screen as vector of column of rows. Note this
     * screen is device independent - it's the screen defined by the
     * GIF file parameters.
     */
    if ((ScreenBuffer = (GifRowType *)
    malloc(GifFile->SHeight * sizeof(GifRowType))) == NULL)
        GIF_EXIT("Failed to allocate memory required, aborted.");

    Size = GifFile->SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
    if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
    GIF_EXIT("Failed to allocate memory required, aborted.");

    for (i = 0; i < GifFile->SWidth; i++)  /* Set its color to BackGround. */
    ScreenBuffer[0][i] = GifFile->SBackGroundColor;
    for (i = 1; i < GifFile->SHeight; i++) {
        /* Allocate the other rows, and set their color to background too: */
        if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
            GIF_EXIT("Failed to allocate memory required, aborted.");
        memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
    }

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
        if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
            PrintGifError(GifFile->Error);
            exit(EXIT_FAILURE);
        }
        switch (RecordType) {
            case IMAGE_DESC_RECORD_TYPE:
                {
                    if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
                        PrintGifError(GifFile->Error);
                        exit(EXIT_FAILURE);
                    }
                    Row = GifFile->Image.Top; /* Image Position relative to Screen. */
                    Col = GifFile->Image.Left;
                    Width = GifFile->Image.Width;
                    Height = GifFile->Image.Height;
                    GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
                        PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
                    if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth ||
                        GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) {
                            fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n",ImageNum);
                            exit(EXIT_FAILURE);
                    }
                    if (GifFile->Image.Interlace) {
                        /* Need to perform 4 passes on the images: */
                        for (Count = i = 0; i < 4; i++)
                            for (j = Row + InterlacedOffset[i]; j < Row + Height;
                                j += InterlacedJumps[i]) {
                                    GifQprintf("\b\b\b\b%-4d", Count++);
                                    if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
                                        Width) == GIF_ERROR) {
                                            PrintGifError(GifFile->Error);
                                            exit(EXIT_FAILURE);
                                    }
                            }
                    }
                    else {
                        for (i = 0; i < Height; i++) {
                            GifQprintf("\b\b\b\b%-4d", i);
                            if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
                                Width) == GIF_ERROR) {
                                    PrintGifError(GifFile->Error);
                                    exit(EXIT_FAILURE);
                            }
                        }
                    }
                    break;
                }
            case EXTENSION_RECORD_TYPE:
                {
                    /* Skip any extension blocks in file: */
                    if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
                        PrintGifError(GifFile->Error);
                        exit(EXIT_FAILURE);
                    }
                    while (Extension != NULL) {
                        if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
                            PrintGifError(GifFile->Error);
                            exit(EXIT_FAILURE);
                        }
                    }
                    break;
                }
            case TERMINATE_RECORD_TYPE:
                {
                    break;
                }
            default:		    /* Should be trapped by DGifGetRecordType. */
                break;
        }
    } while (RecordType != TERMINATE_RECORD_TYPE);

    /* Lets dump it - set the global variables required and do it: */
    ColorMap = (GifFile->Image.ColorMap
        ? GifFile->Image.ColorMap
        : GifFile->SColorMap);
    if (ColorMap == NULL) {
        fprintf(stderr, "Gif Image does not have a colormap\n");
        exit(EXIT_FAILURE);
    }

    DumpScreen2RGB(OutFileName, OneFileFlag,
           ColorMap,
           ScreenBuffer, 
           GifFile->SWidth, GifFile->SHeight);

    (void)free(ScreenBuffer);

    if (DGifCloseFile(GifFile, &Error) == GIF_ERROR) {
    PrintGifError(Error);
    exit(EXIT_FAILURE);
    }

}
Ejemplo n.º 5
0
//int fh_gif_load(char *name,unsigned char *buffer, unsigned char ** alpha, int x,int y)
int fh_gif_load(aml_dec_para_t* para , aml_image_info_t* image)
{
  int in_nextrow[4]={8,8,4,2};   //interlaced jump to the row current+in_nextrow
  int in_beginrow[4]={0,4,2,1};  //begin pass j from that row number
  int transparency=-1;  //-1 means not transparency present
    int px,py,i,ibxs;
    int j;
    char *fbptr;
    char *lb;
    char *slb;
    GifFileType *gft;
    GifByteType *extension;
    int extcode;
    GifRecordType rt;
    ColorMapObject *cmap;
    int cmaps;
    char *p,*q;
    int buf_len;
    char* name;
    char* buffer;
    char* alpha = NULL;
    int x,y;    
    name = para->fn;
    buffer = (unsigned char*) malloc(para->iwidth * para->iheight * 4);
    buf_len = para->iwidth * para->iheight;
    x = para->iwidth;
    y = para->iheight;
    gft=DGifOpenFileName(name);
    if(gft==NULL){printf("err5\n"); gflush;} //////////
    do
    {
	if(DGifGetRecordType(gft,&rt) == GIF_ERROR) grflush;
	switch(rt)
	{
	    case IMAGE_DESC_RECORD_TYPE:
		if(DGifGetImageDesc(gft)==GIF_ERROR) grflush;
		px=gft->Image.Width;
		py=gft->Image.Height;
		lb=(char*)malloc(px*3);
		slb=(char*) malloc(px);
//  printf("reading...\n");
		if(lb!=NULL && slb!=NULL)
		{
			unsigned char *alphaptr = NULL;
			
		    cmap=(gft->Image.ColorMap ? gft->Image.ColorMap : gft->SColorMap);
		    cmaps=cmap->ColorCount;

		    ibxs=ibxs*3;
		    fbptr=(char*)buffer;
			
			if(transparency != -1)
			{
				alphaptr = malloc(px * py);
				alpha = alphaptr;
			}
			
		    if(!(gft->Image.Interlace))
		    {
			for(i=0;i<py;i++,fbptr+=px*3)
			{
				int j;
			    if(DGifGetLine(gft,(GifPixelType*)slb,px)==GIF_ERROR) mgrflush;
			    m_rend_gif_decodecolormap((unsigned char*)slb,(unsigned char*)lb,cmap,cmaps,px,transparency);
			    memcpy(fbptr,lb,px*3);
				if(alphaptr)
					for(j = 0; j<px; j++) *(alphaptr++) = (((unsigned char*) slb)[j] == transparency) ? 0x00 : 0xff;
        		}
                    }
                    else
		    {
				unsigned char * aptr = NULL;
				
	               for(j=0;j<4;j++)
	               {
						int k;
				        if(alphaptr)
							aptr = alphaptr + (in_beginrow[j] * px);
							
					    fbptr=(char*)buffer + (in_beginrow[j] * px * 3);

					    for(i = in_beginrow[j]; i<py; i += in_nextrow[j], fbptr += px * 3 * in_nextrow[j], aptr += px * in_nextrow[j])
			    {
				if(DGifGetLine(gft,(GifPixelType*)slb,px)==GIF_ERROR) mgrflush; /////////////
				m_rend_gif_decodecolormap((unsigned char*)slb,(unsigned char*)lb,cmap,cmaps,px,transparency);
				memcpy(fbptr,lb,px*3);
				if(alphaptr)
					for(k = 0; k<px; k++) aptr[k] = (((unsigned char*) slb)[k] == transparency) ? 0x00 : 0xff;
          		    }
			}
		    }
		}
		if(lb) free(lb);
		if(slb) free(slb);
                break;
	    case EXTENSION_RECORD_TYPE:
		if(DGifGetExtension(gft,&extcode,&extension)==GIF_ERROR) grflush; //////////
		if(extcode==0xf9) //look image transparency in graph ctr extension
		{
			if(extension[1] & 1)
			{
				transparency = extension[4];

			}
//		    tran_off=(int)*extension;
//		    transparency=(int)*(extension+tran_off);
//			printf("transparency: %d\n", transparency);
                }
		while(extension!=NULL)
		    if(DGifGetExtensionNext(gft,&extension) == GIF_ERROR) grflush
		break;
	    default:
		break;
	}
    }
    while( rt!= TERMINATE_RECORD_TYPE );
    DGifCloseFile(gft);
    p = buffer;
    q = alpha ;    
    for(i = buf_len ; i >0 ;i--){
        if(!q){
            p[4*i - 1] = 0xff; 
        }else{
            p[4*i - 1] = q[i-1];         //a
        }
        p[4*i - 2] = p[3*i - 3];     //r
        p[4*i - 3] = p[3*i - 2];     //g
        p[4*i - 4] = p[3*i - 1];     //b
    }    
    image->data = buffer;
    image->width = x;
    image->height = y;
    image->depth = 32;
    image->bytes_per_line = x << 2 ;
    image->nbytes = image->bytes_per_line * y;        
    return(FH_ERROR_OK);
}
Ejemplo n.º 6
0
int fh_gif_load(char *name, unsigned char *buf, unsigned char ** alpha, int x, int y)
{
    Log(LOG_DEBUG, "function:%s --- paralist:name=%s,x=%d,y=%d\n", __func__, name, x, y);

	int in_nextrow[4] = { 8, 8, 4, 2 }; //interlaced jump to the row current+in_nextrow
	int in_beginrow[4] = { 0, 4, 2, 1 }; //begin pass j from that row number
	int transparency = -1; //-1 means not transparency present
	int px, py, i, j;
	int cmaps;
	int extcode;
	char *fbptr;
	char *lb;
	char *slb;
	GifFileType *gft;
	GifByteType *extension;
	GifRecordType rt;
	ColorMapObject *cmap;

	int delay = 0;
	//int error = 0;
	struct image *img = NULL;
	unsigned char *buffer = NULL;

	//if(NULL == (gft=DGifOpenFileName(name, &error))){
	if (NULL == (gft = DGifOpenFileName(name))) {
		Log(LOG_WARN, "function:%s --- gif file open failed!\n", __func__);
		gflush;
	}

	if (NULL == (img = (struct image *) malloc(sizeof(struct image)))) {
		Log(LOG_WARN, "function:%s --- gif malloc failed!\n", __func__);
		grflush;
	}

	do {
		if (DGifGetRecordType(gft, &rt) == GIF_ERROR) {
			Log(LOG_WARN, "function:%s --- gif get record type failed!\n", __func__);
			grflush
		}

		switch (rt) {
			case IMAGE_DESC_RECORD_TYPE:
				if (DGifGetImageDesc(gft) == GIF_ERROR) {
					Log(LOG_WARN, "function:%s --- gif get desc failed!\n", __func__);
					grflush
				}

				px = gft->Image.Width;
				py = gft->Image.Height;

				Log(LOG_INFO, "function:%s --- paralist:name=%s,x=%d,y=%d\n", __func__, name, px, py);

				lb = (char*) malloc(px * 3);
				slb = (char*) malloc(px);
				buffer = (unsigned char *) malloc(px * py * 3);

				if (lb != NULL && slb != NULL && buffer != NULL) {
					unsigned char *alphaptr = NULL;

					cmap = (gft->Image.ColorMap ? gft->Image.ColorMap : gft->SColorMap);
					cmaps = cmap->ColorCount;

					fbptr = (char*) buffer;

					if (transparency != -1) {
						if (NULL == (alphaptr = malloc(px * py))) {
							Log(LOG_WARN, "function:%s --- alphaptr malloc failed!\n", __func__);
						}
						*alpha = alphaptr;
					}

					if (!(gft->Image.Interlace)) {
						for (i = 0; i < py; i++, fbptr += px * 3) {
							int j;

							if (DGifGetLine(gft, (GifPixelType*) slb, px) == GIF_ERROR) {
								Log(LOG_WARN, "function:%s --- gif get line failed!\n", __func__);
								mgrflush;
							}

							m_rend_gif_decodecolormap((unsigned char*) slb, (unsigned char*) lb, cmap, cmaps, px,
							        transparency);
							memcpy(fbptr, lb, px * 3);

							if (alphaptr)
								for (j = 0; j < px; j++) {
									*(alphaptr++) = (((unsigned char*) slb)[j] == transparency) ? 0x00 : 0xff;
								}
						}
					} else {
						unsigned char * aptr = NULL;

						for (j = 0; j < 4; j++) {
							int k;

							if (alphaptr)
								aptr = alphaptr + (in_beginrow[j] * px);

							fbptr = (char*) buffer + (in_beginrow[j] * px * 3);

							for (i = in_beginrow[j]; i < py;
							        i += in_nextrow[j], fbptr += px * 3 * in_nextrow[j], aptr += px * in_nextrow[j]) {
								if (DGifGetLine(gft, (GifPixelType*) slb, px) == GIF_ERROR) {
									Log(LOG_WARN, "function:%s --- gif get line failed!\n", __func__);
									mgrflush
								}

								m_rend_gif_decodecolormap((unsigned char*) slb, (unsigned char*) lb, cmap, cmaps, px,
								        transparency);
								memcpy(fbptr, lb, px * 3);

								if (alphaptr)
									for (k = 0; k < px; k++) {
										aptr[k] = (((unsigned char*) slb)[k] == transparency) ? 0x00 : 0xff;
									}
							}
						}
					}
Ejemplo n.º 7
0
int
readGif(char *fileName, dblData result, int alpha2, int level)
{
	GifFileType *file;

	ColorMapObject *colorMap;
	unsigned char *bits;
	unsigned char *data;
	unsigned char *p;
	int i, nColors, size, alpha, bgColor, alignedWidth, bytesPerColor;
	unsigned long outsize;

	if((file = DGifOpenFileName(fileName)) == NULL)
		return 0;

	if(DGifSlurp(file) != GIF_OK)
	//	error("Error slurping file");
		return 0;

	/* data should now be available */

	/* Local colormap has precedence over Global colormap */
	colorMap = file->Image.ColorMap ? file->Image.ColorMap : file->SColorMap;

	nColors = colorMap->ColorCount;
	alpha = getTransparentColor(file);

	/* bgColor is the background color to fill the bitmap with
	 * if an image is smaller than screen coordinates
	 */
	if (file->SColorMap)			/* There is a GlobalColorMap */
		bgColor = file->SBackGroundColor;   /* The BackGroundColor is meaningful */
	else
	if (alpha >= 0)			/* There is a transparency color */
		bgColor = alpha;			/* set the bgColor to tranparent */
	else
		bgColor = 0;			/* Don't know what to do here.
					 * If this doesn't work, we could
					 * create a new color and set the
					 * alpha-channel to transparent
					 * (unless we are using all the 256
					 * colors, in which case either we
					 * give up, or move to 16-bits palette
					 */
	result->hasalpha = 0;
	bytesPerColor = 3;
	if (alpha >= 0) {
		bytesPerColor += 1;	/* if tranparent color, use the alpha
							 * channel (RGBA instead of RGB)
							 */
		result->hasalpha = 1;
	}
	
	/* Ah! The Flash specs says scanlines must be DWORD ALIGNED!
	 * (but image width is the correct number of pixels)
	 */
	alignedWidth = (file->SWidth + 3) & ~3;

	/* size = size-of-colormap + size-of-bitmap */
	size = (nColors * bytesPerColor) + (alignedWidth * file->SHeight);
	data = malloc(size);

	result->format = 3;
	result->width = file->SWidth;
	result->height = file->SHeight;
	result->format2 = nColors-1;			/* size(colorMap) - 1 */

	p = data;

	/* create ColorMap */
	for(i=0; i<nColors; ++i)
	{
		GifColorType c = colorMap->Colors[i];

		if (bytesPerColor == 3) {	/* RGB */
			*p++ = c.Red;
			*p++ = c.Green;
			*p++ = c.Blue;
		} else {			/* RGBA */
#if 1				/* You would think that an alpha value of 0
				 * would mean fully transparent, but Flash
				 * player doesn't seem to think so.
				 * So, we just set the transparency color 
				 * as 0,0,0,0
				 */
			if (i != alpha) {
				*p++ = c.Red;
				*p++ = c.Green;
				*p++ = c.Blue;
				*p++ = 255;	/* Fully opaque */
			} else {
				*p++ = 0;		/* red */
				*p++ = 0;		/* green */
				*p++ = 0;		/* blue */
				*p++ = 0;		/* Fully transparent */
    		}
#else
			*p++ = c.Red;
			*p++ = c.Green;
			*p++ = c.Blue;
			*p++ = (i != alpha) ? 255 : 0; /* set alpha to 0 for transparent color */
#endif
		}
	}

	bits = file->SavedImages[0].RasterBits;

	if (alignedWidth == file->SWidth
	  && file->Image.Width == file->SWidth 
	  && file->Image.Height == file->SHeight) {

	/* we are all nicely aligned and don't need to move the bitmap around.
	 * Just copy the bits into the output buffer.
	 */
		memcpy(p, bits, file->SWidth * file->SHeight);

	} else {
	/* here we need to pad the scanline or to move the bitmap around
	 * (if the image is not at 0,0 in the logical screen)
	 */
		int screenWidth = file->SWidth;
		int screenHeight = file->SHeight;

		int imageTop = file->Image.Top;
		int imageBottom = file->Image.Top + file->Image.Height;
		int imageLeft = file->Image.Left;
		int imageWidth = file->Image.Width;

		for (i=0; i < screenHeight; i++, p += alignedWidth) {

		/* the image is smaller than the logical "screen":
		 * Fill the reminder with the background color.
	 	*/
			if (imageWidth != screenWidth)
				memset(p, bgColor, screenWidth);

		/* finally, copy scanline
		 */
			if (i >= imageTop && i < imageBottom) {
				memcpy(p + imageLeft, bits, imageWidth);
				bits += imageWidth;
			}
		}
	}

	/* Done! */
	DGifCloseFile(file);

	result->data = malloc(outsize = (int)floor(size*1.01+12));

  /* zlib-compress the gif data */

	compress2(result->data, &outsize, data, size, level);
	free(data);

	result->length = outsize;
	return 1;
}
Ejemplo n.º 8
0
/******************************************************************************
 Interpret the command line, prepar global data and call the Gif routines.
******************************************************************************/
int main(int argc, char **argv)
{
    int	NumFiles, ImageWidth, ImageHeight, Dummy, Red, Green, Blue, ErrorCode;
    static bool Error,
	ImageSizeFlag = false, ColorMapFlag = false, HelpFlag = false,
	TextifyFlag = false;
    char **FileName = NULL, *ColorMapFile;
    ColorMapObject *ColorMap;
    FILE *InColorMapFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint,
		&ImageSizeFlag, &ImageWidth, &ImageHeight,
		&ColorMapFlag, &ColorMapFile,
		&TextifyFlag,
		&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) {
	(void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    if (ImageSizeFlag) {
	if (ColorMapFlag) {
	    int ColorMapSize;

	    /* Read color map from given file: */
	    if ((InColorMapFile = fopen(ColorMapFile, "rt")) == NULL) {
		GIF_MESSAGE("Failed to open COLOR MAP file (not exists!?).");
		exit(EXIT_FAILURE);
	    }
	    if ((ColorMap = GifMakeMapObject(256, NULL)) == NULL) {
		GIF_MESSAGE("Failed to allocate bitmap, aborted.");
		exit(EXIT_FAILURE);
	    }

	    for (ColorMapSize = 0;
		 ColorMapSize < 256 && !feof(InColorMapFile);
		 ColorMapSize++) {
		if (fscanf(InColorMapFile, "%3d %3d %3d %3d\n",
			   &Dummy, &Red, &Green, &Blue) == 4) {
		    ColorMap->Colors[ColorMapSize].Red = Red;
		    ColorMap->Colors[ColorMapSize].Green = Green;
		    ColorMap->Colors[ColorMapSize].Blue = Blue;
		}
	    }
	}
	else {
	    ColorMap = GifMakeMapObject(EGA_PALETTE_SIZE, EGAPalette);
	}

	if (NumFiles == 1) {
	    int InFileHandle;
    #ifdef _WIN32
	    if ((InFileHandle = open(*FileName, O_RDONLY | O_BINARY)) == -1) {
    #else
	    if ((InFileHandle = open(*FileName, O_RDONLY)) == -1) {
    #endif /* _WIN32 */
		GIF_MESSAGE("Failed to open RAW image file (not exists!?).");
		exit(EXIT_FAILURE);
	    }
	    dup2(InFileHandle, 0);		       /* Make stdin from this file. */
	}
	else {
    #ifdef _WIN32
	    _setmode(0, O_BINARY);		  /* Make sure it is in binary mode. */
    #endif /* _WIN32 */
	}

	/* Convert Raw image from stdin to GIF file in stdout: */
	Raw2Gif(ImageWidth, ImageHeight, ColorMap);
    }
    else {
	GifFileType *GifFile;

	if (NumFiles == 1) {
	    if ((GifFile = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) {
		PrintGifError(ErrorCode);
		exit(EXIT_FAILURE);
	    }
	}
	else {
	    /* Use stdin instead: */
	    if ((GifFile = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
		PrintGifError(ErrorCode);
		exit(EXIT_FAILURE);
	    }
	}
	Gif2Raw(GifFile, TextifyFlag);
    }

    return 0;
    // cppcheck-suppress resourceLeak
}

/******************************************************************************
 Convert raw image (One byte per pixel) into GIF file. Raw data is read from
 stdin, and GIF is dumped to stdout. ImagwWidth times ImageHeight bytes are
 read. Color map is dumped from ColorMap.
******************************************************************************/
void Raw2Gif(int ImageWidth, int ImageHeight, ColorMapObject *ColorMap)
{
    int i, j, ErrorCode;
    static GifPixelType *ScanLine;
    GifFileType *GifFile;

    if ((ScanLine = (GifPixelType *) malloc(sizeof(GifPixelType) * ImageWidth))
								== NULL) {
	GIF_MESSAGE("Failed to allocate scan line, aborted.");
	exit(EXIT_FAILURE);
    }

    if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {	   /* Gif to stdout. */
	free((char *) ScanLine);
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, ColorMap->BitsPerPixel,
			  0, ColorMap) == GIF_ERROR) {
	free((char *) ScanLine);
	PrintGifError(GifFile->Error);
	exit(EXIT_FAILURE);
    }

    if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, false,
			 NULL) == GIF_ERROR) {
	free((char *) ScanLine);
	PrintGifError(GifFile->Error);
	exit(EXIT_FAILURE);
    }

    /* Here it is - get one raw line from stdin, and dump to stdout Gif: */
    GifQprintf("\n%s: Image 1 at (0, 0) [%dx%d]:     ",
	PROGRAM_NAME, ImageWidth, ImageHeight);
    for (i = 0; i < ImageHeight; i++) {
	/* Note we assume here PixelSize == Byte, which is not necessarily   */
	/* so. If not - must read one byte at a time, and coerce to pixel.   */
	if (fread(ScanLine, 1, ImageWidth, stdin) != (unsigned)ImageWidth) {
	    GIF_MESSAGE("RAW input file ended prematurely.");
	    exit(EXIT_FAILURE);
	}

	for (j = 0; j < ImageWidth; j++)
	    if (ScanLine[j] >= ColorMap->ColorCount)
		GIF_MESSAGE("Warning: RAW data color > maximum color map entry.");

	if (EGifPutLine(GifFile, ScanLine, ImageWidth) == GIF_ERROR) {
	    free((char *) ScanLine);
	    PrintGifError(GifFile->Error);
	    exit(EXIT_FAILURE);
	}
	GifQprintf("\b\b\b\b%-4d", i);
    }

    if (EGifCloseFile(GifFile) == GIF_ERROR) {
	free((char *) ScanLine);
	PrintGifError(GifFile->Error);
	exit(EXIT_FAILURE);
    }

    free((char *) ScanLine);
}
Ejemplo n.º 9
0
// Read animated GIF bitstream from 'filename' into 'AnimatedImage' struct.
static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
                           int dump_frames, const char dump_folder[]) {
  uint32_t frame_count;
  uint32_t canvas_width, canvas_height;
  uint32_t i;
  int gif_error;
  GifFileType* gif;

  gif = DGifOpenFileName(filename, NULL);
  if (gif == NULL) {
    fprintf(stderr, "Could not read file: %s.\n", filename);
    return 0;
  }

  gif_error = DGifSlurp(gif);
  if (gif_error != GIF_OK) {
    fprintf(stderr, "Could not parse image: %s.\n", filename);
    GIFDisplayError(gif, gif_error);
    DGifCloseFile(gif, NULL);
    return 0;
  }

  // Animation properties.
  image->canvas_width = (uint32_t)gif->SWidth;
  image->canvas_height = (uint32_t)gif->SHeight;
  if (image->canvas_width > MAX_CANVAS_SIZE ||
      image->canvas_height > MAX_CANVAS_SIZE) {
    fprintf(stderr, "Invalid canvas dimension: %d x %d\n",
            image->canvas_width, image->canvas_height);
    DGifCloseFile(gif, NULL);
    return 0;
  }
  image->loop_count = GetLoopCountGIF(gif);
  image->bgcolor = GetBackgroundColorGIF(gif);

  frame_count = (uint32_t)gif->ImageCount;
  if (frame_count == 0) {
    DGifCloseFile(gif, NULL);
    return 0;
  }

  if (image->canvas_width == 0 || image->canvas_height == 0) {
    image->canvas_width = gif->SavedImages[0].ImageDesc.Width;
    image->canvas_height = gif->SavedImages[0].ImageDesc.Height;
    gif->SavedImages[0].ImageDesc.Left = 0;
    gif->SavedImages[0].ImageDesc.Top = 0;
    if (image->canvas_width == 0 || image->canvas_height == 0) {
      fprintf(stderr, "Invalid canvas size in GIF.\n");
      DGifCloseFile(gif, NULL);
      return 0;
    }
  }
  // Allocate frames.
  AllocateFrames(image, frame_count);

  canvas_width = image->canvas_width;
  canvas_height = image->canvas_height;

  // Decode and reconstruct frames.
  for (i = 0; i < frame_count; ++i) {
    const int canvas_width_in_bytes = canvas_width * kNumChannels;
    const SavedImage* const curr_gif_image = &gif->SavedImages[i];
    GraphicsControlBlock curr_gcb;
    DecodedFrame* curr_frame;
    uint8_t* curr_rgba;

    memset(&curr_gcb, 0, sizeof(curr_gcb));
    DGifSavedExtensionToGCB(gif, i, &curr_gcb);

    curr_frame = &image->frames[i];
    curr_rgba = curr_frame->rgba;
    curr_frame->duration = GetFrameDurationGIF(gif, i);

    if (i == 0) {  // Initialize as transparent.
      curr_frame->is_key_frame = 1;
      ZeroFillCanvas(curr_rgba, canvas_width, canvas_height);
    } else {
      DecodedFrame* const prev_frame = &image->frames[i - 1];
      const GifImageDesc* const prev_desc = &gif->SavedImages[i - 1].ImageDesc;
      GraphicsControlBlock prev_gcb;
      memset(&prev_gcb, 0, sizeof(prev_gcb));
      DGifSavedExtensionToGCB(gif, i - 1, &prev_gcb);

      curr_frame->is_key_frame =
          IsKeyFrameGIF(prev_desc, prev_gcb.DisposalMode, prev_frame,
                        canvas_width, canvas_height);

      if (curr_frame->is_key_frame) {  // Initialize as transparent.
        ZeroFillCanvas(curr_rgba, canvas_width, canvas_height);
      } else {
        int prev_frame_disposed, curr_frame_opaque;
        int prev_frame_completely_covered;
        // Initialize with previous canvas.
        uint8_t* const prev_rgba = image->frames[i - 1].rgba;
        CopyCanvas(prev_rgba, curr_rgba, canvas_width, canvas_height);

        // Dispose previous frame rectangle.
        prev_frame_disposed =
            (prev_gcb.DisposalMode == DISPOSE_BACKGROUND ||
             prev_gcb.DisposalMode == DISPOSE_PREVIOUS);
        curr_frame_opaque =
            (curr_gcb.TransparentColor == NO_TRANSPARENT_COLOR);
        prev_frame_completely_covered =
            curr_frame_opaque &&
            CoversFrameGIF(&curr_gif_image->ImageDesc, prev_desc);

        if (prev_frame_disposed && !prev_frame_completely_covered) {
          switch (prev_gcb.DisposalMode) {
            case DISPOSE_BACKGROUND: {
              ZeroFillFrameRect(curr_rgba, canvas_width_in_bytes,
                                prev_desc->Left, prev_desc->Top,
                                prev_desc->Width, prev_desc->Height);
              break;
            }
            case DISPOSE_PREVIOUS: {
              int src_frame_num = i - 2;
              while (src_frame_num >= 0) {
                GraphicsControlBlock src_frame_gcb;
                memset(&src_frame_gcb, 0, sizeof(src_frame_gcb));
                DGifSavedExtensionToGCB(gif, src_frame_num, &src_frame_gcb);
                if (src_frame_gcb.DisposalMode != DISPOSE_PREVIOUS) break;
                --src_frame_num;
              }
              if (src_frame_num >= 0) {
                // Restore pixels inside previous frame rectangle to
                // corresponding pixels in source canvas.
                uint8_t* const src_frame_rgba =
                    image->frames[src_frame_num].rgba;
                CopyFrameRectangle(src_frame_rgba, curr_rgba,
                                   canvas_width_in_bytes,
                                   prev_desc->Left, prev_desc->Top,
                                   prev_desc->Width, prev_desc->Height);
              } else {
                // Source canvas doesn't exist. So clear previous frame
                // rectangle to background.
                ZeroFillFrameRect(curr_rgba, canvas_width_in_bytes,
                                  prev_desc->Left, prev_desc->Top,
                                  prev_desc->Width, prev_desc->Height);
              }
              break;
            }
            default:
              break;  // Nothing to do.
          }
        }
      }
    }

    // Decode current frame.
    if (!ReadFrameGIF(curr_gif_image, gif->SColorMap, curr_gcb.TransparentColor,
                      canvas_width_in_bytes, curr_rgba)) {
      DGifCloseFile(gif, NULL);
      return 0;
    }

    if (dump_frames) {
      if (!DumpFrame(filename, dump_folder, i, curr_rgba,
                     canvas_width, canvas_height)) {
        DGifCloseFile(gif, NULL);
        return 0;
      }
    }
  }
  DGifCloseFile(gif, NULL);
  return 1;
}
Ejemplo n.º 10
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
    int	NumFiles, ExtCode;
    bool Error;
    GifRecordType RecordType;
    GifByteType *Extension;
    char **FileName = NULL;
    GifRowType *ImageBuffer;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint,
		&InterlacedFlag, &SequencialFlag, &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) {
	(void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR);
	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);
    }

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

    /* And dump out exactly same screen information: */
    if (EGifPutScreenDesc(GifFileOut,
	GifFileIn->SWidth, GifFileIn->SHeight,
	GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
	GifFileIn->SColorMap) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);

    /* 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);

		/* Put the image descriptor to out file: */
		if (EGifPutImageDesc(GifFileOut,
		    GifFileIn->Image.Left, GifFileIn->Image.Top,
		    GifFileIn->Image.Width, GifFileIn->Image.Height,
		    InterlacedFlag,
		    GifFileIn->Image.ColorMap) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		/* Load the image (either Interlaced or not), and dump it as */
		/* defined in GifFileOut->Image.Interlaced.		     */
		if (LoadImage(GifFileIn, &ImageBuffer) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (DumpImage(GifFileOut, ImageBuffer) == 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);
		if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
							Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		/* No support to more than one extension blocks, so discard: */
		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);

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

    return 0;
}
Ejemplo n.º 11
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count;
    GifRecordType RecordType;
    GifByteType *Extension;
    char **FileName = NULL;
    GifRowType *ScreenBuffer;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,&GifQuietPrint,
		&ForceXFlag, &ForceYFlag, &SizeFlag, &PSSizeX, &PSSizeY,
		&PosFlag, &PSPosX, &PSPosY,
		&InvertFlag, &NumCopiesFlag, &NumOfCopies, &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 (ForceXFlag)
        PSOrientation = HORIZONTAL_ORIENT;
    else if (ForceYFlag)
        PSOrientation = VERTICAL_ORIENT;
    else
	PSOrientation = UNKNOWN_ORIENT;

    if (NumFiles == 1) {
	if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
    }
    else {
	/* Use the stdin instead: */

#ifdef __MSDOS__
	setmode(0, O_BINARY);
#endif /* __MSDOS__ */
	if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
    }

    /* Allocate the screen as vector of column of rows. We cannt allocate    */
    /* the all screen at once, as this broken minded CPU can allocate up to  */
    /* 64k at a time and our image can be bigger than that:		     */
    /* Note this screen is device independent - its the screen as defined by */
    /* the GIF file parameters itself.					     */
    if ((ScreenBuffer = (GifRowType *)
	malloc(GifFile->SHeight * sizeof(GifRowType *))) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");

    Size = GifFile->SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
    if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
	GIF_EXIT("Failed to allocate memory required, aborted.");

    for (i = 0; i < GifFile->SWidth; i++) /* Set its color to BackGround. */
	ScreenBuffer[0][i] = GifFile->SBackGroundColor;
    for (i = 1; i < GifFile->SHeight; i++) {
	/* Allocate the other rows, and set their color to background too:  */
	if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");

	memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
    }

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
		    PrintGifError();
		    exit(EXIT_FAILURE);
		}
		Row = GifFile->Image.Top; /* Image Position relative to Screen. */
		Col = GifFile->Image.Left;
		Width = GifFile->Image.Width;
		Height = GifFile->Image.Height;
		GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
		    PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
		if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth ||
		   GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) {
		    fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n",ImageNum);
		    exit(EXIT_FAILURE);
		}
		if (GifFile->Image.Interlace) {
		    /* Need to perform 4 passes on the images: */
 		    for (Count = i = 0; i < 4; i++)
			for (j = Row + InterlacedOffset[i]; j < Row + Height;
						 j += InterlacedJumps[i]) {
			    GifQprintf("\b\b\b\b%-4d", Count++);
			    if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
				Width) == GIF_ERROR) {
				PrintGifError();
				exit(EXIT_FAILURE);
			    }
			}
		}
		else {
		    for (i = 0; i < Height; i++) {
			GifQprintf("\b\b\b\b%-4d", i);
			if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
				Width) == GIF_ERROR) {
			    PrintGifError();
			    exit(EXIT_FAILURE);
			}
		    }
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
		    PrintGifError();
		    exit(EXIT_FAILURE);
		}
		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
			PrintGifError();
			exit(EXIT_FAILURE);
		    }
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    /* Lets display it - set the global variables required and do it: */
    BackGround = GifFile->SBackGroundColor;
    ColorMap = (GifFile->Image.ColorMap
		? GifFile->Image.ColorMap->Colors
		: GifFile->SColorMap->Colors);
    DumpScreen2PS(ScreenBuffer, GifFile->SWidth, GifFile->SHeight);

    if (DGifCloseFile(GifFile) == GIF_ERROR) {
	PrintGifError();
	exit(EXIT_FAILURE);
    }

    return 0;
}
Ejemplo n.º 12
0
int fh_gif_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/)
{
	int px,py,i/*,ibxs*/;
	int j;
	unsigned char *fbptr;
	unsigned char *lb;
	unsigned char *slb;
	GifFileType *gft;
	GifByteType *extension;
	int extcode;
	GifRecordType rt;
	ColorMapObject *cmap;
	int cmaps;
#if GIFLIB_MAJOR >= 5
	int error;

	gft=DGifOpenFileName(name, &error);
#else
	gft=DGifOpenFileName(name);
#endif
	if(gft==NULL) gflush;
	do
	{
		if(DGifGetRecordType(gft,&rt) == GIF_ERROR) grflush;
		switch(rt)
		{
			case IMAGE_DESC_RECORD_TYPE:

				if(DGifGetImageDesc(gft)==GIF_ERROR) grflush;
				px=gft->Image.Width;
				py=gft->Image.Height;
				lb=(unsigned char*)malloc(px*3);
				slb=(unsigned char*) malloc(px);
//		printf("reading...\n");
				if(lb!=NULL && slb!=NULL)
				{
					cmap=(gft->Image.ColorMap ? gft->Image.ColorMap : gft->SColorMap);
					cmaps=cmap->ColorCount;

//					ibxs=ibxs*3;
					fbptr=*buffer;
					if(!(gft->Image.Interlace))
					{
						for(i=0;i<py;i++,fbptr+=px*3)
						{
							if(DGifGetLine(gft,slb,px)==GIF_ERROR)	mgrflush;
							m_rend_gif_decodecolormap(slb,lb,cmap,cmaps,px);
							memmove(fbptr,lb,px*3);
						}
					}
					else
					{
						for(j=0;j<4;j++)
						{
							fbptr=*buffer;
							for(i=0;i<py;i++,fbptr+=px*3)
							{
								if(DGifGetLine(gft,slb,px)==GIF_ERROR)	mgrflush;
								m_rend_gif_decodecolormap(slb,lb,cmap,cmaps,px);
								memmove(fbptr,lb,px*3);
							}
						}
					}
				}
				if(lb) free(lb);
				if(slb) free(slb);
				break;
			case EXTENSION_RECORD_TYPE:
				if(DGifGetExtension(gft,&extcode,&extension)==GIF_ERROR)	grflush;
				while(extension!=NULL)
					if(DGifGetExtensionNext(gft,&extension)==GIF_ERROR) grflush;
				break;
			default:
				break;
		}
	}
	while( rt!= TERMINATE_RECORD_TYPE );
	DGIFCLOSEFILE(gft);
	return(FH_ERROR_OK);
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
/************************************************************************
return NULL if error
http://www.imagemagick.org/Usage/anim_basics/#dispose
http://wwwcdf.pd.infn.it/libgif/gif89.txt
http://wwwcdf.pd.infn.it/libgif/gif_lib.html
************************************************************************/
static anim_t * giflib_load(SDL_Renderer * render, const char * filename)
{
	GifFileType * gif = NULL;
	int i = 0;
	int j = 0;
	int transparent = 0;
	unsigned char transparent_color = 0;
	int disposal = 0;
	int delay = 0;
	ColorMapObject * global_pal = NULL;
	ColorMapObject * pal = NULL;
	SDL_Surface* surf = NULL;
	SDL_Surface* prev_surf = NULL;
	int x = 0;
	int y = 0;
	int col = 0;
	int pix_index = 0;
	anim_t * anim = NULL;
	int render_width;
	int render_height;
	int frame_left = 0;
	int frame_top = 0;
	int frame_width = 0;
	int frame_height = 0;
	int allow_draw = 1;
	int error = 0;
	int ret;

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

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

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

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

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

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

	global_pal = gif->SColorMap;
	pal = global_pal;

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

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

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

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

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

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

		/* Prepare next rendering depending of disposal */
		allow_draw = 1;
		switch( disposal ) {
		/* Do not touch render for next frame */
		case DISPOSE_DO_NOT:
			allow_draw = 0;
			break;
		case DISPOSE_BACKGROUND:
			/* Draw transparent color in frame */
			for(y=0; y<frame_height; y++) {
				for(x=0; x<frame_width; x++) {
					pix_index = ((x+frame_left)+((y+frame_top)*render_width))*4;
					((char*)surf->pixels)[pix_index+3] = 0;
					((char*)surf->pixels)[pix_index+2] = 0;
					((char*)surf->pixels)[pix_index+1] = 0;
					((char*)surf->pixels)[pix_index+0] = 0;
				}
			}
			break;
		case DISPOSE_PREVIOUS:
			/* Restore previous render in frame*/
			memcpy(surf->pixels,prev_surf->pixels, render_height * render_width * 4);
			break;
		default:
			break;
		}
	}
Ejemplo n.º 15
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, Error, NumFiles, ExtCode, CodeSize, ImageNum = 0,
	ImageFlag = FALSE, ImageNFlag = FALSE, ImageN, ImageX1, ImageY1,
	ImageX2, ImageY2, ImageWidth, ImageDepth,
	Complement = FALSE, HelpFlag = FALSE;
    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, &Complement,
		&ImageFlag, &ImageX1, &ImageY1, &ImageX2, &ImageY2,
		&ImageNFlag, &ImageN, &ImageX1, &ImageY1, &ImageX2, &ImageY2,
		&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);
    }

    /* Test to make sure exactly one of ImageFlag & ImageNFlag is set: */
    if ((ImageFlag && ImageNFlag) || (!ImageFlag && !ImageNFlag)) {
	GIF_MESSAGE("Exactly one of [-i ...] && [-n ...] please.");
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }
    if (ImageFlag) ImageN = 1;		    /* Its first image we are after. */

    /* Make sure the first coordinates of clipping box are smaller: */
    if (ImageX1 > ImageX2) {
	i = ImageX1;
	ImageX1 = ImageX2;
	ImageX2 = i;
    }
    if (ImageY1 > ImageY2) {
	i = ImageX1;
	ImageY1 = ImageY2;
	ImageY2 = i;
    }

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

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

    /* Width and depth of clipped image. */
    if (!Complement)
	ImageWidth = ImageX2 - ImageX1 + 1;
    else
	ImageWidth = GifFileIn->SWidth
	    - (ImageX2 != ImageX1) * (ImageX2 - ImageX1 + 1);
    if (!Complement)
	ImageDepth = ImageY2 - ImageY1 + 1;
    else
	ImageDepth = GifFileIn->SHeight
	    - (ImageY2 != ImageY1) * (ImageY2 - ImageY1 + 1);

    /* And dump out exactly same screen information: */
    if (EGifPutScreenDesc(GifFileOut,
	GifFileIn->SWidth, GifFileIn->SHeight,
	GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
	GifFileIn->SColorMap) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);

    /* 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 (++ImageNum == ImageN) {
		    /* We can handle only non interlaced images here: */
		    if (GifFileIn->Image.Interlace)
			GIF_EXIT("Image to clip is interlaced - use GifInter first.");

		    /* This is the image we should clip - test sizes and     */
		    /* dump out new clipped screen descriptor if o.k.	     */
		    if (GifFileIn->Image.Width <= ImageX2 ||
			GifFileIn->Image.Height <= ImageY2)
			GIF_EXIT("Image is smaller than given clip dimensions.");

		    /* Put the image descriptor to out file: */
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			ImageWidth, ImageDepth,
			FALSE, GifFileIn->Image.ColorMap) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		    /* o.k. - read the image and clip it: */
		    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);

		    /* Skip lines below ImageY1: */
		    for (i = 0; i < ImageY1; i++) {
			if (DGifGetLine(GifFileIn, Line, GifFileIn->Image.Width)
			    == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);

			if (Complement) {
			    if (ImageX1 == ImageX2) {
				/* don't remove any vertical band */
				if (EGifPutLine(GifFileOut, Line,
						ImageWidth) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			    else
			    {
				if (EGifPutLine(GifFileOut, Line,
						ImageX1) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);

				if (EGifPutLine(GifFileOut,
						&Line[ImageX2 + 1],
						GifFileIn->SWidth - (ImageX2 + 1)
						) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			}

			GifQprintf("\b\b\b\b%-4d", i);
		    }

		    /* Clip the lines from ImageY1 to ImageY2 (to X1 - X2): */
		    for (i = ImageY1; i <= ImageY2; i++) {
			if (DGifGetLine(GifFileIn, Line, GifFileIn->Image.Width)
			    == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);

			if (!Complement)
			    if (EGifPutLine(GifFileOut, &Line[ImageX1],
					    ImageWidth) == GIF_ERROR)
				QuitGifError(GifFileIn, GifFileOut);

			GifQprintf("\b\b\b\b%-4d", i);
		    }

		    /* Skip lines above ImageY2: */
		    for (i = ImageY2 + 1; i < GifFileIn->Image.Height; i++) {
			if (DGifGetLine(GifFileIn, Line, GifFileIn->Image.Width)
			    == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);

			if (Complement) {
			    if (ImageX1 == ImageX2) {
				/* don't remove any vertical band */
				if (EGifPutLine(GifFileOut, Line,
						ImageWidth) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			    else
			    {
				if (EGifPutLine(GifFileOut, Line,
						ImageX1) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);

				if (EGifPutLine(GifFileOut,
						&Line[ImageX2 + 1],
						GifFileIn->SWidth - (ImageX2 + 1)
						) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			}

			GifQprintf("\b\b\b\b%-4d", i);
		    }

		    free((char *) Line);
		}
		else {
		    /* Copy the image as is (we dont modify this one): */
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height,
			GifFileIn->Image.Interlace,
			GifFileIn->Image.ColorMap) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		    /* 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
		     || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL)
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
			    EGifPutCodeNext(GifFileOut, 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);
		if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
							Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		/* No support to more than one extension blocks, so discard: */
		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);

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

    return 0;
}
Ejemplo n.º 16
0
void ProcessGif::read_image(char file_name[], cv::Mat **image)
{
	GifFileType *gif_image = NULL;
	GifRowType *ScreenBuffer = NULL;
	int size_of_each_row = 0, BackGround = 0, i, j, Row = 0, Col = 0, Width = 0, Height = 0,
			ImageNum = 0, ExtCode, Count, img_width = 0, img_height = 0,
			InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
		    InterlacedJumps[] = { 8, 8, 4, 2 };    /* be read - offsets and jumps... */;
	ColorMapObject *ColorMap;
	GifRowType GifRow;
	static GifColorType *ColorMapEntry;
	GifRecordType RecordType;
	GifByteType *Extension;
	unsigned char *BufferP, *image_buffer;

	gif_image = DGifOpenFileName(file_name);

	img_height = gif_image->SHeight;
	img_width = gif_image->SWidth;

	image_buffer = new unsigned char[img_height * img_width * 3];

	if ((ScreenBuffer = (GifRowType *) malloc(img_height * sizeof(GifRowType *))) == NULL)
		GIF_EXIT("Failed to allocate memory required, aborted.");

	size_of_each_row = img_width * sizeof(GifPixelType);/* Size in bytes one row.*/
	if ((ScreenBuffer[0] = (GifRowType) malloc(size_of_each_row)) == NULL) /* First row. */
		GIF_EXIT("Failed to allocate memory required, aborted.");

	for (i = 0; i < gif_image->SWidth; i++)  /* Set first row's color to BackGround. */
		ScreenBuffer[0][i] = gif_image->SBackGroundColor;

	for (i = 1; i < img_height; i++)
	{
		/* Allocate the other rows, and set their color to background too: */
		if ((ScreenBuffer[i] = (GifRowType) malloc(size_of_each_row)) == NULL)
			GIF_EXIT("Failed to allocate memory required, aborted.");

		memcpy(ScreenBuffer[i], ScreenBuffer[0], size_of_each_row);
	}

	/* Scan the content of the GIF file and load the image(s) in: */
	do {
		if (DGifGetRecordType(gif_image, &RecordType) == GIF_ERROR)
		{
			PrintGifError();
			exit(EXIT_FAILURE);
		}
		switch (RecordType) {
		case IMAGE_DESC_RECORD_TYPE:
			if (DGifGetImageDesc(gif_image) == GIF_ERROR)
			{
				PrintGifError();
				exit(EXIT_FAILURE);
			}

			Row = gif_image->Image.Top; /* Image Position relative to Screen. */
			Col = gif_image->Image.Left;
			Width = gif_image->Image.Width;
			Height = gif_image->Image.Height;

			if (gif_image->Image.Left + gif_image->Image.Width > gif_image->SWidth ||
					gif_image->Image.Top + gif_image->Image.Height > gif_image->SHeight)
			{
				fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n",ImageNum);
				exit(EXIT_FAILURE);
			}
			if (gif_image->Image.Interlace) {
				/* Need to perform 4 passes on the images: */
				for (Count = i = 0; i < 4; i++)
					for (j = Row + InterlacedOffset[i]; j < Row + Height; j += InterlacedJumps[i])
					{
						if (DGifGetLine(gif_image, &ScreenBuffer[j][Col], Width) == GIF_ERROR)
						{
							PrintGifError();
							exit(EXIT_FAILURE);
						}
					}
			}
			else {
				for (i = 0; i < Height; i++) {
					if (DGifGetLine(gif_image, &ScreenBuffer[Row++][Col], Width) == GIF_ERROR)
					{
						PrintGifError();
						exit(EXIT_FAILURE);
					}
				}
			}
			break;
		case EXTENSION_RECORD_TYPE:
			/* Skip any extension blocks in file: */
			if (DGifGetExtension(gif_image, &ExtCode, &Extension) == GIF_ERROR)
			{
				PrintGifError();
				exit(EXIT_FAILURE);
			}
			while (Extension != NULL) {
				if (DGifGetExtensionNext(gif_image, &Extension) == GIF_ERROR)
				{
					PrintGifError();
					exit(EXIT_FAILURE);
				}
			}
			break;
		case TERMINATE_RECORD_TYPE:
			break;
		default:		    /* Should be traps by DGifGetRecordType. */
			break;
		}
	} while (RecordType != TERMINATE_RECORD_TYPE);

	BackGround = gif_image->SBackGroundColor;
	ColorMap = (gif_image->Image.ColorMap
			? gif_image->Image.ColorMap
					: gif_image->SColorMap);
	if (ColorMap == NULL)
	{
		fprintf(stderr, "Gif Image does not have a colormap\n");
		exit(EXIT_FAILURE);
	}

	for (i = 0, BufferP = image_buffer; i < img_height; i++)
	{
		GifRow = ScreenBuffer[i];

		for (j = 0; j < img_width; j++) {
			ColorMapEntry = &ColorMap->Colors[GifRow[j]];
			*BufferP++ = ColorMapEntry->Red;
			*BufferP++ = ColorMapEntry->Green;
			*BufferP++ = ColorMapEntry->Blue;
		}

		free(ScreenBuffer[i]);
	}

	free(ScreenBuffer);

	DGifCloseFile(gif_image);

	(*image) = new cv::Mat(cv::Size(img_width, img_height), CV_8UC3, image_buffer);

	convert_to_binary(image);
}
Ejemplo n.º 17
0
/*
 * Partially based on code in gif2rgb from giflib, by Gershon Elber.
 */
RImage*
RLoadGIF(RContext *context, char *file, int index)
{
    RImage *image = NULL;
    unsigned char *cptr;
    GifFileType *gif = NULL;
    GifPixelType *buffer = NULL;
    int i, j, k;
    int width, height;
    GifRecordType recType;
    ColorMapObject *colormap;
    unsigned char rmap[256];
    unsigned char gmap[256];
    unsigned char bmap[256];

    if (index < 0)
        index = 0;

    /* default error message */
    RErrorCode = RERR_BADINDEX;

    gif = DGifOpenFileName(file);

    if (!gif) {
        switch (GifLastError()) {
        case D_GIF_ERR_OPEN_FAILED:
            RErrorCode = RERR_OPEN;
            break;
        case D_GIF_ERR_READ_FAILED:
            RErrorCode = RERR_READ;
            break;
        default:
            RErrorCode = RERR_BADIMAGEFILE;
            break;
        }
        return NULL;
    }

    if (gif->SWidth<1 || gif->SHeight<1) {
        DGifCloseFile(gif);
        RErrorCode = RERR_BADIMAGEFILE;
        return NULL;
    }

    colormap = gif->SColorMap;

    i = 0;

    do {
        int extCode;
        GifByteType *extension;

        if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
            goto giferr;
        }
        switch (recType) {
        case IMAGE_DESC_RECORD_TYPE:
            if (i++ != index)
                break;

            if (DGifGetImageDesc(gif)==GIF_ERROR) {
                goto giferr;
            }

            width = gif->Image.Width;
            height = gif->Image.Height;

            if (gif->Image.ColorMap)
                colormap = gif->Image.ColorMap;

            /* the gif specs talk about a default colormap, but it
             * doesnt say what the heck is this default colormap */
            if (!colormap) {
                /*
                 * Well, since the spec says the colormap can be anything,
                 * lets just render it with whatever garbage the stack
                 * has :)
                 *

                 goto bye;
                 */
            } else {
                for (j = 0; j < colormap->ColorCount; j++) {
                    rmap[j] = colormap->Colors[j].Red;
                    gmap[j] = colormap->Colors[j].Green;
                    bmap[j] = colormap->Colors[j].Blue;
                }
            }

            buffer = malloc(width * sizeof(GifColorType));
            if (!buffer) {
                RErrorCode = RERR_NOMEMORY;
                goto bye;
            }

            image = RCreateImage(width, height, False);
            if (!image) {
                goto bye;
            }

            if (gif->Image.Interlace) {
                int l;
                int pelsPerLine;

                if (RRGBAFormat==image->format)
                    pelsPerLine = width * 4;
                else
                    pelsPerLine = width * 3;

                for (j = 0; j < 4; j++) {
                    for (k = InterlacedOffset[j]; k < height;
                         k += InterlacedJumps[j]) {
                        if (DGifGetLine(gif, buffer, width)==GIF_ERROR) {
                            goto giferr;
                        }
                        cptr = image->data + (k*pelsPerLine);
                        for (l = 0; l < width; l++) {
                            int pixel = buffer[l];
                            *cptr++ = rmap[pixel];
                            *cptr++ = gmap[pixel];
                            *cptr++ = bmap[pixel];
                        }
                    }
                }
            } else {
                cptr = image->data;
                for (j = 0; j < height; j++) {
                    if (DGifGetLine(gif, buffer, width)==GIF_ERROR) {
                        goto giferr;
                    }
                    for (k = 0; k < width; k++) {
                        int pixel = buffer[k];
                        *cptr++ = rmap[pixel];
                        *cptr++ = gmap[pixel];
                        *cptr++ = bmap[pixel];
                        if (RRGBAFormat==image->format)
                            cptr++;
                    }
                }
            }
            break;

        case EXTENSION_RECORD_TYPE:
            /* skip all extension blocks */
            if (DGifGetExtension(gif, &extCode, &extension)==GIF_ERROR) {
                goto giferr;
            }
            while (extension) {
                if (DGifGetExtensionNext(gif, &extension)==GIF_ERROR) {
                    goto giferr;
                }
            }
            break;

        default:
            break;
        }
    } while (recType != TERMINATE_RECORD_TYPE && i <= index);

    /* yuck! */
    goto did_not_get_any_errors;
giferr:
    switch (GifLastError()) {
    case D_GIF_ERR_OPEN_FAILED:
        RErrorCode = RERR_OPEN;
        break;
    case D_GIF_ERR_READ_FAILED:
        RErrorCode = RERR_READ;
        break;
    default:
        RErrorCode = RERR_BADIMAGEFILE;
        break;
    }
bye:
    if (image)
        RReleaseImage(image);
    image = NULL;
did_not_get_any_errors:

    if (buffer)
        free(buffer);

    if (gif)
        DGifCloseFile(gif);

    return image;
}
Ejemplo n.º 18
0
/******************************************************************************
 Interpret the command line and scan the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
    int	NumFiles, ExtCode, CodeSize, ImageNum = 0, 
	ImageN, HasGIFOutput, ErrorCode;
    bool Error, ImageNFlag = false, HelpFlag = false;
    GifRecordType RecordType;
    GifByteType *Extension, *CodeBlock;
    char **FileName = NULL, *ColorFileName, *TranslateFileName;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &SaveFlag, 
		&TranslateFlag, &TranslateFileName,
		&LoadFlag, &ColorFileName,
		&GammaFlag, &Gamma, &ImageNFlag, &ImageN,
		&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) {
	(void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    if (SaveFlag + LoadFlag + GammaFlag + TranslateFlag > 1)
	GIF_EXIT("Can not handle more than one of -s -l, -t, or -g at the same time.");

    /* Default action is to dump colormaps */
    if (!SaveFlag && !LoadFlag && !GammaFlag && !TranslateFlag)
	SaveFlag = true;

    if (NumFiles == 1) {
	if ((GifFileIn = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) {
	    PrintGifError(ErrorCode);
	    exit(EXIT_FAILURE);
	}
    }
    else {
	/* Use stdin instead: */
	if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
	    PrintGifError(ErrorCode);
	    exit(EXIT_FAILURE);
	}
    }

    if (SaveFlag) {
	/* We are dumping out the color map as text file to stdout: */
	ColorFile = stdout;
    }
    else {
	if (TranslateFlag) {
	    /* We are loading new color map from specified file: */
	    if ((TranslateFile = fopen(TranslateFileName, "rt")) == NULL)
		GIF_EXIT("Failed to open specified color translation file.");
	}

	if (LoadFlag) {
	    /* We are loading new color map from specified file: */
	    if ((ColorFile = fopen(ColorFileName, "rt")) == NULL)
		GIF_EXIT("Failed to open specified color map file.");
	}
    }

    if ((HasGIFOutput = (LoadFlag || TranslateFlag || GammaFlag)) != 0) {
	/* Open stdout for GIF output file: */
	if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
	    PrintGifError(ErrorCode);
	    exit(EXIT_FAILURE);
	}
    }

    if (!ImageNFlag) {
	/* We are suppose to modify the screen color map, so do it: */
	// cppcheck-suppress nullPointer
	GifFileIn->SColorMap = ModifyColorMap(GifFileIn->SColorMap);
	if (!HasGIFOutput) {
	    /* We can quit here, as we have the color map: */
	    if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
	    fclose(ColorFile);
	    exit(EXIT_SUCCESS);
	}
    }
    /* And dump out its new possible repositioned screen information: */
    if (HasGIFOutput)
	if (EGifPutScreenDesc(GifFileOut,
	    GifFileIn->SWidth, GifFileIn->SHeight,
	    GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
	    GifFileIn->SColorMap) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

    /* 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 ((++ImageNum == ImageN) && ImageNFlag) {
		    /* We are suppose to modify this image color map, do it: */
		    GifFileIn->SColorMap =ModifyColorMap(GifFileIn->SColorMap);
		    if (!HasGIFOutput) {
			/* We can quit here, as we have the color map: */
			if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
			fclose(ColorFile);
			exit(EXIT_SUCCESS);
		    }
		}
		if (HasGIFOutput)
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height,
			GifFileIn->Image.Interlace,
			GifFileIn->Image.ColorMap) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		if (!TranslateFlag || (ImageNFlag && (ImageN != ImageNum)))
		{
		    /* Now read image itself in decoded form as we don't */
		    /* really care what we have there, and this is much  */
		    /* faster.						 */
		    if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    if (HasGIFOutput)
			if (EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL) {
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
			if (HasGIFOutput)
			    if (EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
				QuitGifError(GifFileIn, GifFileOut);
		    }
		}
		else	/* we need to mung pixels intices */
		{
		    int	i;
		    register GifPixelType *cp;

		    GifPixelType *Line
			= (GifPixelType *) malloc(GifFileIn->Image.Width *
						  sizeof(GifPixelType));
		    for (i = 0; i < GifFileIn->Image.Height; i++) {
			if (DGifGetLine(GifFileIn, Line,GifFileIn->Image.Width)
			    == GIF_ERROR) {
			    QuitGifError(GifFileIn, GifFileOut);
			}

			/* translation step goes here */
			for (cp = Line; cp < Line+GifFileIn->Image.Width; cp++)
			    *cp = Translation[*cp];

			if (EGifPutLine(GifFileOut,
					Line, GifFileIn->Image.Width)
			    == GIF_ERROR) {
			    QuitGifError(GifFileIn, GifFileOut);
			}
		    }
		    free((char *) Line);
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		assert(GifFileOut != NULL);	/* might pacify Coverity */
		/* pass through extension records */
		if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (EGifPutExtensionBlock(GifFileOut, 
					  Extension[0],
					  Extension + 1) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFileIn, &Extension)==GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    if (Extension != NULL)
			if (EGifPutExtensionBlock(GifFileOut, 
						  Extension[0],
						  Extension + 1) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
		}
		if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be trapped by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

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

    return 0;
}
Ejemplo n.º 19
0
/******************************************************************************
* Perform the assembly operation - take few input files into one output.      *
******************************************************************************/
static void DoAssembly(int NumFiles, char **FileNames)
{
    int	i, ExtCode, CodeSize;
    GifRecordType RecordType;
    GifByteType *Extension, *CodeBlock;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

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

    /* Scan the content of the GIF file and load the image(s) in: */
    for (i = 0; i < NumFiles; i++) {
	if ((GifFileIn = DGifOpenFileName(FileNames[i])) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);

	/* And dump out screen descriptor iff its first image.	*/
	if (i == 0)
	    if (EGifPutScreenDesc(GifFileOut,
		GifFileIn -> SWidth, GifFileIn -> SHeight,
		GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
		GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR)
		QuitGifError(GifFileIn, GifFileOut);

	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);
		    /* Put image descriptor to out file: */
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn -> ILeft, GifFileIn -> ITop,
			GifFileIn -> IWidth, GifFileIn -> IHeight,
			GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
			GifFileIn -> IColorMap) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		    /* Now read image itself in decoded form as we dont      */
		    /* dont care what is there, and this is much faster.     */
		    if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR
		     || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL)
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
			    EGifPutCodeNext(GifFileOut, 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);
		    if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
						       Extension) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		    /* No support to more than one extension blocks, discard.*/
		    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);

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

    if (EGifCloseFile(GifFileOut) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);
}
Ejemplo n.º 20
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
void main(int argc, char **argv)
{
    int	i, j, Error, NumFiles, ImageNum = 0, Size, Row, Col, Width, Height,
        ExtCode, Count;
    GifRecordType RecordType;
    GifByteType *Extension;
    char **FileName = NULL;
    GifRowType *ScreenBuffer;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifQuitePrint, &PosFlag, &XPosX, &XPosY,
	        &DisplayFlag, &DisplayName, &ForceFlag,
		&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(1);
    }

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

    if (NumFiles == 1) {
	if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
	    PrintGifError();
	    exit(-1);
	}
    }
    else {
	/* Use the stdin instead: */

#ifdef __MSDOS__
	setmode(0, O_BINARY);
#endif /* __MSDOS__ */
	if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
	    PrintGifError();
	    exit(-1);
	}
    }

    /* Lets see if we can get access to the X server before we even start: */
    if ((XDisplay = (Display *) XOpenDisplay(DisplayName)) == NULL)
	GIF_EXIT("Failed to access X server, abored.");
    XScreen = DefaultScreen(XDisplay);
    Xroot = RootWindow(XDisplay, XScreen);
    XColorMap = DefaultColormap(XDisplay, XScreen);
    XGraphContext = DefaultGC(XDisplay, XScreen);
    XVisual = DefaultVisual(XDisplay, XScreen);
    XSetBackground(XDisplay, XGraphContext, BlackPixel(XDisplay, XScreen));
    XSetForeground(XDisplay, XGraphContext, WhitePixel(XDisplay, XScreen));

    /* Allocate the screen as vector of column of rows. We cannt allocate    */
    /* the all screen at once, as this broken minded CPU can allocate up to  */
    /* 64k at a time and our image can be bigger than that:		     */
    /* Note this screen is device independent - its the screen as defined by */
    /* the GIF file parameters itself.					     */
    if ((ScreenBuffer = (GifRowType *)
	malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");

    Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
    if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
	GIF_EXIT("Failed to allocate memory required, aborted.");

    for (i = 0; i < GifFile -> SWidth; i++)  /* Set its color to BackGround. */
	ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
    for (i = 1; i < GifFile -> SHeight; i++) {
	/* Allocate the other rows, and set their color to background too: */
	if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");

	memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
    }

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
	    PrintGifError();
	    exit(-1);
	}
	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
		    PrintGifError();
		    exit(-1);
		}
		Row = GifFile -> ITop; /* Image Position relative to Screen. */
		Col = GifFile -> ILeft;
		Width = GifFile -> IWidth;
		Height = GifFile -> IHeight;
		GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
		    PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
		if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
		   GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
		    fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
		    exit(-2);
		}
		if (GifFile -> IInterlace) {
		    /* Need to perform 4 passes on the images: */
		    for (Count = i = 0; i < 4; i++)
			for (j = Row + InterlacedOffset[i]; j<Row + Height;
						 j += InterlacedJumps[i]) {
			    GifQprintf("\b\b\b\b%-4d", Count++);
			    if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
				Width) == GIF_ERROR) {
				PrintGifError();
				exit(-1);
			    }
			}
		}
		else {
		    for (i = 0; i < Height; i++) {
			GifQprintf("\b\b\b\b%-4d", i);
			if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
				Width) == GIF_ERROR) {
			    PrintGifError();
			    exit(-1);
			}
		    }
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
		    PrintGifError();
		    exit(-1);
		}
		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
			PrintGifError();
			exit(-1);
		    }
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    /* Lets display it - set the global variables required and do it: */
    BackGround = GifFile -> SBackGroundColor;
    ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
				       GifFile -> SColorMap);
    ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
				                GifFile -> SBitsPerPixel);
    Screen2X(argc, argv, ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);

    if (DGifCloseFile(GifFile) == GIF_ERROR) {
	PrintGifError();
	exit(-1);
    }
    GifQprintf("\n");
}
Ejemplo n.º 21
0
/* Originally based on, but in its current form merely inspired by Imlib2's
 * src/modules/loaders/loader_gif.c:load(), written by Carsten Haitzler.
 */
bool img_load_gif(img_t *img, const fileinfo_t *file) {
	GifFileType *gif;
	GifRowType *rows = NULL;
	GifRecordType rec;
	ColorMapObject *cmap;
	DATA32 bgpixel, *data, *ptr;
	DATA32 *prev_frame = NULL;
	Imlib_Image *im;
	int i, j, bg, r, g, b;
	int x, y, w, h, sw, sh;
	int intoffset[] = { 0, 4, 2, 1 };
	int intjump[] = { 8, 8, 4, 2 };
	int transp = -1;
	unsigned int delay = 0;
	bool err = false;

	if (img->multi.cap == 0) {
		img->multi.cap = 8;
		img->multi.frames = (img_frame_t*)
		                    s_malloc(sizeof(img_frame_t) * img->multi.cap);
	}
	img->multi.cnt = 0;
	img->multi.sel = 0;

	gif = DGifOpenFileName(file->path);
	if (gif == NULL) {
		warn("could not open gif file: %s", file->name);
		return false;
	}
	bg = gif->SBackGroundColor;
	sw = gif->SWidth;
	sh = gif->SHeight;

	do {
		if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
			err = true;
			break;
		}
		if (rec == EXTENSION_RECORD_TYPE) {
			int ext_code;
			GifByteType *ext = NULL;

			DGifGetExtension(gif, &ext_code, &ext);
			while (ext) {
				if (ext_code == 0xf9) {
					if (ext[1] & 1)
						transp = (int) ext[4];
					else
						transp = -1;

					delay = 10 * ((unsigned int) ext[3] << 8 | (unsigned int) ext[2]);
					if (delay)
						delay = MAX(delay, MIN_GIF_DELAY);

					/* TODO: handle disposal method, section 23.c.iv of
					         http://www.w3.org/Graphics/GIF/spec-gif89a.txt */
				}
				ext = NULL;
				DGifGetExtensionNext(gif, &ext);
			}
		} else if (rec == IMAGE_DESC_RECORD_TYPE) {
			if (DGifGetImageDesc(gif) == GIF_ERROR) {
				err = true;
				break;
			}
			x = gif->Image.Left;
			y = gif->Image.Top;
			w = gif->Image.Width;
			h = gif->Image.Height;

			rows = (GifRowType*) s_malloc(h * sizeof(GifRowType));
			for (i = 0; i < h; i++)
				rows[i] = (GifRowType) s_malloc(w * sizeof(GifPixelType));
			if (gif->Image.Interlace) {
				for (i = 0; i < 4; i++) {
					for (j = intoffset[i]; j < h; j += intjump[i])
						DGifGetLine(gif, rows[j], w);
				}
			} else {
				for (i = 0; i < h; i++)
					DGifGetLine(gif, rows[i], w);
			}

			ptr = data = (DATA32*) s_malloc(sizeof(DATA32) * sw * sh);
			cmap = gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap;
			r = cmap->Colors[bg].Red;
			g = cmap->Colors[bg].Green;
			b = cmap->Colors[bg].Blue;
			bgpixel = 0x00ffffff & (r << 16 | g << 8 | b);

			for (i = 0; i < sh; i++) {
				for (j = 0; j < sw; j++) {
					if (i < y || i >= y + h || j < x || j >= x + w ||
					    rows[i-y][j-x] == transp)
					{
						if (prev_frame != NULL)
							*ptr = prev_frame[i * sw + j];
						else
							*ptr = bgpixel;
					} else {
						r = cmap->Colors[rows[i-y][j-x]].Red;
						g = cmap->Colors[rows[i-y][j-x]].Green;
						b = cmap->Colors[rows[i-y][j-x]].Blue;
						*ptr = 0xff << 24 | r << 16 | g << 8 | b;
					}
					ptr++;
				}
			}

			im = imlib_create_image_using_copied_data(sw, sh, data);

			for (i = 0; i < h; i++)
				free(rows[i]);
			free(rows);
			free(data);

			if (im == NULL) {
				err = true;
				break;
			}

			imlib_context_set_image(im);
			prev_frame = imlib_image_get_data_for_reading_only();

			imlib_image_set_format("gif");
			if (transp >= 0)
				imlib_image_set_has_alpha(1);

			if (img->multi.cnt == img->multi.cap) {
				img->multi.cap *= 2;
				img->multi.frames = (img_frame_t*)
				                    s_realloc(img->multi.frames,
				                              img->multi.cap * sizeof(img_frame_t));
			}
			img->multi.frames[img->multi.cnt].im = im;
			img->multi.frames[img->multi.cnt].delay = delay ? delay : GIF_DELAY;
			img->multi.cnt++;
		}
	} while (rec != TERMINATE_RECORD_TYPE);

	DGifCloseFile(gif);

	if (err && !file->loaded)
		warn("corrupted gif file: %s", file->name);

	if (img->multi.cnt > 1) {
		imlib_context_set_image(img->im);
		imlib_free_image();
		img->im = img->multi.frames[0].im;
		img->multi.animate = GIF_AUTOPLAY;
	} else if (img->multi.cnt == 1) {
		imlib_context_set_image(img->multi.frames[0].im);
		imlib_free_image();
		img->multi.cnt = 0;
		img->multi.animate = false;
	}

	imlib_context_set_image(img->im);

	return !err;
}
Ejemplo n.º 22
0
LICE_IBitmap *LICE_LoadGIF(const char *filename, LICE_IBitmap *bmp, int *nframes)
{
  GifFileType *fp=DGifOpenFileName(filename);
  if (!fp)
    return 0;


  GifRecordType RecordType;
  GifByteType *Extension;
  int ExtCode;
  do 
  {
	  if (DGifGetRecordType(fp, &RecordType) == GIF_ERROR) 
    {
      DGifCloseFile(fp);
      return 0;
	  }
  	switch (RecordType) 
    {
	    case IMAGE_DESC_RECORD_TYPE:
		    if (DGifGetImageDesc(fp) == GIF_ERROR) 
        {
          DGifCloseFile(fp);
          return 0;
  		  }

        // todo: support transparency
        // todo: have it buffer all frames and output frame count
        if (nframes) *nframes=1; // placeholder 

        {
          int width=fp->Image.Width,height=fp->Image.Height;
          if (bmp)
          {
            bmp->resize(width,height);
            if (bmp->getWidth() != (int)width || bmp->getHeight() != (int)height) 
            {
              DGifCloseFile(fp);
              return 0;
            }
          }
          else bmp=new LICE_MemBitmap(width,height);

          LICE_pixel *bmpptr = bmp->getBits();
          int dbmpptr=bmp->getRowSpan();
          if (bmp->isFlipped())
          {
            bmpptr += dbmpptr*(bmp->getHeight()-1);
            dbmpptr=-dbmpptr;
          }
          GifPixelType *linebuf=(GifPixelType*)malloc(width*sizeof(GifPixelType));
          int y;
          int cmap[256];
          for (y=0;y<256;y++)
          {
            if (fp->SColorMap&&y<fp->SColorMap->ColorCount&&fp->SColorMap->Colors)
            {
              GifColorType *ct=fp->SColorMap->Colors+y;
              cmap[y]=LICE_RGBA(ct->Red,ct->Green,ct->Blue,255);
            }
            else cmap[y]=0;
          }

          for (y=0; y < height; y ++)
          {
            if (DGifGetLine(fp,linebuf,width)==GIF_ERROR) break;

            int x;
            for (x = 0; x < width; x ++)
            {
              bmpptr[x]=cmap[linebuf[x]&0xff];
            }
            bmpptr += dbmpptr;
          }



          free(linebuf);
          DGifCloseFile(fp);
          return bmp;
        }
  		break;
	    case EXTENSION_RECORD_TYPE:
    		if (DGifGetExtension(fp, &ExtCode, &Extension) == GIF_ERROR) 
        {
          DGifCloseFile(fp);
          return 0;
        }
    		while (Extension != NULL) 
        {
		      if (DGifGetExtensionNext(fp, &Extension) == GIF_ERROR) 
          {
            DGifCloseFile(fp);
            return 0;
  		    }
		    }
      break;
	    case TERMINATE_RECORD_TYPE:
  		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
	  	break;
	  }
  }
  while (RecordType != TERMINATE_RECORD_TYPE);

  DGifCloseFile(fp);
  return 0;

}
Ejemplo n.º 23
0
Archivo: rwgif.c Proyecto: schani/rwimg
void*
open_gif_file (const char *filename, int *width, int *height)
{
    int interlace_offset[] = { 0, 4, 2, 1 };
    int interlace_jump[] = { 8, 8, 4, 2 };    
    GifColorType *colormap;
    GifRecordType record_type;
    GifRowType *buffer = NULL;
    
    int i, j;
    int color_index;
    unsigned char *ptr = NULL;
                
    gif_data_t *data = (gif_data_t*)malloc(sizeof(gif_data_t));
    
    assert(data != 0);
    
    int error;
    data->file = DGifOpenFileName(filename, &error);
    
    assert(data->file !=0);
        
    do
    {
        assert(DGifGetRecordType(data->file, &record_type) != GIF_ERROR) ;

        switch (record_type)
        {
        case IMAGE_DESC_RECORD_TYPE:
            assert(DGifGetImageDesc(data->file) != GIF_ERROR);
            
            *width = data->file->Image.Width;
            *height = data->file->Image.Height;
            data->width = *width;
            data->height = *height;
            
            buffer = malloc(*height * sizeof(GifRowType *));
            assert(buffer != NULL);
            
            for (i = 0; i < *height; i++) 
            {
                buffer[i] = malloc(*width * sizeof(GifPixelType));
                assert(buffer[i] != NULL);
            }
            
            if (data->file->Image.Interlace)
            {
                for (i = 0; i < 4; i++)
                    for (j = interlace_offset[i]; j < *height; 
                         j += interlace_jump[i])
                        DGifGetLine(data->file, buffer[j], *width);
            }
            else
            {
                for (i = 0; i < *height; i++)
                    DGifGetLine(data->file, buffer[i], *width);
            }
            break;
        case EXTENSION_RECORD_TYPE:
        {
            /* Skip extension blocks */
            int ext_code;
            GifByteType *ext;
            assert(DGifGetExtension(data->file, &ext_code, &ext) != GIF_ERROR); 
            
            while (ext != NULL) 
            {
                assert(DGifGetExtensionNext(data->file, &ext) != GIF_ERROR); 
            }
        }
        break;
        case TERMINATE_RECORD_TYPE:
            break;
        default:
            fprintf(stderr, "unknown record type in GIF file\n");
            break;
        }
    } while (record_type != TERMINATE_RECORD_TYPE);
    
    
    colormap = (data->file->Image.ColorMap ? data->file->Image.ColorMap->Colors
                : data->file->SColorMap->Colors);

    data->rgb = (unsigned char*)malloc( (data->width* data->height * 3) );
    assert(data->rgb != NULL);
    
    ptr = data->rgb;
    
    for (j = 0; j < *height; j++)
    {
        for (i = 0; i < *width; i++)
        {
            color_index = (int) buffer[j][i];
            *ptr++ = (unsigned char) colormap[color_index].Red;
            *ptr++ = (unsigned char) colormap[color_index].Green;
            *ptr++ = (unsigned char) colormap[color_index].Blue;
        }
        free(buffer[j]);
    }
    free(buffer);
    
    assert(DGifCloseFile(data->file) == GIF_OK);
    
    return data;
}
Ejemplo n.º 24
0
pictw_t *
sgif_read(session_t *ps, const char *path) {
	assert(path);
	pictw_t *pictw = NULL;
	GifPixelType *data = NULL;
	unsigned char *tdata = NULL;

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

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

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

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

	return pictw;
}
Ejemplo n.º 25
0
int main (int argc, char **argv)
{
    // inverse flag
    int rflag = 0, mflag = 0, cflag = 0, ch;
    while ((ch = getopt (argc, argv, "rmc")) != -1)
    {
        switch (ch)
        {
        case 'r':
            rflag = 1;
            break;
        case 'm':
            mflag = 1;
            break;
        case 'c':
            cflag = 1;
            break;
        default:
            // print error and exit
            usage ();
            return 1;
        }
    }

    // adjust args array post-getopt
    argc -= optind;
    argv += optind;

    if (argv[0] == NULL)
    {
        // print error and exit
        fputs ("File name missing\n", stderr);
        usage ();
        return 1;
    }

    char *fname = argv[0];

    // open the GIF file
    GifFileType *SpriteGif;
    SpriteGif = DGifOpenFileName (fname);

    // check for error
    if (SpriteGif == NULL)
    {
        // print error and exit
        PrintGifError ();
        exit (1);
    }

    if (DGifSlurp (SpriteGif) == GIF_ERROR)
    {
        // print error and exit
        PrintGifError ();
        exit (1);
    }

    int rc; // return code
    if (cflag && mflag)
    {
        rc = DecodeMultiColorCharacterGraphics (SpriteGif);
    }
    else if (cflag)
    {
        rc = DecodeHiResCharacterGraphics (SpriteGif);
    }
    else if (mflag)
    {
        rc = DecodeMultiColorSpriteGraphics (SpriteGif);
    }
    else
    {
        rc = DecodeHiResSpriteGraphics (SpriteGif, rflag);
    }

    // close the file object
    if (DGifCloseFile (SpriteGif) == GIF_ERROR)
    {
        // print error and exit
        PrintGifError ();
        return 1;
    }

    return rc;
}
Ejemplo n.º 26
0
Archivo: gif.c Proyecto: McNeight/GLsat
int
read_gif(const char *filename, int *width, int *height, unsigned char **rgb)
{
    int interlace_offset[] = { 0, 4, 2, 1 };
    int interlace_jump[] = { 8, 8, 4, 2 };
    GifColorType *colormap;
    GifFileType *infile;
    GifRecordType record_type;
    GifRowType *buffer = NULL;

    int i, j;
    int color_index;
    unsigned char *ptr = NULL;

    infile = DGifOpenFileName(filename);

    if (infile == NULL)
    {
        PrintGifError();
        return(0);
    }

    do
    {
        if (DGifGetRecordType(infile, &record_type) == GIF_ERROR) 
        {
            PrintGifError();
            return(0);
        }

        switch (record_type)
        {
        case IMAGE_DESC_RECORD_TYPE:
            if (DGifGetImageDesc(infile) == GIF_ERROR)
            {
                PrintGifError();
                return(0);
            }

            *width = infile->Image.Width;
            *height = infile->Image.Height;

            buffer = malloc(*height * sizeof(GifRowType *));
            if (buffer == NULL)
            {
                fprintf(stderr, "Can't allocate memory for GIF file.\n");
                return(0);
            }
            
            for (i = 0; i < *height; i++) 
            {
                buffer[i] = malloc(*width * sizeof(GifPixelType));
                if (buffer[i] == NULL)
                {
                    fprintf(stderr, "Can't allocate memory for GIF line.\n");
                    return(0);
                }
            }
            
            if (infile->Image.Interlace)
            {
                for (i = 0; i < 4; i++)
                    for (j = interlace_offset[i]; j < *height; 
                         j += interlace_jump[i])
                        DGifGetLine(infile, buffer[j], *width);
            }
            else
            {
                for (i = 0; i < *height; i++)
                    DGifGetLine(infile, buffer[i], *width);
            }
            break;
        case EXTENSION_RECORD_TYPE:
        {
            /* Skip extension blocks */
            int ext_code;
            GifByteType *ext;
            if (DGifGetExtension(infile, &ext_code, &ext) == GIF_ERROR) 
            {
                PrintGifError();
                return(0);
            }
            while (ext != NULL) 
            {
                if (DGifGetExtensionNext(infile, &ext) == GIF_ERROR) 
                {
                    PrintGifError();
                    return(0);
                }
            }
        }
        break;
        case TERMINATE_RECORD_TYPE:
            break;
        default:
            fprintf(stderr, "unknown record type in GIF file\n");
            break;
        }
    } while (record_type != TERMINATE_RECORD_TYPE);

    colormap = (infile->Image.ColorMap ? infile->Image.ColorMap->Colors
                : infile->SColorMap->Colors);

    rgb[0] = malloc(3 * *width * *height);
    if (rgb[0] == NULL)
    {
        fprintf(stderr, "Can't allocate memory for GIF file.\n");
        return(0);
    }

    ptr = rgb[0];

    for (j = 0; j < *height; j++)
    {
        for (i = 0; i < *width; i++)
        {
            color_index = (int) buffer[j][i];
            *ptr++ = (unsigned char) colormap[color_index].Red;
            *ptr++ = (unsigned char) colormap[color_index].Green;
            *ptr++ = (unsigned char) colormap[color_index].Blue;
        }
        free(buffer[j]);
    }
    
    free(buffer);

    DGifCloseFile(infile);
    return(1);
}
Ejemplo n.º 27
0
static void Gif2Icon(char *FileName,
		     int fdin, int fdout,
		     char NameTable[])
{
    int i, ExtCode, ImageNum = 1;
    GifPixelType *Line, *cp;
    GifRecordType RecordType;
    GifByteType *Extension;
    GifFileType *GifFile;

    if (fdin == -1) {
	if ((GifFile = DGifOpenFileName(FileName)) == NULL) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
    }
    else {
	/* Use stdin instead: */
	if ((GifFile = DGifOpenFileHandle(fdin)) == NULL) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
    }

    printf("screen width %d\nscreen height %d\n",
	   GifFile->SWidth, GifFile->SHeight);

    printf("screen colors %d\nscreen background %d\n\n",
	   GifFile->SColorResolution,
	   GifFile->SBackGroundColor);

    if (GifFile->SColorMap)
    {
	if (GifFile->SColorMap->ColorCount >= (int)strlen(NameTable))
	{
	    (void) fprintf(stderr,
			   "%s: global color map has unprintable pixels\n",
			   FileName);
	    exit(EXIT_FAILURE);
	}

	printf("screen map\n");

	for (i = 0; i < GifFile->SColorMap->ColorCount; i++)
	    printf("\trgb %03d %03d %03d is %c\n",
		   GifFile->SColorMap ->Colors[i].Red,
		   GifFile->SColorMap ->Colors[i].Green,
		   GifFile->SColorMap ->Colors[i].Blue,
		   NameTable[i]);
	printf("end\n\n");
    }

    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
	switch (RecordType) {
	case IMAGE_DESC_RECORD_TYPE:
	    if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
		PrintGifError();
		exit(EXIT_FAILURE);
	    }
	    printf("image # %d\nimage left %d\nimage top %d\n",
		   ImageNum++,
		   GifFile->Image.Left, GifFile->Image.Top);
	    if (GifFile->Image.Interlace)
		printf("interlaced\n");

	    if (GifFile->Image.ColorMap)
	    {
		if (GifFile->Image.ColorMap->ColorCount >= (int)strlen(NameTable))
		{
		    (void) fprintf(stderr,
				   "%s: global color map has unprintable pixels\n",
				   FileName);
		    exit(EXIT_FAILURE);
		}

		printf("image map\n");

		for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++)
		    printf("\trgb %03d %03d %03d is %c\n",
			   GifFile->Image.ColorMap ->Colors[i].Red,
			   GifFile->Image.ColorMap ->Colors[i].Green,
			   GifFile->Image.ColorMap ->Colors[i].Blue,
			   NameTable[i]);
		printf("end\n\n");
	    }

	    printf("image bits %d by %d\n",
		   GifFile->Image.Width, GifFile->Image.Height);

	    Line = (GifPixelType *) malloc(GifFile->Image.Width *
					   sizeof(GifPixelType));
	    for (i = 0; i < GifFile->Image.Height; i++) {
		if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
		    == GIF_ERROR) {
		    PrintGifError();
		    exit(EXIT_FAILURE);
		}
		for (cp = Line; cp < Line + GifFile->Image.Width; cp++)
		    putchar(NameTable[*cp]);
		putchar('\n');
	    }
	    free((char *) Line);
	    putchar('\n');

	    break;
	case EXTENSION_RECORD_TYPE:
	    if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
		PrintGifError();
		exit(EXIT_FAILURE);
	    }

	    if (ExtCode == COMMENT_EXT_FUNC_CODE)
		printf("comment\n");
	    else if (ExtCode == PLAINTEXT_EXT_FUNC_CODE)
		printf("plaintext\n");
	    else if (isalpha(ExtCode))
		printf("extension %02x    # %c\n", ExtCode, ExtCode);
	    else
		printf("extension %02x\n", ExtCode);

	    while (Extension != NULL) {
		VisibleDumpBuffer((char *)(Extension + 1), Extension[0]);
		putchar('\n');

		if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
		    PrintGifError();
		    exit(EXIT_FAILURE);
		}
	    }
	    printf("end\n\n");

	    break;
	case TERMINATE_RECORD_TYPE:
	    break;
	default:		/* Should be traps by DGifGetRecordType */
	    break;
	}
    }
    while
	(RecordType != TERMINATE_RECORD_TYPE);

    /* Tell EMACS this is a picture... */
    printf("# The following sets edit modes for GNU EMACS\n");
    printf("# Local ");		/* ...break this up, so that EMACS doesn't */
    printf("Variables:\n");	/* get confused when visiting *this* file! */
    printf("# mode:picture\n");
    printf("# truncate-lines:t\n");
    printf("# End:\n");

    if (fdin == -1)
	(void) printf("# End of %s dump\n", FileName);

    if (DGifCloseFile(GifFile) == GIF_ERROR) {
	PrintGifError();
	exit(EXIT_FAILURE);
    }
}
Ejemplo n.º 28
0
bool
GIFInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec)
{
    GifColorType *local_colormap = NULL;

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

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

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

    if (! m_gif_file) {

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

        m_subimage = -1;

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

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

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

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

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

    return true;
}
Ejemplo n.º 29
0
/******************************************************************************
* Perform the disassembly operation - take one input files into few output.   *
******************************************************************************/
static int DoDisassemblyAll(const char *InFileName, char *OutFileName)
{
    int	ExtCode, CodeSize, FileNum = 0, FileEmpty;
    GifRecordType RecordType;
    char CrntFileName[80], *p;
    GifByteType *Extension, *CodeBlock;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
	int ErrorCode;

    /* If name has type postfix, strip it out, and make sure name is less    */
    /* or equal to 6 chars, so we will have 2 chars in name for numbers.     */
    //strupr(OutFileName);		      /* Make sure all is upper case */
    if ((p = strrchr(OutFileName, '.')) != NULL && strlen(p) <= 4) p[0] = 0;
    if ((p = strrchr(OutFileName, '/')) != NULL ||
	(p = strrchr(OutFileName, '\\')) != NULL ||
	(p = strrchr(OutFileName, ':')) != NULL) {
	if (strlen(p) > 7) p[7] = 0;   /* p includes the '/', '\\', ':' char */
    }
    else {
	/* Only name is given for current directory: */
	if (strlen(OutFileName) > 6) OutFileName[6] = 0;
    }

    /* Open input file: */
    if (InFileName != NULL) {
	if ((GifFileIn = DGifOpenFileName(InFileName, &ErrorCode)) == NULL)
	    return QuitGifError(GifFileIn, GifFileOut);
    }
    else {
	/* Use the stdin instead: */
	if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL)
	    return QuitGifError(GifFileIn, GifFileOut);
    }

    /* Scan the content of GIF file and dump image(s) to seperate file(s): */
    do {
	sprintf(CrntFileName, "%s%02d.gif", OutFileName, FileNum++);
	if ((GifFileOut = EGifOpenFileName(CrntFileName, TRUE, &ErrorCode)) == NULL)
	    return QuitGifError(GifFileIn, GifFileOut);
	FileEmpty = TRUE;

	/* And dump out its exactly same screen information: */
	if (EGifPutScreenDesc(GifFileOut,
	    GifFileIn->SWidth, GifFileIn->SHeight,
	    GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
	    GifFileIn->SColorMap) == GIF_ERROR)
	    return QuitGifError(GifFileIn, GifFileOut);

	do {
	    if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
			return QuitGifError(GifFileIn, GifFileOut);

	    switch (RecordType) {
		case IMAGE_DESC_RECORD_TYPE:
		    FileEmpty = FALSE;
		    if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);
		    /* Put same image descriptor to out file: */
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height,
			GifFileIn->Image.Interlace,
			GifFileIn->Image.ColorMap) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);

		    /* 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
		     || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL)
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
			    EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);
		    break;
		case EXTENSION_RECORD_TYPE:
		    FileEmpty = FALSE;
		    /* Skip any extension blocks in file: */
		    if (DGifGetExtension(GifFileIn, &ExtCode, &Extension)
			== GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);
		    if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
							Extension) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);

		    /* No support to more than one extension blocks, discard */
		    while (Extension != NULL)
			if (DGifGetExtensionNext(GifFileIn, &Extension)
			    == GIF_ERROR)
			    return QuitGifError(GifFileIn, GifFileOut);
		    break;
		case TERMINATE_RECORD_TYPE:
		    break;
		default:	     /* Should be traps by DGifGetRecordType */
		    break;
	    }
	}
	while (RecordType != IMAGE_DESC_RECORD_TYPE &&
	       RecordType != TERMINATE_RECORD_TYPE);

	if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR)
	    return QuitGifError(GifFileIn, GifFileOut);
	if (FileEmpty) {
	    /* Might happen on last file - delete it if so: */
	    unlink(CrntFileName);
	}
   	}
    while (RecordType != TERMINATE_RECORD_TYPE);

    if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
		return QuitGifError(GifFileIn, GifFileOut);
}
Ejemplo n.º 30
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
void main(int argc, char **argv)
{
    int	i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count;
    GifRecordType RecordType;
    GifByteType *Extension;
    char **FileName = NULL;
    GifRowType *ScreenBuffer;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifQuitePrint, &DitherFlag, &DitherSize,
		&BWThresholdFlag, &Threshold,
		&MappingFlag, &Mapping,	&InvertFlag,
		&NiceFlag, &PrinterFlag, &PrinterName, &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(1);
    }

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

    if (!PrinterFlag) PrinterName = "";

    if (DitherFlag) {
	/* Make sure we are o.k.: */
	if (DitherSize > DITHER_MAX_MATRIX) DitherSize = DITHER_MAX_MATRIX;
	if (DitherSize < DITHER_MIN_MATRIX) DitherSize = DITHER_MAX_MATRIX;
    }

    /* As Threshold is in [0..100] range and BWThreshold is [0..25500]: */
    if (BWThresholdFlag) {
	if (Threshold > 100 || Threshold < 0)
	    GIF_EXIT("Threshold not in 0..100 percent.");
	BWThreshold = Threshold * 255;
	if (BWThreshold == 0) BWThreshold = 1;   /* Overcome divide by zero! */
    }

    /* No message is emitted, but mapping method is clipped to exists method.*/
    if (MappingFlag) ColorToBWMapping = Mapping % C2BW_NUM_METHODS;

    if (NumFiles == 1) {
	if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
	    PrintGifError();
	    exit(-1);
	}
    }
    else {
	/* Use the stdin instead: */

#ifdef __MSDOS__
	setmode(0, O_BINARY);
#endif /* __MSDOS__ */
	if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
	    PrintGifError();
	    exit(-1);
	}
    }

    /* Allocate the screen as vector of column of rows. We cannt allocate    */
    /* the all screen at once, as this broken minded CPU can allocate up to  */
    /* 64k at a time and our image can be bigger than that:		     */
    /* Note this screen is device independent - its the screen as defined by */
    /* the GIF file parameters itself.					     */
    if ((ScreenBuffer = (GifRowType *)
	malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");

    Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
    if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
	GIF_EXIT("Failed to allocate memory required, aborted.");

    for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
	ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
    for (i = 1; i < GifFile -> SHeight; i++) {
	/* Allocate the other rows, andset their color to background too:   */
	if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.\n");

	memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
    }

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
	    PrintGifError();
	    exit(-1);
	}
	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
		    PrintGifError();
		    exit(-1);
		}
		Row = GifFile -> ITop; /* Image Position relative to Screen. */
		Col = GifFile -> ILeft;
		Width = GifFile -> IWidth;
		Height = GifFile -> IHeight;
		GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
		    PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
		if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
		   GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
		    fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
		    exit(-2);
		}
		if (GifFile -> IInterlace) {
		    /* Need to perform 4 passes on the images: */
		    for (Count = i = 0; i < 4; i++)
			for (j = Row + InterlacedOffset[i]; j < Row + Height;
						 j += InterlacedJumps[i]) {
			    GifQprintf("\b\b\b\b%-4d", Count++);
			    if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
				Width) == GIF_ERROR) {
				PrintGifError();
				exit(-1);
			    }
			}
		}
		else {
		    for (i = 0; i < Height; i++) {
			GifQprintf("\b\b\b\b%-4d", i);
			if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
				Width) == GIF_ERROR) {
			    PrintGifError();
			    exit(-1);
			}
		    }
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
		    PrintGifError();
		    exit(-1);
		}
		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
			PrintGifError();
			exit(-1);
		    }
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    /* Lets display it - set the global variables required and do it: */
    BackGround = GifFile -> SBackGroundColor;
    ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
				       GifFile -> SColorMap);
    DumpScreen2Epsn(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);

    if (DGifCloseFile(GifFile) == GIF_ERROR) {
	PrintGifError();
	exit(-1);
    }
}