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

 
Output of file : GIFINTER.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 flip interlaced and non interlaced images in GIF files. *
* Options: *
* -i : Force all images to be intelaced. *
* -s : Force all images to be sequencial (non interlaced). This is default. *
* -h : on line help *
******************************************************************************
* History: *
* 5 Jul 89 - Version 1.0 by Gershon Elber. *
*****************************************************************************/

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

#define PROGRAM_NAME "GifInter"
#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%- s%- h%- GifFile!*s";
static char
*ProgramName;

/* Make some variables global, so we could access them faster: */
static int
ImageNum = 0,
SequencialFlag = FALSE,
InterlacedFlag = FALSE,
HelpFlag = FALSE,
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should */
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */

static int LoadImage(GifFileType *GifFile, RowType **ImageBuffer);
static int DumpImage(GifFileType *GifFile, RowType *ImageBuffer);
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut);

/******************************************************************************
* Interpret the command line and scan the given GIF file. *
******************************************************************************/
void main(int argc, char **argv)
{
int Error, NumFiles, ExtCode;
GifRecordType RecordType;
ByteType *Extension;
char **FileName = NULL;
RowType *ImageBuffer;
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

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

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

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);

/* Put the image descriptor to out file: */
if (EGifPutImageDesc(GifFileOut,
GifFileIn -> ILeft, GifFileIn -> ITop,
GifFileIn -> IWidth, GifFileIn -> IHeight,
InterlacedFlag, GifFileIn -> IBitsPerPixel,
GifFileIn -> IColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);

/* Load the image (either Interlaced or not), and dump it as */
/* defined in GifFileOut -> IInterlaced. */
if (LoadImage(GifFileIn, &ImageBuffer) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (DumpImage(GifFileOut, ImageBuffer) == 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);
}

/******************************************************************************
* Routine to read Image out. The image can be Interlaced or None interlaced. *
* The memory required to hold the image is allocate by the routine itself. *
* The image is always loaded sequencially into the buffer. *
* Return OK if succesful, ERROR otherwise. *
******************************************************************************/
static int LoadImage(GifFileType *GifFile, RowType **ImageBufferPtr)
{
int Size, i, j, Count;
RowType *ImageBuffer;

/* Allocate the image as vector of column of rows. We cannt allocate */
/* the all screen at once, as this broken minded CPU can allocate up to */
/* 64k at a time and our image can be bigger than that: */
if ((ImageBuffer = (RowType *)
malloc(GifFile -> IHeight * sizeof(RowType *))) == NULL)
EXIT("Failed to allocate memory required, aborted");

Size = GifFile -> IWidth * sizeof(PixelType); /* One row size in bytes */
for (i=0; i IHeight; i++) {
/* Allocate the rows: */
if ((ImageBuffer[i] = (RowType) malloc(Size)) == NULL)
EXIT("Failed to allocate memory required, aborted\n");
}

*ImageBufferPtr = ImageBuffer;

fprintf(stderr, "\n%s: Image %d at (%d, %d) [%dx%d]: ",
ProgramName, ++ImageNum, GifFile -> ILeft, GifFile -> ITop,
GifFile -> IWidth, GifFile -> IHeight);
if (GifFile -> IInterlace) {
/* Need to perform 4 passes on the images: */
for (Count=i=0; i<4; i++)
for (j=InterlacedOffset[i]; j IHeight;
j += InterlacedJumps[i]) {
fprintf(stderr, "\b\b\b\b%-4d", Count++);
if (DGifGetLine(GifFile, ImageBuffer[j], GifFile -> IWidth)
== ERROR) return ERROR;
}
}
else {
for (i=0; i IHeight; i++) {
fprintf(stderr, "\b\b\b\b%-4d", i);
if (DGifGetLine(GifFile, ImageBuffer[i], GifFile -> IWidth)
== ERROR) return ERROR;
}
}

return OK;
}

/******************************************************************************
* Routine to dump image out. The given Image buffer should always hold the *
* image sequencially. Image will be dumped according to IInterlaced flag in *
* GifFile structure. Once dumped, the memory holding the image is freed. *
* Return OK if succesful, ERROR otherwise. *
******************************************************************************/
static int DumpImage(GifFileType *GifFile, RowType *ImageBuffer)
{
int i, j, Count;

if (GifFile -> IInterlace) {
/* Need to perform 4 passes on the images: */
for (Count=GifFile -> IHeight, i=0; i<4; i++)
for (j=InterlacedOffset[i]; j IHeight;
j += InterlacedJumps[i]) {
fprintf(stderr, "\b\b\b\b%-4d", Count--);
if (EGifPutLine(GifFile, ImageBuffer[j], GifFile -> IWidth)
== ERROR) return ERROR;
}
}
else {
for (Count=GifFile -> IHeight, i=0; i IHeight; i++) {
fprintf(stderr, "\b\b\b\b%-4d", Count--);
if (EGifPutLine(GifFile, ImageBuffer[i], GifFile -> IWidth)
== ERROR) return ERROR;
}
}

/* Free the memory used for this image: */
for (i=0; i IHeight; i++) free((char *) ImageBuffer[i]);
free((char *) ImageBuffer);

return OK;
}

/******************************************************************************
* 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 : GIFINTER.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/