Category : C Source Code
Archive   : GIF_LIB.ZIP
Filename : GIFCLIP.C

 
Output of file : GIFCLIP.C contained in archive : GIF_LIB.ZIP
/*****************************************************************************
* "Gif-Lib" - Yet another gif library. *
* *
* Written by: Gershon Elber IBM PC Ver 0.1, Jul. 1989 *
******************************************************************************
* Program to clip an image and dump out only portion of it. *
* Options: *
* -i left top width bottom : clipping information for first image. *
* -n n left top width bottom : clipping information for nth image. *
* -h : on line help *
******************************************************************************
* History: *
* 8 Jul 89 - Version 1.0 by Gershon Elber. *
*****************************************************************************/

#include
#include
#include
#include
#include
#include "gif_lib.h"
#include "getarg.h"

#define PROGRAM_NAME "GifClip"
#define VERSION "á Version 1.0, "

extern unsigned int
_stklen = 16384; /* Increase default stack size */

static char
*VersionStr =
PROGRAM_NAME
" IBMPC "
VERSION
" Gershon Elber, "
__DATE__ ", " __TIME__ "\n"
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
static char
*CtrlStr =
PROGRAM_NAME
" i%-Xmin|Ymin|Xmax|Ymax!d!d!d!d n%-n|Xmin|Ymin|Xmax|Ymax!d!d!d!d!d h%- GifFile!*s";
static char
*ProgramName;

static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut);

/******************************************************************************
* Interpret the command line and scan the given GIF file. *
******************************************************************************/
void main(int argc, char **argv)
{
int i, Error, NumFiles, ExtCode, CodeSize, ImageNum = 0,
ImageFlag = FALSE, ImageNFlag = FALSE, ImageN, ImageX1, ImageY1,
ImageX2, ImageY2, ImageWidth, HelpFlag = FALSE;
GifRecordType RecordType;
ByteType *Extension, *CodeBlock;
char **FileName = NULL;
RowType Line;
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

if (strlen(ProgramName = argv[0]) == 0) /* DOS 3.x only! */
ProgramName = PROGRAM_NAME; /* Do something reasonable for 2.x */

/* Same image dimension vars for both Image & ImageN as only one allowed */
if ((Error = GAGetArgs(argc, argv, CtrlStr,
&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)
MESSAGE("Error in command line parsing - one GIF file please\n");
GAPrintHowTo(CtrlStr);
exit(1);
}

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

/* Test to make sure exactly one of ImageFlag & ImageNFlag is set: */
if ((ImageFlag && ImageNFlag) || (!ImageFlag && !ImageNFlag)) {
MESSAGE("Exactly one of [-i ...] && [-n ...] please\n");
GAPrintHowTo(CtrlStr);
exit(1);
}
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;
}
ImageWidth = ImageX2 - ImageX1 + 1; /* Width of clipped image */

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

/* Scan the content of the GIF file and load the image(s) in: */
do {
if (DGifGetRecordType(GifFileIn, &RecordType) == ERROR)
QuitGifError(GifFileIn, GifFileOut);

switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFileIn) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (++ImageNum == ImageN) {
/* We can handle only non interlaced images here: */
if (GifFileIn -> IInterlace)
EXIT("Image to clip is interlaced - use GifInter first\n");

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

/* Put the image descriptor to out file: */
if (EGifPutImageDesc(GifFileOut,
GifFileIn -> ILeft, GifFileIn -> ITop,
ImageWidth, ImageY2 - ImageY1 + 1,
FALSE, GifFileIn -> IBitsPerPixel,
GifFileIn -> IColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);

/* o.k. - read the image and clip it: */
Line = (RowType) malloc(GifFileIn -> IWidth *
sizeof(PixelType));
fprintf(stderr, "\n%s: Image %d at (%d, %d) [%dx%d]: ",
ProgramName, ImageNum,
GifFileIn -> ILeft, GifFileIn -> ITop,
GifFileIn -> IWidth, GifFileIn -> IHeight);

/* Skip lines below ImageY1: */
for (i=0; i if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth)
== ERROR)
QuitGifError(GifFileIn, GifFileOut);
fprintf(stderr, "\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 -> IWidth)
== ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifPutLine(GifFileOut, &Line[ImageX1],
ImageWidth) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
fprintf(stderr, "\b\b\b\b%-4d", i);
}

/* Skip lines above ImageY2: */
for (i=ImageY2+1; i IHeight; i++) {
if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth)
== ERROR)
QuitGifError(GifFileIn, GifFileOut);
fprintf(stderr, "\b\b\b\b%-4d", i);
}

free((char *) Line);
}
else {
/* Copy the image as is (we dont modify this one): */
if (EGifPutImageDesc(GifFileOut,
GifFileIn -> ILeft, GifFileIn -> ITop,
GifFileIn -> IWidth, GifFileIn -> IHeight,
GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
GifFileIn -> IColorMap) == 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) == ERROR
|| EGifPutCode(GifFileOut, CodeSize, CodeBlock) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (CodeBlock != NULL)
if (DGifGetCodeNext(GifFileIn, &CodeBlock) == ERROR ||
EGifPutCodeNext(GifFileOut, CodeBlock) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
break;
case EXTENSION_RECORD_TYPE:
/* Skip any extension blocks in file: */
if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
Extension) == ERROR)
QuitGifError(GifFileIn, GifFileOut);

/* No support to more than one extension blocks, so discard: */
while (Extension != NULL) {
if (DGifGetExtensionNext(GifFileIn, &Extension) == 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) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifCloseFile(GifFileOut) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}

/******************************************************************************
* Close both input and output file (if open), and exit. *
******************************************************************************/
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
{
PrintGifError();
if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
if (GifFileOut != NULL) EGifCloseFile(GifFileOut);
exit(1);
}



  3 Responses to “Category : C Source Code
Archive   : GIF_LIB.ZIP
Filename : GIFCLIP.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/