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

 
Output of file : GIFFLIP.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 rotate image 90 degrees to the right/left or flip the image *
* horizintally/vertically (mirror). *
* Options: *
* -r : rotate 90 degrees to the right (default). *
* -l : rotate 90 degrees to the left. *
* -x : Mirror the image horizontally (first line switch places with last). *
* -y : Mirror the image vertically (first column switch places with last). *
* -h : on line help *
******************************************************************************
* History: *
* 10 Jul 89 - Version 1.0 by Gershon Elber. *
*****************************************************************************/

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

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

enum {
FLIP_NONE,
FLIP_RIGHT,
FLIP_LEFT,
FLIP_HORIZ,
FLIP_VERT
};

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
" r%- l%- x%- y%- h%- GifFile!*s";
static char
*ProgramName;

/* Make some variables global, so we could access them faster: */
static int
ImageNum = 0;

static int LoadImage(GifFileType *GifFile, RowType **ImageBuffer);
static int DumpImage(GifFileType *GifFile, RowType *ImageBuffer,
int Width, int Height, int FlipDirection);
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, FlipDirection,
RightFlag = FALSE, LeftFlag = FALSE,
HorizFlag = FALSE, VertFlag = FALSE, HelpFlag = FALSE;
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,
&RightFlag, &LeftFlag, &HorizFlag, &VertFlag, &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 ((i = (RightFlag != 0) + (LeftFlag != 0) +
(HorizFlag != 0) + (VertFlag != 0)) > 1)
EXIT("Only one of -r, -l, -x, -y please\n");
if (i == 0) FlipDirection = FLIP_RIGHT; /* Make it the default */
else {
if (RightFlag) FlipDirection = FLIP_RIGHT;
if (LeftFlag) FlipDirection = FLIP_LEFT;
if (HorizFlag) FlipDirection = FLIP_HORIZ;
if (VertFlag) FlipDirection = FLIP_VERT;
}

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

if (RightFlag || LeftFlag) {
/* Dump out same screen information, but flip Screen Width/Height: */
if (EGifPutScreenDesc(GifFileOut,
GifFileIn -> SHeight, GifFileIn -> SWidth,
GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
else {
/* 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 (GifFileIn -> IInterlace)
EXIT("Cannt flip interlaced images - use GifInter first\n");

/* Put the image descriptor to out file: */
if (RightFlag) {
/* Rotate to the right: */
if (EGifPutImageDesc(GifFileOut,
GifFileIn -> SHeight - GifFileIn -> IHeight -
GifFileIn -> ITop,
GifFileIn -> ILeft,
GifFileIn -> IHeight, GifFileIn -> IWidth,
FALSE, GifFileIn -> IBitsPerPixel,
GifFileIn -> IColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
else
if (LeftFlag) {
/* Rotate to the left: */
if (EGifPutImageDesc(GifFileOut,
GifFileIn -> ITop,
GifFileIn -> SWidth - GifFileIn -> IWidth -
GifFileIn -> ILeft,
GifFileIn -> IHeight, GifFileIn -> IWidth,
FALSE, GifFileIn -> IBitsPerPixel,
GifFileIn -> IColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
else {
/* No rotation - only flipping vert. or horiz.: */
if (EGifPutImageDesc(GifFileOut,
GifFileIn -> ILeft, GifFileIn -> ITop,
GifFileIn -> IWidth, GifFileIn -> IHeight,
FALSE, GifFileIn -> IBitsPerPixel,
GifFileIn -> IColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}

/* Load the image (either Interlaced or not), and dump it */
/* fliped as requrested by Flags: */
if (LoadImage(GifFileIn, &ImageBuffer) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (DumpImage(GifFileOut, ImageBuffer, GifFileIn -> IWidth,
GifFileIn -> IHeight, FlipDirection) == 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 Non interlaced only. *
* The memory required to hold the image is allocate by the routine itself. *
* Return OK if succesful, ERROR otherwise. *
******************************************************************************/
static int LoadImage(GifFileType *GifFile, RowType **ImageBufferPtr)
{
int Size, i;
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);

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, and Width & Height hold image dimensions BEFORE flip. *
* Image will be dumped according to FlipDirection. *
* Once dumped, the memory holding the image is freed. *
* Return OK if succesful, ERROR otherwise. *
******************************************************************************/
static int DumpImage(GifFileType *GifFile, RowType *ImageBuffer,
int Width, int Height, int FlipDirection)
{
int i, j, Count;
RowType Line; /* New scan line is copied to it */

/* Allocate scan line that will fit both image width and height: */
if ((Line = (RowType) malloc((Width > Height ? Width : Height)
* sizeof(PixelType))) == NULL)
EXIT("Failed to allocate memory required, aborted\n");

switch (FlipDirection) {
case FLIP_RIGHT:
for (Count=Width, i=0; i fprintf(stderr, "\b\b\b\b%-4d", Count--);
for (j=0; j Line[j] = ImageBuffer[Height - j - 1][i];
if (EGifPutLine(GifFile, Line, Height) == ERROR) return ERROR;
}
break;
case FLIP_LEFT:
for (i=Width-1; i>=0; i--) {
fprintf(stderr, "\b\b\b\b%-4d", i + 1);
for (j=0; j Line[j] = ImageBuffer[j][i];
if (EGifPutLine(GifFile, Line, Height) == ERROR) return ERROR;
}
break;
case FLIP_HORIZ:
for (i=Height-1; i>=0; i--) {
fprintf(stderr, "\b\b\b\b%-4d", i);
if (EGifPutLine(GifFile, ImageBuffer[i], Width) == ERROR)
return ERROR;
}
break;
case FLIP_VERT:
for (Count=Height, i=0; i fprintf(stderr, "\b\b\b\b%-4d", Count--);
for (j=0; j Line[j] = ImageBuffer[i][Width - j - 1];
if (EGifPutLine(GifFile, Line, Width) == ERROR) return ERROR;
}
break;
}

/* Free the memory used for this image, and the temporary scan line: */
for (i=0; i free((char *) ImageBuffer);

free((char *) Line);

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 : GIFFLIP.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/