예제 #1
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;
}
예제 #2
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);
}