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