Imported Upstream version 5.1.9
[platform/upstream/giflib.git] / gifecho.c
1 /*****************************************************************************
2
3 gifecho - generate a GIF from ASCII text
4
5 *****************************************************************************/
6
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <ctype.h>
10 #include <string.h>
11 #include <stdbool.h>
12
13 #include "gif_lib.h"
14 #include "getarg.h"
15
16 #define PROGRAM_NAME    "gifecho"
17
18 #define MAX_NUM_TEXT_LINES      100      /* Maximum number of lines in file. */
19
20 #define LINE_LEN                256      /* Maximum length of one text line. */
21
22 #define DEFAULT_FG_INDEX        1                  /* Text foreground index. */
23
24 #define DEFAULT_COLOR_RED       255                /* Text foreground color. */
25 #define DEFAULT_COLOR_GREEN     255
26 #define DEFAULT_COLOR_BLUE      255
27
28 static char
29     *VersionStr =
30         PROGRAM_NAME
31         VERSION_COOKIE
32         "       Gershon Elber,  "
33         __DATE__ ",   " __TIME__ "\n"
34         "(C) Copyright 1989 Gershon Elber.\n";
35 static char
36     *CtrlStr =
37         PROGRAM_NAME
38         " v%- s%-ClrMapSize!d f%-FGClr!d c%-R|G|B!d!d!d t%-\"Text\"!s h%-";
39
40 static unsigned int
41     RedColor = DEFAULT_COLOR_RED,
42     GreenColor = DEFAULT_COLOR_GREEN,
43     BlueColor = DEFAULT_COLOR_BLUE;
44
45 static void QuitGifError(GifFileType *GifFile);
46 static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine,
47                                         int BufferWidth, int ForeGroundIndex);
48
49 /******************************************************************************
50  Interpret the command line and generate the given GIF file.
51 ******************************************************************************/
52 int main(int argc, char **argv)
53 {
54     int i, j, l, ImageWidth, ImageHeight, NumOfLines, LogNumLevels,
55         ErrorCode, NumLevels, ColorMapSize = 1, 
56         ForeGroundIndex = DEFAULT_FG_INDEX;
57     bool Error, ClrMapSizeFlag = false, ForeGroundFlag = false,
58         TextLineFlag = false, HelpFlag = false, ColorFlag = false;
59     char *TextLines[MAX_NUM_TEXT_LINES];
60     GifRowType RasterBuffer[GIF_FONT_HEIGHT];
61     ColorMapObject *ColorMap;
62     GifFileType *GifFile;
63
64     if ((Error = GAGetArgs(argc, argv, CtrlStr,
65                 &GifNoisyPrint, &ClrMapSizeFlag, &ColorMapSize,
66                 &ForeGroundFlag, &ForeGroundIndex,
67                 &ColorFlag, &RedColor, &GreenColor, &BlueColor,
68                 &TextLineFlag, &TextLines[0],
69                 &HelpFlag)) != false) {
70         GAPrintErrMsg(Error);
71         GAPrintHowTo(CtrlStr);
72         exit(EXIT_FAILURE);
73     }
74
75     if (HelpFlag) {
76         (void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR);
77         GAPrintHowTo(CtrlStr);
78         exit(EXIT_SUCCESS);
79     }
80
81     if (ForeGroundIndex > 255 || ForeGroundIndex < 1)
82         GIF_EXIT("Foregound (-f) should be in the range 1..255, aborted.");
83
84     if (ColorMapSize > 8 || ColorMapSize < 1)
85         GIF_EXIT("ColorMapSize (-s) should be in the range 1..8, aborted.");
86
87     if (TextLineFlag) {
88         NumOfLines = 1;
89         ImageHeight = GIF_FONT_HEIGHT;
90         ImageWidth = GIF_FONT_WIDTH * strlen(TextLines[0]);
91     }
92     else {
93         char Line[LINE_LEN];
94         NumOfLines = l = 0;
95         while (fgets(Line, LINE_LEN - 1, stdin)) {
96             for (i = strlen(Line); i > 0 && Line[i-1] <= ' '; i--);
97             Line[i] = 0;
98             if (l < i) l = i;
99             TextLines[NumOfLines++] = strdup(Line);
100             if (NumOfLines == MAX_NUM_TEXT_LINES)
101                 GIF_EXIT("Input file has too many lines, aborted.");
102         }
103         if (NumOfLines == 0)
104             GIF_EXIT("No input text, aborted.");
105         ImageHeight = GIF_FONT_HEIGHT * NumOfLines;
106         ImageWidth = GIF_FONT_WIDTH * l;
107     }
108
109     /* Allocate the raster buffer for GIF_FONT_HEIGHT scan lines (one text line). */
110     for (i = 0; i < GIF_FONT_HEIGHT; i++)
111         if ((RasterBuffer[i] = (GifRowType) malloc(sizeof(GifPixelType) *
112                                                         ImageWidth)) == NULL)
113             GIF_EXIT("Failed to allocate memory required, aborted.");
114
115     /* Open stdout for the output file: */
116     if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
117         PrintGifError(ErrorCode);
118         exit(EXIT_FAILURE);
119     }
120
121     /* Dump out screen description with given size and generated color map: */
122     for (LogNumLevels = 1, NumLevels = 2;
123          NumLevels < ForeGroundIndex;
124          LogNumLevels++, NumLevels <<= 1);
125     if (NumLevels < (1 << ColorMapSize)) {
126         NumLevels = (1 << ColorMapSize);
127         LogNumLevels = ColorMapSize;
128     }
129
130     if ((ColorMap = GifMakeMapObject(NumLevels, NULL)) == NULL)
131         GIF_EXIT("Failed to allocate memory required, aborted.");
132
133     for (i = 0; i < NumLevels; i++)
134         ColorMap->Colors[i].Red = ColorMap->Colors[i].Green = ColorMap->Colors[i].Blue = 0;
135     ColorMap->Colors[ForeGroundIndex].Red = RedColor;
136     ColorMap->Colors[ForeGroundIndex].Green = GreenColor;
137     ColorMap->Colors[ForeGroundIndex].Blue = BlueColor;
138
139     if (EGifPutScreenDesc(GifFile,
140         ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap)
141         == GIF_ERROR)
142         QuitGifError(GifFile);
143
144     /* Dump out the image descriptor: */
145     if (EGifPutImageDesc(GifFile,
146         0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR)
147         QuitGifError(GifFile);
148
149     GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]:     ",
150                     PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top,
151                     GifFile->Image.Width, GifFile->Image.Height);
152
153     for (i = l = 0; i < NumOfLines; i++) {
154         GenRasterTextLine(RasterBuffer, TextLines[i], ImageWidth,
155                                                         ForeGroundIndex);
156         for (j = 0; j < GIF_FONT_HEIGHT; j++) {
157             if (EGifPutLine(GifFile, RasterBuffer[j], ImageWidth) == GIF_ERROR)
158                 QuitGifError(GifFile);
159             GifQprintf("\b\b\b\b%-4d", l++);
160         }
161     }
162
163     if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR)
164     {
165         PrintGifError(ErrorCode);
166         exit(EXIT_FAILURE);
167     }
168
169     return 0;
170 }
171
172 /******************************************************************************
173  Generate raster bits corresponding to given text
174 ******************************************************************************/
175 static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine,
176                                         int BufferWidth, int ForeGroundIndex)
177 {
178     unsigned char Byte, Mask;
179     int i, j, k, CharPosX, Len = strlen(TextLine);
180
181     for (i = 0; i < BufferWidth; i++)
182         for (j = 0; j < GIF_FONT_HEIGHT; j++) RasterBuffer[j][i] = 0;
183
184     for (i = CharPosX = 0; i < Len; i++, CharPosX += GIF_FONT_WIDTH) {
185         unsigned char c = TextLine[i];
186         for (j = 0; j < GIF_FONT_HEIGHT; j++) {
187             Byte = GifAsciiTable8x8[(unsigned short)c][j];
188             for (k = 0, Mask = 128; k < GIF_FONT_WIDTH; k++, Mask >>= 1)
189                 if (Byte & Mask)
190                     RasterBuffer[j][CharPosX + k] = ForeGroundIndex;
191         }
192     }
193 }
194
195 /******************************************************************************
196 * Close output file (if open), and exit.
197 ******************************************************************************/
198 static void QuitGifError(GifFileType *GifFile)
199 {
200     if (GifFile != NULL) {
201         PrintGifError(GifFile->Error);
202         EGifCloseFile(GifFile, NULL);
203     }
204     exit(EXIT_FAILURE);
205 }
206
207 /* end */