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