Esempio n. 1
0
static void SaveGif(const char* FileName,
    GifByteType *OutputBuffer,
    ColorMapObject *OutputColorMap,
    int ExpColorMapSize, int Width, int Height)
{
    int i;
    GifFileType *GifFile;
    GifByteType *Ptr = OutputBuffer;

    if ((GifFile = EGifOpenFileName(FileName,0)) == NULL)
       QuitGifError(GifFile);

    if (EGifPutScreenDesc(GifFile,
          Width, Height, ExpColorMapSize, 0,
          OutputColorMap) == GIF_ERROR ||
        EGifPutImageDesc(GifFile,
          0, 0, Width, Height, FALSE, NULL) == GIF_ERROR)
       QuitGifError(GifFile);

    printf("Image '%s' at (%d, %d) [%dx%d]\n", FileName,
       GifFile->Image.Left, GifFile->Image.Top,
       GifFile->Image.Width, GifFile->Image.Height);

    for (i = 0; i < Height; i++) {
      if (EGifPutLine(GifFile, Ptr, Width) == GIF_ERROR)
         QuitGifError(GifFile);
      Ptr += Width;
    }

    if (EGifCloseFile(GifFile) == GIF_ERROR)
        QuitGifError(GifFile);
}
Esempio n. 2
0
/******************************************************************************
* Save the GIF resulting image.						      *
******************************************************************************/
static void RotateGifImage(GifRowType *ScreenBuffer, GifFileType *SrcGifFile,
			   int Angle, GifColorType *ColorMap,
			   int ExpColorMapSize, int DstWidth, int DstHeight)
{
    int i,
	LineSize = DstWidth * sizeof(GifPixelType);
    GifFileType *DstGifFile;
    GifRowType LineBuffer;

    if ((LineBuffer = (GifRowType) malloc(LineSize)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

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

    if (EGifPutScreenDesc(DstGifFile, DstWidth, DstHeight,
			  ExpColorMapSize, 0, ExpColorMapSize,
			  ColorMap) == GIF_ERROR ||
	EGifPutImageDesc(DstGifFile, 0, 0, DstWidth, DstHeight,
			 FALSE, ExpColorMapSize, NULL) == GIF_ERROR)
	QuitGifError(DstGifFile);

    for (i = 0; i < DstHeight; i++) {
	RotateGifLine(ScreenBuffer, SrcGifFile -> SBackGroundColor,
		      SrcGifFile -> SWidth, SrcGifFile -> SHeight,
		      Angle, LineBuffer, DstWidth, DstHeight, i);
	if (EGifPutLine(DstGifFile, LineBuffer, DstWidth) == GIF_ERROR)
	    QuitGifError(DstGifFile);
	GifQprintf("\b\b\b\b%-4d", DstHeight - i - 1);
    }

    if (EGifCloseFile(DstGifFile) == GIF_ERROR)
	QuitGifError(DstGifFile);
}
Esempio n. 3
0
/******************************************************************************
* Save the GIF resulting image.						      *
******************************************************************************/
static void SaveGif(GifByteType *OutputBuffer,
		    ColorMapObject *OutputColorMap,
		    int ExpColorMapSize, int Width, int Height)
{
    int i;
    GifFileType *GifFile;
    GifByteType *Ptr = OutputBuffer + Width * (Height - 1);

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

    if (EGifPutScreenDesc(GifFile,
			  Width, Height, ExpColorMapSize, 0,
			  OutputColorMap) == GIF_ERROR ||
	EGifPutImageDesc(GifFile,
			 0, 0, Width, Height, FALSE, NULL) ==
	                                                             GIF_ERROR)
	QuitGifError(GifFile);

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

    for (i = 0; i < Height; i++) {
	if (EGifPutLine(GifFile, Ptr, Width) == GIF_ERROR)
	    QuitGifError(GifFile);
	GifQprintf("\b\b\b\b%-4d", Height - i - 1);

	Ptr -= Width;
    }

    if (EGifCloseFile(GifFile) == GIF_ERROR)
	QuitGifError(GifFile);
}
Esempio n. 4
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, Error, NumFiles, Width, Height;
    char **FileName = NULL;
    GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL,
        *OutputBuffer = NULL;
    ColorMapObject *OutputColorMap = NULL;

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

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

    ColorMapSize = 1 << ExpNumOfColors;

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

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

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

    return 0;
}
Esempio n. 5
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, iy, last_iy, l, t, w, h, Error, NumFiles, ExtCode,
	ImageNum = 0,
	SizeFlag = FALSE,
	ScaleFlag = FALSE,
	XScaleFlag = FALSE,
	YScaleFlag = FALSE,
	HelpFlag = FALSE;
    double Scale, y;
    GifRecordType RecordType;
    char s[80];
    GifByteType *Extension;
    GifRowType LineIn, LineOut;
    char **FileName = NULL;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifQuietPrint, &SizeFlag, &XSize, &YSize, &ScaleFlag, &Scale,
		&XScaleFlag, &XScale, &YScaleFlag, &YScale,
		&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 specific direction was set, set other direction to 1: */
    if (!XScaleFlag && YScaleFlag) XScale = 1.0;
    if (!YScaleFlag && XScaleFlag) YScale = 1.0;

    /* If the specific direction was not set, but global one did use it: */
    if (!XScaleFlag && ScaleFlag) XScale = Scale;
    if (!YScaleFlag && ScaleFlag) YScale = Scale;

    if (XScale > MAX_SCALE) {
	sprintf(s, "XScale too big, maximum scale selected instead (%f).",
								MAX_SCALE);
	GIF_MESSAGE(s);
	XScale = MAX_SCALE;
    }
    if (YScale > MAX_SCALE) {
	sprintf(s, "YScale too big, maximum scale selected instead (%f).",
								MAX_SCALE);
	GIF_MESSAGE(s);
	YScale = MAX_SCALE;
    }

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

    /* If size was specified, it is used to derive the scale: */
    if (SizeFlag) {
	XScale = XSize / ((double) GifFileIn->SWidth);
	YScale = YSize / ((double) GifFileIn->SHeight);
    }
    else
    {
	XSize = (int) (GifFileIn->SWidth * XScale + 0.5);
	YSize = (int) (GifFileIn->SHeight * YScale + 0.5);
    }

    /* As at this time we know the Screen size of the input gif file, and as */
    /* all image(s) in file must be less/equal to it, we can allocate the    */
    /* scan lines for the input file, and output file. The number of lines   */
    /* to allocate for each is set by ScaleDown & XScale & YScale:	     */
    LineOut = (GifRowType) malloc(XSize * sizeof(GifPixelType));
    LineIn = (GifRowType) malloc(GifFileIn->SWidth * sizeof(GifPixelType));

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

    /* And dump out its new scaled screen information: */
    if (EGifPutScreenDesc(GifFileOut, XSize, YSize,
	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: */
		l = (int) (GifFileIn->Image.Left * XScale + 0.5);
		w = (int) (GifFileIn->Image.Width * XScale + 0.5);
		t = (int) (GifFileIn->Image.Top * YScale + 0.5);
		h = (int) (GifFileIn->Image.Height * YScale + 0.5);
		if (l < 0) l = 0;
		if (t < 0) t = 0;
		if (l + w > XSize) w = XSize - l;
		if (t + h > YSize) h = YSize - t;

		if (EGifPutImageDesc(GifFileOut, l, t, w, h,
		    GifFileIn->Image.Interlace,
		    GifFileIn->Image.ColorMap) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		if (GifFileIn->Image.Interlace) {
		    GIF_EXIT("Cannt resize interlaced images - use GifInter first.");
		}
		else {
		    GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
			PROGRAM_NAME, ++ImageNum,
			GifFileOut->Image.Left, GifFileOut->Image.Top,
			GifFileOut->Image.Width, GifFileOut->Image.Height);

		    for (i = GifFileIn->Image.Height, y = 0.0, last_iy = -1;
			 i-- > 0;
			 y += YScale) {
			if (DGifGetLine(GifFileIn, LineIn,
					GifFileIn->Image.Width) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);

			iy = (int) y;
			if (last_iy < iy && last_iy < YSize) {
			    ResizeLine(LineIn, LineOut,
				       GifFileIn->Image.Width, GifFileOut->Image.Width);

			    for (;
				 last_iy < iy && last_iy < GifFileOut->Image.Height - 1;
				 last_iy++) {
				GifQprintf("\b\b\b\b%-4d", last_iy + 1);
				if (EGifPutLine(GifFileOut, LineOut,
						GifFileOut->Image.Width) ==
								    GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			}
		    }

		    /* If scale is not dividable - dump last lines: */
		    while (++last_iy < GifFileOut->Image.Height) {
			GifQprintf("\b\b\b\b%-4d", last_iy);
			if (EGifPutLine(GifFileOut, LineOut,
					GifFileOut->Image.Width) == 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);

    free(LineOut);
    free(LineIn);

    return 0;
}
Esempio n. 6
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, Error, NumFiles, ExtCode, Row, Col, Width, Height,
	DarkestColor = 0, ColorIntens = 10000, HelpFlag = FALSE;
    GifRecordType RecordType;
    GifByteType *Extension;
    char **FileName = NULL;
    GifRowType LineBuffer;
    ColorMapObject *ColorMap;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &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);
    }

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

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

    if ((LineBuffer = (GifRowType) malloc(GifFileIn->SWidth)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    /* 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.Interlace)
		    GIF_EXIT("Cannt fix interlaced images.");

		Row = GifFileIn->Image.Top; /* Image Position relative to Screen. */
		Col = GifFileIn->Image.Left;
		Width = GifFileIn->Image.Width;
		Height = GifFileIn->Image.Height;
		GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
		    PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);

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

		/* Find the darkest color in color map to use as a filler. */
		ColorMap = (GifFileIn->Image.ColorMap ? GifFileIn->Image.ColorMap :
						     GifFileIn->SColorMap);
		for (i = 0; i < ColorMap->ColorCount; i++) {
		    j = ((int) ColorMap->Colors[i].Red) * 30 +
			((int) ColorMap->Colors[i].Green) * 59 +
			((int) ColorMap->Colors[i].Blue) * 11;
		    if (j < ColorIntens) {
			ColorIntens = j;
			DarkestColor = i;
		    }
		}

		/* Load the image, and dump it. */
		for (i = 0; i < Height; i++) {
		    GifQprintf("\b\b\b\b%-4d", i);
		    if (DGifGetLine(GifFileIn, LineBuffer, Width)
			== GIF_ERROR) break;
		    if (EGifPutLine(GifFileOut, LineBuffer, Width)
			== GIF_ERROR) QuitGifError(GifFileIn, GifFileOut);
		}

		if (i < Height) {
		    fprintf(stderr, "\nFollowing error occured (and ignored):");
		    PrintGifError();

		    /* Fill in with the darkest color in color map. */
		    for (j = 0; j < Width; j++)
			LineBuffer[j] = DarkestColor;
		    for (; i < Height; i++)
			if (EGifPutLine(GifFileOut, LineBuffer, Width)
			    == 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 (Extension && 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;
}
Esempio n. 7
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
void main(int argc, char **argv)
{
    int	Error, NumFiles, ExtCode;
    GifRecordType RecordType;
    GifByteType *Extension;
    char **FileName = NULL;
    GifRowType *ImageBuffer;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
		&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(1);
    }

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

    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 -> SBitsPerPixel, 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 -> ILeft, GifFileIn -> ITop,
		    GifFileIn -> IWidth, GifFileIn -> IHeight,
		    InterlacedFlag, GifFileIn -> IBitsPerPixel,
		    GifFileIn -> IColorMap) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		/* Load the image (either Interlaced or not), and dump it as */
		/* defined in GifFileOut -> IInterlaced.		     */
		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);
}
Esempio n. 8
0
/******************************************************************************
* Perform the disassembly operation - take one input files into few output.   *
******************************************************************************/
static int DoDisassemblyNum(const char *InFileName, char *OutFileName, int FileNum)
{
    int	ExtCode, CodeSize, 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 0
	printf("OutFileName : %s\n", OutFileName);
	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;
    }
	printf("OutFileName : %s\n", OutFileName);
	#endif

    /* 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): */
	//sprintf(CrntFileName, "%s_%02d.gif", OutFileName, FileNum);
	sprintf(CrntFileName, "%s", OutFileName);
	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);
	}

    if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
		return QuitGifError(GifFileIn, GifFileOut);
}
Esempio n. 9
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);
}
Esempio n. 10
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;
}
Esempio n. 11
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
void main(int argc, char **argv)
{
    int	i, j, l, c, Error, LevelStep, LogNumLevels,
	Count = 0, LevelsFlag = FALSE, SizeFlag = FALSE, HelpFlag = FALSE;
    GifRowType Line;
    GifColorType *ColorMap;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifQuitePrint, &LevelsFlag, &NumLevels,
		&SizeFlag, &ImageWidth, &ImageHeight,
		&HelpFlag)) != FALSE) {
	GAPrintErrMsg(Error);
	GAPrintHowTo(CtrlStr);
	exit(1);
    }

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

    /* Make sure the number of levels is power of 2 (up to 32 levels.). */
    for (i = 1; i < 6; i++) if (NumLevels == (1 << i)) break;
    if (i == 6) GIF_EXIT("#Lvls (-l option) is not power of 2 up to 32.");
    LogNumLevels = i + 3;		       /* Multiple by 8 (see below). */
    LevelStep = 256 / NumLevels;

    /* Make sure the image dimension is a multiple of NumLevels horizontally */
    /* and 7 (White, Red, Green, Blue and Yellow Cyan Magenta) vertically.   */
    ImageWidth = (ImageWidth / NumLevels) * NumLevels;
    ImageHeight = (ImageHeight / 7) * 7;

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

    /* Dump out screen description with given size and generated color map:  */
    /* The color map has 7 NumLevels colors for White, Red, Green and then   */
    /* The secondary colors Yellow Cyan and magenta.			     */
    if ((ColorMap = (GifColorType *)
	    malloc(8 * NumLevels * sizeof(GifColorType))) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    for (i = 0; i < 8; i++)				   /* Set color map. */
	for (j = 0; j < NumLevels; j++) {
	    l = LevelStep * j;
	    c = i * NumLevels + j;
	    ColorMap[c].Red = (i == 0 || i == 1 || i == 4 || i == 6) * l;
	    ColorMap[c].Green =	(i == 0 || i == 2 || i == 4 || i == 5) * l;
	    ColorMap[c].Blue = (i == 0 || i == 3 || i == 5 || i == 6) * l;
	}

    if (EGifPutScreenDesc(GifFile,
	ImageWidth, ImageHeight, LogNumLevels, 0, LogNumLevels, ColorMap)
	== GIF_ERROR)
	QuitGifError(GifFile);

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

    GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]:     ",
		    PROGRAM_NAME, GifFile -> ILeft, GifFile -> ITop,
		    GifFile -> IWidth, GifFile -> IHeight);

    /* Allocate one scan line to be used for all image.			     */
    if ((Line = (GifRowType) malloc(sizeof(GifPixelType) * ImageWidth)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    /* Dump the pixels: */
    for (c = 0; c < 7; c++) {
	for (i = 0, l = 0; i < NumLevels; i++)
	    for (j = 0; j < ImageWidth / NumLevels; j++)
		Line[l++] = i + NumLevels * c;
	for (i = 0; i < ImageHeight / 7; i++) {
	    if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR)
		QuitGifError(GifFile);
	    GifQprintf("\b\b\b\b%-4d", Count++);
	}
    }

    if (EGifCloseFile(GifFile) == GIF_ERROR)
	QuitGifError(GifFile);
}
Esempio n. 12
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;
}
Esempio n. 13
0
/******************************************************************************
 Interpret the command line and generate the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, l, GifNoisyPrint, ColorMapSize, ErrorCode;
    bool Error, BackGroundFlag = false, HelpFlag = false;
    char Line[LINE_LEN];
    GifRowType RasterBuffer[GIF_FONT_HEIGHT];
    ColorMapObject *ColorMap;
    GifFileType *GifFile;
    GifColorType	ScratchMap[256];
    int red, green, blue;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
			   &GifNoisyPrint,
			   &BackGroundFlag, &BackGround,
			   &HelpFlag)) != false) {
	GAPrintErrMsg(Error);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

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

    /* Allocate the raster buffer for GIF_FONT_HEIGHT scan lines. */
    for (i = 0; i < GIF_FONT_HEIGHT; i++)
    {
	if ((RasterBuffer[i] = (GifRowType) malloc(sizeof(GifPixelType) *
							IMAGEWIDTH)) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");
    }

    /* Open stdout for the output file: */
    if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    /* Read the color map in ColorFile into this color map: */
    ColorMapSize = 0;
    while (fscanf(stdin,
		  "%*3d %3d %3d %3d\n",
		  &red, &green, &blue) == 3) {
	    ScratchMap[ColorMapSize].Red = red;
	    ScratchMap[ColorMapSize].Green = green;
	    ScratchMap[ColorMapSize].Blue = blue;
	    ColorMapSize++;
	}

    if ((ColorMap = GifMakeMapObject(1 << GifBitSize(ColorMapSize), ScratchMap)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    if (EGifPutScreenDesc(GifFile,
			  IMAGEWIDTH, ColorMapSize * GIF_FONT_HEIGHT,
			  GifBitSize(ColorMapSize),
			  BackGround, ColorMap) == GIF_ERROR)
	QuitGifError(GifFile);

    /* Dump out the image descriptor: */
    if (EGifPutImageDesc(GifFile,
	0, 0, IMAGEWIDTH, ColorMapSize * GIF_FONT_HEIGHT, false, NULL) == GIF_ERROR)
	QuitGifError(GifFile);

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

    for (i = l = 0; i < ColorMap->ColorCount; i++) {
	(void)snprintf(Line, sizeof(Line),
		       "Color %-3d: [%-3d, %-3d, %-3d] ", i,
		       ColorMap->Colors[i].Red,
		       ColorMap->Colors[i].Green,
		       ColorMap->Colors[i].Blue);
	GenRasterTextLine(RasterBuffer, Line, IMAGEWIDTH, i);
	for (j = 0; j < GIF_FONT_HEIGHT; j++) {
	    if (EGifPutLine(GifFile, RasterBuffer[j], IMAGEWIDTH) == GIF_ERROR)
		QuitGifError(GifFile);
	    GifQprintf("\b\b\b\b%-4d", l++);
	}
    }

    if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR)
    {
	PrintGifError(ErrorCode);
	if (GifFile != NULL) {
	    EGifCloseFile(GifFile, NULL);
	}
	exit(EXIT_FAILURE);
    }

    return 0;
}
Esempio n. 14
0
static int ImageToGif(UCHAR **Image,int ImageWidth,int ImageHeight,
		char *GifFileName,int Paleta,int Laplas)
 {
    int	NumLevels=255,i;	/* Konwersja ekranu wirtualnego do postaci */
    GifColorType *ColorMap;     /* obrazu w formacie GIF */
    GifFileType *GifFile;	/* Oparte na bibliotece giflib */

    if(prn==ON)
      fprintf(stdout,"<<< TWORZENIE OBRAZU W FORMACIE GIF'A : %s >>>\n",GifFileName);

    if((GifFile=EGifOpenFileName(GifFileName,0))==NULL)
     {
       QuitGifError(GifFile);
       return -1;
     }

    if((ColorMap=(GifColorType *)malloc(NumLevels*sizeof(GifColorType)))==NULL)
     {
      fprintf(stderr,"Failed to allocate memory required, aborted.\n");
      QuitGifError(GifFile);
      return -1;
     }

    if(prn==ON)
      fprintf(stdout,"<<< GENERACJA PALETY BARW (%s) >>>\n",
	      ((Paleta==COLOR) ? "TERM" : 
	       ( (Paleta==INVERT_GRAY) ? "INVERT GARY" : "GRAY") ) );

    MakePalette(ColorMap,Paleta,Laplas);
    if(EGifPutScreenDesc(GifFile,ImageWidth,ImageHeight,8,0,
       8,ColorMap)==GIF_ERROR)
     {
       QuitGifError(GifFile);
       free((void *)ColorMap);
       return -1;
     }

    if(EGifPutImageDesc(GifFile,0,0,ImageWidth,ImageHeight,
       FALSE,8,NULL)==GIF_ERROR)
     {
       QuitGifError(GifFile);
       free((void *)ColorMap);
       return -1;
     }

    if(prn==ON)
      fprintf(stdout,"<<< KODOWANIE OBRAZU >>>\n");

    for(i=0 ; i<ImageHeight ; i++)
     if(EGifPutLine(GifFile,Image[i],ImageWidth)==GIF_ERROR)
      {
	QuitGifError(GifFile);
	free((void *)ColorMap);
	return -1;
     }

    if(EGifCloseFile(GifFile)==GIF_ERROR)
     {
       QuitGifError(GifFile);
       free((void *)ColorMap);
       return -1;
     }

    free((void *)ColorMap);
    return 0;
 }
Esempio n. 15
0
/******************************************************************************
 Main sequence
******************************************************************************/
int main(int argc, char **argv)
{
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
    GifRecordType RecordType;
    int CodeSize, ExtCode, ErrorCode;
    GifByteType *CodeBlock, *Extension;

    /*
     * Command-line processing goes here.
     */

    /* Use stdin as input (note this also read screen descriptor in: */
    if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    /* Use the stdout as output: */
    if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    /* And dump out its 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 input 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 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)
		    QuitGifError(GifFileIn, GifFileOut);

		/* Now read image itself in decoded form as we dont really   */
		/* care what we have 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:
		/* 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, &ErrorCode) == GIF_ERROR)
    {
	PrintGifError(ErrorCode);
	if (GifFileIn != NULL) {
	    EGifCloseFile(GifFileIn, NULL);
	}
	exit(EXIT_FAILURE);
    }
    if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR)
    {
	PrintGifError(ErrorCode);
	if (GifFileOut != NULL) {
	    EGifCloseFile(GifFileOut, NULL);
	}
	exit(EXIT_FAILURE);
    }

    return 0;
}
Esempio n. 16
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);
}
Esempio n. 17
0
/******************************************************************************
 Interpret the command line and scan the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
    unsigned int Ratio;
    int	i, l, LevelWidth, LogNumLevels, ErrorCode, Count = 0;
    bool Error, FlipDir, DoAllMaximum = false,
	DirectionFlag = false, LevelsFlag = false, ColorFlag = false,
	MinFlag = false, MaxFlag = false, SizeFlag = false, HelpFlag = false;
    GifPixelType Color;
    char *DirectionStr = DEFAULT_DIR;
    GifRowType Line;
    ColorMapObject *ColorMap;
    GifFileType *GifFile;

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

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

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

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

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

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

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

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

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

    /* Open stdout for the output file: */
    if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

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

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

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

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

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

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

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

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

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

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

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &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) {
	fprintf(stderr, VersionStr);
	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.");

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

    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)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    if (!ImageNFlag) {
	/* We are suppose to modify the screen color map, so 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);
	}
    }
    /* 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:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (HasGIFOutput)
		    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 (HasGIFOutput)
	if (EGifCloseFile(GifFileOut) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

    return 0;
}
Esempio n. 19
0
/******************************************************************************
 Interpret the command line and generate the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, l, ImageWidth, ImageHeight, NumOfLines, LogNumLevels,
	ErrorCode, NumLevels, ColorMapSize = 1, 
	ForeGroundIndex = DEFAULT_FG_INDEX;
    bool Error, ClrMapSizeFlag = false, ForeGroundFlag = false,
	TextLineFlag = false, HelpFlag = false, ColorFlag = false;
    char *TextLines[MAX_NUM_TEXT_LINES], Line[LINE_LEN];
    GifRowType RasterBuffer[GIF_FONT_HEIGHT];
    ColorMapObject *ColorMap;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifNoisyPrint, &ClrMapSizeFlag, &ColorMapSize,
		&ForeGroundFlag, &ForeGroundIndex,
		&ColorFlag, &RedColor, &GreenColor, &BlueColor,
		&TextLineFlag, &TextLines[0],
		&HelpFlag)) != false) {
	GAPrintErrMsg(Error);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

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

    if (ForeGroundIndex > 255 || ForeGroundIndex < 1)
	GIF_EXIT("Foregound (-f) should be in the range 1..255, aborted.");

    if (ColorMapSize > 8 || ColorMapSize < 1)
	GIF_EXIT("ColorMapSize (-s) should be in the range 1..8, aborted.");

    if (TextLineFlag) {
	NumOfLines = 1;
	ImageHeight = GIF_FONT_HEIGHT;
	ImageWidth = GIF_FONT_WIDTH * strlen(TextLines[0]);
    }
    else {
	NumOfLines = l = 0;
	while (fgets(Line, LINE_LEN - 1, stdin)) {
	    for (i = strlen(Line); i > 0 && Line[i-1] <= ' '; i--);
	    Line[i] = 0;
	    if (l < i) l = i;
	    TextLines[NumOfLines++] = strdup(Line);
	    if (NumOfLines == MAX_NUM_TEXT_LINES)
		GIF_EXIT("Input file has too many lines, aborted.");
	}
	if (NumOfLines == 0)
	    GIF_EXIT("No input text, aborted.");
	ImageHeight = GIF_FONT_HEIGHT * NumOfLines;
	ImageWidth = GIF_FONT_WIDTH * l;
    }

    /* Allocate the raster buffer for GIF_FONT_HEIGHT scan lines (one text line). */
    for (i = 0; i < GIF_FONT_HEIGHT; i++)
	if ((RasterBuffer[i] = (GifRowType) malloc(sizeof(GifPixelType) *
							ImageWidth)) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");

    /* Open stdout for the output file: */
    if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    /* Dump out screen description with given size and generated color map: */
    for (LogNumLevels = 1, NumLevels = 2;
	 NumLevels < ForeGroundIndex;
	 LogNumLevels++, NumLevels <<= 1);
    if (NumLevels < (1 << ColorMapSize)) {
    	NumLevels = (1 << ColorMapSize);
	LogNumLevels = ColorMapSize;
    }

    if ((ColorMap = GifMakeMapObject(NumLevels, NULL)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    for (i = 0; i < NumLevels; i++)
	ColorMap->Colors[i].Red = ColorMap->Colors[i].Green = ColorMap->Colors[i].Blue = 0;
    ColorMap->Colors[ForeGroundIndex].Red = RedColor;
    ColorMap->Colors[ForeGroundIndex].Green = GreenColor;
    ColorMap->Colors[ForeGroundIndex].Blue = BlueColor;

    if (EGifPutScreenDesc(GifFile,
	ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap)
	== GIF_ERROR)
	QuitGifError(GifFile);

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

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

    for (i = l = 0; i < NumOfLines; i++) {
	GenRasterTextLine(RasterBuffer, TextLines[i], ImageWidth,
							ForeGroundIndex);
	for (j = 0; j < GIF_FONT_HEIGHT; j++) {
	    if (EGifPutLine(GifFile, RasterBuffer[j], ImageWidth) == GIF_ERROR)
		QuitGifError(GifFile);
	    GifQprintf("\b\b\b\b%-4d", l++);
	}
    }

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

    return 0;
}