mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-14 03:40:55 +00:00
255 lines
7.9 KiB
C
255 lines
7.9 KiB
C
/*****************************************************************************
|
|
* "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 : quiet 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 HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifdef __MSDOS__
|
|
#include <dos.h>
|
|
#include <alloc.h>
|
|
#include <stdlib.h>
|
|
#include <graphics.h>
|
|
#include <io.h>
|
|
#endif /* __MSDOS__ */
|
|
|
|
#ifndef __MSDOS__
|
|
#include <stdlib.h>
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef HAVE_FCNTL_H
|
|
#include <fcntl.h>
|
|
#endif /* HAVE_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 toolkit module,\t\tGershon Elber\n\
|
|
(C) Copyright 1989 Gershon Elber.\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.\n";
|
|
static char
|
|
*CtrlStr =
|
|
PROGRAM_NAME
|
|
" q%- s!-Width|Height!d!d p%-ColorMapFile!s h%- RawFile!*s";
|
|
#endif /* SYSV */
|
|
|
|
static GifColorType EGAPalette[] = /* Default color map is EGA palette. */
|
|
{
|
|
{ 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_PALETTE_SIZE (sizeof(EGAPalette) / sizeof(GifColorType))
|
|
|
|
int Raw2Gif(int ImagwWidth, int ImagwHeight, ColorMapObject *ColorMap);
|
|
static int HandleGifError(GifFileType *GifFile);
|
|
|
|
/******************************************************************************
|
|
* Interpret the command line, prepar global data and call the Gif routines. *
|
|
******************************************************************************/
|
|
int 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;
|
|
ColorMapObject *ColorMap;
|
|
FILE *InColorMapFile;
|
|
|
|
if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint,
|
|
&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(EXIT_FAILURE);
|
|
}
|
|
|
|
if (HelpFlag) {
|
|
fprintf(stderr, VersionStr);
|
|
GAPrintHowTo(CtrlStr);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
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(EXIT_FAILURE);
|
|
}
|
|
if ((ColorMap = MakeMapObject(256, NULL)) == NULL) {
|
|
GIF_MESSAGE("Failed to allocate bitmap, aborted.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
for (ColorMapSize = 0;
|
|
ColorMapSize < 256 && !feof(InColorMapFile);
|
|
ColorMapSize++) {
|
|
fscanf(InColorMapFile, "%3d %3d %3d %3d\n",
|
|
&Dummy, &Red, &Green, &Blue);
|
|
ColorMap->Colors[ColorMapSize].Red = Red;
|
|
ColorMap->Colors[ColorMapSize].Green = Green;
|
|
ColorMap->Colors[ColorMapSize].Blue = Blue;
|
|
}
|
|
}
|
|
else {
|
|
ColorMap = MakeMapObject(16, EGAPalette);
|
|
}
|
|
|
|
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(EXIT_FAILURE);
|
|
}
|
|
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);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* 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, ColorMapObject *ColorMap)
|
|
{
|
|
int i, j;
|
|
static GifPixelType *ScanLine;
|
|
GifFileType *GifFile;
|
|
|
|
if ((ScanLine = (GifPixelType *) malloc(sizeof(GifPixelType) * ImageWidth))
|
|
== NULL) {
|
|
GIF_MESSAGE("Failed to allocate scan line, aborted.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if ((GifFile = EGifOpenFileHandle(1)) == NULL) { /* Gif to stdout. */
|
|
free((char *) ScanLine);
|
|
return HandleGifError(GifFile);
|
|
}
|
|
|
|
if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, ColorMap->BitsPerPixel,
|
|
0, ColorMap) == GIF_ERROR) {
|
|
free((char *) ScanLine);
|
|
return HandleGifError(GifFile);
|
|
}
|
|
|
|
if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, FALSE,
|
|
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) != (unsigned)ImageWidth) {
|
|
GIF_MESSAGE("RAW input file ended prematurely.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
for (j = 0; j < ImageWidth; j++)
|
|
if (ScanLine[j] >= ColorMap->ColorCount)
|
|
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;
|
|
}
|