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

 
Output of file : GIFHISTO.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 create histogram of the colors used by the given GIF file. *
* Dumps out GIF file of constants size GIF_WIDTH by GIF_HEIGHT. *
* Options: *
* -t : Dump out text instead of GIF - #Colors lines, each with #appearances. *
* -i W H : size of GIF image to generate. Colors of input GIF file are *
* spread homogeneously along Height, which better by dividable by the *
* number of colors in input image. *
* -n n : select image number to generate histogram to (1 by default). *
* -b : strip off background color count. *
* -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 "GifHisto"
#define VERSION "á Version 1.0, "

#define DEFAULT_HISTO_WIDTH 100 /* Histogram image diemnsions */
#define DEFAULT_HISTO_HEIGHT 256
#define HISTO_BITS_PER_PIXEL 2 /* Size of bitmap for histogram GIF */

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
" t%- s%-Width|Height!d!d n%-ImageNumber!d b%- h%- GifFile!*s";
static char
*ProgramName;
static int
ImageWidth = DEFAULT_HISTO_WIDTH,
ImageHeight = DEFAULT_HISTO_HEIGHT,
ImageN = 1;
static GifColorType
HistoColorMap[] = { /* Constant bit map for histograms: */
{ 0, 0, 0 },
{ 255, 0, 0 },
{ 0, 255, 0 },
{ 0, 0, 255 }
};

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, j, Size, Error, NumFiles, ExtCode, CodeSize, NumColors, Color,
Count, ImageNum = 0, TextFlag = FALSE, SizeFlag = FALSE,
ImageNFlag = FALSE, BackGroundFlag = FALSE, HelpFlag = FALSE;
long Scaler, Histogram[256];
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,
&TextFlag, &SizeFlag, &ImageWidth, &ImageHeight,
&ImageNFlag, &ImageN, &BackGroundFlag,
&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 (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) == ERROR)
QuitGifError(GifFileIn, GifFileOut);

switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFileIn) == ERROR)
QuitGifError(GifFileIn, GifFileOut);

if (GifFileIn -> IColorMap)
NumColors = (1 << GifFileIn -> IBitsPerPixel);
else
if (GifFileIn -> SColorMap)
NumColors = (1 << GifFileIn -> SBitsPerPixel);
else EXIT("Neither Screen nor Image color map exists\n");

if ((ImageHeight / NumColors) * NumColors != ImageHeight)
EXIT("Image height specified not dividable by #colors\n");

if (++ImageNum == ImageN) {
/* This is the image we should make histogram for: */
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);

for (i=0; i IHeight; i++) {
if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth)
== ERROR)
QuitGifError(GifFileIn, GifFileOut);
for (j=0; j IWidth; j++)
Histogram[Line[j]]++;
fprintf(stderr, "\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) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (CodeBlock != NULL)
if (DGifGetCodeNext(GifFileIn, &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);

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

/* We we requested to kill back ground count: */
if (BackGroundFlag) Histogram[GifFileIn -> SBackGroundColor] = 0;

if (DGifCloseFile(GifFileIn) == ERROR)
QuitGifError(GifFileIn, GifFileOut);


/* We may required to dump out the histogram as text file: */
if (TextFlag) {
for (i=0; 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,
HISTO_BITS_PER_PIXEL, HistoColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);

/* Dump out image descriptor to fit histogram dimensions: */
if (EGifPutImageDesc(GifFileOut,
0, 0, ImageWidth, ImageHeight,
FALSE, HISTO_BITS_PER_PIXEL, NULL) == ERROR)
QuitGifError(GifFileIn, GifFileOut);

/* Prepare scan line for histogram file, and find scaler to scale */
/* histogram to be between 0 and ImageWidth: */
Line = (RowType) malloc(ImageWidth * sizeof(PixelType));
for (Scaler=0, i=0; 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 if ((Size = Histogram[i] / Scaler) > ImageWidth) Size = ImageWidth;
for (j=0; j Line[j] = Color;
for (j=Size; 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 if (EGifPutLine(GifFileOut, Line, ImageWidth) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
fprintf(stderr, "\b\b\b\b%-4d", Count--);
}
}

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