示例#1
0
/******************************************************************************
* Handle last GIF error. Try to close the file and free all allocated memory. *
******************************************************************************/
static int HandleGifError(GifFileType *GifFile)
{
    int i = GifLastError();

    if (EGifCloseFile(GifFile) == GIF_ERROR) {
	GifLastError();
    }
    return i;
}
示例#2
0
static int gif_err(GifFileType *gf)
{
#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
	return gf->Error;
#else
	(void) gf;
	return GifLastError();
#endif
}
示例#3
0
void
GIFInput::report_last_error (void)
{
    // N.B. Only GIFLIB_MAJOR >= 5 looks properly thread-safe, in that the
    // error is guaranteed to be specific to this open file.  We use a  spin
    // mutex to prevent a thread clash for older versions, but it still
    // appears to be a global call, so we can't be absolutely sure that the
    // error was for *this* file.  So if you're using giflib prior to
    // version 5, beware.
#if GIFLIB_MAJOR >= 5
    error ("%s", GifErrorString (m_gif_file->Error));
#elif GIFLIB_MAJOR == 4 && GIFLIB_MINOR >= 2
    spin_lock lock (gif_error_mutex);
    error ("%s", GifErrorString());
#else
    spin_lock lock (gif_error_mutex);
    error ("GIF error %d", GifLastError());
#endif
}
示例#4
0
/******************************************************************************
* Interpret the command line, prepar global data and call the Gif routines.   *
******************************************************************************/
void main(int argc, char **argv)
{
    int	Error, NumFiles, ImageWidth, ImageHeight, Dummy, Red, Green, Blue,
	ColorMapSize, InFileHandle,
	ImageSizeFlag = FALSE, ColorMapFlag = FALSE, HelpFlag = FALSE;
    char **FileName = NULL, *ColorMapFile;
    GifColorType *ColorMap;
    FILE *InColorMapFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
		&ImageSizeFlag, &ImageWidth, &ImageHeight,
		&ColorMapFlag, &ColorMapFile,
		&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 (ColorMapFlag) {
	/* Read color map from given file: */
	if ((InColorMapFile = fopen(ColorMapFile, "rt")) == NULL) {
	    GIF_MESSAGE("Failed to open COLOR MAP file (not exists!?).");
	    exit(2);
	}
	if ((ColorMap = (GifColorType *) 
	                malloc(sizeof(GifColorType) * 255))  /* Biggest map. */
	    == NULL) {
	    GIF_MESSAGE("Failed to allocate bitmap, aborted.");
	    exit(3);
	}

	for (ColorMapSize = 0;
	     ColorMapSize < 256 && !feof(InColorMapFile);
	     ColorMapSize++) {
	    fscanf(InColorMapFile, "%3d %3d %3d %3d\n",
						&Dummy, &Red, &Green, &Blue);
	    ColorMap[ColorMapSize].Red = Red;
	    ColorMap[ColorMapSize].Green = Green;
	    ColorMap[ColorMapSize].Blue = Blue;
	}
    }
    else {
	ColorMap = EGAPallete;
	ColorMapSize = EGA_PALLETE_SIZE;
    }

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

#ifdef __MSDOS__
    setvbuf(stdin, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);
#endif /* __MSDOS__ */

    /* Conver Raw image from stdin to Gif file in stdout: */
    Raw2Gif(ImageWidth, ImageHeight, ColorMap, ColorMapSize);
}

/******************************************************************************
* 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.				      *
******************************************************************************/
int Raw2Gif(int ImageWidth, int ImageHeight,
				GifColorType *ColorMap, int ColorMapSize)
{
    static int BitsPerPixelArray[] = { 2, 4 ,8, 16, 32, 64, 128, 256 };
    int i, j, BitsPerPixel;
    static GifPixelType *ScanLine;
    GifFileType *GifFile;

    for (BitsPerPixel = 0;
	 BitsPerPixel < 8 && BitsPerPixelArray[BitsPerPixel] != ColorMapSize;
	 BitsPerPixel++);
    if (++BitsPerPixel > 8) {
	GIF_MESSAGE("Number of color map is NOT power of 2 up to 256.");
	exit(3);
    }

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

    if ((GifFile = EGifOpenFileHandle(1)) == NULL) {	   /* Gif to stdout. */
	free((char *) ScanLine);
	return HandleGifError(GifFile);
    }

    if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, BitsPerPixel,
			  0, BitsPerPixel, ColorMap) == GIF_ERROR) {
	free((char *) ScanLine);
	return HandleGifError(GifFile);
    }

    if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, FALSE, 1,
			 NULL) == GIF_ERROR) {
	free((char *) ScanLine);
	return HandleGifError(GifFile);
    }

    /* 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) != ImageWidth) {
	    GIF_MESSAGE("RAW input file ended prematurely.");
	    exit(3);
	}

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

	if (EGifPutLine(GifFile, ScanLine, ImageWidth) == GIF_ERROR) {
	    free((char *) ScanLine);
	    return HandleGifError(GifFile);
	}
	GifQprintf("\b\b\b\b%-4d", i);
    }

    if (EGifCloseFile(GifFile) == GIF_ERROR) {
	free((char *) ScanLine);
	return HandleGifError(GifFile);
    }

    free((char *) ScanLine);
    return 0;
}

/******************************************************************************
* Handle last GIF error. Try to close the file and free all allocated memory. *
******************************************************************************/
static int HandleGifError(GifFileType *GifFile)
{
    int i = GifLastError();

    if (EGifCloseFile(GifFile) == GIF_ERROR) {
	GifLastError();
    }
    return i;
}
示例#5
0
文件: gif.c 项目: crmafra/wmaker
/*
 * Partially based on code in gif2rgb from giflib, by Gershon Elber.
 */
RImage *RLoadGIF(const 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;
}
示例#6
0
	GifException::GifException()
		: runtime_error("Gif Error: " + GifLastError()),
		  code_(GifLastError())
	{
	}