First commit ~0,10
This commit is contained in:
28
G/UTIL/GETARG.H
Normal file
28
G/UTIL/GETARG.H
Normal file
@ -0,0 +1,28 @@
|
||||
/***************************************************************************
|
||||
* Error numbers as returned by GAGetArg routine: *
|
||||
* *
|
||||
* Gershon Elber Mar 88 *
|
||||
****************************************************************************
|
||||
* History: *
|
||||
* 11 Mar 88 - Version 1.0 by Gershon Elber. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef GET_ARG_H
|
||||
#define GET_ARG_H
|
||||
|
||||
#define CMD_ERR_NotAnOpt 1 /* None Option found. */
|
||||
#define CMD_ERR_NoSuchOpt 2 /* Undefined Option Found. */
|
||||
#define CMD_ERR_WildEmpty 3 /* Empty input for !*? seq. */
|
||||
#define CMD_ERR_NumRead 4 /* Failed on reading number. */
|
||||
#define CMD_ERR_AllSatis 5 /* Fail to satisfy (must-'!') option. */
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
int GAGetArgs(int va_alist, ...);
|
||||
#else
|
||||
int GAGetArgs(int argc, char **argv, char *CtrlStr, ...);
|
||||
#endif /* USE_VARARGS */
|
||||
|
||||
void GAPrintErrMsg(int Error);
|
||||
void GAPrintHowTo(char *CtrlStr);
|
||||
|
||||
#endif /* GET_ARG_H */
|
941
G/UTIL/GIF2BGI.C
Normal file
941
G/UTIL/GIF2BGI.C
Normal file
@ -0,0 +1,941 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to display GIF file using the BGI device indepedent routines *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -d BGI path : specify the directory where to look for bgi drivers. *
|
||||
* -u BGIUserDriverName.Mode : use user driver instead of auto detection. *
|
||||
* -z factor : zoom the pixels by the given factor. *
|
||||
* -b : beeps disabled. *
|
||||
* -h : on line help. *
|
||||
* *
|
||||
* In this file Screen refers to GIF file screen, while Device to BGI size. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 31 Jul 90 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#include <graphics.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <conio.h>
|
||||
#include <ctype.h>
|
||||
#include <alloc.h>
|
||||
#include <string.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "Gif2BGI"
|
||||
|
||||
#define KEY_LEFT 256 /* Key Codes returned for operational keys */
|
||||
#define KEY_RIGHT 257 /* as return by the GetKey routine. */
|
||||
#define KEY_UP 258
|
||||
#define KEY_DOWN 259
|
||||
#define KEY_RETURN 260
|
||||
#define KEY_DELETE 261
|
||||
#define KEY_INSERT 262
|
||||
#define KEY_BSPACE 263
|
||||
#define KEY_ESC 264
|
||||
#define KEY_HOME 265
|
||||
#define KEY_END 266
|
||||
#define KEY_PGUP 267
|
||||
#define KEY_PGDN 268
|
||||
|
||||
#define SET_POSITION_RESET 0 /* Situations need positionings: */
|
||||
#define SET_POSITION_ZOOM_U 1
|
||||
#define SET_POSITION_ZOOM_D 2
|
||||
#define SET_POSITION_PAN 3
|
||||
|
||||
#define CURSOR_TEXT_X 120
|
||||
|
||||
#define BGI_USER_INSTALL 999 /* BGI User installed driver device. */
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- d%-BGI|Directory!s u%-UserBGIDrv.Mode!s z%-ZoomFactor!d b%- h%- GifFile!*s";
|
||||
static char
|
||||
*GifFileName,
|
||||
*BGIPath = "",
|
||||
*BGIUserDriverName = NULL;
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ImageNum = 0,
|
||||
BackGround = 0,
|
||||
ForeGround = 1, /* As close to white as possible. */
|
||||
BeepsDisabled = FALSE,
|
||||
ZoomFactor = 1,
|
||||
MaximumScreenHeight = 1,
|
||||
BGIUserDriverMode = -1,
|
||||
DeviceMaxX = 640, DeviceMaxY = 400, /* Physical device dimensions. */
|
||||
ScreenWidth = 320, ScreenHeight = 200, /* Gif image screen size. */
|
||||
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
|
||||
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
|
||||
static GifColorType
|
||||
*ColorMap;
|
||||
|
||||
static int huge detectVGA(void);
|
||||
static void BGIInstallUserDriver(char *BGIUserDriverNameMode);
|
||||
static void DisplayScreen(GifRowType *ScreenBuffer, GifFileType *GifFile);
|
||||
static void PrintSettingStatus(GifFileType *GifFile);
|
||||
static void CPrintStr(char *Str, int y);
|
||||
static void SetPosition(int Why,
|
||||
int *ScreenLeft, int *ScreenTop,
|
||||
int *DeviceLeft, int *DeviceTop,
|
||||
int MoveX, int MoveY);
|
||||
static void DrawScreen(GifRowType *ScreenBuffer,
|
||||
int ScreenLeft, int ScreenTop, int DeviceLeft, int DeviceTop);
|
||||
static void DoCursorMode(GifRowType *ScreenBuffer,
|
||||
int ScreenLeft, int ScreenTop, int DeviceLeft, int DeviceTop);
|
||||
static int MyKbHit(void);
|
||||
static int MyGetCh(void);
|
||||
static int GetKey(void);
|
||||
static void Tone(int Frequency, int Time);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, k, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode,
|
||||
Count, ColorMapSize, GraphDriver, GraphMode, Sum,
|
||||
HelpFlag = FALSE,
|
||||
BGIPathFlag = FALSE,
|
||||
BGIUserDriverFlag = FALSE,
|
||||
ZoomFlag = FALSE;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char Str[80], *BGIUserDriverNameMode,
|
||||
**FileName = NULL;
|
||||
GifRowType *ScreenBuffer;
|
||||
GifFileType *GifFile;
|
||||
struct text_info TextInfo; /* So we can restore starting text mode. */
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&GifQuitePrint, &BGIPathFlag, &BGIPath,
|
||||
&BGIUserDriverFlag, &BGIUserDriverNameMode,
|
||||
&ZoomFlag, &ZoomFactor,
|
||||
&BeepsDisabled, &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 (BGIUserDriverFlag) {
|
||||
/* Use the driver supplied by the user! */
|
||||
BGIInstallUserDriver(BGIUserDriverNameMode);
|
||||
installuserdriver(BGIUserDriverName, detectVGA);
|
||||
GraphDriver = BGI_USER_INSTALL;
|
||||
}
|
||||
else {
|
||||
/* Sense type of display we have and attempt to load right driver. */
|
||||
detectgraph(&GraphDriver, &GraphMode);
|
||||
if (GraphDriver < 0)
|
||||
GIF_EXIT("BGI Auto detect: No graphics device detected.");
|
||||
}
|
||||
|
||||
/* Put in the following any graphic driver specific setup: */
|
||||
switch (GraphDriver) {
|
||||
case CGA:
|
||||
GraphMode = CGAHI;
|
||||
break;
|
||||
case EGA:
|
||||
GraphMode = EGAHI;
|
||||
break;
|
||||
case EGA64:
|
||||
GraphMode = EGA64HI;
|
||||
break;
|
||||
case EGAMONO:
|
||||
GraphMode = EGAMONOHI;
|
||||
break;
|
||||
case HERCMONO:
|
||||
GraphMode = HERCMONOHI;
|
||||
break;
|
||||
case VGA:
|
||||
GraphMode = VGAHI;
|
||||
break;
|
||||
case BGI_USER_INSTALL:
|
||||
GraphDriver = DETECT;
|
||||
GraphMode = BGIUserDriverMode;
|
||||
break;
|
||||
default:
|
||||
GIF_EXIT("Requested graphic device is not supported.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (NumFiles == 1) {
|
||||
GifFileName = *FileName;
|
||||
if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
GifFileName = "Stdin";
|
||||
setmode(0, O_BINARY);
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the screen 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: */
|
||||
/* Note this screen is device independent - its the screen as defined by */
|
||||
/* the GIF file parameters itself. */
|
||||
if ((ScreenBuffer = (GifRowType *)
|
||||
malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes of one row.*/
|
||||
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
|
||||
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
|
||||
MaximumScreenHeight = GifFile -> SHeight - 1;
|
||||
for (i = 1; i < GifFile -> SHeight; i++) {
|
||||
/* Allocate the other rows, and set their color to background too: */
|
||||
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) {
|
||||
if (i > 30) {
|
||||
/* Free some memory for the BGI driver and auxilary. */
|
||||
for (j = 1; j < 28; j++)
|
||||
free((char *) ScreenBuffer[i - j]);
|
||||
MaximumScreenHeight = i - 28;
|
||||
fprintf(stderr, "\n%s: Failed to allocate all memory required, last line %d.\n",
|
||||
PROGRAM_NAME, MaximumScreenHeight);
|
||||
break;
|
||||
}
|
||||
else
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
}
|
||||
|
||||
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
|
||||
}
|
||||
|
||||
/* Scan the content of the GIF file and load the image(s) in: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
break;
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
Row = GifFile -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFile -> ILeft;
|
||||
Width = GifFile -> IWidth;
|
||||
Height = GifFile -> IHeight;
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
|
||||
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
|
||||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
|
||||
fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (GifFile -> IInterlace) {
|
||||
/* Need to perform 4 passes on the images: */
|
||||
for (Count = i = 0; i < 4; i++)
|
||||
for (j = Row + InterlacedOffset[i]; j < Row + Height;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile,
|
||||
&ScreenBuffer[MIN(j, MaximumScreenHeight)][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++, Row++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[MIN(Row, MaximumScreenHeight)][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
MaximumScreenHeight = MIN(i - 1, MaximumScreenHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
/* Lets display it - set the global variables required and do it: */
|
||||
BackGround = GifFile -> SBackGroundColor;
|
||||
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
|
||||
GifFile -> SColorMap);
|
||||
ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
|
||||
GifFile -> SBitsPerPixel);
|
||||
|
||||
gettextinfo(&TextInfo); /* Save current mode so we can recover. */
|
||||
|
||||
initgraph(&GraphDriver, &GraphMode, BGIPath);
|
||||
if (graphresult() != grOk) /* Error occured during init. */
|
||||
GIF_EXIT("Graphics System Error, failed to initialize driver.");
|
||||
|
||||
if (getmaxcolor() + 1 < ColorMapSize) {
|
||||
sprintf(Str, "GIF Image color map (%d) is too big for device (%d).\n",
|
||||
ColorMapSize, getmaxcolor() + 1);
|
||||
closegraph();
|
||||
GIF_EXIT(Str);
|
||||
}
|
||||
|
||||
/* Initialize hardware pallete and also select fore/background color. */
|
||||
BackGround = ForeGround = 1;
|
||||
Sum = ((int) ColorMap[1].Red) +
|
||||
((int) ColorMap[1].Green) +
|
||||
((int) ColorMap[1].Blue);
|
||||
j = k = Sum;
|
||||
for (i = 0; i < ColorMapSize; i++) {
|
||||
setrgbpalette(i, ColorMap[i].Red >> 2,
|
||||
ColorMap[i].Green >> 2,
|
||||
ColorMap[i].Blue >> 2);
|
||||
|
||||
Sum = ((int) ColorMap[i].Red) +
|
||||
((int) ColorMap[i].Green) +
|
||||
((int) ColorMap[i].Blue);
|
||||
if (i != 0 && Sum > j) { /* Dont use color 0. */
|
||||
ForeGround = i;
|
||||
j = Sum;
|
||||
}
|
||||
if (i != 0 && Sum <= k) { /* Dont use color 0. */
|
||||
BackGround = i;
|
||||
k = Sum;
|
||||
}
|
||||
}
|
||||
|
||||
DeviceMaxX = getmaxx(); /* Read size of physical screen. */
|
||||
DeviceMaxY = getmaxy();
|
||||
ScreenWidth = GifFile -> SWidth;
|
||||
ScreenHeight = MIN(GifFile -> SHeight, MaximumScreenHeight);
|
||||
|
||||
Tone(500, 10);
|
||||
DisplayScreen(ScreenBuffer, GifFile);
|
||||
|
||||
if (DGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
closegraph();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
closegraph();
|
||||
|
||||
textmode(TextInfo.currmode);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Routine to be called for the user installed driver: *
|
||||
****************************************************************************/
|
||||
static int huge detectVGA(void)
|
||||
{
|
||||
return BGIUserDriverMode;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Routine to install the user BGI driver information. *
|
||||
****************************************************************************/
|
||||
static void BGIInstallUserDriver(char *BGIUserDriverNameMode)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = strrchr(BGIUserDriverNameMode, '/')) != NULL ||
|
||||
(p = strrchr(BGIUserDriverNameMode, '\\')) != NULL) {
|
||||
p[0] = 0;
|
||||
BGIPath = strdup(BGIUserDriverNameMode);
|
||||
p++;
|
||||
}
|
||||
|
||||
p = strtok(p, ".");
|
||||
BGIUserDriverName = strdup(p);
|
||||
|
||||
p = strtok(NULL, ".");
|
||||
if (sscanf(p, "%d", &BGIUserDriverMode) != 1 || BGIUserDriverName == NULL)
|
||||
GIF_EXIT("User [-u] BGI specification has wrong format.");
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Given the screen buffer, display it: *
|
||||
* The following commands are available (case insensitive). *
|
||||
* 1. Four arrow to move along the screen (only if ScreenBuffer > physical *
|
||||
* screen in that direction. *
|
||||
* 2. C - goto cursor mode - print current color & position in GIF screen *
|
||||
* of the current pixel cursor is on. *
|
||||
* 3. D - zoom out by factor of 2. *
|
||||
* 4. R - redraw current image. *
|
||||
* 5. S - Print Current status/options. *
|
||||
* 6. U - zoom in by factor of 2. *
|
||||
* 7. ' ' - stop drawing current image. *
|
||||
* 8. ESC - to quit. *
|
||||
******************************************************************************/
|
||||
static void DisplayScreen(GifRowType *ScreenBuffer, GifFileType *GifFile)
|
||||
{
|
||||
int DeviceTop, DeviceLeft, /* Where ScreenBuffer is to mapped to ours. */
|
||||
ScreenTop, ScreenLeft, /* Porsion of ScreenBuffer to start display. */
|
||||
XPanning, YPanning, /* Amount to move using the arrows. */
|
||||
GetK, DrawIt = TRUE;
|
||||
|
||||
XPanning = DeviceMaxX / 2;
|
||||
YPanning = DeviceMaxY / 2;
|
||||
|
||||
SetPosition(SET_POSITION_RESET,
|
||||
&ScreenLeft, &ScreenTop,
|
||||
&DeviceLeft, &DeviceTop,
|
||||
0, 0);
|
||||
|
||||
do {
|
||||
if (DrawIt && !MyKbHit()) {
|
||||
DrawScreen(ScreenBuffer, ScreenLeft, ScreenTop,
|
||||
DeviceLeft, DeviceTop);
|
||||
Tone(2000, 200);
|
||||
}
|
||||
DrawIt = TRUE;
|
||||
switch (GetK = GetKey()) {
|
||||
case 'C':
|
||||
DoCursorMode(ScreenBuffer, ScreenLeft, ScreenTop,
|
||||
DeviceLeft, DeviceTop);
|
||||
DrawIt = TRUE;
|
||||
break;
|
||||
case 'D':
|
||||
if (ZoomFactor > 1) {
|
||||
ZoomFactor >>= 1;
|
||||
SetPosition(SET_POSITION_ZOOM_D,
|
||||
&ScreenLeft, &ScreenTop,
|
||||
&DeviceLeft, &DeviceTop,
|
||||
0, 0);
|
||||
}
|
||||
else {
|
||||
Tone(1000, 100);
|
||||
DrawIt = FALSE;
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
break;
|
||||
case 'S':
|
||||
PrintSettingStatus(GifFile);
|
||||
break;
|
||||
case 'U':
|
||||
if (ZoomFactor < 256) {
|
||||
ZoomFactor <<= 1;
|
||||
SetPosition(SET_POSITION_ZOOM_U,
|
||||
&ScreenLeft, &ScreenTop,
|
||||
&DeviceLeft, &DeviceTop,
|
||||
0, 0);
|
||||
}
|
||||
else {
|
||||
Tone(1000, 100);
|
||||
DrawIt = FALSE;
|
||||
}
|
||||
break;
|
||||
case KEY_ESC:
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
SetPosition(SET_POSITION_PAN,
|
||||
&ScreenLeft, &ScreenTop,
|
||||
&DeviceLeft, &DeviceTop,
|
||||
-XPanning, 0);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
SetPosition(SET_POSITION_PAN,
|
||||
&ScreenLeft, &ScreenTop,
|
||||
&DeviceLeft, &DeviceTop,
|
||||
XPanning, 0);
|
||||
break;
|
||||
case KEY_UP:
|
||||
SetPosition(SET_POSITION_PAN,
|
||||
&ScreenLeft, &ScreenTop,
|
||||
&DeviceLeft, &DeviceTop,
|
||||
0, -YPanning);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
SetPosition(SET_POSITION_PAN,
|
||||
&ScreenLeft, &ScreenTop,
|
||||
&DeviceLeft, &DeviceTop,
|
||||
0, YPanning);
|
||||
break;
|
||||
default:
|
||||
DrawIt = FALSE;
|
||||
Tone(800, 100);
|
||||
Tone(300, 200);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (GetK != KEY_ESC);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to print (in text mode), current program status. *
|
||||
******************************************************************************/
|
||||
static void PrintSettingStatus(GifFileType *GifFile)
|
||||
{
|
||||
char s[80];
|
||||
|
||||
setcolor(ForeGround);
|
||||
|
||||
CPrintStr(PROGRAM_NAME, 1);
|
||||
|
||||
sprintf(s, "GIF File - %s.", GifFileName);
|
||||
CPrintStr(s, 10);
|
||||
|
||||
sprintf(s, "Gif Screen Size = [%d, %d]. Contains %d image(s).",
|
||||
GifFile -> SWidth, GifFile -> SHeight, ImageNum);
|
||||
CPrintStr(s, 20);
|
||||
|
||||
if (GifFile -> SColorMap)
|
||||
sprintf(s,
|
||||
"Has Screen Color map of %d bits. BackGround = [%d, %d, %d].",
|
||||
GifFile -> SBitsPerPixel,
|
||||
GifFile -> SColorMap[GifFile -> SBackGroundColor].Red,
|
||||
GifFile -> SColorMap[GifFile -> SBackGroundColor].Green,
|
||||
GifFile -> SColorMap[GifFile -> SBackGroundColor].Blue);
|
||||
else
|
||||
sprintf(s, "No Screen color map.");
|
||||
CPrintStr(s, 30);
|
||||
|
||||
if (GifFile -> IColorMap)
|
||||
sprintf(s, "Has Image map of %d bits (last image). Image is %s.",
|
||||
GifFile -> IBitsPerPixel,
|
||||
(GifFile -> IInterlace ? "interlaced" : "non interlaced"));
|
||||
else
|
||||
sprintf(s, "No Image color map.");
|
||||
CPrintStr(s, 40);
|
||||
|
||||
CPrintStr("Press anything to continue:", 60);
|
||||
MyGetCh();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to cprintf given string centered at given Y level, and attr: *
|
||||
******************************************************************************/
|
||||
static void CPrintStr(char *Str, int y)
|
||||
{
|
||||
setfillstyle(SOLID_FILL, BackGround);
|
||||
bar(0, y, textwidth(Str) + 2, y + textheight(Str) + 2);
|
||||
|
||||
setcolor(ForeGround);
|
||||
outtextxy(1, y + 1, Str);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to set the position of Screen in Device, and what porsion of the *
|
||||
* screen should be visible: *
|
||||
* MoveX, MoveY are the panning factors (if both zero - initialize). *
|
||||
******************************************************************************/
|
||||
static void SetPosition(int Why,
|
||||
int *ScreenLeft, int *ScreenTop,
|
||||
int *DeviceLeft, int *DeviceTop,
|
||||
int MoveX, int MoveY)
|
||||
{
|
||||
|
||||
MoveX /= ZoomFactor; /* Make sure move move same amount independent. */
|
||||
MoveY /= ZoomFactor; /* of what ZommFactor is. */
|
||||
|
||||
/* Figure out position of GIF file in real device X axis: */
|
||||
if (ScreenWidth * ZoomFactor <= DeviceMaxX + 1) {
|
||||
/* Device is big enough to hold all the image X axis: */
|
||||
*ScreenLeft = 0;
|
||||
*DeviceLeft = (DeviceMaxX - ScreenWidth * ZoomFactor) / 2;
|
||||
}
|
||||
else {
|
||||
/* Device is too small to hold all the image X axis: */
|
||||
switch (Why) {
|
||||
case SET_POSITION_RESET:
|
||||
*ScreenLeft = 0;
|
||||
break;
|
||||
case SET_POSITION_ZOOM_U:
|
||||
*ScreenLeft += DeviceMaxX / (2 * ZoomFactor);
|
||||
break;
|
||||
case SET_POSITION_ZOOM_D:
|
||||
*ScreenLeft -= DeviceMaxX / (4 * ZoomFactor);
|
||||
break;
|
||||
case SET_POSITION_PAN:
|
||||
if (MoveX != 0) *ScreenLeft += MoveX;
|
||||
break;
|
||||
}
|
||||
if (*ScreenLeft < 0) *ScreenLeft = 0;
|
||||
if ((ScreenWidth - *ScreenLeft) * ZoomFactor < DeviceMaxX + 1)
|
||||
*ScreenLeft = (ScreenWidth * ZoomFactor -
|
||||
DeviceMaxX + 1) / ZoomFactor;
|
||||
*DeviceLeft = 0;
|
||||
}
|
||||
|
||||
/* Figure out position of GIF file in real device Y axis: */
|
||||
if (ScreenHeight * ZoomFactor <= DeviceMaxY + 1) {
|
||||
/* Device is big enough to hold all the image Y axis: */
|
||||
*ScreenTop = 0;
|
||||
*DeviceTop = (DeviceMaxY - ScreenHeight * ZoomFactor) / 2;
|
||||
}
|
||||
else {
|
||||
/* Device is too small to hold all the image Y axis: */
|
||||
switch (Why) {
|
||||
case SET_POSITION_RESET:
|
||||
*ScreenTop = 0;
|
||||
break;
|
||||
case SET_POSITION_ZOOM_U:
|
||||
*ScreenTop += DeviceMaxY / (2 * ZoomFactor);
|
||||
break;
|
||||
case SET_POSITION_ZOOM_D:
|
||||
*ScreenTop -= DeviceMaxY / (4 * ZoomFactor);
|
||||
break;
|
||||
case SET_POSITION_PAN:
|
||||
if (MoveY != 0) *ScreenTop += MoveY;
|
||||
break;
|
||||
}
|
||||
if (*ScreenTop < 0) *ScreenTop = 0;
|
||||
if ((ScreenHeight - *ScreenTop) * ZoomFactor < DeviceMaxY + 1)
|
||||
*ScreenTop = (ScreenHeight * ZoomFactor -
|
||||
DeviceMaxY - 1) / ZoomFactor;
|
||||
*DeviceTop = 0;
|
||||
}
|
||||
|
||||
/* Make sure the position is on Byte boundary (8 pixels per byte): */
|
||||
*DeviceLeft &= 0xfff8;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The real drawing of the image is performed here. Few things are taken into *
|
||||
* account: *
|
||||
* 1. The zoom factor. If > 1 each pixel is multiplied this amount vertically *
|
||||
* and horizontally. *
|
||||
* The image is drawn from ScreenBuffer ScreenTop/Left in the bottom/right *
|
||||
* directions, onto the Device DeviceTop/Left in the bottom/right direction *
|
||||
* Pressing space during drawing will abort this routine. *
|
||||
******************************************************************************/
|
||||
static void DrawScreen(GifRowType *ScreenBuffer,
|
||||
int ScreenLeft, int ScreenTop, int DeviceLeft, int DeviceTop)
|
||||
{
|
||||
int i, j, k, l, CountZoomJ, CountZoomI,
|
||||
DeviceWidth, DeviceRight, ScreenBottom;
|
||||
unsigned char *ImageBuffer, *p;
|
||||
GifPixelType *Line;
|
||||
|
||||
/* Make sure we start from scratch. Note cleardevice() uses color 0 even */
|
||||
/* if it may be non black. */
|
||||
cleardevice();
|
||||
|
||||
if (getmaxcolor() + 1 == 256) {
|
||||
/* Optimize this case - one byte per pixel. */
|
||||
DeviceWidth = ScreenWidth * ZoomFactor;
|
||||
if (DeviceWidth + DeviceLeft > DeviceMaxX)
|
||||
DeviceWidth = DeviceMaxX - DeviceLeft;
|
||||
DeviceRight = DeviceLeft + DeviceWidth - 1;
|
||||
ScreenBottom = ScreenTop + ScreenHeight - 1;
|
||||
|
||||
if ((ImageBuffer = malloc(imagesize(DeviceLeft, DeviceTop,
|
||||
DeviceRight, DeviceTop))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
getimage(DeviceLeft, DeviceTop, DeviceRight, DeviceTop, ImageBuffer);
|
||||
|
||||
for (k = DeviceTop; k < DeviceMaxY && ScreenTop <= ScreenBottom;) {
|
||||
Line = ScreenBuffer[ScreenTop++];
|
||||
p = ImageBuffer + 4; /* point on first pixel in bitmap. */
|
||||
if (ZoomFactor == 1)
|
||||
memcpy(p, &Line[ScreenLeft], DeviceWidth);
|
||||
else {
|
||||
for (i = 0, j = ScreenLeft, CountZoomI = ZoomFactor;
|
||||
i < DeviceWidth;
|
||||
i++) {
|
||||
*p++ = Line[j];
|
||||
if (--CountZoomI == 0) {
|
||||
CountZoomI = ZoomFactor;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Abort drawing if space bar was pressed: */
|
||||
if (MyKbHit() && GetKey() == ' ') break;
|
||||
|
||||
for (i = 0; i < ZoomFactor; i++)
|
||||
putimage(DeviceLeft, k++, ImageBuffer, COPY_PUT);
|
||||
}
|
||||
|
||||
free((char *) ImageBuffer);
|
||||
}
|
||||
else {
|
||||
for (CountZoomJ = ZoomFactor, j = ScreenTop, l = DeviceTop;
|
||||
j < ScreenHeight && l <= DeviceMaxY; l++) {
|
||||
Line = ScreenBuffer[j];
|
||||
|
||||
/* Abort drawing if space bar was pressed: */
|
||||
if (MyKbHit() && GetKey() == ' ') break;
|
||||
|
||||
for (CountZoomI = ZoomFactor, i = ScreenLeft, k = DeviceLeft;
|
||||
i < ScreenWidth && k <= DeviceMaxX;) {
|
||||
putpixel(k++, l, Line[i]);
|
||||
|
||||
if (!--CountZoomI) {
|
||||
/* Go to next column: */
|
||||
i++;
|
||||
CountZoomI = ZoomFactor;
|
||||
}
|
||||
}
|
||||
|
||||
if (!--CountZoomJ) {
|
||||
/* Go to next row: */
|
||||
j++;
|
||||
CountZoomJ = ZoomFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Walks along the current image, while printing pixel value and position. *
|
||||
* 4 arrows may be used, and any other key will abort this operation *
|
||||
******************************************************************************/
|
||||
static void DoCursorMode(GifRowType *ScreenBuffer,
|
||||
int ScreenLeft, int ScreenTop, int DeviceLeft, int DeviceTop)
|
||||
{
|
||||
int GetK, DeviceRight, DeviceBottom, x, y, Step;
|
||||
GifPixelType Pixel;
|
||||
char s[80];
|
||||
|
||||
DeviceRight = DeviceLeft + (ScreenWidth - ScreenLeft) * ZoomFactor;
|
||||
if (DeviceRight > DeviceMaxX) DeviceRight = DeviceMaxX;
|
||||
|
||||
DeviceBottom = DeviceTop + (ScreenHeight - ScreenTop) * ZoomFactor;
|
||||
if (DeviceBottom > DeviceMaxY) DeviceBottom = DeviceMaxY;
|
||||
|
||||
x = (DeviceLeft + DeviceRight) / 2;
|
||||
y = (DeviceTop + DeviceBottom) / 2;
|
||||
|
||||
setwritemode(XOR_PUT);
|
||||
|
||||
while (TRUE) {
|
||||
Pixel = ScreenBuffer[ScreenTop + (y - DeviceTop) / ZoomFactor]
|
||||
[ScreenLeft + (x - DeviceLeft) / ZoomFactor];
|
||||
sprintf(s, "Color = %3d [%3d, %3d, %3d], X = %3d, Y = %3d",
|
||||
Pixel,
|
||||
ColorMap[Pixel].Red,
|
||||
ColorMap[Pixel].Green,
|
||||
ColorMap[Pixel].Blue,
|
||||
(x - DeviceLeft) / ZoomFactor,
|
||||
(y - DeviceTop) / ZoomFactor);
|
||||
|
||||
setfillstyle(SOLID_FILL, BackGround);
|
||||
bar(0, 0, textwidth(s) + 2, textheight(s) + 2);
|
||||
|
||||
setcolor(ForeGround);
|
||||
outtextxy(1, 1, s);
|
||||
|
||||
line(0, y, DeviceMaxX, y);
|
||||
line(x, 0, x, DeviceMaxY);
|
||||
GetK = GetKey();
|
||||
line(0, y, DeviceMaxX, y);
|
||||
line(x, 0, x, DeviceMaxY);
|
||||
|
||||
Step = 10;
|
||||
switch (GetK) {
|
||||
case '1':
|
||||
GetK = KEY_END;
|
||||
break;
|
||||
case '2':
|
||||
GetK = KEY_DOWN;
|
||||
break;
|
||||
case '3':
|
||||
GetK = KEY_PGDN;
|
||||
break;
|
||||
case '4':
|
||||
GetK = KEY_LEFT;
|
||||
break;
|
||||
case '6':
|
||||
GetK = KEY_RIGHT;
|
||||
break;
|
||||
case '7':
|
||||
GetK = KEY_HOME;
|
||||
break;
|
||||
case '8':
|
||||
GetK = KEY_UP;
|
||||
break;
|
||||
case '9':
|
||||
GetK = KEY_PGUP;
|
||||
break;
|
||||
default:
|
||||
Step = 1;
|
||||
}
|
||||
|
||||
switch (GetK) {
|
||||
case KEY_LEFT:
|
||||
x -= Step;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
x += Step;
|
||||
break;
|
||||
case KEY_UP:
|
||||
y -= Step;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
y += Step;
|
||||
break;
|
||||
case KEY_PGUP:
|
||||
y -= Step;
|
||||
x += Step;
|
||||
break;
|
||||
case KEY_PGDN:
|
||||
y += Step;
|
||||
x += Step;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
y -= Step;
|
||||
x -= Step;
|
||||
break;
|
||||
case KEY_END:
|
||||
y += Step;
|
||||
x -= Step;
|
||||
break;
|
||||
default:
|
||||
setwritemode(COPY_PUT);
|
||||
return;
|
||||
}
|
||||
if (x < DeviceLeft) x = DeviceLeft;
|
||||
if (x >= DeviceRight) x = DeviceRight;
|
||||
if (y < DeviceTop) y = DeviceTop;
|
||||
if (y >= DeviceBottom) y = DeviceBottom;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Return non zero value if at list one character exists in keyboard queue. *
|
||||
* This routine emulates kbhit() which do uses stdin and useless for us. *
|
||||
******************************************************************************/
|
||||
static int MyKbHit(void)
|
||||
{
|
||||
return bioskey(1);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Get a key from keyboard directly (bypass stdin as we might redirect it). *
|
||||
* This routine emulates getch() which do uses stdin and useless for us. *
|
||||
******************************************************************************/
|
||||
static int MyGetCh(void)
|
||||
{
|
||||
static int Extended = 0;
|
||||
int c;
|
||||
|
||||
if (Extended) {
|
||||
c = Extended;
|
||||
Extended = 0;
|
||||
return c;
|
||||
}
|
||||
else {
|
||||
c = bioskey(0);
|
||||
if (c & 0x0ff)
|
||||
return c;
|
||||
else {
|
||||
Extended = c >> 8;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Get a key from keyboard, and translating operational keys into special *
|
||||
* codes (>255). Lower case characters are upercased. *
|
||||
******************************************************************************/
|
||||
static int GetKey(void)
|
||||
{
|
||||
char c;
|
||||
|
||||
while (TRUE) switch (c = MyGetCh()) {
|
||||
case 0: /* Extended code - get the next extended char. */
|
||||
switch (MyGetCh()) {
|
||||
case 75: return KEY_LEFT;
|
||||
case 77: return KEY_RIGHT;
|
||||
case 72: return KEY_UP;
|
||||
case 80: return KEY_DOWN;
|
||||
case 71: return KEY_HOME;
|
||||
case 79: return KEY_END;
|
||||
case 73: return KEY_PGUP;
|
||||
case 81: return KEY_PGDN;
|
||||
case 83: return KEY_DELETE;
|
||||
case 82: return KEY_INSERT;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
return KEY_BSPACE;
|
||||
case 10:
|
||||
case 13:
|
||||
return KEY_RETURN;
|
||||
case 27:
|
||||
return KEY_ESC;
|
||||
default:
|
||||
if (isprint(c)) {
|
||||
if (islower(c))
|
||||
return toupper(c);
|
||||
else
|
||||
return c;
|
||||
}
|
||||
else {
|
||||
Tone(800, 100);
|
||||
Tone(300, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to make some sound with given Frequency, Time milliseconds: *
|
||||
******************************************************************************/
|
||||
static void Tone(int Frequency, int Time)
|
||||
{
|
||||
if (BeepsDisabled) return;
|
||||
|
||||
sound(Frequency);
|
||||
delay(Time);
|
||||
nosound();
|
||||
}
|
590
G/UTIL/GIF2EPSN.C
Normal file
590
G/UTIL/GIF2EPSN.C
Normal file
@ -0,0 +1,590 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to dump GIF file into EPSON type printers *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -d factor : use dithering of matrix of size factor by factor. *
|
||||
* -t level : set the threshold level of white in the result (0..100). *
|
||||
* -m mapping : methods for mapping the 24bits colors into 1 BW bit. *
|
||||
* -p printer : specify printer to print to (lpt1: by default). *
|
||||
* -n : nice mode : uses double density to achieve better quality. *
|
||||
* -i : invert the image. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 15 Jul 89 - Version 1.0 by Gershon Elber. *
|
||||
* 22 Dec 89 - Fix problems with const strings been modified (Version 1.1). *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "Gif2Epsn"
|
||||
|
||||
#define C2BW_BACK_GROUND 0 /*Methods to map 24bits Colors to 1 BW bit.*/
|
||||
#define C2BW_GREY_LEVELS 1
|
||||
#define C2BW_DITHER 2
|
||||
#define C2BW_NUM_METHODS 3 /* Always hold # of methods. */
|
||||
|
||||
#define DEFAULT_THRESHOLD 5000 /* Color -> BW threshold level. */
|
||||
|
||||
#define DITHER_MIN_MATRIX 2
|
||||
#define DITHER_MAX_MATRIX 4
|
||||
|
||||
/* The epson specific are defined here: */
|
||||
#define EPSON_WIDTH 80 /* 80 char per line. */
|
||||
#define EPSON_PIXEL_2_CHAR 8 /* 8 pixels per char, in REG_DENSITY. */
|
||||
|
||||
#define EPSON_ESC "\033" /* Actually regular escape char. */
|
||||
#define EPSON_RESET "\033@" /* Reset the printer. */
|
||||
#define EPSON_VERTICAL_SPACE "\033A\010" /* 8/72 inch vertically. */
|
||||
#define EPSON_REG_DENSITY "\033K" /* 640 pixels per 7.5" (line). */
|
||||
#define EPSON_DUAL_DENSITY "\033L" /* 1280 pixels per 7.5" (line). */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Gif2Epsn q%- d%-DitherSize!d t%-BWThreshold!d m%-Mapping!d i%- n%- p%-PrinterName!s h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- d%-DitherSize!d t%-BWThreshold!d m%-Mapping!d i%- n%- p%-PrinterName!s h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
static char
|
||||
*PrinterName = NULL;
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ImageNum = 0,
|
||||
BackGround = 0,
|
||||
DitherSize = 2, DitherFlag = FALSE,
|
||||
BWThresholdFlag = FALSE, Threshold,
|
||||
BWThreshold = DEFAULT_THRESHOLD, /* Color -> BW mapping threshold. */
|
||||
Mapping, MappingFlag = FALSE,
|
||||
InvertFlag = FALSE,
|
||||
NiceFlag = FALSE,
|
||||
PrinterFlag = FALSE,
|
||||
HelpFlag = FALSE,
|
||||
ColorToBWMapping = C2BW_BACK_GROUND,
|
||||
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should */
|
||||
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
|
||||
static GifColorType
|
||||
*ColorMap;
|
||||
|
||||
static void EvalDitheredScanline(GifRowType *ScreenBuffer, int Row,
|
||||
int RowSize, GifRowType *DitherBuffer);
|
||||
static void DumpScreen2Epsn(GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight);
|
||||
static void PutString(FILE *Prt, int DirectPrint, char *Str, int Len);
|
||||
static void PutString2(FILE *Prt, int DirectPrint, char *Str, int Len);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char **FileName = NULL;
|
||||
GifRowType *ScreenBuffer;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&GifQuitePrint, &DitherFlag, &DitherSize,
|
||||
&BWThresholdFlag, &Threshold,
|
||||
&MappingFlag, &Mapping, &InvertFlag,
|
||||
&NiceFlag, &PrinterFlag, &PrinterName, &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 (!PrinterFlag) PrinterName = "";
|
||||
|
||||
if (DitherFlag) {
|
||||
/* Make sure we are o.k.: */
|
||||
if (DitherSize > DITHER_MAX_MATRIX) DitherSize = DITHER_MAX_MATRIX;
|
||||
if (DitherSize < DITHER_MIN_MATRIX) DitherSize = DITHER_MAX_MATRIX;
|
||||
}
|
||||
|
||||
/* As Threshold is in [0..100] range and BWThreshold is [0..25500]: */
|
||||
if (BWThresholdFlag) {
|
||||
if (Threshold > 100 || Threshold < 0)
|
||||
GIF_EXIT("Threshold not in 0..100 percent.");
|
||||
BWThreshold = Threshold * 255;
|
||||
if (BWThreshold == 0) BWThreshold = 1; /* Overcome divide by zero! */
|
||||
}
|
||||
|
||||
/* No message is emitted, but mapping method is clipped to exists method.*/
|
||||
if (MappingFlag) ColorToBWMapping = Mapping % C2BW_NUM_METHODS;
|
||||
|
||||
if (NumFiles == 1) {
|
||||
if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the screen 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: */
|
||||
/* Note this screen is device independent - its the screen as defined by */
|
||||
/* the GIF file parameters itself. */
|
||||
if ((ScreenBuffer = (GifRowType *)
|
||||
malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
|
||||
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
|
||||
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
|
||||
for (i = 1; i < GifFile -> SHeight; i++) {
|
||||
/* Allocate the other rows, andset their color to background too: */
|
||||
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.\n");
|
||||
|
||||
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
|
||||
}
|
||||
|
||||
/* Scan the content of the GIF file and load the image(s) in: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
Row = GifFile -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFile -> ILeft;
|
||||
Width = GifFile -> IWidth;
|
||||
Height = GifFile -> IHeight;
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
|
||||
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
|
||||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
|
||||
fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (GifFile -> IInterlace) {
|
||||
/* Need to perform 4 passes on the images: */
|
||||
for (Count = i = 0; i < 4; i++)
|
||||
for (j = Row + InterlacedOffset[i]; j < Row + Height;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
/* Lets display it - set the global variables required and do it: */
|
||||
BackGround = GifFile -> SBackGroundColor;
|
||||
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
|
||||
GifFile -> SColorMap);
|
||||
DumpScreen2Epsn(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);
|
||||
|
||||
if (DGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Routine to evaluate dithered scanlines out of given ones, using Size *
|
||||
* dithering matrix, starting from Row. The given scanlines are NOT modified. *
|
||||
*****************************************************************************/
|
||||
static void EvalDitheredScanline(GifRowType *ScreenBuffer, int Row,
|
||||
int RowSize, GifRowType *DitherBuffer)
|
||||
{
|
||||
static char Dither2[2][2] = { /* See Foley & Van Dam pp. 597-601. */
|
||||
{ 1, 3 },
|
||||
{ 4, 2 }
|
||||
};
|
||||
static char Dither3[3][3] = {
|
||||
{ 7, 9, 5 },
|
||||
{ 2, 1, 4 },
|
||||
{ 6, 3, 8 }
|
||||
};
|
||||
static char Dither4[4][4] = {
|
||||
{ 1, 9, 3, 11 },
|
||||
{ 13, 5, 15, 7 },
|
||||
{ 4, 12, 2, 10 },
|
||||
{ 16, 8, 14, 6 }
|
||||
};
|
||||
int i, j, k, Level;
|
||||
long Intensity;
|
||||
GifColorType *ColorMapEntry;
|
||||
|
||||
/* Scan the Rows (Size rows) evaluate intensity every Size pixel and use */
|
||||
/* the dither matrix to set the dithered result; */
|
||||
for (i = 0; i <= RowSize - DitherSize; i += DitherSize) {
|
||||
Intensity = 0;
|
||||
for (j = Row; j < Row + DitherSize; j++)
|
||||
for (k = 0; k < DitherSize; k++) {
|
||||
ColorMapEntry = &ColorMap[ScreenBuffer[j][i+k]];
|
||||
Intensity += 30 * ((int) ColorMapEntry->Red) +
|
||||
59 * ((int) ColorMapEntry->Green) +
|
||||
11 * ((int) ColorMapEntry->Blue);
|
||||
}
|
||||
|
||||
/* Find the intensity level (between 0 and Size^2) of our matrix: */
|
||||
/* Expression is "Intensity * BWThreshold / (25500 * DefThresh)" */
|
||||
/* but to prevent from overflow in the long evaluation we do this: */
|
||||
Level = ((Intensity / 2550) * ((long) DEFAULT_THRESHOLD) /
|
||||
(((long) BWThreshold) * 10));
|
||||
switch (DitherSize) {
|
||||
case 2:
|
||||
for (j = 0; j < DitherSize; j++)
|
||||
for (k = 0; k < DitherSize; k++)
|
||||
DitherBuffer[j][i+k] = Dither2[j][k] <= Level;
|
||||
break;
|
||||
case 3:
|
||||
for (j = 0; j < DitherSize; j++)
|
||||
for (k = 0; k < DitherSize; k++)
|
||||
DitherBuffer[j][i+k] = Dither3[j][k] <= Level;
|
||||
break;
|
||||
case 4:
|
||||
for (j = 0; j < DitherSize; j++)
|
||||
for (k = 0; k < DitherSize; k++)
|
||||
DitherBuffer[j][i+k] = Dither4[j][k] <= Level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The real dumping routine. Few things are taken into account: *
|
||||
* 1. The Nice flag. If TRUE each pixel is printed twice in double density. *
|
||||
* 2. The Invert flag. If TRUE each pixel before drawn is inverted. *
|
||||
* 3. The rendering mode and dither matrix flag if dithering is selected. *
|
||||
* The image is drawn from ScreenBuffer ScreenTop/Left in the bottom/right *
|
||||
* directions. *
|
||||
* Unfortunatelly, there is a BUG in DOS that does not handle ctrl-Z *
|
||||
* correctly if we open lptx: device in binary mode (should treat it as any *
|
||||
* other char). Therefore I had to write to it directly using biosprint. I *
|
||||
* dont like it either, and if you have better way to do it, let me know. *
|
||||
******************************************************************************/
|
||||
static void DumpScreen2Epsn(GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight)
|
||||
{
|
||||
int i, j, p, Size, LeftCWidth, Len, DirectPrint = 0,
|
||||
DitheredLinesLeft = 0, DitheredLinesCount = 0, MapInvert[2];
|
||||
char LinePrefixLen[2]; /* Length of scan line. */
|
||||
GifByteType *EpsonBuffer;
|
||||
GifPixelType *Line;
|
||||
GifRowType *DitherBuffer;
|
||||
GifColorType *ColorMapEntry;
|
||||
FILE *Prt = NULL;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
for (i = 0; i < strlen(PrinterName); i++)
|
||||
if (islower(PrinterName[i]))
|
||||
PrinterName[i] = toupper(PrinterName[i]);
|
||||
|
||||
if (strcmp(PrinterName, "LPT1") == 0 ||
|
||||
strcmp(PrinterName, "PRN") == 0)
|
||||
DirectPrint = 1;
|
||||
else if (strcmp(PrinterName, "LPT2") == 0)
|
||||
DirectPrint = 2;
|
||||
else if (strcmp(PrinterName, "LPT3") == 0)
|
||||
DirectPrint = 3;
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
if (!DirectPrint) {
|
||||
#ifdef __MSDOS__
|
||||
if (strlen(PrinterName) == 0) {
|
||||
setmode(1, O_BINARY); /* Make sure it is in binary mode. */
|
||||
Prt = stdout;
|
||||
}
|
||||
else if ((Prt = fopen(PrinterName, "wb")) == NULL ||
|
||||
setvbuf(Prt, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE))
|
||||
#else
|
||||
if (strlen(PrinterName) == 0)
|
||||
Prt = stdout;
|
||||
else if ((Prt = fopen(PrinterName, "w")) == NULL)
|
||||
#endif /* __MSDOS__ */
|
||||
GIF_EXIT("Failed to open output (printer) file.");
|
||||
}
|
||||
|
||||
if ((EpsonBuffer = (GifByteType *) malloc(ScreenWidth)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
/* Allocate the buffer to save the dithered information. */
|
||||
if (ColorToBWMapping == C2BW_DITHER) {
|
||||
if ((DitherBuffer = (GifRowType *)
|
||||
malloc(DITHER_MAX_MATRIX * sizeof(GifRowType *))) != NULL) {
|
||||
Size = ScreenWidth * sizeof(GifPixelType); /* Size of one row. */
|
||||
for (i = 0; i < DITHER_MAX_MATRIX; i++) {
|
||||
if ((DitherBuffer[i] = (GifRowType) malloc(Size)) == NULL) {
|
||||
DitherBuffer = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DitherBuffer == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
}
|
||||
else
|
||||
DitherBuffer = NULL;
|
||||
|
||||
/* Reset the printer, and make sure no space between adjacent lines: */
|
||||
PutString(Prt, DirectPrint, EPSON_RESET, 2);
|
||||
PutString(Prt, DirectPrint, EPSON_VERTICAL_SPACE, 3);
|
||||
|
||||
/* Prepar left spacing to begin with, so image will be in the middle. */
|
||||
LeftCWidth = (EPSON_WIDTH - (ScreenWidth / EPSON_PIXEL_2_CHAR)) / 2;
|
||||
|
||||
if (InvertFlag) { /* Make the inversion as fast a possible. */
|
||||
MapInvert[0] = 1;
|
||||
MapInvert[1] = 0;
|
||||
}
|
||||
else {
|
||||
MapInvert[0] = 0;
|
||||
MapInvert[1] = 1;
|
||||
}
|
||||
|
||||
for (i = 0, p = 0; i < ScreenHeight; i++, p++) {
|
||||
GifQprintf("\b\b\b\b%-4d", ScreenHeight - i);
|
||||
Line = ScreenBuffer[i];
|
||||
|
||||
/* If 8 lines were accumulated in printer buffer - dump them out. */
|
||||
if (p == 8) {
|
||||
for (Len = ScreenWidth-1; Len >= 0; Len--)
|
||||
if (EpsonBuffer[Len]) break;
|
||||
|
||||
/* Only in case this line is not empty: */
|
||||
if (Len++ >= 0) {
|
||||
/* Make the left space, so image will be centered: */
|
||||
for (j = 0; j < LeftCWidth; j++)
|
||||
PutString(Prt, DirectPrint, " ", 1);
|
||||
|
||||
/* Full printer line is ready to be dumped - send it out: */
|
||||
if (NiceFlag) {
|
||||
PutString(Prt, DirectPrint, EPSON_DUAL_DENSITY, 2);
|
||||
LinePrefixLen[0] = (Len * 2) % 256;
|
||||
LinePrefixLen[1] = (Len * 2) / 256;
|
||||
PutString(Prt, DirectPrint, LinePrefixLen, 2);
|
||||
PutString2(Prt, DirectPrint, (char *) EpsonBuffer, Len);
|
||||
}
|
||||
else {
|
||||
PutString(Prt, DirectPrint, EPSON_REG_DENSITY, 2);
|
||||
LinePrefixLen[0] = Len % 256;
|
||||
LinePrefixLen[1] = Len / 256;
|
||||
PutString(Prt, DirectPrint, LinePrefixLen, 2);
|
||||
PutString(Prt, DirectPrint, (char *) EpsonBuffer, Len);
|
||||
}
|
||||
}
|
||||
PutString(Prt, DirectPrint, "\015\012", 2);
|
||||
p = 0;
|
||||
}
|
||||
|
||||
/* We decide right here what method to map Colors to BW so the inner */
|
||||
/* loop will be independent of it (and therefore faster): */
|
||||
switch(ColorToBWMapping) {
|
||||
case C2BW_BACK_GROUND:
|
||||
for (j = 0; j < ScreenWidth; j++)
|
||||
EpsonBuffer[j] = (EpsonBuffer[j] << 1) +
|
||||
MapInvert[Line[j] != BackGround];
|
||||
break;
|
||||
case C2BW_GREY_LEVELS:
|
||||
for (j = 0; j < ScreenWidth; j++) {
|
||||
ColorMapEntry = &ColorMap[Line[j]];
|
||||
/* For the transformation from RGB to BW, see Folley & */
|
||||
/* Van Dam pp 613: The Y channel is the BW we need: */
|
||||
/* As colors are 255 maximum, the result can be up to */
|
||||
/* 25500 which is still in range of our 16 bits integers */
|
||||
EpsonBuffer[j] = (EpsonBuffer[j] << 1) +
|
||||
MapInvert[(30 * (int) ColorMapEntry->Red) +
|
||||
59 * ((int) ColorMapEntry->Green) +
|
||||
11 * ((int) ColorMapEntry->Blue) >
|
||||
BWThreshold];
|
||||
}
|
||||
break;
|
||||
case C2BW_DITHER:
|
||||
if (DitheredLinesLeft-- == 0) {
|
||||
EvalDitheredScanline(ScreenBuffer,
|
||||
(i < ScreenHeight - DitherSize ? i :
|
||||
ScreenHeight - DitherSize),
|
||||
ScreenWidth, DitherBuffer);
|
||||
DitheredLinesLeft = DitherSize - 1;
|
||||
DitheredLinesCount = 0;
|
||||
}
|
||||
Line = DitherBuffer[DitheredLinesCount++];
|
||||
for (j = 0; j < ScreenWidth; j++)
|
||||
EpsonBuffer[j] = (EpsonBuffer[j] << 1) +
|
||||
MapInvert[Line[j]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If buffer in incomplete - complete it and dump it out: */
|
||||
if (p != 0) {
|
||||
for (Len = ScreenWidth - 1; Len >= 0; Len--)
|
||||
if (EpsonBuffer[Len]) break;
|
||||
if (Len++ >= 0) {
|
||||
i = 8 - p; /* Amount to shift. */
|
||||
for (j = 0; j < ScreenWidth; j++) EpsonBuffer[j] <<= i;
|
||||
|
||||
/* Make the left space, so image will be centered: */
|
||||
for (j = 0; j < LeftCWidth; j++)
|
||||
PutString(Prt, DirectPrint, " ", 1);
|
||||
|
||||
if (NiceFlag) {
|
||||
PutString(Prt, DirectPrint, EPSON_DUAL_DENSITY, 2);
|
||||
LinePrefixLen[0] = (Len * 2) % 256;
|
||||
LinePrefixLen[1] = (Len * 2) / 256;
|
||||
PutString(Prt, DirectPrint, LinePrefixLen, 2);
|
||||
PutString2(Prt, DirectPrint, (char *) EpsonBuffer, Len);
|
||||
}
|
||||
else {
|
||||
PutString(Prt, DirectPrint, EPSON_REG_DENSITY, 2);
|
||||
LinePrefixLen[0] = Len % 256;
|
||||
LinePrefixLen[1] = Len / 256;
|
||||
PutString(Prt, DirectPrint, LinePrefixLen, 2);
|
||||
PutString(Prt, DirectPrint, (char *) EpsonBuffer, Len);
|
||||
}
|
||||
}
|
||||
PutString(Prt, DirectPrint, "\015\012", 2);
|
||||
}
|
||||
|
||||
fclose(Prt);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Dumps the string of given length, to Prt. No char in Str has special *
|
||||
* meaning, and even zero (NULL) chars are dumped. *
|
||||
* If however DirectPrint is non zero, string is dumped to specifed lpt port. *
|
||||
******************************************************************************/
|
||||
static void PutString(FILE *Prt, int DirectPrint, char *Str, int Len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (DirectPrint) {
|
||||
#ifdef __MSDOS__
|
||||
for (i = 0; i < Len; i++) biosprint(0, Str[i], DirectPrint - 1);
|
||||
#else
|
||||
GIF_EXIT("Can not print directly to a printer if not MSDOS.");
|
||||
#endif /* __MSDOS__ */
|
||||
}
|
||||
else
|
||||
for (i = 0; i < Len; i++) fputc(Str[i], Prt);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Dumps the string of given length, to Prt. No char in Str has special *
|
||||
* meaning, and even zero (NULL) chars are dumped. Every char is dumped twice. *
|
||||
* If however DirectPrint is non zero, string is dumped to specifed lpt port. *
|
||||
******************************************************************************/
|
||||
static void PutString2(FILE *Prt, int DirectPrint, char *Str, int Len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (DirectPrint) {
|
||||
#ifdef __MSDOS__
|
||||
for (i = 0; i < Len; i++) {
|
||||
biosprint(0, Str[i], DirectPrint - 1);
|
||||
biosprint(0, Str[i], DirectPrint - 1);
|
||||
}
|
||||
#else
|
||||
GIF_EXIT("Can not print directly to a printer if not MSDOS.");
|
||||
#endif /* __MSDOS__ */
|
||||
}
|
||||
else
|
||||
for (i = 0; i < Len; i++) {
|
||||
fputc(Str[i], Prt);
|
||||
fputc(Str[i], Prt);
|
||||
}
|
||||
}
|
1108
G/UTIL/GIF2HERC.C
Normal file
1108
G/UTIL/GIF2HERC.C
Normal file
File diff suppressed because it is too large
Load Diff
283
G/UTIL/GIF2IRIS.C
Normal file
283
G/UTIL/GIF2IRIS.C
Normal file
@ -0,0 +1,283 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber UNIX Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to display GIF file under X11 window system. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -f : force the process to be in foreground. *
|
||||
* -p PosX PosY : defines the position where to put the image. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 13 mar 90 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include "gl.h"
|
||||
#include "device.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "Gif2Iris"
|
||||
|
||||
#define ABS(x) ((x) > 0 ? (x) : (-(x)))
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Gif2Iris q%- f%- p%-PosX|PosY!d!d h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- f%- p%-PosX|PosY!d!d h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
PosFlag = FALSE,
|
||||
HelpFlag = FALSE,
|
||||
ForeGroundFlag = FALSE,
|
||||
ColorMapSize = 0,
|
||||
BackGround = 0,
|
||||
IrisPosX = 0,
|
||||
IrisPosY = 0,
|
||||
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
|
||||
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
|
||||
static GifColorType
|
||||
*ColorMap;
|
||||
|
||||
static void Screen2Iris(GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Error, NumFiles, ImageNum = 0, Size, Row, Col, Width, Height,
|
||||
ExtCode, Count;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char **FileName = NULL;
|
||||
GifRowType *ScreenBuffer;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&GifQuitePrint, &ForeGroundFlag,
|
||||
&PosFlag, &IrisPosX, &IrisPosY,
|
||||
&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 ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the screen 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: */
|
||||
/* Note this screen is device independent - its the screen as defined by */
|
||||
/* the GIF file parameters itself. */
|
||||
if ((ScreenBuffer = (GifRowType *)
|
||||
malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
|
||||
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
|
||||
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
|
||||
for (i = 1; i < GifFile -> SHeight; i++) {
|
||||
/* Allocate the other rows, and set their color to background too: */
|
||||
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
|
||||
}
|
||||
|
||||
/* Scan the content of the GIF file and load the image(s) in: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
Row = GifFile -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFile -> ILeft;
|
||||
Width = GifFile -> IWidth;
|
||||
Height = GifFile -> IHeight;
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
|
||||
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
|
||||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
|
||||
fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (GifFile -> IInterlace) {
|
||||
/* Need to perform 4 passes on the images: */
|
||||
for (Count = i = 0; i < 4; i++)
|
||||
for (j = Row + InterlacedOffset[i]; j < Row + Height;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
/* Lets display it - set the global variables required and do it: */
|
||||
BackGround = GifFile -> SBackGroundColor;
|
||||
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
|
||||
GifFile -> SColorMap);
|
||||
ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
|
||||
GifFile -> SBitsPerPixel);
|
||||
GifQprintf("\n");
|
||||
Screen2Iris(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);
|
||||
|
||||
if (DGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The real display routine. *
|
||||
******************************************************************************/
|
||||
static void Screen2Iris(GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight)
|
||||
{
|
||||
short Val;
|
||||
int i, j;
|
||||
unsigned long *IrisScreenBuffer, *PBuffer;
|
||||
|
||||
if (ScreenWidth > XMAXSCREEN + 1 ||
|
||||
ScreenHeight > YMAXSCREEN + 1)
|
||||
GIF_EXIT("Input image is too big.");
|
||||
|
||||
if (PosFlag)
|
||||
prefposition(IrisPosX, IrisPosX + ScreenWidth - 1,
|
||||
IrisPosY, IrisPosY + ScreenHeight - 1);
|
||||
else
|
||||
prefsize(ScreenWidth, ScreenHeight);
|
||||
if (ForeGroundFlag)
|
||||
foreground();
|
||||
|
||||
winopen(PROGRAM_NAME);
|
||||
RGBmode();
|
||||
gconfig();
|
||||
if ((IrisScreenBuffer = (unsigned long *)
|
||||
malloc(ScreenWidth * ScreenHeight * sizeof(unsigned long))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
PBuffer = IrisScreenBuffer;
|
||||
for (i = ScreenHeight - 1; i >= 0; i--)
|
||||
for (j = 0; j < ScreenWidth; j++)
|
||||
*PBuffer++ = ColorMap[ScreenBuffer[i][j]].Red +
|
||||
(ColorMap[ScreenBuffer[i][j]].Green << 8) +
|
||||
(ColorMap[ScreenBuffer[i][j]].Blue << 16);
|
||||
|
||||
reshapeviewport();
|
||||
lrectwrite(0, 0, ScreenWidth - 1, ScreenHeight - 1, IrisScreenBuffer);
|
||||
|
||||
while (TRUE) {
|
||||
if (qread(&Val) == REDRAW) {
|
||||
reshapeviewport();
|
||||
lrectwrite(0, 0, ScreenWidth - 1, ScreenHeight - 1,
|
||||
IrisScreenBuffer);
|
||||
}
|
||||
}
|
||||
}
|
387
G/UTIL/GIF2PS.C
Normal file
387
G/UTIL/GIF2PS.C
Normal file
@ -0,0 +1,387 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to dump GIF file into PostScript type printers *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -x : force image to be horizontal. *
|
||||
* -y : force image to be vertical. *
|
||||
* -s x y : force image to be of given size. *
|
||||
* -p x y : force image to be positioned at given position in page. *
|
||||
* -i : invert the image. *
|
||||
* -n n : number of copies. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 22 Dec 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "Gif2PS"
|
||||
|
||||
#define PAGE_WIDTH 7.5 /* All dimensions are in inches. */
|
||||
#define PAGE_HEIGHT 9.0
|
||||
#define FULL_PAGE_WIDTH 8.5
|
||||
#define FULL_PAGE_HEIGHT 11.0
|
||||
|
||||
#define UNKNOWN_ORIENT 0
|
||||
#define HORIZONTAL_ORIENT 1
|
||||
#define VERTICAL_ORIENT 2
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Gif2PS q%- x%- y%- s%-SizeX|SizeY!F!F p%-PosX|PosY!F!F i%- n%-#Copies!d h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- x%- y%- s%-SizeX|SizeY!F!F p%-PosX|PosY!F!F i%- n%-#Copies!d h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ImageNum = 0,
|
||||
BackGround = 0,
|
||||
ForceXFlag = FALSE,
|
||||
ForceYFlag = FALSE,
|
||||
SizeFlag = FALSE,
|
||||
PosFlag = FALSE,
|
||||
InvertFlag = FALSE,
|
||||
NumCopiesFlag = FALSE,
|
||||
HelpFlag = FALSE,
|
||||
NumOfCopies = 1,
|
||||
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
|
||||
InterlacedJumps[] = { 8, 8, 4, 2 }, /* be read - offsets and jumps... */
|
||||
PSOrientation;
|
||||
static double PSSizeX, PSSizeY, PSPosX, PSPosY;
|
||||
static GifColorType
|
||||
*ColorMap;
|
||||
|
||||
static void DumpScreen2PS(GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight);
|
||||
static void PutString(unsigned char *Line, int Len);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char **FileName = NULL;
|
||||
GifRowType *ScreenBuffer;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,&GifQuitePrint,
|
||||
&ForceXFlag, &ForceYFlag, &SizeFlag, &PSSizeX, &PSSizeY,
|
||||
&PosFlag, &PSPosX, &PSPosY,
|
||||
&InvertFlag, &NumCopiesFlag, &NumOfCopies, &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 (ForceXFlag)
|
||||
PSOrientation = HORIZONTAL_ORIENT;
|
||||
else if (ForceYFlag)
|
||||
PSOrientation = VERTICAL_ORIENT;
|
||||
else
|
||||
PSOrientation = UNKNOWN_ORIENT;
|
||||
|
||||
if (NumFiles == 1) {
|
||||
if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the screen 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: */
|
||||
/* Note this screen is device independent - its the screen as defined by */
|
||||
/* the GIF file parameters itself. */
|
||||
if ((ScreenBuffer = (GifRowType *)
|
||||
malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
|
||||
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
|
||||
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
|
||||
for (i = 1; i < GifFile -> SHeight; i++) {
|
||||
/* Allocate the other rows, and set their color to background too: */
|
||||
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
|
||||
}
|
||||
|
||||
/* Scan the content of the GIF file and load the image(s) in: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
Row = GifFile -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFile -> ILeft;
|
||||
Width = GifFile -> IWidth;
|
||||
Height = GifFile -> IHeight;
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
|
||||
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
|
||||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
|
||||
fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (GifFile -> IInterlace) {
|
||||
/* Need to perform 4 passes on the images: */
|
||||
for (Count = i = 0; i < 4; i++)
|
||||
for (j = Row + InterlacedOffset[i]; j < Row + Height;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
/* Lets display it - set the global variables required and do it: */
|
||||
BackGround = GifFile -> SBackGroundColor;
|
||||
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
|
||||
GifFile -> SColorMap);
|
||||
DumpScreen2PS(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);
|
||||
|
||||
if (DGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The real dumping routine. *
|
||||
******************************************************************************/
|
||||
static void DumpScreen2PS(GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight)
|
||||
{
|
||||
int i, j;
|
||||
double Aspect;
|
||||
GifByteType *OutLine, Data;
|
||||
GifPixelType *Line;
|
||||
GifColorType *ColorMapEntry;
|
||||
|
||||
/* If user did not enforce orientation, pick the best one. */
|
||||
if (PSOrientation == UNKNOWN_ORIENT)
|
||||
if (ScreenWidth > ScreenHeight)
|
||||
PSOrientation = VERTICAL_ORIENT;
|
||||
else
|
||||
PSOrientation = HORIZONTAL_ORIENT;
|
||||
|
||||
Aspect = ((double) ScreenHeight) / ((double) ScreenWidth);
|
||||
|
||||
if (!SizeFlag)
|
||||
switch (PSOrientation) {
|
||||
case HORIZONTAL_ORIENT:
|
||||
if (Aspect > PAGE_HEIGHT / PAGE_WIDTH) {
|
||||
PSSizeX = PAGE_HEIGHT / Aspect;
|
||||
PSSizeY = PAGE_HEIGHT;
|
||||
}
|
||||
else {
|
||||
PSSizeX = PAGE_WIDTH;
|
||||
PSSizeY = PAGE_WIDTH * Aspect;
|
||||
}
|
||||
break;
|
||||
case VERTICAL_ORIENT:
|
||||
if (1 / Aspect > PAGE_HEIGHT / PAGE_WIDTH) {
|
||||
PSSizeX = PAGE_HEIGHT * Aspect;
|
||||
PSSizeY = PAGE_HEIGHT;
|
||||
}
|
||||
else {
|
||||
PSSizeX = PAGE_WIDTH;
|
||||
PSSizeY = PAGE_WIDTH / Aspect;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (PAGE_WIDTH < PSSizeX) {
|
||||
GIF_MESSAGE("X Size specified is too big, page size selected.");
|
||||
PSSizeX = PAGE_WIDTH;
|
||||
}
|
||||
if (PAGE_HEIGHT < PSSizeY) {
|
||||
GIF_MESSAGE("Y Size specified is too big, page size selected.");
|
||||
PSSizeX = PAGE_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PosFlag) {
|
||||
PSPosX = (FULL_PAGE_WIDTH - PSSizeX) / 2;
|
||||
PSPosY = (FULL_PAGE_HEIGHT - PSSizeY) / 2;
|
||||
}
|
||||
else {
|
||||
if (PSPosX + PSSizeX > PAGE_WIDTH || PSPosY + PSSizeY > PAGE_HEIGHT)
|
||||
GIF_EXIT("Requested position will put image out of page, aborted.");
|
||||
}
|
||||
|
||||
/* Time to dump out the PostScript header: */
|
||||
printf("%%!\n");
|
||||
printf("%%%%Creator: %s\n", PROGRAM_NAME);
|
||||
printf("/#copies %d def\n", NumOfCopies);
|
||||
printf("gsave\n");
|
||||
printf("72 72 scale\t\t\t\t%% Lets talk inches.\n");
|
||||
printf("/oneline %d string def\t\t\t%% Allocate one scan line.\n",
|
||||
ScreenWidth);
|
||||
printf("/drawimage {\n");
|
||||
printf("\t%d %d 8 [%d 0 0 %d 0 %d]\n", ScreenWidth, ScreenHeight,
|
||||
ScreenWidth, -ScreenHeight, ScreenHeight);
|
||||
printf("\t{ currentfile oneline readhexstring pop } image\n");
|
||||
printf("} def\n");
|
||||
switch (PSOrientation) {
|
||||
case HORIZONTAL_ORIENT:
|
||||
printf("%lf %lf translate\n", PSPosX, PSPosY);
|
||||
printf("%lf %lf scale\n", PSSizeX, PSSizeY);
|
||||
break;
|
||||
case VERTICAL_ORIENT:
|
||||
printf("%lf %lf translate\n", PSPosX + PSSizeX, PSPosY);
|
||||
printf("90 rotate\n");
|
||||
printf("%lf %lf scale\n", PSSizeY, PSSizeX);
|
||||
break;
|
||||
}
|
||||
printf("drawimage\n");
|
||||
|
||||
if ((OutLine = (GifByteType *) malloc(sizeof(GifByteType) * ScreenWidth))
|
||||
== NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < ScreenHeight; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", ScreenHeight - i);
|
||||
|
||||
Line = ScreenBuffer[i];
|
||||
for (j = 0; j < ScreenWidth; j++) {
|
||||
ColorMapEntry = &ColorMap[Line[j]];
|
||||
Data = (30 * ((unsigned int) ColorMapEntry->Red) +
|
||||
59 * ((unsigned int) ColorMapEntry->Green) +
|
||||
11 * ((unsigned int) ColorMapEntry->Blue)) / 100;
|
||||
OutLine[j] = InvertFlag ? 255 - Data : Data;
|
||||
}
|
||||
|
||||
PutString(OutLine, ScreenWidth);
|
||||
}
|
||||
free(OutLine);
|
||||
|
||||
printf("\nshowpage\n");
|
||||
printf("grestore\n");
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Dumps the string of given length as 2 hexdigits per byte 39 bytes per line. *
|
||||
******************************************************************************/
|
||||
static void PutString(unsigned char *Line, int Len)
|
||||
{
|
||||
int i;
|
||||
static Counter = 0;
|
||||
static char *Hex = "0123456789ABCDEF";
|
||||
|
||||
for (i = 0; i < Len; i++) {
|
||||
if (++Counter % 40 == 0) {
|
||||
putchar('\n');
|
||||
Counter = 1;
|
||||
}
|
||||
putchar(Hex[Line[i] >> 4]);
|
||||
putchar(Hex[Line[i] & 0x0f]);
|
||||
}
|
||||
}
|
337
G/UTIL/GIF2RGB.C
Normal file
337
G/UTIL/GIF2RGB.C
Normal file
@ -0,0 +1,337 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to convert GIF file to RGB 24 bits. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -1 : dump as one file using RGBRGB triples. *
|
||||
* -h : on line help. *
|
||||
* -o FileName : specify the output file name(s). *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 5 Jan 90 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "Gif2RGB"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Gif2RGB q%- 1%- o%-OutFileName!s h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- 1%- o%-OutFileName!s h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ImageNum = 0,
|
||||
BackGround = 0,
|
||||
OneFileFlag = FALSE,
|
||||
HelpFlag = FALSE,
|
||||
ColorMapSize = 0,
|
||||
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
|
||||
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
|
||||
static GifColorType
|
||||
*ColorMap;
|
||||
|
||||
static void DumpScreen2RGB(char *FileName, int OneFileFlag,
|
||||
GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count,
|
||||
OutFileFlag = FALSE;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char *OutFileName,
|
||||
**FileName = NULL;
|
||||
GifRowType *ScreenBuffer;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&OneFileFlag, &OutFileFlag, &OutFileName,
|
||||
&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 (!OutFileFlag) OutFileName = NULL;
|
||||
|
||||
if (NumFiles == 1) {
|
||||
if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the screen 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: */
|
||||
/* Note this screen is device independent - its the screen as defined by */
|
||||
/* the GIF file parameters itself. */
|
||||
if ((ScreenBuffer = (GifRowType *)
|
||||
malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
|
||||
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
|
||||
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
|
||||
for (i = 1; i < GifFile -> SHeight; i++) {
|
||||
/* Allocate the other rows, and set their color to background too: */
|
||||
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
|
||||
}
|
||||
|
||||
/* Scan the content of the GIF file and load the image(s) in: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
Row = GifFile -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFile -> ILeft;
|
||||
Width = GifFile -> IWidth;
|
||||
Height = GifFile -> IHeight;
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
|
||||
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
|
||||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
|
||||
fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (GifFile -> IInterlace) {
|
||||
/* Need to perform 4 passes on the images: */
|
||||
for (Count = i = 0; i < 4; i++)
|
||||
for (j = Row + InterlacedOffset[i]; j < Row + Height;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
/* Lets dump it - set the global variables required and do it: */
|
||||
BackGround = GifFile -> SBackGroundColor;
|
||||
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
|
||||
GifFile -> SColorMap);
|
||||
ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
|
||||
GifFile -> SBitsPerPixel);
|
||||
DumpScreen2RGB(OutFileName, OneFileFlag,
|
||||
ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);
|
||||
|
||||
if (DGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The real dumping routine. *
|
||||
******************************************************************************/
|
||||
static void DumpScreen2RGB(char *FileName, int OneFileFlag,
|
||||
GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight)
|
||||
{
|
||||
int i, j;
|
||||
GifRowType GifRow;
|
||||
static GifColorType
|
||||
*ColorMapEntry;
|
||||
FILE *f[3];
|
||||
|
||||
if (FileName != NULL) {
|
||||
char OneFileName[80];
|
||||
|
||||
if (OneFileFlag) {
|
||||
#ifdef __MSDOS__
|
||||
if ((f[0] = fopen(FileName, "wb")) == NULL)
|
||||
#else
|
||||
if ((f[0] = fopen(FileName, "w")) == NULL)
|
||||
#endif /* __MSDOS__ */
|
||||
GIF_EXIT("Can't open input file name.");
|
||||
}
|
||||
else {
|
||||
static char *Postfixes[] = { ".R", ".G", ".B" };
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
strcpy(OneFileName, FileName);
|
||||
strcat(OneFileName, Postfixes[i]);
|
||||
|
||||
#ifdef __MSDOS__
|
||||
if ((f[i] = fopen(OneFileName, "wb")) == NULL)
|
||||
#else
|
||||
if ((f[i] = fopen(OneFileName, "w")) == NULL)
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
GIF_EXIT("Can't open input file name.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
OneFileFlag = TRUE;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
f[0] = stdout;
|
||||
}
|
||||
|
||||
if (OneFileFlag) {
|
||||
unsigned char *Buffer, *BufferP;
|
||||
|
||||
if ((Buffer = (unsigned char *) malloc(ScreenWidth * 3)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < ScreenHeight; i++) {
|
||||
GifRow = ScreenBuffer[i];
|
||||
GifQprintf("\b\b\b\b%-4d", ScreenHeight - i);
|
||||
for (j = 0, BufferP = Buffer; j < ScreenWidth; j++) {
|
||||
ColorMapEntry = &ColorMap[GifRow[j]];
|
||||
*BufferP++ = ColorMapEntry -> Red;
|
||||
*BufferP++ = ColorMapEntry -> Green;
|
||||
*BufferP++ = ColorMapEntry -> Blue;
|
||||
}
|
||||
if (fwrite(Buffer, ScreenWidth * 3, 1, f[0]) != 1)
|
||||
GIF_EXIT("Write to file(s) failed.");
|
||||
}
|
||||
|
||||
free((char *) Buffer);
|
||||
fclose(f[0]);
|
||||
}
|
||||
else {
|
||||
unsigned char *Buffers[3];
|
||||
|
||||
if ((Buffers[0] = (unsigned char *) malloc(ScreenWidth)) == NULL ||
|
||||
(Buffers[1] = (unsigned char *) malloc(ScreenWidth)) == NULL ||
|
||||
(Buffers[2] = (unsigned char *) malloc(ScreenWidth)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < ScreenHeight; i++) {
|
||||
GifRow = ScreenBuffer[i];
|
||||
GifQprintf("\b\b\b\b%-4d", ScreenHeight - i);
|
||||
for (j = 0; j < ScreenWidth; j++) {
|
||||
ColorMapEntry = &ColorMap[GifRow[j]];
|
||||
Buffers[0][j] = ColorMapEntry -> Red;
|
||||
Buffers[1][j] = ColorMapEntry -> Green;
|
||||
Buffers[2][j] = ColorMapEntry -> Blue;
|
||||
}
|
||||
if (fwrite(Buffers[0], ScreenWidth, 1, f[0]) != 1 ||
|
||||
fwrite(Buffers[1], ScreenWidth, 1, f[1]) != 1 ||
|
||||
fwrite(Buffers[2], ScreenWidth, 1, f[2]) != 1)
|
||||
GIF_EXIT("Write to file(s) failed.");
|
||||
}
|
||||
|
||||
free((char *) Buffers[0]);
|
||||
free((char *) Buffers[1]);
|
||||
free((char *) Buffers[2]);
|
||||
fclose(f[0]);
|
||||
fclose(f[1]);
|
||||
fclose(f[2]);
|
||||
}
|
||||
}
|
276
G/UTIL/GIF2RLE.C
Normal file
276
G/UTIL/GIF2RLE.C
Normal file
@ -0,0 +1,276 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to convert GIF file RLE format (utah raster toolkit). *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -a : add alpha channel with full coverage. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 5 Jan 90 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#include "rle.h" /* The rle tool kit header files. */
|
||||
|
||||
#define PROGRAM_NAME "Gif2Rle"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Gif2Rle q%- a%- h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- a%- h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ImageNum = 0,
|
||||
BackGround = 0,
|
||||
AlphaFlag = FALSE,
|
||||
HelpFlag = FALSE,
|
||||
ColorMapSize = 0,
|
||||
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
|
||||
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
|
||||
static GifColorType
|
||||
*ColorMap;
|
||||
|
||||
static void DumpScreen2Rle(GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char **FileName = NULL;
|
||||
GifRowType *ScreenBuffer;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&AlphaFlag, &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 ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the screen 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: */
|
||||
/* Note this screen is device independent - its the screen as defined by */
|
||||
/* the GIF file parameters itself. */
|
||||
if ((ScreenBuffer = (GifRowType *)
|
||||
malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
|
||||
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
|
||||
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
|
||||
for (i = 1; i < GifFile -> SHeight; i++) {
|
||||
/* Allocate the other rows, and set their color to background too: */
|
||||
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
|
||||
}
|
||||
|
||||
/* Scan the content of the GIF file and load the image(s) in: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
Row = GifFile -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFile -> ILeft;
|
||||
Width = GifFile -> IWidth;
|
||||
Height = GifFile -> IHeight;
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
|
||||
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
|
||||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
|
||||
fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (GifFile -> IInterlace) {
|
||||
/* Need to perform 4 passes on the images: */
|
||||
for (Count = i = 0; i < 4; i++)
|
||||
for (j = Row + InterlacedOffset[i]; j < Row + Height;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
/* Lets display it - set the global variables required and do it: */
|
||||
BackGround = GifFile -> SBackGroundColor;
|
||||
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
|
||||
GifFile -> SColorMap);
|
||||
ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
|
||||
GifFile -> SBitsPerPixel);
|
||||
DumpScreen2Rle(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);
|
||||
|
||||
if (DGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The real dumping routine. *
|
||||
******************************************************************************/
|
||||
static void DumpScreen2Rle(GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight)
|
||||
{
|
||||
int i, j;
|
||||
char Comment[80];
|
||||
rle_pixel *rows[4];
|
||||
GifRowType GifRow;
|
||||
static GifColorType
|
||||
*ColorMapEntry;
|
||||
|
||||
if (AlphaFlag) RLE_SET_BIT(rle_dflt_hdr, RLE_ALPHA);
|
||||
rle_dflt_hdr.alpha = AlphaFlag != 0;
|
||||
rle_dflt_hdr.rle_file = stdout;
|
||||
rle_dflt_hdr.xmin = 0;
|
||||
rle_dflt_hdr.ymin = 0;
|
||||
rle_dflt_hdr.xmax = ScreenWidth - 1;
|
||||
rle_dflt_hdr.ymax = ScreenHeight - 1;
|
||||
sprintf(Comment, "origin=GIF format, %d colors.", ColorMapSize);
|
||||
rle_putcom(Comment, &rle_dflt_hdr);
|
||||
rle_put_setup(&rle_dflt_hdr);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
if ((rows[i] = (rle_pixel *) malloc(sizeof(rle_pixel) * ScreenWidth))
|
||||
== NULL)
|
||||
GIF_EXIT("Failed to allocated memory required, aborted.");
|
||||
|
||||
if (AlphaFlag) {
|
||||
/* Initial the alpha channel to full coverage: */
|
||||
for (i = 0; i < ScreenWidth; i++) rows[0][i] = 255;
|
||||
}
|
||||
|
||||
for (i = 0; i < ScreenHeight; i++) {
|
||||
/* Flip the image vertically as rle files start at the bollom... */
|
||||
GifRow = ScreenBuffer[ScreenHeight - i - 1];
|
||||
GifQprintf("\b\b\b\b%-4d", ScreenHeight - i);
|
||||
for (j = 0; j < ScreenWidth; j++) {
|
||||
ColorMapEntry = &ColorMap[GifRow[j]];
|
||||
rows[1][j] = ColorMapEntry -> Red;
|
||||
rows[2][j] = ColorMapEntry -> Green;
|
||||
rows[3][j] = ColorMapEntry -> Blue;
|
||||
}
|
||||
rle_putrow( &rows[1], ScreenWidth, &rle_dflt_hdr );
|
||||
}
|
||||
|
||||
rle_puteof( &rle_dflt_hdr );
|
||||
}
|
517
G/UTIL/GIF2X11.C
Normal file
517
G/UTIL/GIF2X11.C
Normal file
@ -0,0 +1,517 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to display GIF file under X11 window system. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -p PosX PosY : defines the position where to put the image. *
|
||||
* -d Display : what display should go to. *
|
||||
* -f : force attempt to allocate the exact colors. This usually look bad... *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 28 Dec 89 - Version 1.0 by Gershon Elber, color allocation is based on the *
|
||||
* xgif program by John Bradley, bradley@cis.ipenn.edu. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "Gif2X11"
|
||||
|
||||
#define ICON_SIZE 60
|
||||
#define ABS(x) ((x) > 0 ? (x) : (-(x)))
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Gif2X11 q%- p%-PosX|PosY!d!d d%-Display!s f%- h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- p%-PosX|PosY!d!d d%-Display!s f%- h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
PosFlag = FALSE,
|
||||
HelpFlag = FALSE,
|
||||
DisplayFlag = FALSE,
|
||||
ForceFlag = FALSE,
|
||||
ColorMapSize = 0,
|
||||
BackGround = 0,
|
||||
XPosX = 0,
|
||||
XPosY = 0,
|
||||
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
|
||||
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
|
||||
static char
|
||||
*DisplayName = NULL;
|
||||
static GifColorType
|
||||
*ColorMap;
|
||||
|
||||
/* X specific staff goes here. XColorTable will hold the GIF image colors, */
|
||||
/* while XPixelTable will hold the pixel number so we can redirect through */
|
||||
/* it when forming the image bitmap in X format. */
|
||||
/* Note the table has 256 entry which is the maximum allowed in GIF format. */
|
||||
static XColor XColorTable[256];
|
||||
static unsigned long XPixelTable[256];
|
||||
static Display *XDisplay;
|
||||
static int XScreen;
|
||||
static Window Xroot, XImageWndw;
|
||||
static Colormap XColorMap;
|
||||
static GC XGraphContext;
|
||||
static Visual *XVisual;
|
||||
static XImage *XImageBuffer;
|
||||
static Pixmap XIcon;
|
||||
static Cursor XCursor;
|
||||
|
||||
static void Screen2X(int argc, char **argv, GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight);
|
||||
static void AllocateColors1(void);
|
||||
static void AllocateColors2(void);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Error, NumFiles, ImageNum = 0, Size, Row, Col, Width, Height,
|
||||
ExtCode, Count;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char **FileName = NULL;
|
||||
GifRowType *ScreenBuffer;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&GifQuitePrint, &PosFlag, &XPosX, &XPosY,
|
||||
&DisplayFlag, &DisplayName, &ForceFlag,
|
||||
&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 ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lets see if we can get access to the X server before we even start: */
|
||||
if ((XDisplay = (Display *) XOpenDisplay(DisplayName)) == NULL)
|
||||
GIF_EXIT("Failed to access X server, abored.");
|
||||
XScreen = DefaultScreen(XDisplay);
|
||||
Xroot = RootWindow(XDisplay, XScreen);
|
||||
XColorMap = DefaultColormap(XDisplay, XScreen);
|
||||
XGraphContext = DefaultGC(XDisplay, XScreen);
|
||||
XVisual = DefaultVisual(XDisplay, XScreen);
|
||||
XSetBackground(XDisplay, XGraphContext, BlackPixel(XDisplay, XScreen));
|
||||
XSetForeground(XDisplay, XGraphContext, WhitePixel(XDisplay, XScreen));
|
||||
|
||||
/* Allocate the screen 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: */
|
||||
/* Note this screen is device independent - its the screen as defined by */
|
||||
/* the GIF file parameters itself. */
|
||||
if ((ScreenBuffer = (GifRowType *)
|
||||
malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
|
||||
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
|
||||
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
|
||||
for (i = 1; i < GifFile -> SHeight; i++) {
|
||||
/* Allocate the other rows, and set their color to background too: */
|
||||
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
|
||||
}
|
||||
|
||||
/* Scan the content of the GIF file and load the image(s) in: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
Row = GifFile -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFile -> ILeft;
|
||||
Width = GifFile -> IWidth;
|
||||
Height = GifFile -> IHeight;
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
|
||||
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
|
||||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
|
||||
fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (GifFile -> IInterlace) {
|
||||
/* Need to perform 4 passes on the images: */
|
||||
for (Count = i = 0; i < 4; i++)
|
||||
for (j = Row + InterlacedOffset[i]; j<Row + Height;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
/* Lets display it - set the global variables required and do it: */
|
||||
BackGround = GifFile -> SBackGroundColor;
|
||||
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
|
||||
GifFile -> SColorMap);
|
||||
ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
|
||||
GifFile -> SBitsPerPixel);
|
||||
Screen2X(argc, argv, ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);
|
||||
|
||||
if (DGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
GifQprintf("\n");
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The real display routine. *
|
||||
******************************************************************************/
|
||||
static void Screen2X(int argc, char **argv, GifRowType *ScreenBuffer,
|
||||
int ScreenWidth, int ScreenHeight)
|
||||
{
|
||||
int i, j, c, Size, x, y,
|
||||
MinIntensity, MaxIntensity, AvgIntensity, IconSizeX, IconSizeY;
|
||||
char *XImageData, *XIconData, KeyBuffer[81];
|
||||
double Aspect;
|
||||
GifByteType *OutLine, Data;
|
||||
unsigned long ValueMask;
|
||||
GifPixelType *Line;
|
||||
GifRowType *DitherBuffer;
|
||||
GifColorType *ColorMapEntry = ColorMap;
|
||||
XSetWindowAttributes SetWinAttr;
|
||||
XSizeHints Hints;
|
||||
XEvent Event;
|
||||
XExposeEvent *EEvent;
|
||||
XComposeStatus Stat;
|
||||
KeySym KS;
|
||||
|
||||
/* Let find out what are the intensities in the color map: */
|
||||
MaxIntensity = 0;
|
||||
MinIntensity = 256 * 100;
|
||||
for (i = 0; i < ColorMapSize; i++) {
|
||||
c = ColorMapEntry[i].Red * 30 +
|
||||
ColorMapEntry[i].Green * 59 +
|
||||
ColorMapEntry[i].Blue * 11;
|
||||
if (c > MaxIntensity) MaxIntensity = c;
|
||||
if (c < MinIntensity) MinIntensity = c;
|
||||
}
|
||||
AvgIntensity = (MinIntensity + MaxIntensity) / 2;
|
||||
|
||||
/* The big trick here is to select the colors so lets do this first: */
|
||||
if (ForceFlag)
|
||||
AllocateColors2();
|
||||
else
|
||||
AllocateColors1();
|
||||
|
||||
SetWinAttr.background_pixel = BlackPixel( XDisplay, XScreen );
|
||||
SetWinAttr.border_pixel = WhitePixel( XDisplay, XScreen );
|
||||
ValueMask = CWBackPixel | CWBorderPixel;
|
||||
|
||||
Hints.flags = PSize | PMinSize | PMaxSize;
|
||||
Hints.x = Hints.y = 1;
|
||||
Hints.width = Hints.min_width = Hints.max_width = ScreenWidth;
|
||||
Hints.height = Hints.min_height = Hints.max_height = ScreenHeight;
|
||||
if (PosFlag) {
|
||||
Hints.flags |= USPosition;
|
||||
Hints.x = XPosX;
|
||||
Hints.y = XPosY;
|
||||
}
|
||||
|
||||
XImageWndw = XCreateWindow(XDisplay, Xroot, XPosX, XPosY,
|
||||
ScreenWidth, ScreenHeight,
|
||||
1, 0,
|
||||
CopyFromParent, CopyFromParent,
|
||||
ValueMask, &SetWinAttr);
|
||||
|
||||
/* Set up the icon bit map to be a shrinked BW version of the image: */
|
||||
if (ScreenWidth > ScreenHeight) {
|
||||
IconSizeX = (ICON_SIZE / 8) * 8;
|
||||
IconSizeY = (ScreenHeight * ICON_SIZE) / ScreenWidth;
|
||||
}
|
||||
else {
|
||||
IconSizeY = ICON_SIZE;
|
||||
IconSizeX = (((ScreenWidth * ICON_SIZE) / ScreenHeight) / 8) * 8;
|
||||
}
|
||||
XIconData = (char *) malloc(IconSizeX * IconSizeY / 8);
|
||||
memset(XIconData, 0, IconSizeX * IconSizeY / 8);
|
||||
for (i = 0; i < IconSizeY; i++) {
|
||||
y = (i * ScreenHeight / IconSizeY);
|
||||
Size = i * IconSizeX / 8;
|
||||
for (j = 0; j < IconSizeX; j++) {
|
||||
x = j * ScreenWidth / IconSizeX;
|
||||
c = ScreenBuffer[y][x];
|
||||
c = ColorMapEntry[c].Red * 30 +
|
||||
ColorMapEntry[c].Green * 59 +
|
||||
ColorMapEntry[c].Blue * 11 > AvgIntensity;
|
||||
XIconData[Size + j / 8] |= c << (j % 8);
|
||||
}
|
||||
}
|
||||
|
||||
XIcon = XCreateBitmapFromData(XDisplay, XImageWndw, XIconData,
|
||||
IconSizeX, IconSizeY);
|
||||
|
||||
XSetStandardProperties(XDisplay, XImageWndw,
|
||||
PROGRAM_NAME, PROGRAM_NAME, XIcon,
|
||||
argv, argc,
|
||||
&Hints);
|
||||
|
||||
XSelectInput(XDisplay, XImageWndw, ExposureMask | KeyPressMask);
|
||||
|
||||
/* Set out own cursor: */
|
||||
XCursor = XCreateFontCursor(XDisplay, XC_diamond_cross);
|
||||
XDefineCursor(XDisplay, XImageWndw, XCursor);
|
||||
|
||||
XMapWindow(XDisplay, XImageWndw);
|
||||
|
||||
/* Create the image in X format: */
|
||||
if ((XImageData = (char *) malloc(ScreenWidth * ScreenHeight)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < ScreenHeight; i++) {
|
||||
y = i * ScreenWidth;
|
||||
for (j = 0; j < ScreenWidth; j++)
|
||||
XImageData[y + j] = XPixelTable[ScreenBuffer[i][j]];
|
||||
}
|
||||
XImageBuffer = XCreateImage(XDisplay, XVisual, 8, ZPixmap, 0,
|
||||
XImageData, ScreenWidth, ScreenHeight,
|
||||
8, ScreenWidth);
|
||||
|
||||
while (TRUE) {
|
||||
XNextEvent(XDisplay, &Event);
|
||||
switch (Event.type) {
|
||||
case Expose:
|
||||
EEvent = (XExposeEvent *) &Event;
|
||||
XPutImage(XDisplay, XImageWndw, XGraphContext, XImageBuffer,
|
||||
EEvent -> x, EEvent -> y,
|
||||
EEvent -> x, EEvent -> y,
|
||||
EEvent -> width, EEvent -> height);
|
||||
break;
|
||||
case KeyPress:
|
||||
XLookupString(&Event, KeyBuffer, 80, &KS, &Stat);
|
||||
if (KeyBuffer[0] == 3) return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to allocate the requested colors from the X server. *
|
||||
* Colors are allocated until success by stripping off the least bits of the *
|
||||
* colors. *
|
||||
******************************************************************************/
|
||||
static void AllocateColors1(void)
|
||||
{
|
||||
int Strip, Msk, i, j;
|
||||
char Msg[80];
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
XPixelTable[i] = 0; /* Put reasonable color for out of range. */
|
||||
|
||||
for (Strip = 0, Msk = 0xff; Strip < 8; Strip++, Msk <<= 1) {
|
||||
for (i = 0; i < ColorMapSize; i++) {
|
||||
/* Prepere color entry in X format. */
|
||||
XColorTable[i].red = (ColorMap[i].Red & Msk) << 8;
|
||||
XColorTable[i].green = (ColorMap[i].Green & Msk) << 8;
|
||||
XColorTable[i].blue = (ColorMap[i].Blue & Msk) << 8;
|
||||
XColorTable[i].flags = DoRed | DoGreen | DoBlue;
|
||||
if (XAllocColor(XDisplay, XColorMap, &XColorTable[i]))
|
||||
XPixelTable[i] = XColorTable[i].pixel;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (i < ColorMapSize)
|
||||
XFreeColors(XDisplay, XColorMap, XPixelTable, i, 0L);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (Strip == 8)
|
||||
GIF_EXIT("Can not display the image - not enough colors available.");
|
||||
|
||||
if (Strip != 0) {
|
||||
sprintf(Msg, "%d bits were stripped off the color map.", Strip);
|
||||
GIF_MESSAGE(Msg);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to allocate the requested colors from the X server. *
|
||||
* Two stages are performed: *
|
||||
* 1. Colors are requested directly. *
|
||||
* 2. If not enough colors can be allocated, the closest current color *
|
||||
* in current table is selected instead. *
|
||||
* This allocation is not optimal as when fail to allocate all colors one *
|
||||
* should pick the right colors to do allocate in order to minimize the *
|
||||
* closest distance from the unallocated ones under some norm (what is a good *
|
||||
* norm for the RGB space?). Improve it if you are bored. *
|
||||
******************************************************************************/
|
||||
static void AllocateColors2(void)
|
||||
{
|
||||
int i, j, Index = 0, Count = 0, XNumOfColors;
|
||||
char Msg[80];
|
||||
unsigned long D, Distance, AvgDistance = 0, Red, Green, Blue;
|
||||
GifBooleanType Failed = FALSE;
|
||||
XColor *XOldColorTable;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (i < ColorMapSize) { /* Prepere color entry in X format. */
|
||||
XColorTable[i].red = ColorMap[i].Red << 8;
|
||||
XColorTable[i].green = ColorMap[i].Green << 8;
|
||||
XColorTable[i].blue = ColorMap[i].Blue << 8;
|
||||
XColorTable[i].flags = DoRed | DoGreen | DoBlue;
|
||||
XPixelTable[i] = -1; /* Not allocated yet. */
|
||||
}
|
||||
else
|
||||
XPixelTable[i] = 0; /* Put reasonable color for out of range. */
|
||||
}
|
||||
|
||||
for (i = 0; i < ColorMapSize; i++) /* Allocate the colors from X: */
|
||||
if (XAllocColor(XDisplay, XColorMap, &XColorTable[i]))
|
||||
XPixelTable[i] = XColorTable[i].pixel;
|
||||
else
|
||||
Failed = TRUE;
|
||||
|
||||
if (Failed) {
|
||||
XNumOfColors = DisplayCells(XDisplay, XScreen);
|
||||
XOldColorTable = (XColor *) malloc(sizeof(XColor) * XNumOfColors);
|
||||
for (i = 0; i < XNumOfColors; i++) XOldColorTable[i].pixel = i;
|
||||
XQueryColors(XDisplay, XColorMap, XOldColorTable, XNumOfColors);
|
||||
|
||||
for (i = 0; i < ColorMapSize; i++) {
|
||||
/* Allocate closest colors from X: */
|
||||
if (XPixelTable[i] == -1) { /* Failed to allocate this one. */
|
||||
Distance = 0xffffffff;
|
||||
|
||||
Red = XColorTable[i].red;
|
||||
Green = XColorTable[i].green;
|
||||
Blue = XColorTable[i].blue;
|
||||
|
||||
for (j = 0; j < XNumOfColors; j++) {
|
||||
/* Find the closest color in 3D RGB space using L1 norm. */
|
||||
if ((D = ABS(Red - XOldColorTable[j].red) +
|
||||
ABS(Green - XOldColorTable[j].green) +
|
||||
ABS(Blue - XOldColorTable[j].blue)) < Distance) {
|
||||
Distance = D;
|
||||
Index = j;
|
||||
}
|
||||
}
|
||||
XPixelTable[i] = Index;
|
||||
|
||||
AvgDistance += Distance;
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
free(XOldColorTable);
|
||||
|
||||
sprintf(Msg, "Colors will be approximated (average error = %d).\n",
|
||||
AvgDistance / Count);
|
||||
GIF_MESSAGE(Msg);
|
||||
}
|
||||
}
|
314
G/UTIL/GIFASM.C
Normal file
314
G/UTIL/GIFASM.C
Normal file
@ -0,0 +1,314 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to assemble/disassemble GIF files: disassembles multi image file *
|
||||
* into seperated files, or assembles few single image GIF files into one. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -a : assemble few files into one (default) *
|
||||
* -d name : disassmble given GIF file into seperate files derived from name. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 7 Jul 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifAsm"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifAsm q%- a%- d%-OutFileName!s h%- GifFile(s)!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- a%- d%-OutFileName!s h%- GifFile(s)!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
static int
|
||||
AsmFlag = FALSE;
|
||||
|
||||
static void DoAssembly(int NumFiles, char **FileNames);
|
||||
static void DoDisassembly(char *InFileName, char *OutFileName);
|
||||
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, DisasmFlag = FALSE, HelpFlag = FALSE;
|
||||
char **FileNames = NULL, *OutFileName;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&GifQuitePrint, &AsmFlag, &DisasmFlag, &OutFileName,
|
||||
&HelpFlag, &NumFiles, &FileNames)) != FALSE) {
|
||||
GAPrintErrMsg(Error);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (HelpFlag) {
|
||||
fprintf(stderr, VersionStr);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!AsmFlag && !DisasmFlag) AsmFlag = TRUE; /* Make default - assemble. */
|
||||
if (AsmFlag && NumFiles < 2) {
|
||||
GIF_MESSAGE("At list two GIF files are required to assembly operation.");
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(1);
|
||||
}
|
||||
if (!AsmFlag && NumFiles > 1) {
|
||||
GIF_MESSAGE("Error in command line parsing - one GIF file please.");
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (AsmFlag)
|
||||
DoAssembly(NumFiles, FileNames);
|
||||
else
|
||||
DoDisassembly(NumFiles == 1 ? *FileNames : NULL, OutFileName);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Perform the disassembly operation - take one input files into few output. *
|
||||
******************************************************************************/
|
||||
static void DoDisassembly(char *InFileName, char *OutFileName)
|
||||
{
|
||||
int i, ExtCode, CodeSize, FileNum = 0, FileEmpty;
|
||||
GifRecordType RecordType;
|
||||
char CrntFileName[80], *p;
|
||||
GifByteType *Extension, *CodeBlock;
|
||||
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
|
||||
|
||||
/* 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. */
|
||||
for (i = 0; i < strlen(OutFileName); i++)/* Make sure all is upper case.*/
|
||||
if (islower(OutFileName[i]))
|
||||
OutFileName[i] = toupper(OutFileName[i]);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Open input file: */
|
||||
if (InFileName != NULL) {
|
||||
if ((GifFileIn = DGifOpenFileName(InFileName)) == NULL)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
}
|
||||
|
||||
/* Scan the content of GIF file and dump image(s) to seperate file(s): */
|
||||
do {
|
||||
sprintf(CrntFileName, "%s%02d.gif", OutFileName, FileNum++);
|
||||
if ((GifFileOut = EGifOpenFileName(CrntFileName, TRUE)) == NULL)
|
||||
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 -> 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:
|
||||
FileEmpty = FALSE;
|
||||
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
/* Put same 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 */
|
||||
/* 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:
|
||||
FileEmpty = FALSE;
|
||||
/* 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 != IMAGE_DESC_RECORD_TYPE &&
|
||||
RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
if (EGifCloseFile(GifFileOut) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
if (FileEmpty) {
|
||||
/* Might happen on last file - delete it if so: */
|
||||
unlink(CrntFileName);
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
if (DGifCloseFile(GifFileIn) == GIF_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);
|
||||
}
|
362
G/UTIL/GIFBG.C
Normal file
362
G/UTIL/GIFBG.C
Normal file
@ -0,0 +1,362 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to generate back ground image that can be used to replace constant *
|
||||
* background. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -d direction : set direction image should increase intensity. *
|
||||
* -l levels : number of color levels. *
|
||||
* -c r g b : colors of the back ground. *
|
||||
* -m min : minimin intensity in percent. *
|
||||
* -M max : maximum intensity in percent. *
|
||||
* -s width height : size of image to create. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 9 Jul 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifBG"
|
||||
|
||||
#define DEFAULT_WIDTH 640
|
||||
#define DEFAULT_HEIGHT 350
|
||||
|
||||
#define DEFAULT_COLOR_RED 0
|
||||
#define DEFAULT_COLOR_GREEN 0
|
||||
#define DEFAULT_COLOR_BLUE 255
|
||||
|
||||
#define DEFAULT_MIN_INTENSITY 10 /* In percent. */
|
||||
#define DEFAULT_MAX_INTENSITY 100
|
||||
|
||||
#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image. */
|
||||
|
||||
#define DIR_NONE 0 /* Direction the levels can be changed: */
|
||||
#define DIR_TOP 1
|
||||
#define DIR_TOP_RIGHT 2
|
||||
#define DIR_RIGHT 3
|
||||
#define DIR_BOT_RIGHT 4
|
||||
#define DIR_BOT 5
|
||||
#define DIR_BOT_LEFT 6
|
||||
#define DIR_LEFT 7
|
||||
#define DIR_TOP_LEFT 8
|
||||
|
||||
#define DEFAULT_DIR "T" /* TOP (North) direction. */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module \t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifBG q%- d%-Dir!s l%-#Lvls!d c%-R|G|B!d!d!d m%-MinI!d M%-MaxI!d s%-W|H!d!d h%-";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- d%-Dir!s l%-#Lvls!d c%-R|G|B!d!d!d m%-MinI!d M%-MaxI!d s%-W|H!d!d h%-";
|
||||
#endif /* SYSV */
|
||||
|
||||
static int
|
||||
MaximumIntensity = DEFAULT_MAX_INTENSITY, /* In percent. */
|
||||
MinimumIntensity = DEFAULT_MIN_INTENSITY,
|
||||
NumLevels = DEFAULT_NUM_LEVELS,
|
||||
ImageWidth = DEFAULT_WIDTH,
|
||||
ImageHeight = DEFAULT_HEIGHT,
|
||||
Direction;
|
||||
static unsigned int
|
||||
RedColor = DEFAULT_COLOR_RED,
|
||||
GreenColor = DEFAULT_COLOR_GREEN,
|
||||
BlueColor = DEFAULT_COLOR_BLUE;
|
||||
|
||||
static void QuitGifError(GifFileType *GifFile);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
unsigned int Ratio;
|
||||
int i, j, l, LevelHeight, LevelWidth, Error, LogNumLevels, FlipDir,
|
||||
Accumulator, StartX, StepX, Count = 0, DoAllMaximum = FALSE,
|
||||
DirectionFlag = FALSE, LevelsFlag = FALSE, ColorFlag = FALSE,
|
||||
MinFlag = FALSE, MaxFlag = FALSE, SizeFlag = FALSE, HelpFlag = FALSE;
|
||||
GifPixelType Color;
|
||||
char *DirectionStr = DEFAULT_DIR;
|
||||
GifRowType Line;
|
||||
GifColorType *ColorMap;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&DirectionFlag, &DirectionStr, &LevelsFlag, &NumLevels,
|
||||
&ColorFlag, &RedColor, &GreenColor, &BlueColor,
|
||||
&MinFlag, &MinimumIntensity, &MaxFlag, &MaximumIntensity,
|
||||
&SizeFlag, &ImageWidth, &ImageHeight,
|
||||
&HelpFlag)) != FALSE) {
|
||||
GAPrintErrMsg(Error);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (HelpFlag) {
|
||||
fprintf(stderr, VersionStr);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
for (i = 0; i < strlen(DirectionStr); i++) /* Make sure its upper case. */
|
||||
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 wierd!");
|
||||
|
||||
/* 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)) == NULL)
|
||||
QuitGifError(GifFile);
|
||||
|
||||
/* Dump out screen description with given size and generated color map: */
|
||||
if ((ColorMap = (GifColorType *) malloc(NumLevels * sizeof(GifColorType)))
|
||||
== 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[i-1].Red = (RedColor * Ratio) / 100;
|
||||
ColorMap[i-1].Green = (GreenColor * Ratio) / 100;
|
||||
ColorMap[i-1].Blue = (BlueColor * Ratio) / 100;
|
||||
}
|
||||
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 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) {
|
||||
/* 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) {
|
||||
/* 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++) {
|
||||
if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR)
|
||||
QuitGifError(GifFile);
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* 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) == GIF_ERROR)
|
||||
QuitGifError(GifFile);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void QuitGifError(GifFileType *GifFile)
|
||||
{
|
||||
PrintGifError();
|
||||
if (GifFile != NULL) EGifCloseFile(GifFile);
|
||||
exit(1);
|
||||
}
|
256
G/UTIL/GIFCLIP.C
Normal file
256
G/UTIL/GIFCLIP.C
Normal file
@ -0,0 +1,256 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to clip an image and dump out only portion of it. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -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. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifClip"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifClip q%- i%-Xmin|Ymin|Xmax|Ymax!d!d!d!d n%-n|Xmin|Ymin|Xmax|Ymax!d!d!d!d!d h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- i%-Xmin|Ymin|Xmax|Ymax!d!d!d!d n%-n|Xmin|Ymin|Xmax|Ymax!d!d!d!d!d h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
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;
|
||||
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, &GifQuitePrint,
|
||||
&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(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)) {
|
||||
GIF_MESSAGE("Exactly one of [-i ...] && [-n ...] please.");
|
||||
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) == 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 -> IInterlace)
|
||||
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 -> IWidth <= ImageX2 ||
|
||||
GifFileIn -> IHeight <= ImageY2)
|
||||
GIF_EXIT("Image is smaller than given clip dimensions.");
|
||||
|
||||
/* Put the image descriptor to out file: */
|
||||
if (EGifPutImageDesc(GifFileOut,
|
||||
GifFileIn -> ILeft, GifFileIn -> ITop,
|
||||
ImageWidth, ImageY2 - ImageY1 + 1,
|
||||
FALSE, GifFileIn -> IBitsPerPixel,
|
||||
GifFileIn -> IColorMap) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
|
||||
/* o.k. - read the image and clip it: */
|
||||
Line = (GifRowType) malloc(GifFileIn -> IWidth *
|
||||
sizeof(GifPixelType));
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ImageNum,
|
||||
GifFileIn -> ILeft, GifFileIn -> ITop,
|
||||
GifFileIn -> IWidth, GifFileIn -> IHeight);
|
||||
|
||||
/* Skip lines below ImageY1: */
|
||||
for (i = 0; i < ImageY1; i++) {
|
||||
if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth)
|
||||
== 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 -> IWidth)
|
||||
== GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
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 -> IHeight; i++) {
|
||||
if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth)
|
||||
== 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 -> 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 */
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
279
G/UTIL/GIFCLRMP.C
Normal file
279
G/UTIL/GIFCLRMP.C
Normal file
@ -0,0 +1,279 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to modify GIF file color map(s). Images are not modified at all. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -s : save screen color map (unless -i - see below), to stdout. *
|
||||
* -l colormap.file : substitute given colormap.file colormap into screen *
|
||||
* colormap (unless -i - see below). *
|
||||
* -g correction : apply gamma correction to the screen colormap (unless -i - *
|
||||
* see below). *
|
||||
* -i n : select image number n color map instead of screen map for above *
|
||||
* operations (n = 1 for first image). *
|
||||
* -h : on line help. *
|
||||
* All color maps are ascii text files, with one line per color of the *
|
||||
* form: index, Red color, Green color, Blue color - all in the range 0..255. *
|
||||
* All color maps should be in the exact same length. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 17 Jul 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifClrMp"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifClrMp q%- s%- l%-ColorMapFile!s g%-Gamma!F i%-Image#!d h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- s%- l%-ColorMapFile!s g%-Gamma!F i%-Image#!d h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
static int
|
||||
SaveFlag = FALSE,
|
||||
LoadFlag = FALSE,
|
||||
GammaFlag = FALSE;
|
||||
static
|
||||
double Gamma = 1.0;
|
||||
static
|
||||
FILE *ColorFile = NULL;
|
||||
|
||||
|
||||
static void ModifyColorMap(GifColorType *ColorMap, int BitsPerPixel);
|
||||
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, CodeSize, ImageNum = 0,
|
||||
ImageNFlag = FALSE, ImageN, HelpFlag = FALSE, HasGIFOutput;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension, *CodeBlock;
|
||||
char **FileName = NULL, *ColorFileName;
|
||||
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&SaveFlag, &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(1);
|
||||
}
|
||||
|
||||
if (HelpFlag) {
|
||||
fprintf(stderr, VersionStr);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (SaveFlag && LoadFlag || SaveFlag && GammaFlag || LoadFlag && GammaFlag)
|
||||
GIF_EXIT("Can not handle more than one of -s -l or -g at the same time.");
|
||||
|
||||
if (NumFiles == 1) {
|
||||
if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
}
|
||||
else {
|
||||
/* Use the 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 (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 || 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: */
|
||||
ModifyColorMap(GifFileIn -> SColorMap, GifFileIn -> SBitsPerPixel);
|
||||
if (!HasGIFOutput) {
|
||||
/* We can quit here, as we have the color map: */
|
||||
if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
|
||||
fclose(ColorFile);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
/* And dump out its new possible repositioned screen information: */
|
||||
if (HasGIFOutput)
|
||||
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);
|
||||
if (++ImageNum == ImageN && ImageNFlag) {
|
||||
/* We are suppose to modify this image color map, do it: */
|
||||
ModifyColorMap(GifFileIn -> SColorMap,
|
||||
GifFileIn -> SBitsPerPixel);
|
||||
if (!HasGIFOutput) {
|
||||
/* We can quit here, as we have the color map: */
|
||||
if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
|
||||
fclose(ColorFile);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
if (HasGIFOutput)
|
||||
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 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Modify the given colormap according to global variables setting. *
|
||||
******************************************************************************/
|
||||
static void ModifyColorMap(GifColorType *ColorMap, int BitsPerPixel)
|
||||
{
|
||||
int i, Dummy, Red, Green, Blue;
|
||||
double Gamma1;
|
||||
|
||||
if (SaveFlag) {
|
||||
/* Save this color map to ColorFile: */
|
||||
for (i = 0; i < (1 << BitsPerPixel); i++)
|
||||
fprintf(ColorFile, "%3d %3d %3d %3d\n", i,
|
||||
ColorMap[i].Red, ColorMap[i].Green, ColorMap[i].Blue);
|
||||
}
|
||||
else if (LoadFlag) {
|
||||
/* Read the color map in ColorFile into this color map: */
|
||||
for (i = 0; i < (1 << BitsPerPixel); i++) {
|
||||
if (feof(ColorFile))
|
||||
GIF_EXIT("Color file to load color map from, too small.");
|
||||
fscanf(ColorFile, "%3d %3d %3d %3d\n", &Dummy, &Red, &Green, &Blue);
|
||||
ColorMap[i].Red = Red;
|
||||
ColorMap[i].Green = Green;
|
||||
ColorMap[i].Blue = Blue;
|
||||
}
|
||||
}
|
||||
else if (GammaFlag) {
|
||||
/* Apply gamma correction to this color map: */
|
||||
Gamma1 = 1.0 / Gamma;
|
||||
for (i = 0; i < (1 << BitsPerPixel); i++) {
|
||||
ColorMap[i].Red =
|
||||
((int) (255 * pow(ColorMap[i].Red / 255.0, Gamma1)));
|
||||
ColorMap[i].Green =
|
||||
((int) (255 * pow(ColorMap[i].Green / 255.0, Gamma1)));
|
||||
ColorMap[i].Blue =
|
||||
((int) (255 * pow(ColorMap[i].Blue / 255.0, Gamma1)));
|
||||
}
|
||||
}
|
||||
else
|
||||
GIF_EXIT("Nothing to do!");
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
322
G/UTIL/GIFCOMB.C
Normal file
322
G/UTIL/GIFCOMB.C
Normal file
@ -0,0 +1,322 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to combine 2 GIF images into single one, using optional mask GIF *
|
||||
* file. Result colormap will be the union of the two images colormaps. *
|
||||
* Both images should have exactly the same size, although they may be mapped *
|
||||
* differently on screen. Only First GIF screen descriptor info. is used. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -m mask : optional boolean image, defines where second GIF should be used. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 12 Jul 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* _MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifComb"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifComb q%- m%-MaskGIFFile!s h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- m%-MaskGIFFile!s h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
static int ReadUntilImage(GifFileType *GifFile);
|
||||
static int UnionColorMap(GifColorType *ColorIn1, int ColorIn1Size,
|
||||
GifColorType *ColorIn2, int ColorIn2Size,
|
||||
GifColorType **ColorUnionPtr, int *ColorUnionSize,
|
||||
GifPixelType ColorTransIn2[]);
|
||||
static void QuitGifError(GifFileType *GifFileIn1, GifFileType *GifFileIn2,
|
||||
GifFileType *GifMaskFile, GifFileType *GifFileOut);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Error, NumFiles, Size, ColorUnionSize,
|
||||
ColorIn1Size = 0, ColorIn2Size = 0,
|
||||
MaskFlag = FALSE, HelpFlag = FALSE;
|
||||
char **FileName = NULL, *MaskFileName;
|
||||
GifPixelType ColorTransIn2[256];
|
||||
GifRowType LineIn1 = NULL, LineIn2 = NULL, LineMask = NULL, LineOut = NULL;
|
||||
GifColorType *ColorIn1 = NULL, *ColorIn2 = NULL, *ColorUnion;
|
||||
GifFileType *GifFileIn1 = NULL, *GifFileIn2 = NULL, *GifMaskFile = NULL,
|
||||
*GifFileOut = NULL;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&GifQuitePrint, &MaskFlag, &MaskFileName,
|
||||
&HelpFlag, &NumFiles, &FileName)) != FALSE ||
|
||||
(NumFiles != 2 && !HelpFlag)) {
|
||||
if (Error)
|
||||
GAPrintErrMsg(Error);
|
||||
else if (NumFiles != 2)
|
||||
GIF_MESSAGE("Error in command line parsing - two GIF file please.");
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (HelpFlag) {
|
||||
fprintf(stderr, VersionStr);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Open all input files (two GIF to combine, and optional mask): */
|
||||
if ((GifFileIn1 = DGifOpenFileName(FileName[0])) == NULL ||
|
||||
(GifFileIn2 = DGifOpenFileName(FileName[1])) == NULL ||
|
||||
(MaskFlag && (GifMaskFile = DGifOpenFileName(MaskFileName)) == NULL))
|
||||
QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut);
|
||||
|
||||
if (ReadUntilImage(GifFileIn1) == GIF_ERROR ||
|
||||
ReadUntilImage(GifFileIn2) == GIF_ERROR ||
|
||||
(MaskFlag && ReadUntilImage(GifMaskFile) == GIF_ERROR))
|
||||
QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut);
|
||||
|
||||
if (GifFileIn1 -> IWidth != GifFileIn2 -> IWidth ||
|
||||
GifFileIn2 -> IHeight != GifFileIn2 -> IHeight ||
|
||||
(MaskFlag && (GifFileIn1 -> IWidth != GifMaskFile -> IWidth ||
|
||||
GifFileIn1 -> IHeight != GifMaskFile -> IHeight)))
|
||||
GIF_EXIT("Given GIF files have different image dimensions.");
|
||||
|
||||
/* Open stdout for the output file: */
|
||||
if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
|
||||
QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut);
|
||||
|
||||
Size = sizeof(GifPixelType) * GifFileIn1 -> IWidth;
|
||||
if ((LineIn1 = (GifRowType) malloc(Size)) == NULL ||
|
||||
(LineIn2 = (GifRowType) malloc(Size)) == NULL ||
|
||||
(MaskFlag && (LineMask = (GifRowType) malloc(Size)) == NULL) ||
|
||||
(LineOut = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
if (GifFileIn1 -> IColorMap) {
|
||||
ColorIn1 = GifFileIn1 -> IColorMap;
|
||||
ColorIn1Size = 1 << GifFileIn1 -> IBitsPerPixel;
|
||||
}
|
||||
else if (GifFileIn1 -> SColorMap) {
|
||||
ColorIn1 = GifFileIn1 -> SColorMap;
|
||||
ColorIn1Size = 1 << GifFileIn1 -> SBitsPerPixel;
|
||||
}
|
||||
else
|
||||
GIF_EXIT("Neither Screen nor Image color map exists - GIF file 1.");
|
||||
|
||||
if (GifFileIn2 -> IColorMap) {
|
||||
ColorIn2 = GifFileIn2 -> IColorMap;
|
||||
ColorIn2Size = 1 << GifFileIn2 -> IBitsPerPixel;
|
||||
}
|
||||
else if (GifFileIn2 -> SColorMap) {
|
||||
ColorIn2 = GifFileIn2 -> SColorMap;
|
||||
ColorIn2Size = 1 << GifFileIn2 -> SBitsPerPixel;
|
||||
}
|
||||
else
|
||||
GIF_EXIT("Neither Screen nor Image color map exists - GIF file 2.");
|
||||
|
||||
/* Create union of the two given color maps. ColorIn1 will be copied as */
|
||||
/* is while ColorIn2 will be mapped using ColorTransIn2 table. */
|
||||
/* ColorUnion is allocated by the procedure itself. */
|
||||
if (UnionColorMap(ColorIn1, ColorIn1Size, ColorIn2, ColorIn2Size,
|
||||
&ColorUnion, &ColorUnionSize, ColorTransIn2) == GIF_ERROR)
|
||||
GIF_EXIT("Unioned color map is two big (>256 colors).");
|
||||
|
||||
/* Dump out new image and screen descriptors: */
|
||||
if (EGifPutScreenDesc(GifFileOut,
|
||||
GifFileIn1 -> SWidth, GifFileIn1 -> SHeight,
|
||||
ColorUnionSize, GifFileIn1 -> SBackGroundColor,
|
||||
ColorUnionSize, ColorUnion) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut);
|
||||
free((char *) ColorUnion); /* We dont need this any more... */
|
||||
|
||||
if (EGifPutImageDesc(GifFileOut,
|
||||
GifFileIn1 -> ILeft, GifFileIn1 -> ITop,
|
||||
GifFileIn1 -> IWidth, GifFileIn1 -> IHeight,
|
||||
GifFileIn1 -> IInterlace, GifFileIn1 -> IBitsPerPixel, NULL) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut);
|
||||
|
||||
|
||||
/* Time to do it: read 2 scan lines from 2 files (and optionally from */
|
||||
/* the mask file, merge them and them result out. Do it Height times: */
|
||||
GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, GifFileOut -> ILeft, GifFileOut -> ITop,
|
||||
GifFileOut -> IWidth, GifFileOut -> IHeight);
|
||||
for (i = 0; i < GifFileIn1 -> IHeight; i++) {
|
||||
if (DGifGetLine(GifFileIn1, LineIn1, GifFileIn1 -> IWidth) == GIF_ERROR ||
|
||||
DGifGetLine(GifFileIn2, LineIn2, GifFileIn2 -> IWidth) == GIF_ERROR ||
|
||||
(MaskFlag &&
|
||||
DGifGetLine(GifMaskFile, LineMask, GifMaskFile -> IWidth)
|
||||
== GIF_ERROR))
|
||||
QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut);
|
||||
if (MaskFlag) {
|
||||
/* Every time Mask has non background color, use LineIn1 pixel, */
|
||||
/* otherwise use LineIn2 pixel instead. */
|
||||
for (j = 0; j < GifFileIn1 -> IWidth; j++) {
|
||||
if (LineMask[j] != GifMaskFile -> SBackGroundColor)
|
||||
LineOut[j] = LineIn1[j];
|
||||
else
|
||||
LineOut[j] = ColorTransIn2[LineIn2[j]];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Every time Color of Image 1 is equal to background - take it */
|
||||
/* From Image 2 instead of the background. */
|
||||
for (j = 0; j < GifFileIn1 -> IWidth; j++) {
|
||||
if (LineIn1[j] != GifFileIn1 -> SBackGroundColor)
|
||||
LineOut[j] = LineIn1[j];
|
||||
else
|
||||
LineOut[j] = ColorTransIn2[LineIn2[j]];
|
||||
}
|
||||
}
|
||||
if (EGifPutLine(GifFileOut, LineOut, GifFileOut -> IWidth)
|
||||
== GIF_ERROR)
|
||||
QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut);
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
}
|
||||
|
||||
if (DGifCloseFile(GifFileIn1) == GIF_ERROR ||
|
||||
DGifCloseFile(GifFileIn2) == GIF_ERROR ||
|
||||
EGifCloseFile(GifFileOut) == GIF_ERROR ||
|
||||
(MaskFlag && DGifCloseFile(GifMaskFile) == GIF_ERROR))
|
||||
QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Read until first image in GIF file is detected and read its descriptor. *
|
||||
******************************************************************************/
|
||||
static int ReadUntilImage(GifFileType *GifFile)
|
||||
{
|
||||
int ExtCode;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
|
||||
/* Scan the content of the GIF file, until image descriptor is detected: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
|
||||
return GIF_ERROR;
|
||||
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
return DGifGetImageDesc(GifFile);
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR)
|
||||
return GIF_ERROR;
|
||||
|
||||
while (Extension != NULL)
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR)
|
||||
return GIF_ERROR;
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
return GIF_ERROR; /* We should be here - no image was found! */
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Create union of the two given color maps and return it. If result can not *
|
||||
* fit into 256 colors, GIF_ERROR is returned, GIF_OK otherwise. *
|
||||
* ColorIn1 is copied as it to ColorUnion, while colors from ColorIn2 are *
|
||||
* copied iff they dont exists before. ColorTransIn2 is used to map old *
|
||||
* ColorIn2 into ColorUnion color map table. *
|
||||
******************************************************************************/
|
||||
static int UnionColorMap(GifColorType *ColorIn1, int ColorIn1Size,
|
||||
GifColorType *ColorIn2, int ColorIn2Size,
|
||||
GifColorType **ColorUnionPtr, int *ColorUnionSize,
|
||||
GifPixelType ColorTransIn2[])
|
||||
{
|
||||
int i, j, CrntSlot;
|
||||
GifColorType *ColorUnion;
|
||||
|
||||
/* Allocate table which will hold result for sure: */
|
||||
*ColorUnionPtr = ColorUnion = (GifColorType *) malloc(sizeof(GifColorType)
|
||||
* (ColorIn1Size > ColorIn2Size ? ColorIn1Size : ColorIn2Size) * 2);
|
||||
|
||||
/* Copy ColorIn1 to ColorUnionSize; */
|
||||
for (i = 0; i < ColorIn1Size; i++) ColorUnion[i] = ColorIn1[i];
|
||||
CrntSlot = ColorIn1Size; /* Current Empty slot. */
|
||||
|
||||
/* Copy ColorIn2 to ColorUnionSize (use old colors if exists): */
|
||||
for (i = 0; i < ColorIn2Size && CrntSlot<=256; i++) {
|
||||
/* Let see if this color already exists: */
|
||||
for (j = 0; j < ColorIn1Size; j++) {
|
||||
/* If memcmp does not exists for you, use the following: */
|
||||
/*
|
||||
if (ColorIn1[j].Red == ColorIn2[i].Red &&
|
||||
ColorIn1[j].Green == ColorIn2[i].Green &&
|
||||
ColorIn1[j].Blue == ColorIn2[i].Blue) break;
|
||||
*/
|
||||
if (memcmp(&ColorIn1[j], &ColorIn2[i], 3) == 0) break;
|
||||
}
|
||||
if (j < ColorIn1Size) {
|
||||
/* We found this color aleardy exists in ColorIn1: */
|
||||
ColorTransIn2[i] = j;
|
||||
}
|
||||
else {
|
||||
/* Its new - copy it to a new slot: */
|
||||
ColorUnion[CrntSlot] = ColorIn2[i];
|
||||
ColorTransIn2[i] = CrntSlot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (CrntSlot > 256) return GIF_ERROR;
|
||||
|
||||
/* Complete the color map to a power of two: */
|
||||
for (i = 1; i <= 8; i++) if ((1 << i) >= CrntSlot) break;
|
||||
for (j = CrntSlot; j < (1 << i); j++)
|
||||
ColorUnion[j].Red = ColorUnion[j].Green = ColorUnion[j].Blue = 0;
|
||||
|
||||
*ColorUnionSize = i;
|
||||
|
||||
return GIF_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close both input and output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void QuitGifError(GifFileType *GifFileIn1, GifFileType *GifFileIn2,
|
||||
GifFileType *GifMaskFile, GifFileType *GifFileOut)
|
||||
{
|
||||
PrintGifError();
|
||||
if (GifFileIn1 != NULL) DGifCloseFile(GifFileIn1);
|
||||
if (GifFileIn2 != NULL) DGifCloseFile(GifFileIn2);
|
||||
if (GifMaskFile != NULL) DGifCloseFile(GifMaskFile);
|
||||
if (GifFileOut != NULL) EGifCloseFile(GifFileOut);
|
||||
exit(1);
|
||||
}
|
BIN
G/UTIL/GIFDEBUG.DSK
Normal file
BIN
G/UTIL/GIFDEBUG.DSK
Normal file
Binary file not shown.
BIN
G/UTIL/GIFDEBUG.PRJ
Normal file
BIN
G/UTIL/GIFDEBUG.PRJ
Normal file
Binary file not shown.
215
G/UTIL/GIFFIX.C
Normal file
215
G/UTIL/GIFFIX.C
Normal file
@ -0,0 +1,215 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to attempt and fix broken GIF images. Currently fix the following: *
|
||||
* 1. EOF terminates before end of image size (adds black in the end). *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -h : on line help *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 5 May 91 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifFix"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifFix q%- h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ImageNum = 0;
|
||||
|
||||
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, Error, NumFiles, ExtCode, ColorMapSize, Row, Col, Width, Height,
|
||||
DarkestColor = 0, ColorIntens = 10000, HelpFlag = FALSE;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char **FileName = NULL;
|
||||
GifRowType LineBuffer;
|
||||
GifColorType *ColorMap;
|
||||
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, &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);
|
||||
|
||||
/* 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);
|
||||
|
||||
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 -> IInterlace)
|
||||
GIF_EXIT("Cannt fix interlaced images.");
|
||||
|
||||
Row = GifFileIn -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFileIn -> ILeft;
|
||||
Width = GifFileIn -> IWidth;
|
||||
Height = GifFileIn -> IHeight;
|
||||
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 -> IBitsPerPixel,
|
||||
GifFileIn -> IColorMap) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
|
||||
/* Find the darkest color in color map to use as a filler. */
|
||||
ColorMap = (GifFileIn -> IColorMap ? GifFileIn -> IColorMap :
|
||||
GifFileIn -> SColorMap);
|
||||
ColorMapSize = 1 << (GifFileIn -> IColorMap ?
|
||||
GifFileIn -> IBitsPerPixel :
|
||||
GifFileIn -> SBitsPerPixel);
|
||||
for (i = 0; i < ColorMapSize; i++) {
|
||||
j = ((int) ColorMap[i].Red) * 30 +
|
||||
((int) ColorMap[i].Green) * 59 +
|
||||
((int) ColorMap[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 (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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close both input and output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
|
||||
{
|
||||
fprintf(stderr, "\nFollowing unrecoverable error occured:");
|
||||
PrintGifError();
|
||||
if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
|
||||
if (GifFileOut != NULL) EGifCloseFile(GifFileOut);
|
||||
exit(1);
|
||||
}
|
341
G/UTIL/GIFFLIP.C
Normal file
341
G/UTIL/GIFFLIP.C
Normal file
@ -0,0 +1,341 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to rotate image 90 degrees to the right/left or flip the image *
|
||||
* horizintally/vertically (mirror). *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -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. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifFlip"
|
||||
|
||||
#define FLIP_NONE 0
|
||||
#define FLIP_RIGHT 1
|
||||
#define FLIP_LEFT 2
|
||||
#define FLIP_HORIZ 3
|
||||
#define FLIP_VERT 4
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifFlip q%- r%- l%- x%- y%- h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- r%- l%- x%- y%- h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ImageNum = 0;
|
||||
|
||||
static int LoadImage(GifFileType *GifFile, GifRowType **ImageBuffer);
|
||||
static int DumpImage(GifFileType *GifFile, GifRowType *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 = FLIP_RIGHT,
|
||||
RightFlag = FALSE, LeftFlag = FALSE,
|
||||
HorizFlag = FALSE, VertFlag = FALSE, HelpFlag = FALSE;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
char **FileName = NULL;
|
||||
GifRowType *ImageBuffer;
|
||||
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&RightFlag, &LeftFlag, &HorizFlag, &VertFlag, &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 ((i = (RightFlag != 0) + (LeftFlag != 0) +
|
||||
(HorizFlag != 0) + (VertFlag != 0)) > 1)
|
||||
GIF_EXIT("Only one of -r, -l, -x, -y please.");
|
||||
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) == GIF_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) == 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 (GifFileIn -> IInterlace)
|
||||
GIF_EXIT("Cannt flip interlaced images - use GifInter first.");
|
||||
|
||||
/* 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) == GIF_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) == GIF_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) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
}
|
||||
|
||||
/* Load the image (either Interlaced or not), and dump it */
|
||||
/* fliped as requrested by Flags: */
|
||||
if (LoadImage(GifFileIn, &ImageBuffer) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
if (DumpImage(GifFileOut, ImageBuffer, GifFileIn -> IWidth,
|
||||
GifFileIn -> IHeight, FlipDirection) == 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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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 GIF_OK if succesful, GIF_ERROR otherwise. *
|
||||
******************************************************************************/
|
||||
static int LoadImage(GifFileType *GifFile, GifRowType **ImageBufferPtr)
|
||||
{
|
||||
int Size, i;
|
||||
GifRowType *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 = (GifRowType *)
|
||||
malloc(GifFile -> IHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> IWidth * sizeof(GifPixelType);/* One row size in bytes.*/
|
||||
for (i = 0; i < GifFile -> IHeight; i++) {
|
||||
/* Allocate the rows: */
|
||||
if ((ImageBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
}
|
||||
|
||||
*ImageBufferPtr = ImageBuffer;
|
||||
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, GifFile -> ILeft, GifFile -> ITop,
|
||||
GifFile -> IWidth, GifFile -> IHeight);
|
||||
|
||||
for (i = 0; i < GifFile -> IHeight; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, ImageBuffer[i], GifFile -> IWidth)
|
||||
== GIF_ERROR) return GIF_ERROR;
|
||||
}
|
||||
|
||||
return GIF_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 GIF_OK if succesful, GIF_ERROR otherwise. *
|
||||
******************************************************************************/
|
||||
static int DumpImage(GifFileType *GifFile, GifRowType *ImageBuffer,
|
||||
int Width, int Height, int FlipDirection)
|
||||
{
|
||||
int i, j, Count;
|
||||
GifRowType Line; /* New scan line is copied to it. */
|
||||
|
||||
/* Allocate scan line that will fit both image width and height: */
|
||||
if ((Line = (GifRowType) malloc((Width > Height ? Width : Height)
|
||||
* sizeof(GifPixelType))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
switch (FlipDirection) {
|
||||
case FLIP_RIGHT:
|
||||
for (Count = Width, i = 0; i < Width; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count--);
|
||||
for (j = 0; j < Height; j++)
|
||||
Line[j] = ImageBuffer[Height - j - 1][i];
|
||||
if (EGifPutLine(GifFile, Line, Height) == GIF_ERROR)
|
||||
return GIF_ERROR;
|
||||
}
|
||||
break;
|
||||
case FLIP_LEFT:
|
||||
for (i = Width - 1; i >= 0; i--) {
|
||||
GifQprintf("\b\b\b\b%-4d", i + 1);
|
||||
for (j = 0; j < Height; j++)
|
||||
Line[j] = ImageBuffer[j][i];
|
||||
if (EGifPutLine(GifFile, Line, Height) == GIF_ERROR)
|
||||
return GIF_ERROR;
|
||||
}
|
||||
break;
|
||||
case FLIP_HORIZ:
|
||||
for (i = Height - 1; i >= 0; i--) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (EGifPutLine(GifFile, ImageBuffer[i], Width) == GIF_ERROR)
|
||||
return GIF_ERROR;
|
||||
}
|
||||
break;
|
||||
case FLIP_VERT:
|
||||
for (Count = Height, i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count--);
|
||||
for (j = 0; j < Width; j++)
|
||||
Line[j] = ImageBuffer[i][Width - j - 1];
|
||||
if (EGifPutLine(GifFile, Line, Width) == GIF_ERROR)
|
||||
return GIF_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Free the memory used for this image, and the temporary scan line: */
|
||||
for (i = 0; i < Height; i++) free((char *) ImageBuffer[i]);
|
||||
free((char *) ImageBuffer);
|
||||
|
||||
free((char *) Line);
|
||||
|
||||
return GIF_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);
|
||||
}
|
264
G/UTIL/GIFHISTO.C
Normal file
264
G/UTIL/GIFHISTO.C
Normal file
@ -0,0 +1,264 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber 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: *
|
||||
* -q : quite printing mode. *
|
||||
* -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. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifHisto"
|
||||
|
||||
#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. */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifHisto q%- t%- s%-Width|Height!d!d n%-ImageNumber!d b%- h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- t%- s%-Width|Height!d!d n%-ImageNumber!d b%- h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
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 = 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, &GifQuitePrint,
|
||||
&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(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) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
|
||||
if (GifFileIn -> IColorMap)
|
||||
NumColors = (1 << GifFileIn -> IBitsPerPixel);
|
||||
else if (GifFileIn -> SColorMap)
|
||||
NumColors = (1 << GifFileIn -> SBitsPerPixel);
|
||||
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 -> IWidth *
|
||||
sizeof(GifPixelType));
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ImageNum,
|
||||
GifFileIn -> ILeft, GifFileIn -> ITop,
|
||||
GifFileIn -> IWidth, GifFileIn -> IHeight);
|
||||
|
||||
for (i = 0; i < GifFileIn -> IHeight; i++) {
|
||||
if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth)
|
||||
== GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
for (j = 0; j < GifFileIn -> IWidth; 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,
|
||||
HISTO_BITS_PER_PIXEL, HistoColorMap) == GIF_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) == 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);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
268
G/UTIL/GIFINTER.C
Normal file
268
G/UTIL/GIFINTER.C
Normal file
@ -0,0 +1,268 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to flip interlaced and non interlaced images in GIF files. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -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. *
|
||||
* 21 Dec 89 - Fix problems with -i and -s flags (Version 1.1). *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifInter"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifInter q%- i%- s%- h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- i%- s%- h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* 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, GifRowType **ImageBuffer);
|
||||
static int DumpImage(GifFileType *GifFile, GifRowType *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;
|
||||
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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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 GIF_OK if succesful, GIF_ERROR otherwise. *
|
||||
******************************************************************************/
|
||||
static int LoadImage(GifFileType *GifFile, GifRowType **ImageBufferPtr)
|
||||
{
|
||||
int Size, i, j, Count;
|
||||
GifRowType *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 = (GifRowType *)
|
||||
malloc(GifFile -> IHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> IWidth * sizeof(GifPixelType);/* One row size in bytes.*/
|
||||
for (i = 0; i < GifFile -> IHeight; i++) {
|
||||
/* Allocate the rows: */
|
||||
if ((ImageBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
}
|
||||
|
||||
*ImageBufferPtr = ImageBuffer;
|
||||
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++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 < GifFile -> IHeight;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile, ImageBuffer[j], GifFile -> IWidth)
|
||||
== GIF_ERROR) return GIF_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < GifFile -> IHeight; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, ImageBuffer[i], GifFile -> IWidth)
|
||||
== GIF_ERROR) return GIF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return GIF_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 GIF_OK if succesful, GIF_ERROR otherwise. *
|
||||
******************************************************************************/
|
||||
static int DumpImage(GifFileType *GifFile, GifRowType *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 < GifFile -> IHeight;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count--);
|
||||
if (EGifPutLine(GifFile, ImageBuffer[j], GifFile -> IWidth)
|
||||
== GIF_ERROR) return GIF_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (Count = GifFile -> IHeight, i = 0; i < GifFile -> IHeight; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count--);
|
||||
if (EGifPutLine(GifFile, ImageBuffer[i], GifFile -> IWidth)
|
||||
== GIF_ERROR) return GIF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the m emory used for this image: */
|
||||
for (i = 0; i < GifFile -> IHeight; i++) free((char *) ImageBuffer[i]);
|
||||
free((char *) ImageBuffer);
|
||||
|
||||
return GIF_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);
|
||||
}
|
159
G/UTIL/GIFINTO.C
Normal file
159
G/UTIL/GIFINTO.C
Normal file
@ -0,0 +1,159 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to read stdin, and save it into the specified file iff the result *
|
||||
* and inspired by the rle utah tool kit I decided to implement and add it. *
|
||||
* -q : quite printing mode. *
|
||||
* -s minsize : the minimum file size to keep it. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 7 Jul 89 - Version 1.0 by Gershon Elber. *
|
||||
* 22 Dec 89 - Fix problem with tmpnam (Version 1.1). *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <io.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifInto"
|
||||
|
||||
#define DEFAULT_MIN_FILE_SIZE 14 /* More than GIF stamp + screen desc. */
|
||||
#define DEFAULT_OUT_NAME "GifInto.Gif"
|
||||
#define DEFAULT_TMP_NAME "TempInto.$$$"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifInto q%- s%-MinFileSize!d h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- s%-MinFileSize!d h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
static int
|
||||
MinFileSize = DEFAULT_MIN_FILE_SIZE;
|
||||
|
||||
/******************************************************************************
|
||||
* The is simply: read until EOF, then close the output, test its length, and *
|
||||
* if non zero then rename it. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int Error, NumFiles,
|
||||
MinSizeFlag = FALSE, HelpFlag = FALSE;
|
||||
char **FileName = NULL,
|
||||
TmpName[80], FoutTmpName[80], FullPath[80], DefaultName[80], s[80], *p;
|
||||
FILE *Fin, *Fout;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&MinSizeFlag, &MinFileSize, &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);
|
||||
}
|
||||
|
||||
/* Open the stdin in binary mode and increase its buffer size: */
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY); /* Make sure it is in binary mode. */
|
||||
if ((Fin = fdopen(0, "rb")) == NULL || /* Make it into a stream: */
|
||||
setvbuf(Fin, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE))/* Incr. stream buf.*/
|
||||
#else
|
||||
if ((Fin = fdopen(0, "r")) == NULL) /* Make it into a stream: */
|
||||
#endif /* __MSDOS__ */
|
||||
GIF_EXIT("Failed to open input.");
|
||||
|
||||
/* Isolate the directory where our destination is, and set tmp file name */
|
||||
/* in the very same directory. */
|
||||
strcpy(FullPath, *FileName);
|
||||
if ((p = strrchr(FullPath, '/')) != NULL ||
|
||||
(p = strrchr(FullPath, '\\')) != NULL)
|
||||
p[1] = 0;
|
||||
else if ((p = strrchr(FullPath, ':')) != NULL)
|
||||
p[1] = 0;
|
||||
else
|
||||
FullPath[0] = 0; /* No directory or disk specified. */
|
||||
|
||||
strcpy(FoutTmpName, FullPath); /* Generate destination temporary name. */
|
||||
/* Make sure the temporary is made in the current directory: */
|
||||
p = tmpnam(TmpName);
|
||||
if (strrchr(p, '/')) p = strrchr(p, '/') + 1;
|
||||
if (strrchr(p, '\\')) p = strrchr(p, '\\') + 1;
|
||||
if (strlen(p) == 0) p = DEFAULT_TMP_NAME;
|
||||
strcat(FoutTmpName, p);
|
||||
|
||||
#ifdef __MSDOS__
|
||||
if ((Fout = fopen(FoutTmpName, "wb")) == NULL ||
|
||||
setvbuf(Fout, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE))/*Incr. stream buf.*/
|
||||
#else
|
||||
if ((Fout = fopen(FoutTmpName, "w")) == NULL)
|
||||
#endif /* __MSDOS__ */
|
||||
GIF_EXIT("Failed to open output.");
|
||||
|
||||
while (!feof(Fin)) {
|
||||
if (putc(getc(Fin), Fout) == EOF)
|
||||
GIF_EXIT("Failed to write output.");
|
||||
}
|
||||
|
||||
fclose(Fin);
|
||||
if (ftell(Fout) >= (long) MinFileSize) {
|
||||
fclose(Fout);
|
||||
unlink(*FileName);
|
||||
if (rename(FoutTmpName, *FileName) != 0) {
|
||||
strcpy(DefaultName, FullPath);
|
||||
strcat(DefaultName, DEFAULT_OUT_NAME);
|
||||
if (rename(FoutTmpName, DefaultName) == 0) {
|
||||
sprintf(s, "Failed to rename out file - left as %s.",
|
||||
DefaultName);
|
||||
GIF_MESSAGE(s);
|
||||
}
|
||||
else {
|
||||
unlink(FoutTmpName);
|
||||
GIF_MESSAGE("Failed to rename out file - deleted.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
fclose(Fout);
|
||||
unlink(FoutTmpName);
|
||||
GIF_MESSAGE("File too small - not renamed.");
|
||||
}
|
||||
}
|
202
G/UTIL/GIFPOS.C
Normal file
202
G/UTIL/GIFPOS.C
Normal file
@ -0,0 +1,202 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to reposition GIF file, by changing screen size and/or image(s) *
|
||||
* position. Neither image(s) not colormap(s) are changed by any mean. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -s w h : set new screen size - width & height. *
|
||||
* -i t l : set new image position - top & left (for first image). *
|
||||
* -n n w h : set new image position - top & left (for image number n). *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 6 Jul 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifPos"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifPos q%- s%-Width|Height!d!d i%-Left|Top!d!d n%-n|Left|Top!d!d!d h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- s%-Width|Height!d!d i%-Left|Top!d!d n%-n|Left|Top!d!d!d h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
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, CodeSize, ImageNum = 0,
|
||||
ScreenFlag = FALSE, ScreenWidth, ScreenHeight,
|
||||
ImageFlag = FALSE, ImageLeft, ImageTop,
|
||||
ImageNFlag = FALSE, ImageN, ImageNLeft, ImageNTop,
|
||||
HelpFlag = FALSE;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension, *CodeBlock;
|
||||
char **FileName = NULL;
|
||||
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&ScreenFlag, &ScreenWidth, &ScreenHeight,
|
||||
&ImageFlag, &ImageLeft, &ImageTop,
|
||||
&ImageNFlag, &ImageN, &ImageNLeft, &ImageNTop,
|
||||
&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 its new possible repositioned screen information: */
|
||||
if (EGifPutScreenDesc(GifFileOut,
|
||||
ScreenFlag ? ScreenWidth : GifFileIn -> SWidth,
|
||||
ScreenFlag ? ScreenHeight : 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 possibly repositioned image descriptor to out file: */
|
||||
if (++ImageNum == 1 && ImageFlag) {
|
||||
/* First image should be repositioned: */
|
||||
if (EGifPutImageDesc(GifFileOut,
|
||||
ImageLeft, ImageTop,
|
||||
GifFileIn -> IWidth, GifFileIn -> IHeight,
|
||||
GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
|
||||
GifFileIn -> IColorMap) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
}
|
||||
else if (ImageNum == ImageN && ImageNFlag) {
|
||||
/* Image N should be repositioned: */
|
||||
if (EGifPutImageDesc(GifFileOut,
|
||||
ImageNLeft, ImageNTop,
|
||||
GifFileIn -> IWidth, GifFileIn -> IHeight,
|
||||
GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
|
||||
GifFileIn -> IColorMap) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
}
|
||||
else {
|
||||
/* No repositioning for this image: */
|
||||
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 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:
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
322
G/UTIL/GIFROTAT.C
Normal file
322
G/UTIL/GIFROTAT.C
Normal file
@ -0,0 +1,322 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Aug. 1991 *
|
||||
******************************************************************************
|
||||
* Program to rotate a GIF image by an arbitrary angle. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -a Angle : angle to rotate with respect to the X axis. *
|
||||
* -s Width Height : specifies size of output image. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 2 Aug 91 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif /* M_PI */
|
||||
|
||||
#define PROGRAM_NAME "GifRotat"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifRotat a!-Angle!d q%- s%-Width|Height!d!d h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" a!-Angle!d q%- s%-Width|Height!d!d h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
static int
|
||||
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
|
||||
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
|
||||
|
||||
static void RotateGifImage(GifRowType *ScreenBuffer, GifFileType *SrcGifFile,
|
||||
int Angle, GifColorType *ColorMap,
|
||||
int ExpColorMapSize, int DstWidth, int DstHeight);
|
||||
static void RotateGifLine(GifRowType *ScreenBuffer, int BackGroundColor,
|
||||
int SrcWidth, int SrcHeight,
|
||||
int Angle, GifRowType DstLine,
|
||||
int DstWidth, int DstHeight, int y);
|
||||
static void QuitGifError(GifFileType *DstGifFile);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Size, Error, NumFiles, Col, Row, Count, ExtCode,
|
||||
ExpColorMapSize, DstWidth, DstHeight, Width, Height,
|
||||
ImageNum = 0,
|
||||
DstSizeFlag = FALSE,
|
||||
AngleFlag = FALSE,
|
||||
Angle = 0,
|
||||
HelpFlag = FALSE;
|
||||
char **FileName = NULL;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *Extension;
|
||||
GifFileType *GifFile;
|
||||
GifRowType *ScreenBuffer;
|
||||
GifColorType *ColorMap = NULL;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&AngleFlag, &Angle, &GifQuitePrint,
|
||||
&DstSizeFlag, &DstWidth, &DstHeight, &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 ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the screen 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: */
|
||||
/* Note this screen is device independent - its the screen as defined by */
|
||||
/* the GIF file parameters itself. */
|
||||
if ((ScreenBuffer = (GifRowType *)
|
||||
malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
|
||||
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
|
||||
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
|
||||
for (i = 1; i < GifFile -> SHeight; i++) {
|
||||
/* Allocate the other rows, and set their color to background too: */
|
||||
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
|
||||
}
|
||||
|
||||
/* Scan the content of the GIF file and load the image(s) in: */
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
Row = GifFile -> ITop; /* Image Position relative to Screen. */
|
||||
Col = GifFile -> ILeft;
|
||||
Width = GifFile -> IWidth;
|
||||
Height = GifFile -> IHeight;
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
|
||||
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
|
||||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
|
||||
fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (GifFile -> IInterlace) {
|
||||
/* Need to perform 4 passes on the images: */
|
||||
for (Count = i = 0; i < 4; i++)
|
||||
for (j = Row + InterlacedOffset[i]; j < Row + Height;
|
||||
j += InterlacedJumps[i]) {
|
||||
GifQprintf("\b\b\b\b%-4d", Count++);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
|
||||
Width) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* Skip any extension blocks in file: */
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
|
||||
GifFile -> SColorMap);
|
||||
ExpColorMapSize = GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
|
||||
GifFile -> SBitsPerPixel;
|
||||
|
||||
if (!DstSizeFlag) {
|
||||
DstWidth = GifFile -> SWidth;
|
||||
DstHeight = GifFile -> SHeight;
|
||||
}
|
||||
|
||||
/* Perform the actual rotation and dump the image: */
|
||||
RotateGifImage(ScreenBuffer, GifFile, Angle, ColorMap, ExpColorMapSize,
|
||||
DstWidth, DstHeight);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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 RotateGifLine(GifRowType *ScreenBuffer, int BackGroundColor,
|
||||
int SrcWidth, int SrcHeight,
|
||||
int Angle, GifRowType DstLine,
|
||||
int DstWidth, int DstHeight, int y)
|
||||
{
|
||||
int x,
|
||||
TransSrcX = SrcWidth / 2,
|
||||
TransSrcY = SrcHeight / 2,
|
||||
TransDstX = DstWidth / 2,
|
||||
TransDstY = DstHeight / 2;
|
||||
double SinAngle = sin(Angle * M_PI / 180.0),
|
||||
CosAngle = cos(Angle * M_PI / 180.0);
|
||||
|
||||
for (x = 0; x < DstWidth; x++)
|
||||
{
|
||||
int xc = x - TransDstX,
|
||||
yc = y - TransDstY,
|
||||
SrcX = xc * CosAngle - yc * SinAngle + TransSrcX,
|
||||
SrcY = xc * SinAngle + yc * CosAngle + TransSrcY;
|
||||
|
||||
if (SrcX < 0 || SrcX >= SrcWidth ||
|
||||
SrcY < 0 || SrcY >= SrcHeight)
|
||||
{
|
||||
/* Out of the source image domain - set it to background color. */
|
||||
*DstLine++ = BackGroundColor;
|
||||
}
|
||||
else
|
||||
*DstLine++ = ScreenBuffer[SrcY][SrcX];
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void QuitGifError(GifFileType *DstGifFile)
|
||||
{
|
||||
PrintGifError();
|
||||
if (DstGifFile != NULL) EGifCloseFile(DstGifFile);
|
||||
exit(1);
|
||||
}
|
306
G/UTIL/GIFRSIZE.C
Normal file
306
G/UTIL/GIFRSIZE.C
Normal file
@ -0,0 +1,306 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to resize GIF by given factors horizontally and vertically. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -S x y : scale into size as specified by x and y. *
|
||||
* -s r : resize both x & y direction by factor r. *
|
||||
* -x r : resize the x direction (horizontally) by factor r. *
|
||||
* -y r : resize the y direction (vertically) by factor r. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 4 Jul 89 - Version 1.0 by Gershon Elber. *
|
||||
* 22 Dec 89 - Fix minor bag in discarding last line of input (Version 1.1). *
|
||||
* 3 Aug 91 - make it scale by an arbitrary size value. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifRSize"
|
||||
|
||||
#define MAX_SCALE 16.0 /* Maximum scaling factor. */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifRSize q%- S%-X|Y!d!d s%-Scale!F x%-XScale!F y%-YScale!F h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- S%-X|Y!d!d s%-Scale!F x%-XScale!F y%-YScale!F h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static GifPixelType
|
||||
BackGroundColor = 0;
|
||||
static double
|
||||
XScale = 0.5,
|
||||
YScale = 0.5;
|
||||
static int
|
||||
XSize = 0,
|
||||
YSize = 0;
|
||||
|
||||
static void ResizeLine(GifRowType LineIn, GifRowType LineOut,
|
||||
int InLineLen, int OutLineLen);
|
||||
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, 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,
|
||||
&GifQuitePrint, &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(1);
|
||||
}
|
||||
|
||||
if (HelpFlag) {
|
||||
fprintf(stderr, VersionStr);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* 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 (%d).",
|
||||
MAX_SCALE);
|
||||
GIF_MESSAGE(s);
|
||||
XScale = MAX_SCALE;
|
||||
}
|
||||
if (YScale > MAX_SCALE) {
|
||||
sprintf(s, "YScale too big, maximum scale selected instead (%d).",
|
||||
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 -> 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: */
|
||||
l = (int) (GifFileIn -> ILeft * XScale + 0.5);
|
||||
w = (int) (GifFileIn -> IWidth * XScale + 0.5);
|
||||
t = (int) (GifFileIn -> ITop * YScale + 0.5);
|
||||
h = (int) (GifFileIn -> IHeight * 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 -> IInterlace, GifFileIn -> IBitsPerPixel,
|
||||
GifFileIn -> IColorMap) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
|
||||
if (GifFileIn -> IInterlace) {
|
||||
GIF_EXIT("Cannt resize interlaced images - use GifInter first.");
|
||||
}
|
||||
else {
|
||||
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
|
||||
PROGRAM_NAME, ++ImageNum,
|
||||
GifFileOut -> ILeft, GifFileOut -> ITop,
|
||||
GifFileOut -> IWidth, GifFileOut -> IHeight);
|
||||
|
||||
for (i = GifFileIn -> IHeight, y = 0.0, last_iy = -1;
|
||||
i-- > 0;
|
||||
y += YScale) {
|
||||
if (DGifGetLine(GifFileIn, LineIn,
|
||||
GifFileIn -> IWidth) == GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
|
||||
iy = (int) y;
|
||||
if (last_iy < iy && last_iy < YSize) {
|
||||
ResizeLine(LineIn, LineOut,
|
||||
GifFileIn -> IWidth, GifFileOut -> IWidth);
|
||||
|
||||
for (;
|
||||
last_iy < iy && last_iy < GifFileOut -> IHeight - 1;
|
||||
last_iy++) {
|
||||
GifQprintf("\b\b\b\b%-4d", last_iy + 1);
|
||||
if (EGifPutLine(GifFileOut, LineOut,
|
||||
GifFileOut -> IWidth) ==
|
||||
GIF_ERROR)
|
||||
QuitGifError(GifFileIn, GifFileOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If scale is not dividable - dump last lines: */
|
||||
while (++last_iy < GifFileOut -> IHeight) {
|
||||
GifQprintf("\b\b\b\b%-4d", last_iy);
|
||||
if (EGifPutLine(GifFileOut, LineOut,
|
||||
GifFileOut -> IWidth) == 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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Line resizing routine - scale given lines as follows: *
|
||||
* Scale (by pixel duplication/elimination) from InLineLen to OutLineLen. *
|
||||
******************************************************************************/
|
||||
static void ResizeLine(GifRowType LineIn, GifRowType LineOut,
|
||||
int InLineLen, int OutLineLen)
|
||||
{
|
||||
int i, ix, last_ix;
|
||||
double x;
|
||||
|
||||
OutLineLen--;
|
||||
|
||||
for (i = InLineLen, x = 0.0, last_ix = -1;
|
||||
i-- > 0;
|
||||
x += XScale, LineIn++)
|
||||
{
|
||||
ix = (int) x;
|
||||
for (; last_ix < ix && last_ix < OutLineLen; last_ix++)
|
||||
*LineOut++ = *LineIn;
|
||||
}
|
||||
|
||||
/* Make sure the line is complete. */
|
||||
for (LineIn--; last_ix < OutLineLen; last_ix++)
|
||||
*LineOut++ = *LineIn;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
459
G/UTIL/GIFTEXT.C
Normal file
459
G/UTIL/GIFTEXT.C
Normal file
@ -0,0 +1,459 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jun. 1989 *
|
||||
******************************************************************************
|
||||
* Program to dump GIF file content as TEXT information *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -c : include the color maps as well. *
|
||||
* -e : include encoded information packed as bytes as well. *
|
||||
* -z : include encoded information (12bits) codes as result from the zl alg. *
|
||||
* -p : dump pixel information instead of encoded information. *
|
||||
* -r : same as -p but dump one pixel as one byte in binary form with no *
|
||||
* other information. This will create a file of size Width by Height. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 28 Jun 89 - Version 1.0 by Gershon Elber. *
|
||||
* 21 Dec 89 - Fix segmentation fault problem in PrintCodeBlock (Version 1.1) *
|
||||
* 25 Dec 89 - Add the -r flag for raw output. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <conio.h>
|
||||
#include <io.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifText"
|
||||
|
||||
#define MAKE_PRINTABLE(c) (isprint(c) ? (c) : ' ')
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifText q%- c%- e%- z%- p%- r%- h%- GifFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- c%- e%- z%- p%- r%- h%- GifFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset);
|
||||
static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset);
|
||||
static void PrintExtBlock(GifByteType *Extension, int Reset);
|
||||
static void PrintLZCodes(GifFileType *GifFile);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, ExtCode, CodeSize, Error, NumFiles, Len,
|
||||
ColorMapFlag = FALSE, EncodedFlag = FALSE, LZCodesFlag = FALSE,
|
||||
PixelFlag = FALSE, HelpFlag = FALSE, RawFlag = FALSE, ImageNum = 1;
|
||||
char *GifFileName, **FileName = NULL;
|
||||
GifPixelType *Line;
|
||||
GifRecordType RecordType;
|
||||
GifByteType *CodeBlock, *Extension;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&GifQuitePrint, &ColorMapFlag, &EncodedFlag,
|
||||
&LZCodesFlag, &PixelFlag, &RawFlag, &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) {
|
||||
GifFileName = *FileName;
|
||||
if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the stdin instead: */
|
||||
GifFileName = "Stdin";
|
||||
if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Because we write binary data - make sure no text will be written. */
|
||||
if (RawFlag) {
|
||||
ColorMapFlag = EncodedFlag = LZCodesFlag = PixelFlag = FALSE;
|
||||
#ifdef __MSDOS__
|
||||
setmode(1, O_BINARY); /* Make sure it is in binary mode. */
|
||||
#endif /* __MSDOS__ */
|
||||
}
|
||||
else {
|
||||
printf("\n%s:\n\n\tScreen Size - Width = %d, Height = %d.\n",
|
||||
GifFileName, GifFile -> SWidth, GifFile -> SHeight);
|
||||
printf("\tColorResolution = %d, BitsPerPixel = %d, BackGround = %d.\n",
|
||||
GifFile -> SColorResolution, GifFile -> SBitsPerPixel,
|
||||
GifFile -> SBackGroundColor);
|
||||
if (GifFile -> SColorMap)
|
||||
printf("\tHas Global Color Map.\n\n");
|
||||
else
|
||||
printf("\tNo Global Color Map.\n\n");
|
||||
if (ColorMapFlag && GifFile -> SColorMap) {
|
||||
printf("\tGlobal Color Map:\n");
|
||||
Len = 1 << GifFile -> SBitsPerPixel;
|
||||
for (i = 0; i < Len; i+=4) {
|
||||
for (j = 0; j < 4 && j < Len; j++) {
|
||||
printf("%3d: %02xh %02xh %02xh ", i + j,
|
||||
GifFile -> SColorMap[i + j].Red,
|
||||
GifFile -> SColorMap[i + j].Green,
|
||||
GifFile -> SColorMap[i + j].Blue);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
switch (RecordType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
if (!RawFlag) {
|
||||
printf("\nImage #%d:\n\n\tImage Size - Left = %d, Top = %d, Width = %d, Height = %d.\n",
|
||||
ImageNum++, GifFile -> ILeft, GifFile -> ITop,
|
||||
GifFile -> IWidth, GifFile -> IHeight);
|
||||
printf("\tImage is %s",
|
||||
GifFile -> IInterlace ? "Interlaced" :
|
||||
"Non Interlaced");
|
||||
if (GifFile -> IColorMap != NULL)
|
||||
printf(", BitsPerPixel = %d.\n",
|
||||
GifFile -> IBitsPerPixel);
|
||||
else
|
||||
printf(".\n");
|
||||
if (GifFile -> IColorMap)
|
||||
printf("\tImage Has Color Map.\n");
|
||||
else
|
||||
printf("\tNo Image Color Map.\n");
|
||||
if (ColorMapFlag && GifFile -> IColorMap) {
|
||||
Len = 1 << GifFile -> IBitsPerPixel;
|
||||
for (i = 0; i < Len; i+=4) {
|
||||
for (j = 0; j < 4 && j < Len; j++) {
|
||||
printf("%3d: %02xh %02xh %02xh ", i + j,
|
||||
GifFile -> IColorMap[i + j].Red,
|
||||
GifFile -> IColorMap[i + j].Green,
|
||||
GifFile -> IColorMap[i + j].Blue);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EncodedFlag) {
|
||||
if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
printf("\nImage LZ compressed Codes (Code Size = %d):\n",
|
||||
CodeSize);
|
||||
PrintCodeBlock(GifFile, CodeBlock, TRUE);
|
||||
while (CodeBlock != NULL) {
|
||||
if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
PrintCodeBlock(GifFile, CodeBlock, FALSE);
|
||||
}
|
||||
}
|
||||
else if (LZCodesFlag) {
|
||||
PrintLZCodes(GifFile);
|
||||
}
|
||||
else if (PixelFlag) {
|
||||
Line = (GifPixelType *) malloc(GifFile -> IWidth *
|
||||
sizeof(GifPixelType));
|
||||
for (i = 0; i < GifFile -> IHeight; i++) {
|
||||
if (DGifGetLine(GifFile, Line, GifFile -> IWidth)
|
||||
== GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
PrintPixelBlock(Line, GifFile -> IWidth, i == 0);
|
||||
}
|
||||
PrintPixelBlock(NULL, GifFile -> IWidth, FALSE);
|
||||
free((char *) Line);
|
||||
}
|
||||
else if (RawFlag) {
|
||||
Line = (GifPixelType *) malloc(GifFile -> IWidth *
|
||||
sizeof(GifPixelType));
|
||||
for (i = 0; i < GifFile -> IHeight; i++) {
|
||||
if (DGifGetLine(GifFile, Line, GifFile -> IWidth)
|
||||
== GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
fwrite(Line, 1, GifFile -> IWidth, stdout);
|
||||
}
|
||||
free((char *) Line);
|
||||
}
|
||||
else {
|
||||
/* Skip the image: */
|
||||
if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
while (CodeBlock != NULL) {
|
||||
if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
if (!RawFlag) {
|
||||
printf("\nExtension Record (Ext Code = %d [%c]):\n",
|
||||
ExtCode, MAKE_PRINTABLE(ExtCode));
|
||||
PrintExtBlock(Extension, TRUE);
|
||||
}
|
||||
while (Extension != NULL) {
|
||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
PrintExtBlock(Extension, FALSE);
|
||||
}
|
||||
break;
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
break;
|
||||
default: /* Should be traps by DGifGetRecordType */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (RecordType != TERMINATE_RECORD_TYPE);
|
||||
|
||||
if (DGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (!RawFlag) printf("\nGif file terminated normally.\n");
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Print the given CodeBlock - a string in pascal notation (size in first *
|
||||
* place). Save local information so printing can be performed continuously, *
|
||||
* or reset to start state if Reset. If CodeBlock is NULL, output is flushed *
|
||||
******************************************************************************/
|
||||
static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset)
|
||||
{
|
||||
static int CrntPlace = 0, Print = TRUE;
|
||||
static long CodeCount = 0;
|
||||
char c;
|
||||
int i, Percent, Len;
|
||||
long NumBytes;
|
||||
|
||||
if (Reset || CodeBlock == NULL) {
|
||||
if (CodeBlock == NULL) {
|
||||
if (CrntPlace > 0) {
|
||||
if (Print) printf("\n");
|
||||
CodeCount += CrntPlace - 16;
|
||||
}
|
||||
if (GifFile -> IColorMap)
|
||||
NumBytes = ((((long) GifFile -> IWidth) * GifFile -> IHeight)
|
||||
* GifFile -> IBitsPerPixel) / 8;
|
||||
else
|
||||
NumBytes = ((((long) GifFile -> IWidth) * GifFile -> IHeight)
|
||||
* GifFile -> SBitsPerPixel) / 8;
|
||||
Percent = 100 * CodeCount / NumBytes;
|
||||
printf("\nCompression ratio: %ld/%ld (%d%%).\n",
|
||||
CodeCount, NumBytes, Percent);
|
||||
return;
|
||||
}
|
||||
CrntPlace = 0;
|
||||
CodeCount = 0;
|
||||
Print = TRUE;
|
||||
}
|
||||
|
||||
Len = CodeBlock[0];
|
||||
for (i = 1; i <= Len; i++) {
|
||||
if (CrntPlace == 0) {
|
||||
if (Print) printf("\n%05lxh: ", CodeCount);
|
||||
CodeCount += 16;
|
||||
}
|
||||
#ifdef __MSDOS__
|
||||
if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
|
||||
#endif /* __MSDOS__ */
|
||||
if (Print) printf(" %02xh", CodeBlock[i]);
|
||||
if (++CrntPlace >= 16) CrntPlace = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Print the given Extension - a string in pascal notation (size in first *
|
||||
* place). Save local information so printing can be performed continuously, *
|
||||
* or reset to start state if Reset. If Extension is NULL, output is flushed *
|
||||
******************************************************************************/
|
||||
static void PrintExtBlock(GifByteType *Extension, int Reset)
|
||||
{
|
||||
static int CrntPlace = 0, Print = TRUE;
|
||||
static long ExtCount = 0;
|
||||
static char HexForm[49], AsciiForm[17];
|
||||
char c;
|
||||
int i, Len;
|
||||
|
||||
if (Reset || Extension == NULL) {
|
||||
if (Extension == NULL) {
|
||||
if (CrntPlace > 0) {
|
||||
HexForm[CrntPlace * 3] = 0;
|
||||
AsciiForm[CrntPlace] = 0;
|
||||
if (Print) printf("\n%05lx: %-49s %-17s\n",
|
||||
ExtCount, HexForm, AsciiForm);
|
||||
return;
|
||||
}
|
||||
else if (Print)
|
||||
printf("\n");
|
||||
}
|
||||
CrntPlace = 0;
|
||||
ExtCount = 0;
|
||||
Print = TRUE;
|
||||
}
|
||||
|
||||
if (!Print) return;
|
||||
|
||||
Len = Extension[0];
|
||||
for (i = 1; i <= Len; i++) {
|
||||
sprintf(&HexForm[CrntPlace * 3], " %02x", Extension[i]);
|
||||
sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(Extension[i]));
|
||||
#ifdef __MSDOS__
|
||||
if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
|
||||
#endif /* __MSDOS__ */
|
||||
if (++CrntPlace == 16) {
|
||||
HexForm[CrntPlace * 3] = 0;
|
||||
AsciiForm[CrntPlace] = 0;
|
||||
if (Print) printf("\n%05lx: %-49s %-17s",
|
||||
ExtCount, HexForm, AsciiForm);
|
||||
ExtCount += 16;
|
||||
CrntPlace = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Print the given PixelBlock of length Len. *
|
||||
* Save local information so printing can be performed continuously, *
|
||||
* or reset to start state if Reset. If PixelBlock is NULL, output is flushed *
|
||||
******************************************************************************/
|
||||
static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset)
|
||||
{
|
||||
static int CrntPlace = 0, Print = TRUE;
|
||||
static long ExtCount = 0;
|
||||
static char HexForm[49], AsciiForm[17];
|
||||
char c;
|
||||
int i;
|
||||
|
||||
if (Reset || PixelBlock == NULL) {
|
||||
if (PixelBlock == NULL) {
|
||||
if (CrntPlace > 0) {
|
||||
HexForm[CrntPlace * 3] = 0;
|
||||
AsciiForm[CrntPlace] = 0;
|
||||
if (Print) printf("\n%05lx: %-49s %-17s\n",
|
||||
ExtCount, HexForm, AsciiForm);
|
||||
}
|
||||
else if (Print)
|
||||
printf("\n");
|
||||
}
|
||||
CrntPlace = 0;
|
||||
ExtCount = 0;
|
||||
Print = TRUE;
|
||||
if (PixelBlock == NULL) return;
|
||||
}
|
||||
|
||||
if (!Print) return;
|
||||
|
||||
for (i = 0; i < Len; i++) {
|
||||
sprintf(&HexForm[CrntPlace * 3], " %02x", PixelBlock[i]);
|
||||
sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(PixelBlock[i]));
|
||||
#ifdef __MSDOS__
|
||||
if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
|
||||
#endif /* __MSDOS__ */
|
||||
if (++CrntPlace == 16) {
|
||||
HexForm[CrntPlace * 3] = 0;
|
||||
AsciiForm[CrntPlace] = 0;
|
||||
if (Print) printf("\n%05lx: %-49s %-17s",
|
||||
ExtCount, HexForm, AsciiForm);
|
||||
ExtCount += 16;
|
||||
CrntPlace = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Print the image as LZ codes (each 12bits), until EOF marker is reached. *
|
||||
******************************************************************************/
|
||||
static void PrintLZCodes(GifFileType *GifFile)
|
||||
{
|
||||
char c;
|
||||
int Code, Print = TRUE, CrntPlace = 0;
|
||||
long CodeCount = 0;
|
||||
|
||||
do {
|
||||
if (Print && CrntPlace == 0) printf("\n%05lx:", CodeCount);
|
||||
if (DGifGetLZCodes(GifFile, &Code) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
exit(-1);
|
||||
}
|
||||
if (Print && Code >= 0)
|
||||
printf(" %03x", Code); /* EOF Code is returned as -1. */
|
||||
CodeCount++;
|
||||
if (++CrntPlace >= 16) CrntPlace = 0;
|
||||
#ifdef __MSDOS__
|
||||
if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
|
||||
#endif /* __MSDOS__ */
|
||||
}
|
||||
while (Code >= 0);
|
||||
}
|
168
G/UTIL/GIFWEDGE.C
Normal file
168
G/UTIL/GIFWEDGE.C
Normal file
@ -0,0 +1,168 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to create a test image of White and Red/Green/Blue levels for *
|
||||
* test purposes. The Primary (RGB) and Secondary (YCM) are also displayed. *
|
||||
* background. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -s Width Height : set image size. *
|
||||
* -l levels : number of color levels. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 4 Jan 90 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "GifWedge"
|
||||
|
||||
#define DEFAULT_WIDTH 640
|
||||
#define DEFAULT_HEIGHT 350
|
||||
|
||||
#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image. */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "GifWedge q%- l%-#Lvls!d s%-Width|Height!d!d h%-";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- l%-#Lvls!d s%-Width|Height!d!d h%-";
|
||||
#endif /* SYSV */
|
||||
|
||||
static int
|
||||
NumLevels = DEFAULT_NUM_LEVELS,
|
||||
ImageWidth = DEFAULT_WIDTH,
|
||||
ImageHeight = DEFAULT_HEIGHT;
|
||||
|
||||
static void QuitGifError(GifFileType *GifFile);
|
||||
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void QuitGifError(GifFileType *GifFile)
|
||||
{
|
||||
PrintGifError();
|
||||
if (GifFile != NULL) DGifCloseFile(GifFile);
|
||||
exit(1);
|
||||
}
|
178
G/UTIL/GIF_LIB.H
Normal file
178
G/UTIL/GIF_LIB.H
Normal file
@ -0,0 +1,178 @@
|
||||
/******************************************************************************
|
||||
* In order to make life a little bit easier when using the GIF file format, *
|
||||
* this library was written, and which does all the dirty work... *
|
||||
* *
|
||||
* Written by Gershon Elber, Jun. 1989 *
|
||||
*******************************************************************************
|
||||
* History: *
|
||||
* 14 Jun 89 - Version 1.0 by Gershon Elber. *
|
||||
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef GIF_LIB_H
|
||||
#define GIF_LIB_H
|
||||
|
||||
#define GIF_LIB_VERSION " Version 1.2, "
|
||||
|
||||
#define GIF_ERROR 0
|
||||
#define GIF_OK 1
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */
|
||||
|
||||
typedef int GifBooleanType;
|
||||
typedef unsigned char GifPixelType;
|
||||
typedef unsigned char * GifRowType;
|
||||
typedef unsigned char GifByteType;
|
||||
|
||||
#define GIF_MESSAGE(Msg) fprintf(stderr, "\n%s: %s\n", PROGRAM_NAME, Msg)
|
||||
#define GIF_EXIT(Msg) { GIF_MESSAGE(Msg); exit(-3); }
|
||||
|
||||
#ifdef SYSV
|
||||
#define VoidPtr char *
|
||||
#else
|
||||
#define VoidPtr void *
|
||||
#endif /* SYSV */
|
||||
|
||||
typedef struct GifColorType {
|
||||
GifByteType Red, Green, Blue;
|
||||
} GifColorType;
|
||||
|
||||
/* Note entries prefixed with S are of Screen information, while entries */
|
||||
/* prefixed with I are of the current defined Image. */
|
||||
typedef struct GifFileType {
|
||||
int SWidth, SHeight, /* Screen dimensions. */
|
||||
SColorResolution, SBitsPerPixel, /* How many colors can we generate? */
|
||||
SBackGroundColor, /* I hope you understand this one... */
|
||||
ILeft, ITop, IWidth, IHeight, /* Current image dimensions. */
|
||||
IInterlace, /* Sequential/Interlaced lines. */
|
||||
IBitsPerPixel; /* How many colors this image has? */
|
||||
GifColorType *SColorMap, *IColorMap; /* NULL if not exists. */
|
||||
VoidPtr Private; /* The regular user should not mess with this one! */
|
||||
} GifFileType;
|
||||
|
||||
typedef enum {
|
||||
UNDEFINED_RECORD_TYPE,
|
||||
SCREEN_DESC_RECORD_TYPE,
|
||||
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
|
||||
EXTENSION_RECORD_TYPE, /* Begin with '!' */
|
||||
TERMINATE_RECORD_TYPE /* Begin with ';' */
|
||||
} GifRecordType;
|
||||
|
||||
/* DumpScreen2Gif routine constants identify type of window/screen to dump. */
|
||||
/* Note all values below 1000 are reserved for the IBMPC different display */
|
||||
/* devices (it has many!) and are compatible with the numbering TC2.0 */
|
||||
/* (Turbo C 2.0 compiler for IBM PC) gives to these devices. */
|
||||
typedef enum {
|
||||
GIF_DUMP_SGI_WINDOW = 1000,
|
||||
GIF_DUMP_X_WINDOW = 1001
|
||||
} GifScreenDumpType;
|
||||
|
||||
/******************************************************************************
|
||||
* O.k. here are the routines one can access in order to encode GIF file: *
|
||||
* (GIF_LIB file EGIF_LIB.C). *
|
||||
******************************************************************************/
|
||||
|
||||
GifFileType *EGifOpenFileName(char *GifFileName, int GifTestExistance);
|
||||
GifFileType *EGifOpenFileHandle(int GifFileHandle);
|
||||
void EGifSetGifVersion(char *Version);
|
||||
int EGifPutScreenDesc(GifFileType *GifFile,
|
||||
int GifWidth, int GifHeight, int GifColorRes, int GifBackGround,
|
||||
int GifBitsPerPixel, GifColorType *GifColorMap);
|
||||
int EGifPutImageDesc(GifFileType *GifFile,
|
||||
int GifLeft, int GifTop, int Width, int GifHeight, int GifInterlace,
|
||||
int GifBitsPerPixel, GifColorType *GifColorMap);
|
||||
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
|
||||
int EGifPutPixel(GifFileType *GifFile, GifPixelType GifPixel);
|
||||
int EGifPutComment(GifFileType *GifFile, char *GifComment);
|
||||
int EGifPutExtension(GifFileType *GifFile, int GifExtCode, int GifExtLen,
|
||||
VoidPtr GifExtension);
|
||||
int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
|
||||
GifByteType *GifCodeBlock);
|
||||
int EGifPutCodeNext(GifFileType *GifFile, GifByteType *GifCodeBlock);
|
||||
int EGifCloseFile(GifFileType *GifFile);
|
||||
|
||||
#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
|
||||
#define E_GIF_ERR_WRITE_FAILED 2
|
||||
#define E_GIF_ERR_HAS_SCRN_DSCR 3
|
||||
#define E_GIF_ERR_HAS_IMAG_DSCR 4
|
||||
#define E_GIF_ERR_NO_COLOR_MAP 5
|
||||
#define E_GIF_ERR_DATA_TOO_BIG 6
|
||||
#define E_GIF_ERR_NOT_ENOUGH_MEM 7
|
||||
#define E_GIF_ERR_DISK_IS_FULL 8
|
||||
#define E_GIF_ERR_CLOSE_FAILED 9
|
||||
#define E_GIF_ERR_NOT_WRITEABLE 10
|
||||
|
||||
/******************************************************************************
|
||||
* O.k. here are the routines one can access in order to decode GIF file: *
|
||||
* (GIF_LIB file DGIF_LIB.C). *
|
||||
******************************************************************************/
|
||||
|
||||
GifFileType *DGifOpenFileName(char *GifFileName);
|
||||
GifFileType *DGifOpenFileHandle(int GifFileHandle);
|
||||
int DGifGetScreenDesc(GifFileType *GifFile);
|
||||
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
|
||||
int DGifGetImageDesc(GifFileType *GifFile);
|
||||
int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
|
||||
int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
|
||||
int DGifGetComment(GifFileType *GifFile, char *GifComment);
|
||||
int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
|
||||
GifByteType **GifExtension);
|
||||
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
|
||||
int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
|
||||
GifByteType **GifCodeBlock);
|
||||
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
|
||||
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
|
||||
int DGifCloseFile(GifFileType *GifFile);
|
||||
|
||||
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
|
||||
#define D_GIF_ERR_READ_FAILED 102
|
||||
#define D_GIF_ERR_NOT_GIF_FILE 103
|
||||
#define D_GIF_ERR_NO_SCRN_DSCR 104
|
||||
#define D_GIF_ERR_NO_IMAG_DSCR 105
|
||||
#define D_GIF_ERR_NO_COLOR_MAP 106
|
||||
#define D_GIF_ERR_WRONG_RECORD 107
|
||||
#define D_GIF_ERR_DATA_TOO_BIG 108
|
||||
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
|
||||
#define D_GIF_ERR_CLOSE_FAILED 110
|
||||
#define D_GIF_ERR_NOT_READABLE 111
|
||||
#define D_GIF_ERR_IMAGE_DEFECT 112
|
||||
#define D_GIF_ERR_EOF_TOO_SOON 113
|
||||
|
||||
/******************************************************************************
|
||||
* O.k. here are the routines from GIF_LIB file QUANTIZE.C. *
|
||||
******************************************************************************/
|
||||
int QuantizeBuffer(unsigned int Width, unsigned int Height, int *ColorMapSize,
|
||||
GifByteType *RedInput, GifByteType *GreenInput, GifByteType *BlueInput,
|
||||
GifByteType *OutputBuffer, GifColorType *OutputColorMap);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* O.k. here are the routines from GIF_LIB file QPRINTF.C. *
|
||||
******************************************************************************/
|
||||
extern int GifQuitePrint;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
void GifQprintf();
|
||||
#else
|
||||
void GifQprintf(char *Format, ...);
|
||||
#endif /* USE_VARARGS */
|
||||
|
||||
/******************************************************************************
|
||||
* O.k. here are the routines from GIF_LIB file GIF_ERR.C. *
|
||||
******************************************************************************/
|
||||
void PrintGifError(void);
|
||||
int GifLastError(void);
|
||||
|
||||
/******************************************************************************
|
||||
* O.k. here are the routines from GIF_LIB file DEV2GIF.C. *
|
||||
******************************************************************************/
|
||||
int DumpScreen2Gif(char *FileName, int ReqGraphDriver, int ReqGraphMode1,
|
||||
int ReqGraphMode2,
|
||||
int ReqGraphMode3);
|
||||
|
||||
#endif /* GIF_LIB_H */
|
26
G/UTIL/HERC2GIF.C
Normal file
26
G/UTIL/HERC2GIF.C
Normal file
@ -0,0 +1,26 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jun. 1989 *
|
||||
******************************************************************************
|
||||
* Program to dump the hercules graphic screen into a GIF file *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 26 Jun 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#include <graphics.h>
|
||||
#include "gif_lib.h"
|
||||
|
||||
#define DEFAULT_NAME "hercules.gif"
|
||||
|
||||
/******************************************************************************
|
||||
* Simple - isnt it? *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
if (argc == 2)
|
||||
DumpScreen2Gif(argv[1], HERCMONO, HERCMONOHI, 0, 0);
|
||||
else
|
||||
DumpScreen2Gif(DEFAULT_NAME, HERCMONO, HERCMONOHI, 0, 0);
|
||||
}
|
1
G/UTIL/M.BAT
Normal file
1
G/UTIL/M.BAT
Normal file
@ -0,0 +1 @@
|
||||
make -fmakefile.tc
|
72
G/UTIL/MAKDEBUG.TC
Normal file
72
G/UTIL/MAKDEBUG.TC
Normal file
@ -0,0 +1,72 @@
|
||||
#
|
||||
# This is the make file for the util subdirectory of the GIF library
|
||||
# In order to run it tcc is assumed to be available, in addition to
|
||||
# tlib and borland make.
|
||||
#
|
||||
# Usage: "make [-DMDL=model]" where model can be l (large) or c (compact) etc.
|
||||
# Note the MDL is optional with large model as default.
|
||||
#
|
||||
#
|
||||
# This make file requires:
|
||||
# 1. Setting the TC libraries directory as CC_LIBS below. Make sure this
|
||||
# is really short (because of DOS stupid limit on command line length).
|
||||
# 2. Setting the executables destination directory as DEST below. Make
|
||||
# sure that directory do exists.
|
||||
# 2. Making new library named graphbgi.lib holds the drivers for the different
|
||||
# devices (using bgiobj.exe and tlib.exe utilities).
|
||||
#
|
||||
# Gershon Elber, Jun 1989
|
||||
#
|
||||
|
||||
|
||||
# Works only on TC++ 1.0 make - swap out make before invoking command.
|
||||
.SWAP
|
||||
|
||||
# Your C compiler
|
||||
CC = bcc
|
||||
|
||||
# MDL set?
|
||||
!if !$d(MDL)
|
||||
MDL=l
|
||||
!endif
|
||||
|
||||
# Where all the include files are:
|
||||
INC = ..\lib
|
||||
GIF_INC = $(INC)\gif_lib.h $(INC)\getarg.h
|
||||
|
||||
# And libararies:
|
||||
GIF_LIB = ..\lib\gif_lib$(MDL).lib
|
||||
CC_LIBS = ..\lib\\
|
||||
LIBS = $(GIF_LIB) $(CC_LIBS)graphics.lib $(CC_LIBS)graphbgi.lib \
|
||||
$(CC_LIBS)emu.lib $(CC_LIBS)math$(MDL).lib
|
||||
|
||||
# Note the tcc xxxxxx.tc files enables ALL warnings for more strict tests so
|
||||
# you should use them during debuging. I didnt add it here as command lines
|
||||
# are limited to 128 chars...
|
||||
#
|
||||
# Optimized version:
|
||||
CFLAGS = -m$(MDL) -a- -f -G -O -r -c -d -w -v- -y- -k- -M-
|
||||
#CFLAGS = ml -a- -f -G -O- -r -c -d -w -v- -y- -k- -M-
|
||||
#
|
||||
# Debugging version:
|
||||
# CFLAGS = -m$(MDL) -a- -f -c -d -w -v -y -k -M-
|
||||
# LFLAGS = -lvlc
|
||||
|
||||
ALL = gifdebug.exe
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
#
|
||||
# Note we go all the way to the exe file using this rule.
|
||||
#
|
||||
# LZEXE is an EXE compressor program. If you dont have it remove the two
|
||||
# lines of 'lzexe $&.exe' and 'del $&.old'.
|
||||
#
|
||||
.c.obj:
|
||||
$(CC) -I$(INC) $(CFLAGS) $&.c
|
||||
$(CC) -m$(MDL) $(LFLAGS) $&.obj $(LIBS)
|
||||
del gifdebug.exe
|
||||
ren gifhn.exe gifdebug.exe
|
||||
|
||||
gifdebug.exe: gifhn.obj
|
||||
gifhn.obj: $(GIF_INC)
|
158
G/UTIL/MAKEFILE.TC
Normal file
158
G/UTIL/MAKEFILE.TC
Normal file
@ -0,0 +1,158 @@
|
||||
#
|
||||
# This is the make file for the util subdirectory of the GIF library
|
||||
# In order to run it tcc is assumed to be available, in addition to
|
||||
# tlib and borland make.
|
||||
#
|
||||
# Usage: "make [-DMDL=model]" where model can be l (large) or c (compact) etc.
|
||||
# Note the MDL is optional with large model as default.
|
||||
#
|
||||
#
|
||||
# This make file requires:
|
||||
# 1. Setting the TC libraries directory as CC_LIBS below. Make sure this
|
||||
# is really short (because of DOS stupid limit on command line length).
|
||||
# 2. Setting the executables destination directory as DEST below. Make
|
||||
# sure that directory do exists.
|
||||
# 2. Making new library named graphbgi.lib holds the drivers for the different
|
||||
# devices (using bgiobj.exe and tlib.exe utilities).
|
||||
#
|
||||
# Gershon Elber, Jun 1989
|
||||
#
|
||||
|
||||
|
||||
# Works only on TC++ 1.0 make and up - swap out make before invoking command.
|
||||
.SWAP
|
||||
|
||||
# Your C compiler
|
||||
CC = bcc
|
||||
|
||||
# MDL set?
|
||||
!if !$d(MDL)
|
||||
MDL=l
|
||||
!endif
|
||||
|
||||
# Where all the include files are:
|
||||
#####################################################################
|
||||
#####################################################################
|
||||
INC = E:\
|
||||
#####################################################################
|
||||
#####################################################################
|
||||
GIF_INC = e:\gif_lib.h e:\getarg.h
|
||||
# $(INC)\gif_lib.h $(INC)\getarg.h
|
||||
|
||||
# And libararies:
|
||||
GIF_LIB = e:\gif_lib$(MDL).lib
|
||||
CC_LIBS = e:\
|
||||
BGI_LIB = e:\graphbgi.lib
|
||||
LIBS = $(GIF_LIB) $(CC_LIBS)graphics.lib $(BGI_LIB) \
|
||||
$(CC_LIBS)emu.lib $(CC_LIBS)math$(MDL).lib
|
||||
|
||||
# Where to copy executables to:
|
||||
DEST = ..\gif
|
||||
|
||||
# Note the tcc xxxxxx.tc files enables ALL warnings for more strict tests so
|
||||
# you should use them during debuging. I didnt add it here as command lines
|
||||
# are limited to 128 chars...
|
||||
#
|
||||
# Optimized version:
|
||||
CFLAGS = -m$(MDL) -a- -f -G -O -r -c -d -w -v- -y- -k- -M-
|
||||
#
|
||||
# Debugging version:
|
||||
# CFLAGS = -m$(MDL) -a- -f -c -d -w -v -y -k -M-
|
||||
# LFLAGS = -lvlc
|
||||
|
||||
ALL = $(DEST)\gif2bgi.exe $(DEST)\gif2epsn.exe $(DEST)\gif2herc.exe \
|
||||
$(DEST)\gif2ps.exe $(DEST)\gif2rgb.exe $(DEST)\gifasm.exe \
|
||||
$(DEST)\gifbg.exe $(DEST)\gifclip.exe $(DEST)\gifclrmp.exe \
|
||||
$(DEST)\gifcomb.exe $(DEST)\giffix.exe $(DEST)\gifflip.exe \
|
||||
$(DEST)\gifhisto.exe $(DEST)\gifinter.exe $(DEST)\gifinto.exe \
|
||||
$(DEST)\gifpos.exe $(DEST)\gifrotat.exe $(DEST)\gifrsize.exe \
|
||||
$(DEST)\giftext.exe $(DEST)\gifwedge.exe $(DEST)\herc2gif.exe \
|
||||
$(DEST)\raw2gif.exe $(DEST)\rgb2gif.exe $(DEST)\text2gif.exe
|
||||
|
||||
allexe: $(ALL)
|
||||
|
||||
#
|
||||
# Note we go all the way to the exe file using this rule.
|
||||
#
|
||||
# LZEXE is an EXE compressor program. If you dont have it remove the two
|
||||
# lines of 'lzexe $&.exe' and 'del $&.old'.
|
||||
#
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) -I$(INC) $&.c
|
||||
$(CC) -m$(MDL) $(LFLAGS) $&.obj $(LIBS)
|
||||
# lzexe $&.exe
|
||||
# del $&.old
|
||||
# copy $&.exe $(DEST)
|
||||
# del $&.exe
|
||||
|
||||
$(DEST)\gif2bgi.exe: gif2bgi.obj
|
||||
gif2bgi.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gif2epsn.exe: gif2epsn.obj
|
||||
gif2epsn.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gif2herc.exe: gif2herc.obj $(GIF_LIB)
|
||||
gif2herc.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gif2ps.exe: gif2ps.obj $(GIF_LIB)
|
||||
gif2ps.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gif2rgb.exe: gif2rgb.obj $(GIF_LIB)
|
||||
gif2rgb.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifasm.exe: gifasm.obj $(GIF_LIB)
|
||||
gifasm.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifbg.exe: gifbg.obj $(GIF_LIB)
|
||||
gifbg.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifclip.exe: gifclip.obj $(GIF_LIB)
|
||||
gifclip.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifclrmp.exe: gifclrmp.c gifclrmp.obj $(GIF_LIB)
|
||||
gifclrmp.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifcomb.exe: gifcomb.obj $(GIF_LIB)
|
||||
gifcomb.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\giffix.exe: giffix.obj $(GIF_LIB)
|
||||
giffix.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifflip.exe: gifflip.obj $(GIF_LIB)
|
||||
gifflip.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifhisto.exe: gifhisto.obj $(GIF_LIB)
|
||||
gifhisto.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifinter.exe: gifinter.obj $(GIF_LIB)
|
||||
gifinter.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifinto.exe: gifinto.obj $(GIF_LIB)
|
||||
gifinto.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifpos.exe: gifpos.obj $(GIF_LIB)
|
||||
gifpos.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifrotat.exe: gifrotat.obj $(GIF_LIB)
|
||||
gifrotat.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifrsize.exe: gifrsize.obj $(GIF_LIB)
|
||||
gifrsize.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\giftext.exe: giftext.obj $(GIF_LIB)
|
||||
giftext.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\gifwedge.exe: gifwedge.obj $(GIF_LIB)
|
||||
gifwedge.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\herc2gif.exe: herc2gif.obj $(GIF_LIB)
|
||||
herc2gif.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\raw2gif.exe: raw2gif.obj $(GIF_LIB)
|
||||
raw2gif.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\rgb2gif.exe: rgb2gif.obj $(GIF_LIB)
|
||||
rgb2gif.obj: $(GIF_INC)
|
||||
|
||||
$(DEST)\text2gif.exe: text2gif.obj $(GIF_LIB)
|
||||
text2gif.obj: $(GIF_INC)
|
189
G/UTIL/MAKEFILE.UNX
Normal file
189
G/UTIL/MAKEFILE.UNX
Normal file
@ -0,0 +1,189 @@
|
||||
#
|
||||
# This is the make file for the util subdirectory of the GIF library
|
||||
# In order to run it gcc is assumed to be available (gnu c compiler)
|
||||
# You may try other c compilers but the must support ansi c!
|
||||
#
|
||||
# Usage: "make -f makefile.unx [all] [rle] [iris]
|
||||
#
|
||||
# This make file is for Unix BSD type of machines.
|
||||
#
|
||||
# Gershon Elber, Dec 1989
|
||||
#
|
||||
|
||||
#
|
||||
# If you have the utah raster tool kit and wants conversion routines to and
|
||||
# from it set the ones below properly.
|
||||
#
|
||||
RLE_INC = -I/u/urt/urt3.0/include
|
||||
RLE_LIB = /u/urt/urt3.0/lib/librle.a
|
||||
X_LIB_DIR = /server/sun4/usr/new/lib/X11R4
|
||||
|
||||
# Where are all the include files and libraryies for the gif utils:
|
||||
INC = -I../lib
|
||||
GIF_LIB = ../lib/libgif.a
|
||||
GIF_LIB_DEPEND = ../lib/libgif.a ../lib/gif_lib.h ../lib/getarg.h
|
||||
|
||||
# Where to copy executables to:
|
||||
DEST = ../bin
|
||||
|
||||
#
|
||||
# These are the flags for gcc, in BSD4.3 or Sun O.S. 4.0.3
|
||||
#
|
||||
# If your system has all function prototypes for gcc, replace all
|
||||
# the -Wxxx with -Wall. I can not add -Wimplicit as my system uses old cc
|
||||
# h files.
|
||||
#
|
||||
#
|
||||
# CC = gcc
|
||||
#
|
||||
# CFLAGS = -O -c -W -Wreturn-type -Wcomment
|
||||
# CFLAGS = -g -pg -c -W -Wreturn-type -Wcomment
|
||||
#
|
||||
# for sun 4 (gunnars@ifi.uib.no). Tested using gcc 1.39.
|
||||
#
|
||||
# CFLAGS = -O -c -sun4 -W -Wreturn-type -Wcomment -DUSE_VARARGS
|
||||
# CFLAGS = -g -c -sun4 -W -Wreturn-type -Wcomment -DUSE_VARARGS
|
||||
#
|
||||
# MORELIBS =
|
||||
|
||||
#
|
||||
# These are the flags for cc on SGI iris4d. O.S. IRIX 3.2. Note you must
|
||||
# Define MORELIBS as well.
|
||||
#
|
||||
CC = cc
|
||||
#
|
||||
CFLAGS = -O -c -DSYSV -DNO_VOID_PTR -Olimit 1000 -Wf,-XNh5000 -Wf,-XNd5000 -G 4
|
||||
# CFLAGS = -g -p -c -DSYSV -DNO_VOID_PTR -Olimit 1000 -Wf,-XNh5000 -Wf,-XNd5000 -G 4
|
||||
# MORELIBS = -lbsd
|
||||
|
||||
#
|
||||
# These are the flags for xlc, ansi compiler for IBM R6000
|
||||
#
|
||||
# CC = xlc
|
||||
#
|
||||
# CFLAGS = -O -c -qnoro -D_POSIX_SOURCE -D_ALL_SOURCE -DR6000
|
||||
# CFLAGS = -g -pg -c -qnoro -D_POSIX_SOURCE -D_ALL_SOURCE -DR6000
|
||||
# MORELIBS =
|
||||
|
||||
|
||||
ALL = $(DEST)/gif2epsn $(DEST)/gif2ps $(DEST)/gif2rgb \
|
||||
$(DEST)/gif2x11 $(DEST)/gifasm $(DEST)/gifbg \
|
||||
$(DEST)/gifclip $(DEST)/gifclrmp $(DEST)/gifcomb \
|
||||
$(DEST)/giffix $(DEST)/gifflip $(DEST)/gifhisto \
|
||||
$(DEST)/gifinter $(DEST)/gifinto $(DEST)/gifpos \
|
||||
$(DEST)/gifrotat $(DEST)/gifrsize $(DEST)/giftext \
|
||||
$(DEST)/gifwedge $(DEST)/raw2gif $(DEST)/rgb2gif \
|
||||
$(DEST)/text2gif
|
||||
|
||||
RLE = $(DEST)/gif2rle $(DEST)/rle2gif
|
||||
|
||||
IRIS = $(DEST)/gif2iris
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(INC) $(RLE_INC) $<
|
||||
|
||||
all: $(ALL)
|
||||
rle: $(RLE)
|
||||
iris: $(IRIS)
|
||||
|
||||
$(DEST)/gif2epsn: gif2epsn.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gif2epsn.o -o gif2epsn $(GIF_LIB)
|
||||
mv -f gif2epsn $(DEST)
|
||||
|
||||
$(DEST)/gif2iris: gif2iris.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gif2iris.o -o gif2iris $(GIF_LIB) -lgl_s
|
||||
mv -f gif2iris $(DEST)
|
||||
|
||||
$(DEST)/gif2ps: gif2ps.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gif2ps.o -o gif2ps $(GIF_LIB)
|
||||
mv -f gif2ps $(DEST)
|
||||
|
||||
$(DEST)/gif2rgb: gif2rgb.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gif2rgb.o -o gif2rgb $(GIF_LIB)
|
||||
mv -f gif2rgb $(DEST)
|
||||
|
||||
$(DEST)/gif2x11: gif2x11.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gif2x11.o -o gif2x11 $(GIF_LIB) -L$(X_LIB_DIR) -lX11 $(MORELIBS)
|
||||
mv -f gif2x11 $(DEST)
|
||||
|
||||
$(DEST)/gifasm: gifasm.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifasm.o -o gifasm $(GIF_LIB)
|
||||
mv -f gifasm $(DEST)
|
||||
|
||||
$(DEST)/gifbg: gifbg.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifbg.o -o gifbg $(GIF_LIB)
|
||||
mv -f gifbg $(DEST)
|
||||
|
||||
$(DEST)/gifclip: gifclip.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifclip.o -o gifclip $(GIF_LIB)
|
||||
mv -f gifclip $(DEST)
|
||||
|
||||
$(DEST)/gifclrmp: gifclrmp.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifclrmp.o -o gifclrmp $(GIF_LIB) -lm
|
||||
mv -f gifclrmp $(DEST)
|
||||
|
||||
$(DEST)/gifcomb: gifcomb.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifcomb.o -o gifcomb $(GIF_LIB)
|
||||
mv -f gifcomb $(DEST)
|
||||
|
||||
$(DEST)/giffix: giffix.o $(GIF_LIB_DEPEND)
|
||||
$(CC) giffix.o -o giffix $(GIF_LIB)
|
||||
mv -f giffix $(DEST)
|
||||
|
||||
$(DEST)/gifflip: gifflip.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifflip.o -o gifflip $(GIF_LIB)
|
||||
mv -f gifflip $(DEST)
|
||||
|
||||
$(DEST)/gifhisto: gifhisto.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifhisto.o -o gifhisto $(GIF_LIB)
|
||||
mv -f gifhisto $(DEST)
|
||||
|
||||
$(DEST)/gifinter: gifinter.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifinter.o -o gifinter $(GIF_LIB)
|
||||
mv -f gifinter $(DEST)
|
||||
|
||||
$(DEST)/gifinto: gifinto.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifinto.o -o gifinto $(GIF_LIB)
|
||||
mv -f gifinto $(DEST)
|
||||
|
||||
$(DEST)/gifpos: gifpos.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifpos.o -o gifpos $(GIF_LIB)
|
||||
mv -f gifpos $(DEST)
|
||||
|
||||
$(DEST)/gifrotat: gifrotat.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifrotat.o -o gifrotat $(GIF_LIB) -lm
|
||||
mv -f gifrotat $(DEST)
|
||||
|
||||
$(DEST)/gifrsize: gifrsize.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifrsize.o -o gifrsize $(GIF_LIB)
|
||||
mv -f gifrsize $(DEST)
|
||||
|
||||
$(DEST)/giftext: giftext.o $(GIF_LIB_DEPEND)
|
||||
$(CC) giftext.o -o giftext $(GIF_LIB)
|
||||
mv -f giftext $(DEST)
|
||||
|
||||
$(DEST)/gifwedge: gifwedge.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gifwedge.o -o gifwedge $(GIF_LIB)
|
||||
mv -f gifwedge $(DEST)
|
||||
|
||||
$(DEST)/raw2gif: raw2gif.o $(GIF_LIB_DEPEND)
|
||||
$(CC) raw2gif.o -o raw2gif $(GIF_LIB)
|
||||
mv -f raw2gif $(DEST)
|
||||
|
||||
$(DEST)/text2gif: text2gif.o $(GIF_LIB_DEPEND)
|
||||
$(CC) text2gif.o -o text2gif $(GIF_LIB)
|
||||
mv -f text2gif $(DEST)
|
||||
|
||||
$(DEST)/rgb2gif: rgb2gif.o $(GIF_LIB_DEPEND)
|
||||
$(CC) rgb2gif.o -o rgb2gif $(GIF_LIB)
|
||||
mv -f rgb2gif $(DEST)
|
||||
|
||||
#
|
||||
# The utah raster toolkit conversion routines:
|
||||
#
|
||||
$(DEST)/gif2rle: gif2rle.o $(GIF_LIB_DEPEND)
|
||||
$(CC) gif2rle.o -o gif2rle $(GIF_LIB) $(RLE_LIB)
|
||||
mv -f gif2rle $(DEST)
|
||||
$(DEST)/rle2gif: rle2gif.o $(GIF_LIB_DEPEND)
|
||||
$(CC) rle2gif.o -o rle2gif $(GIF_LIB) $(RLE_LIB)
|
||||
mv -f rle2gif $(DEST)
|
254
G/UTIL/RAW2GIF.C
Normal file
254
G/UTIL/RAW2GIF.C
Normal file
@ -0,0 +1,254 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jun. 1989 *
|
||||
******************************************************************************
|
||||
* Module to conver raw image into a GIF file. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -s Width Height : specifies size of raw image. *
|
||||
* -p ColorMapFile : specifies color map for ray image (see gifclrmp). *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 15 Oct 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <dos.h>
|
||||
#include <alloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <graphics.h>
|
||||
#include <io.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "getarg.h"
|
||||
#include "gif_lib.h"
|
||||
|
||||
#define PROGRAM_NAME "Raw2Gif"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Raw2Gif q%- s!-Width|Height!d!d p%-ColorMapFile!s h%- RawFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- s!-Width|Height!d!d p%-ColorMapFile!s h%- RawFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
static GifColorType EGAPallete[] = /* Default color map is EGA pallete. */
|
||||
{
|
||||
{ 0, 0, 0 }, /* 0. Black */
|
||||
{ 0, 0, 170 }, /* 1. Blue */
|
||||
{ 0, 170, 0 }, /* 2. Green */
|
||||
{ 0, 170, 170 }, /* 3. Cyan */
|
||||
{ 170, 0, 0 }, /* 4. Red */
|
||||
{ 170, 0, 170 }, /* 5. Magenta */
|
||||
{ 170, 170, 0 }, /* 6. Brown */
|
||||
{ 170, 170, 170 }, /* 7. LightGray */
|
||||
{ 85, 85, 85 }, /* 8. DarkGray */
|
||||
{ 85, 85, 255 }, /* 9. LightBlue */
|
||||
{ 85, 255, 85 }, /* 10. LightGreen */
|
||||
{ 85, 255, 255 }, /* 11. LightCyan */
|
||||
{ 255, 85, 85 }, /* 12. LightRed */
|
||||
{ 255, 85, 255 }, /* 13. LightMagenta */
|
||||
{ 255, 255, 85 }, /* 14. Yellow */
|
||||
{ 255, 255, 255 }, /* 15. White */
|
||||
};
|
||||
#define EGA_PALLETE_SIZE (sizeof(EGAPallete) / sizeof(GifColorType))
|
||||
|
||||
int Raw2Gif(int ImagwWidth, int ImagwHeight,
|
||||
GifColorType *ColorMap, int ColorMapSize);
|
||||
static int HandleGifError(GifFileType *GifFile);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line, prepar global data and call the Gif routines. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int Error, NumFiles, ImageWidth, ImageHeight, Dummy, Red, Green, Blue,
|
||||
ColorMapSize, InFileHandle,
|
||||
ImageSizeFlag = FALSE, ColorMapFlag = FALSE, HelpFlag = FALSE;
|
||||
char **FileName = NULL, *ColorMapFile;
|
||||
GifColorType *ColorMap;
|
||||
FILE *InColorMapFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&ImageSizeFlag, &ImageWidth, &ImageHeight,
|
||||
&ColorMapFlag, &ColorMapFile,
|
||||
&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 (ColorMapFlag) {
|
||||
/* Read color map from given file: */
|
||||
if ((InColorMapFile = fopen(ColorMapFile, "rt")) == NULL) {
|
||||
GIF_MESSAGE("Failed to open COLOR MAP file (not exists!?).");
|
||||
exit(2);
|
||||
}
|
||||
if ((ColorMap = (GifColorType *)
|
||||
malloc(sizeof(GifColorType) * 255)) /* Biggest map. */
|
||||
== NULL) {
|
||||
GIF_MESSAGE("Failed to allocate bitmap, aborted.");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
for (ColorMapSize = 0;
|
||||
ColorMapSize < 256 && !feof(InColorMapFile);
|
||||
ColorMapSize++) {
|
||||
fscanf(InColorMapFile, "%3d %3d %3d %3d\n",
|
||||
&Dummy, &Red, &Green, &Blue);
|
||||
ColorMap[ColorMapSize].Red = Red;
|
||||
ColorMap[ColorMapSize].Green = Green;
|
||||
ColorMap[ColorMapSize].Blue = Blue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ColorMap = EGAPallete;
|
||||
ColorMapSize = EGA_PALLETE_SIZE;
|
||||
}
|
||||
|
||||
if (NumFiles == 1) {
|
||||
#ifdef __MSDOS__
|
||||
if ((InFileHandle = open(*FileName, O_RDONLY | O_BINARY)) == -1) {
|
||||
#else
|
||||
if ((InFileHandle = open(*FileName, O_RDONLY)) == -1) {
|
||||
#endif /* __MSDOS__ */
|
||||
GIF_MESSAGE("Failed to open RAW image file (not exists!?).");
|
||||
exit(2);
|
||||
}
|
||||
dup2(InFileHandle, 0); /* Make stdin from this file. */
|
||||
}
|
||||
else {
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY); /* Make sure it is in binary mode. */
|
||||
#endif /* __MSDOS__ */
|
||||
}
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setvbuf(stdin, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
/* Conver Raw image from stdin to Gif file in stdout: */
|
||||
Raw2Gif(ImageWidth, ImageHeight, ColorMap, ColorMapSize);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Convert Raw image (One byte per pixel) into Gif file. Raw data is read from *
|
||||
* stdin, and Gif is dumped to stdout. ImagwWidth times ImageHeight bytes are *
|
||||
* read. Color map is dumped from ColorMap. *
|
||||
******************************************************************************/
|
||||
int Raw2Gif(int ImageWidth, int ImageHeight,
|
||||
GifColorType *ColorMap, int ColorMapSize)
|
||||
{
|
||||
static int BitsPerPixelArray[] = { 2, 4 ,8, 16, 32, 64, 128, 256 };
|
||||
int i, j, BitsPerPixel;
|
||||
static GifPixelType *ScanLine;
|
||||
GifFileType *GifFile;
|
||||
|
||||
for (BitsPerPixel = 0;
|
||||
BitsPerPixel < 8 && BitsPerPixelArray[BitsPerPixel] != ColorMapSize;
|
||||
BitsPerPixel++);
|
||||
if (++BitsPerPixel > 8) {
|
||||
GIF_MESSAGE("Number of color map is NOT power of 2 up to 256.");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
if ((ScanLine = (GifPixelType *) malloc(sizeof(GifPixelType) * ImageWidth))
|
||||
== NULL) {
|
||||
GIF_MESSAGE("Failed to allocate scan line, aborted.");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
if ((GifFile = EGifOpenFileHandle(1)) == NULL) { /* Gif to stdout. */
|
||||
free((char *) ScanLine);
|
||||
return HandleGifError(GifFile);
|
||||
}
|
||||
|
||||
if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, BitsPerPixel,
|
||||
0, BitsPerPixel, ColorMap) == GIF_ERROR) {
|
||||
free((char *) ScanLine);
|
||||
return HandleGifError(GifFile);
|
||||
}
|
||||
|
||||
if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, FALSE, 1,
|
||||
NULL) == GIF_ERROR) {
|
||||
free((char *) ScanLine);
|
||||
return HandleGifError(GifFile);
|
||||
}
|
||||
|
||||
/* Here it is - get one raw line from stdin, and dump to stdout Gif: */
|
||||
GifQprintf("\n%s: Image 1 at (0, 0) [%dx%d]: ",
|
||||
PROGRAM_NAME, ImageWidth, ImageHeight);
|
||||
for (i = 0; i < ImageHeight; i++) {
|
||||
/* Note we assume here PixelSize == Byte, which is not necessarily */
|
||||
/* so. If not - must read one byte at a time, and coerce to pixel. */
|
||||
if (fread(ScanLine, 1, ImageWidth, stdin) != ImageWidth) {
|
||||
GIF_MESSAGE("RAW input file ended prematurely.");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
for (j = 0; j < ImageWidth; j++)
|
||||
if (ScanLine[j] >= ColorMapSize)
|
||||
GIF_MESSAGE("Warning: RAW data color > maximum color map entry.");
|
||||
|
||||
if (EGifPutLine(GifFile, ScanLine, ImageWidth) == GIF_ERROR) {
|
||||
free((char *) ScanLine);
|
||||
return HandleGifError(GifFile);
|
||||
}
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
}
|
||||
|
||||
if (EGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
free((char *) ScanLine);
|
||||
return HandleGifError(GifFile);
|
||||
}
|
||||
|
||||
free((char *) ScanLine);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Handle last GIF error. Try to close the file and free all allocated memory. *
|
||||
******************************************************************************/
|
||||
static int HandleGifError(GifFileType *GifFile)
|
||||
{
|
||||
int i = GifLastError();
|
||||
|
||||
if (EGifCloseFile(GifFile) == GIF_ERROR) {
|
||||
GifLastError();
|
||||
}
|
||||
return i;
|
||||
}
|
292
G/UTIL/RGB2GIF.C
Normal file
292
G/UTIL/RGB2GIF.C
Normal file
@ -0,0 +1,292 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jun. 1991 *
|
||||
******************************************************************************
|
||||
* Program to convert 24bits RGB files to GIF format. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -c #colors : in power of two, i.e. 7 will allow upto 128 colors in output. *
|
||||
* -1 : one file holding RGBRGB.. triples of bytes *
|
||||
* -s Width Height : specifies size of raw image. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 15 Jun 91 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "RGB2Gif"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "RGB2Gif q%- c%-#Colors!d 1%- s!-Width|Height!d!d h%- RGBFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- c%-#Colors!d 1%- s!-Width|Height!d!d h%- RGBFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ColorFlag = FALSE,
|
||||
ExpNumOfColors = 8,
|
||||
OneFileFlag = FALSE,
|
||||
HelpFlag = FALSE,
|
||||
ColorMapSize = 256;
|
||||
|
||||
static void LoadRGB(char *FileName,
|
||||
int OneFileFlag,
|
||||
GifByteType **RedBuffer,
|
||||
GifByteType **GreenBuffer,
|
||||
GifByteType **BlueBuffer,
|
||||
int Width, int Height);
|
||||
static void SaveGif(GifByteType *OutputBuffer,
|
||||
GifColorType *OutputColorMap,
|
||||
int ExpColorMapSize, int Width, int Height);
|
||||
static void QuitGifError(GifFileType *GifFile);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int Error, NumFiles, Width, Height, SizeFlag;
|
||||
char **FileName = NULL;
|
||||
GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL,
|
||||
*OutputBuffer = NULL;
|
||||
GifColorType *OutputColorMap = NULL;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&ColorFlag, &ExpNumOfColors, &OneFileFlag,
|
||||
&SizeFlag, &Width, &Height, &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);
|
||||
}
|
||||
|
||||
ColorMapSize = 1 << ExpNumOfColors;
|
||||
|
||||
if (NumFiles == 1) {
|
||||
LoadRGB(*FileName, OneFileFlag,
|
||||
&RedBuffer, &GreenBuffer, &BlueBuffer, Width, Height);
|
||||
}
|
||||
else {
|
||||
LoadRGB(NULL, OneFileFlag,
|
||||
&RedBuffer, &GreenBuffer, &BlueBuffer, Width, Height);
|
||||
}
|
||||
|
||||
if ((OutputColorMap = (GifColorType *) malloc(ColorMapSize *
|
||||
sizeof(GifColorType))) == 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) == GIF_ERROR)
|
||||
QuitGifError(NULL);
|
||||
free((char *) RedBuffer);
|
||||
free((char *) GreenBuffer);
|
||||
free((char *) BlueBuffer);
|
||||
|
||||
SaveGif(OutputBuffer, OutputColorMap, ExpNumOfColors, Width, Height);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Load RGB file into internal frame buffer. *
|
||||
******************************************************************************/
|
||||
static void LoadRGB(char *FileName,
|
||||
int OneFileFlag,
|
||||
GifByteType **RedBuffer,
|
||||
GifByteType **GreenBuffer,
|
||||
GifByteType **BlueBuffer,
|
||||
int Width, int Height)
|
||||
{
|
||||
int i, j;
|
||||
unsigned long Size;
|
||||
GifByteType *RedP, *GreenP, *BlueP;
|
||||
FILE *f[3];
|
||||
|
||||
Size = ((long) Width) * Height * sizeof(GifByteType);
|
||||
#ifdef __MSDOS__
|
||||
if (Size > 65500L)
|
||||
GIF_EXIT("Can't allocate more than 64k.");
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
if ((*RedBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL ||
|
||||
(*GreenBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL ||
|
||||
(*BlueBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
RedP = *RedBuffer;
|
||||
GreenP = *GreenBuffer;
|
||||
BlueP = *BlueBuffer;
|
||||
|
||||
if (FileName != NULL) {
|
||||
char OneFileName[80];
|
||||
|
||||
if (OneFileFlag) {
|
||||
#ifdef __MSDOS__
|
||||
if ((f[0] = fopen(FileName, "rb")) == NULL)
|
||||
#else
|
||||
if ((f[0] = fopen(FileName, "r")) == NULL)
|
||||
#endif /* __MSDOS__ */
|
||||
GIF_EXIT("Can't open input file name.");
|
||||
}
|
||||
else {
|
||||
static char *Postfixes[] = { ".R", ".G", ".B" };
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
strcpy(OneFileName, FileName);
|
||||
strcat(OneFileName, Postfixes[i]);
|
||||
|
||||
#ifdef __MSDOS__
|
||||
if ((f[i] = fopen(OneFileName, "rb")) == NULL)
|
||||
#else
|
||||
if ((f[i] = fopen(OneFileName, "r")) == NULL)
|
||||
#endif /* __MSDOS__ */
|
||||
GIF_EXIT("Can't open input file name.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
OneFileFlag = TRUE;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
setmode(0, O_BINARY);
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
f[0] = stdin;
|
||||
}
|
||||
|
||||
GifQprintf("\n%s: RGB image: ", PROGRAM_NAME);
|
||||
|
||||
if (OneFileFlag) {
|
||||
GifByteType *Buffer, *BufferP;
|
||||
|
||||
if ((Buffer = (GifByteType *) malloc(Width * 3)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (fread(Buffer, Width * 3, 1, f[0]) != 1)
|
||||
GIF_EXIT("Input file(s) terminated prematurly.");
|
||||
for (j = 0, BufferP = Buffer; j < Width; j++) {
|
||||
*RedP++ = *BufferP++;
|
||||
*GreenP++ = *BufferP++;
|
||||
*BlueP++ = *BufferP++;
|
||||
}
|
||||
}
|
||||
|
||||
free((char *) Buffer);
|
||||
fclose(f[0]);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Height; i++) {
|
||||
GifQprintf("\b\b\b\b%-4d", i);
|
||||
if (fread(RedP, Width, 1, f[0]) != 1 ||
|
||||
fread(GreenP, Width, 1, f[1]) != 1 ||
|
||||
fread(BlueP, Width, 1, f[2]) != 1)
|
||||
GIF_EXIT("Input file(s) terminated prematurly.");
|
||||
RedP += Width;
|
||||
GreenP += Width;
|
||||
BlueP += Width;
|
||||
}
|
||||
|
||||
fclose(f[0]);
|
||||
fclose(f[1]);
|
||||
fclose(f[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Save the GIF resulting image. *
|
||||
******************************************************************************/
|
||||
static void SaveGif(GifByteType *OutputBuffer,
|
||||
GifColorType *OutputColorMap,
|
||||
int ExpColorMapSize, int Width, int Height)
|
||||
{
|
||||
int i;
|
||||
GifFileType *GifFile;
|
||||
GifByteType *Ptr = OutputBuffer;
|
||||
|
||||
/* Open stdout for the output file: */
|
||||
if ((GifFile = EGifOpenFileHandle(1)) == NULL)
|
||||
QuitGifError(GifFile);
|
||||
|
||||
if (EGifPutScreenDesc(GifFile,
|
||||
Width, Height, ExpColorMapSize, 0, ExpColorMapSize,
|
||||
OutputColorMap) == GIF_ERROR ||
|
||||
EGifPutImageDesc(GifFile,
|
||||
0, 0, Width, Height, FALSE, ExpColorMapSize, 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void QuitGifError(GifFileType *GifFile)
|
||||
{
|
||||
PrintGifError();
|
||||
if (GifFile != NULL) EGifCloseFile(GifFile);
|
||||
exit(1);
|
||||
}
|
234
G/UTIL/RLE2GIF.C
Normal file
234
G/UTIL/RLE2GIF.C
Normal file
@ -0,0 +1,234 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to convert RLE (utah raster toolkit) file to GIF format. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -c #colors : in power of two, i.e. 7 will allow upto 128 colors in output. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 5 Jan 90 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <graphics.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#include "rle.h" /* The rle tool kit header files. */
|
||||
|
||||
#define PROGRAM_NAME "Rle2Gif"
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module,\t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Rle2Gif q%- c%-#Colors!d h%- RleFile!*s";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- c%-#Colors!d h%- RleFile!*s";
|
||||
#endif /* SYSV */
|
||||
|
||||
/* Make some variables global, so we could access them faster: */
|
||||
static int
|
||||
ColorFlag = FALSE,
|
||||
ExpNumOfColors = 8,
|
||||
HelpFlag = FALSE,
|
||||
ColorMapSize = 256;
|
||||
|
||||
static void LoadRle(char *FileName,
|
||||
GifByteType **RedBuffer,
|
||||
GifByteType **GreenBuffer,
|
||||
GifByteType **BlueBuffer,
|
||||
int *Width, int *Height);
|
||||
static void SaveGif(GifByteType *OutputBuffer,
|
||||
GifColorType *OutputColorMap,
|
||||
int ExpColorMapSize, int Width, int Height);
|
||||
static void QuitGifError(GifFileType *GifFile);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and scan the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, Error, NumFiles, Width, Height;
|
||||
char **FileName = NULL;
|
||||
GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL,
|
||||
*OutputBuffer = NULL;
|
||||
GifColorType *OutputColorMap = NULL;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
|
||||
&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(1);
|
||||
}
|
||||
|
||||
if (HelpFlag) {
|
||||
fprintf(stderr, VersionStr);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ColorMapSize = 1 << ExpNumOfColors;
|
||||
|
||||
if (NumFiles == 1) {
|
||||
LoadRle(*FileName,
|
||||
&RedBuffer, &GreenBuffer, &BlueBuffer, &Width, &Height);
|
||||
}
|
||||
else {
|
||||
LoadRle(NULL,
|
||||
&RedBuffer, &GreenBuffer, &BlueBuffer, &Width, &Height);
|
||||
}
|
||||
|
||||
if ((OutputColorMap = (GifColorType *) malloc(ColorMapSize *
|
||||
sizeof(GifColorType))) == 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) == GIF_ERROR)
|
||||
QuitGifError(NULL);
|
||||
free((char *) RedBuffer);
|
||||
free((char *) GreenBuffer);
|
||||
free((char *) BlueBuffer);
|
||||
|
||||
SaveGif(OutputBuffer, OutputColorMap, ExpNumOfColors, Width, Height);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Load RLE file into internal frame buffer. *
|
||||
******************************************************************************/
|
||||
static void LoadRle(char *FileName,
|
||||
GifByteType **RedBuffer,
|
||||
GifByteType **GreenBuffer,
|
||||
GifByteType **BlueBuffer,
|
||||
int *Width, int *Height)
|
||||
{
|
||||
int i, j, k, Size;
|
||||
GifByteType *OutputPtr[3];
|
||||
rle_hdr in_hdr;
|
||||
rle_pixel **rows, *ptr;
|
||||
|
||||
if (FileName != NULL) {
|
||||
if ((in_hdr.rle_file = fopen(FileName, "r")) == NULL)
|
||||
GIF_EXIT("Can't open input file name.");
|
||||
}
|
||||
else
|
||||
in_hdr.rle_file = stdin;
|
||||
|
||||
rle_get_setup_ok( &in_hdr, "rle2gif", FileName );
|
||||
|
||||
*Width = in_hdr.xmax - in_hdr.xmin + 1;
|
||||
*Height = in_hdr.ymax - in_hdr.ymin + 1;
|
||||
|
||||
if (in_hdr.ncolors != 3)
|
||||
GIF_EXIT("Input Rle file does not hold 3 (RGB) colors, aborted.");
|
||||
|
||||
Size = *Width * *Height * sizeof(GifByteType);
|
||||
if (rle_row_alloc(&in_hdr, &rows) ||
|
||||
(*RedBuffer = (GifByteType *) malloc(Size)) == NULL ||
|
||||
(*GreenBuffer = (GifByteType *) malloc(Size)) == NULL ||
|
||||
(*BlueBuffer = (GifByteType *) malloc(Size)) == NULL)
|
||||
GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
OutputPtr[0] = *RedBuffer;
|
||||
OutputPtr[1] = *GreenBuffer;
|
||||
OutputPtr[2] = *BlueBuffer;
|
||||
|
||||
for (i = 0; i < *Height; i++) {
|
||||
rle_getrow(&in_hdr, rows); /* Get one scan line (3 colors). */
|
||||
|
||||
for (j = 0; j < 3; j++) { /* Copy the 3 colors to the given buffers. */
|
||||
ptr = &rows[j][in_hdr.xmin];
|
||||
|
||||
for (k = 0; k < *Width; k++)
|
||||
*OutputPtr[j]++ = *ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Save the GIF resulting image. *
|
||||
******************************************************************************/
|
||||
static void SaveGif(GifByteType *OutputBuffer,
|
||||
GifColorType *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, ExpColorMapSize,
|
||||
OutputColorMap) == GIF_ERROR ||
|
||||
EGifPutImageDesc(GifFile,
|
||||
0, 0, Width, Height, FALSE, ExpColorMapSize, 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void QuitGifError(GifFileType *GifFile)
|
||||
{
|
||||
PrintGifError();
|
||||
if (GifFile != NULL) EGifCloseFile(GifFile);
|
||||
exit(1);
|
||||
}
|
357
G/UTIL/TEXT2GIF.C
Normal file
357
G/UTIL/TEXT2GIF.C
Normal file
@ -0,0 +1,357 @@
|
||||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber Ver 0.1, Jul. 1989 *
|
||||
******************************************************************************
|
||||
* Program to generate GIF image page from a given text by drawing the chars *
|
||||
* using 8 by 8 fixed font. *
|
||||
* Options: *
|
||||
* -q : quite printing mode. *
|
||||
* -s ColorMapSize : in bits, i.e. 6 bits for 64 colors. *
|
||||
* -f ForeGroundIndex : by default foreground is 1. Must be in range 0..255. *
|
||||
* -c R G B : set the foregound color values. By default it is white. *
|
||||
* -t "Text" : Make one line given file (8 pixel high) from the given Text. *
|
||||
* -h : on line help. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 3 May 90 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <stdlib.h>
|
||||
#include <alloc.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "getarg.h"
|
||||
|
||||
#define PROGRAM_NAME "Text2Gif"
|
||||
|
||||
#define MAX_NUM_TEXT_LINES 100 /* Maximum number of lines in file. */
|
||||
|
||||
#define LINE_LEN 256 /* Maximum length of one text line. */
|
||||
|
||||
#define DEFAULT_FG_INDEX 1 /* Text foreground index. */
|
||||
|
||||
#define DEFAULT_COLOR_RED 255 /* Text foreground color. */
|
||||
#define DEFAULT_COLOR_GREEN 255
|
||||
#define DEFAULT_COLOR_BLUE 255
|
||||
|
||||
#ifdef __MSDOS__
|
||||
extern unsigned int
|
||||
_stklen = 16384; /* Increase default stack size. */
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef SYSV
|
||||
static char *VersionStr =
|
||||
"Gif library module \t\tGershon Elber\n\
|
||||
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr = "Text2Gif q%- s%-ClrMapSize!d f%-FGClr!d c%-R|G|B!d!d!d t%-\"Text\"!s h%-";
|
||||
#else
|
||||
static char
|
||||
*VersionStr =
|
||||
PROGRAM_NAME
|
||||
GIF_LIB_VERSION
|
||||
" Gershon Elber, "
|
||||
__DATE__ ", " __TIME__ "\n"
|
||||
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
|
||||
static char
|
||||
*CtrlStr =
|
||||
PROGRAM_NAME
|
||||
" q%- s%-ClrMapSize!d f%-FGClr!d c%-R|G|B!d!d!d t%-\"Text\"!s h%-";
|
||||
#endif /* SYSV */
|
||||
|
||||
static unsigned int
|
||||
RedColor = DEFAULT_COLOR_RED,
|
||||
GreenColor = DEFAULT_COLOR_GREEN,
|
||||
BlueColor = DEFAULT_COLOR_BLUE;
|
||||
|
||||
/*****************************************************************************
|
||||
* Ascii 8 by 8 regular font - only first 128 characters are supported. *
|
||||
*****************************************************************************/
|
||||
static unsigned char AsciiTable[][8] = {
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Ascii 0 */
|
||||
{ 0x3c, 0x42, 0xa5, 0x81, 0xbd, 0x42, 0x3c, 0x00 }, /* Ascii 1 */
|
||||
{ 0x3c, 0x7e, 0xdb, 0xff, 0xc3, 0x7e, 0x3c, 0x00 }, /* Ascii 2 */
|
||||
{ 0x00, 0xee, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00 }, /* Ascii 3 */
|
||||
{ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00 }, /* Ascii 4 */
|
||||
{ 0x00, 0x3c, 0x18, 0xff, 0xff, 0x08, 0x18, 0x00 }, /* Ascii 5 */
|
||||
{ 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x10, 0x38, 0x00 }, /* Ascii 6 */
|
||||
{ 0x00, 0x00, 0x18, 0x3c, 0x18, 0x00, 0x00, 0x00 }, /* Ascii 7 */
|
||||
{ 0xff, 0xff, 0xe7, 0xc3, 0xe7, 0xff, 0xff, 0xff }, /* Ascii 8 */
|
||||
{ 0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0x3c, 0x00 }, /* Ascii 9 */
|
||||
{ 0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0xbd, 0xc3, 0xff }, /* Ascii 10 */
|
||||
{ 0x1f, 0x07, 0x0d, 0x7c, 0xc6, 0xc6, 0x7c, 0x00 }, /* Ascii 11 */
|
||||
{ 0x00, 0x7e, 0xc3, 0xc3, 0x7e, 0x18, 0x7e, 0x18 }, /* Ascii 12 */
|
||||
{ 0x04, 0x06, 0x07, 0x04, 0x04, 0xfc, 0xf8, 0x00 }, /* Ascii 13 */
|
||||
{ 0x0c, 0x0a, 0x0d, 0x0b, 0xf9, 0xf9, 0x1f, 0x1f }, /* Ascii 14 */
|
||||
{ 0x00, 0x92, 0x7c, 0x44, 0xc6, 0x7c, 0x92, 0x00 }, /* Ascii 15 */
|
||||
{ 0x00, 0x00, 0x60, 0x78, 0x7e, 0x78, 0x60, 0x00 }, /* Ascii 16 */
|
||||
{ 0x00, 0x00, 0x06, 0x1e, 0x7e, 0x1e, 0x06, 0x00 }, /* Ascii 17 */
|
||||
{ 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18 }, /* Ascii 18 */
|
||||
{ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 }, /* Ascii 19 */
|
||||
{ 0xff, 0xb6, 0x76, 0x36, 0x36, 0x36, 0x36, 0x00 }, /* Ascii 20 */
|
||||
{ 0x7e, 0xc1, 0xdc, 0x22, 0x22, 0x1f, 0x83, 0x7e }, /* Ascii 21 */
|
||||
{ 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00 }, /* Ascii 22 */
|
||||
{ 0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x00, 0xff }, /* Ascii 23 */
|
||||
{ 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00 }, /* Ascii 24 */
|
||||
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x00 }, /* Ascii 25 */
|
||||
{ 0x00, 0x04, 0x06, 0xff, 0x06, 0x04, 0x00, 0x00 }, /* Ascii 26 */
|
||||
{ 0x00, 0x20, 0x60, 0xff, 0x60, 0x20, 0x00, 0x00 }, /* Ascii 27 */
|
||||
{ 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0x00 }, /* Ascii 28 */
|
||||
{ 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00 }, /* Ascii 29 */
|
||||
{ 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x00, 0x00 }, /* Ascii 30 */
|
||||
{ 0x00, 0x00, 0x00, 0xfe, 0x7c, 0x38, 0x10, 0x00 }, /* Ascii 31 */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
|
||||
{ 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x00 }, /* ! */
|
||||
{ 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* " */
|
||||
{ 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00 }, /* # */
|
||||
{ 0x10, 0x7c, 0xd2, 0x7c, 0x86, 0x7c, 0x10, 0x00 }, /* $ */
|
||||
{ 0xf0, 0x96, 0xfc, 0x18, 0x3e, 0x72, 0xde, 0x00 }, /* % */
|
||||
{ 0x30, 0x48, 0x30, 0x78, 0xce, 0xcc, 0x78, 0x00 }, /* & */
|
||||
{ 0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ' */
|
||||
{ 0x10, 0x60, 0xc0, 0xc0, 0xc0, 0x60, 0x10, 0x00 }, /* ( */
|
||||
{ 0x10, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x10, 0x00 }, /* ) */
|
||||
{ 0x00, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x00, 0x00 }, /* * */
|
||||
{ 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00 }, /* + */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70 }, /* , */
|
||||
{ 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00 }, /* - */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00 }, /* . */
|
||||
{ 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00 }, /* / */
|
||||
{ 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 }, /* 0x */
|
||||
{ 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x3c, 0x00 }, /* 1 */
|
||||
{ 0x7c, 0xc6, 0x06, 0x0c, 0x30, 0x60, 0xfe, 0x00 }, /* 2 */
|
||||
{ 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00 }, /* 3 */
|
||||
{ 0x0e, 0x1e, 0x36, 0x66, 0xfe, 0x06, 0x06, 0x00 }, /* 4 */
|
||||
{ 0xfe, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xfc, 0x00 }, /* 5 */
|
||||
{ 0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00 }, /* 6 */
|
||||
{ 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x60, 0x00 }, /* 7 */
|
||||
{ 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00 }, /* 8 */
|
||||
{ 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00 }, /* 9 */
|
||||
{ 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00 }, /* : */
|
||||
{ 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x20, 0x00 }, /* }, */
|
||||
{ 0x00, 0x1c, 0x30, 0x60, 0x30, 0x1c, 0x00, 0x00 }, /* < */
|
||||
{ 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00 }, /* = */
|
||||
{ 0x00, 0x70, 0x18, 0x0c, 0x18, 0x70, 0x00, 0x00 }, /* > */
|
||||
{ 0x7c, 0xc6, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00 }, /* ? */
|
||||
{ 0x7c, 0x82, 0x9a, 0xaa, 0xaa, 0x9e, 0x7c, 0x00 }, /* @ */
|
||||
{ 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00 }, /* A */
|
||||
{ 0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0x00 }, /* B */
|
||||
{ 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00 }, /* C */
|
||||
{ 0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00 }, /* D */
|
||||
{ 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xfe, 0x00 }, /* E */
|
||||
{ 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0x00 }, /* F */
|
||||
{ 0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7e, 0x00 }, /* G */
|
||||
{ 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00 }, /* H */
|
||||
{ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, /* I */
|
||||
{ 0x1e, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00 }, /* J */
|
||||
{ 0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x00 }, /* K */
|
||||
{ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00 }, /* L */
|
||||
{ 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0x00 }, /* M */
|
||||
{ 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00 }, /* N */
|
||||
{ 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 }, /* O */
|
||||
{ 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00 }, /* P */
|
||||
{ 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x06 }, /* Q */
|
||||
{ 0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0x00 }, /* R */
|
||||
{ 0x78, 0xcc, 0x60, 0x30, 0x18, 0xcc, 0x78, 0x00 }, /* S */
|
||||
{ 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00 }, /* T */
|
||||
{ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 }, /* U */
|
||||
{ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00 }, /* V */
|
||||
{ 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00 }, /* W */
|
||||
{ 0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00 }, /* X */
|
||||
{ 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00 }, /* Y */
|
||||
{ 0xfe, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00 }, /* Z */
|
||||
{ 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00 }, /* [ */
|
||||
{ 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x00 }, /* \ */
|
||||
{ 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00 }, /* ] */
|
||||
{ 0x00, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00 }, /* ^ */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }, /* _ */
|
||||
{ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ` */
|
||||
{ 0x00, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0x7e, 0x00 }, /* a */
|
||||
{ 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0x00 }, /* b */
|
||||
{ 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0x7e, 0x00 }, /* c */
|
||||
{ 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x00 }, /* d */
|
||||
{ 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7e, 0x00 }, /* e */
|
||||
{ 0x1e, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x30, 0x00 }, /* f */
|
||||
{ 0x00, 0x00, 0x7e, 0xc6, 0xce, 0x76, 0x06, 0x7c }, /* g */
|
||||
{ 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00 }, /* */
|
||||
{ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00 }, /* i */
|
||||
{ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0xf0 }, /* j */
|
||||
{ 0xc0, 0xc0, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0x00 }, /* k */
|
||||
{ 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00 }, /* l */
|
||||
{ 0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xc6, 0xc6, 0x00 }, /* m */
|
||||
{ 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00 }, /* n */
|
||||
{ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 }, /* o */
|
||||
{ 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0xc0 }, /* p */
|
||||
{ 0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x06 }, /* q */
|
||||
{ 0x00, 0x00, 0x6e, 0x70, 0x60, 0x60, 0x60, 0x00 }, /* r */
|
||||
{ 0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0xfc, 0x00 }, /* s */
|
||||
{ 0x30, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x1c, 0x00 }, /* t */
|
||||
{ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00 }, /* u */
|
||||
{ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00 }, /* v */
|
||||
{ 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0x6c, 0x00 }, /* w */
|
||||
{ 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00 }, /* x */
|
||||
{ 0x00, 0x00, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x7c }, /* y */
|
||||
{ 0x00, 0x00, 0xfc, 0x18, 0x30, 0x60, 0xfc, 0x00 }, /* z */
|
||||
{ 0x0e, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0e, 0x00 }, /* { */
|
||||
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, /* | */
|
||||
{ 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00 }, /* } */
|
||||
{ 0x00, 0x00, 0x70, 0x9a, 0x0e, 0x00, 0x00, 0x00 }, /* ~ */
|
||||
{ 0x00, 0x00, 0x18, 0x3c, 0x66, 0xff, 0x00, 0x00 } /* Ascii 127 */
|
||||
};
|
||||
|
||||
static void QuitGifError(GifFileType *GifFile);
|
||||
static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine,
|
||||
int BufferWidth, int ForeGroundIndex);
|
||||
|
||||
/******************************************************************************
|
||||
* Interpret the command line and generate the given GIF file. *
|
||||
******************************************************************************/
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
int i, j, l, Error, ImageWidth, ImageHeight, NumOfLines, LogNumLevels,
|
||||
NumLevels, ClrMapSizeFlag = FALSE, ColorMapSize = 1, ColorFlag = FALSE,
|
||||
ForeGroundIndex = DEFAULT_FG_INDEX, ForeGroundFlag = FALSE,
|
||||
TextLineFlag = FALSE, HelpFlag = FALSE;
|
||||
char *TextLines[MAX_NUM_TEXT_LINES], Line[LINE_LEN];
|
||||
GifRowType RasterBuffer[8];
|
||||
GifColorType *ColorMap;
|
||||
GifFileType *GifFile;
|
||||
|
||||
if ((Error = GAGetArgs(argc, argv, CtrlStr,
|
||||
&GifQuitePrint, &ClrMapSizeFlag, &ColorMapSize,
|
||||
&ForeGroundFlag, &ForeGroundIndex,
|
||||
&ColorFlag, &RedColor, &GreenColor, &BlueColor,
|
||||
&TextLineFlag, &TextLines[0],
|
||||
&HelpFlag)) != FALSE) {
|
||||
GAPrintErrMsg(Error);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (HelpFlag) {
|
||||
fprintf(stderr, VersionStr);
|
||||
GAPrintHowTo(CtrlStr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
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 = 8;
|
||||
ImageWidth = 8 * 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 = 8 * NumOfLines;
|
||||
ImageWidth = 8 * l;
|
||||
}
|
||||
|
||||
/* Allocate the raster buffer for 8 scan lines (one text line). */
|
||||
for (i = 0; i < 8; 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)) == NULL)
|
||||
QuitGifError(GifFile);
|
||||
|
||||
/* 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 = (GifColorType *) malloc(NumLevels * sizeof(GifColorType)))
|
||||
== NULL) GIF_EXIT("Failed to allocate memory required, aborted.");
|
||||
|
||||
for (i = 0; i < NumLevels; i++)
|
||||
ColorMap[i].Red = ColorMap[i].Green = ColorMap[i].Blue = 0;
|
||||
ColorMap[ForeGroundIndex].Red = RedColor;
|
||||
ColorMap[ForeGroundIndex].Green = GreenColor;
|
||||
ColorMap[ForeGroundIndex].Blue = BlueColor;
|
||||
|
||||
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);
|
||||
|
||||
for (i = l = 0; i < NumOfLines; i++) {
|
||||
GenRasterTextLine(RasterBuffer, TextLines[i], ImageWidth,
|
||||
ForeGroundIndex);
|
||||
for (j = 0; j < 8; 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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine,
|
||||
int BufferWidth, int ForeGroundIndex)
|
||||
{
|
||||
char c;
|
||||
unsigned char Byte, Mask;
|
||||
int i, j, k, CharPosX, Len = strlen(TextLine);
|
||||
|
||||
for (i = 0; i < BufferWidth; i++)
|
||||
for (j = 0; j < 8; j++) RasterBuffer[j][i] = 0;
|
||||
|
||||
for (i = CharPosX = 0; i < Len; i++, CharPosX += 8) {
|
||||
c = TextLine[i];
|
||||
for (j = 0; j < 8; j++) {
|
||||
Byte = AsciiTable[c][j];
|
||||
for (k = 0, Mask = 128; k < 8; k++, Mask >>= 1)
|
||||
if (Byte & Mask)
|
||||
RasterBuffer[j][CharPosX + k] = ForeGroundIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Close output file (if open), and exit. *
|
||||
******************************************************************************/
|
||||
static void QuitGifError(GifFileType *GifFile)
|
||||
{
|
||||
PrintGifError();
|
||||
if (GifFile != NULL) EGifCloseFile(GifFile);
|
||||
exit(1);
|
||||
}
|
Reference in New Issue
Block a user