1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun ** Easylogo TGA->header converter
3*4882a593Smuzhiyun ** ==============================
4*4882a593Smuzhiyun ** (C) 2000 by Paolo Scaffardi (arsenio@tin.it)
5*4882a593Smuzhiyun ** AIRVENT SAM s.p.a - RIMINI(ITALY)
6*4882a593Smuzhiyun ** (C) 2007-2008 Mike Frysinger <vapier@gentoo.org>
7*4882a593Smuzhiyun **
8*4882a593Smuzhiyun ** This is still under construction!
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <errno.h>
12*4882a593Smuzhiyun #include <getopt.h>
13*4882a593Smuzhiyun #include <stdbool.h>
14*4882a593Smuzhiyun #include <stdio.h>
15*4882a593Smuzhiyun #include <stdlib.h>
16*4882a593Smuzhiyun #include <string.h>
17*4882a593Smuzhiyun #include <unistd.h>
18*4882a593Smuzhiyun #include <sys/stat.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #pragma pack(1)
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun /*#define ENABLE_ASCII_BANNERS */
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun typedef struct {
25*4882a593Smuzhiyun unsigned char id;
26*4882a593Smuzhiyun unsigned char ColorMapType;
27*4882a593Smuzhiyun unsigned char ImageTypeCode;
28*4882a593Smuzhiyun unsigned short ColorMapOrigin;
29*4882a593Smuzhiyun unsigned short ColorMapLenght;
30*4882a593Smuzhiyun unsigned char ColorMapEntrySize;
31*4882a593Smuzhiyun unsigned short ImageXOrigin;
32*4882a593Smuzhiyun unsigned short ImageYOrigin;
33*4882a593Smuzhiyun unsigned short ImageWidth;
34*4882a593Smuzhiyun unsigned short ImageHeight;
35*4882a593Smuzhiyun unsigned char ImagePixelSize;
36*4882a593Smuzhiyun unsigned char ImageDescriptorByte;
37*4882a593Smuzhiyun } tga_header_t;
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun typedef struct {
40*4882a593Smuzhiyun unsigned char r, g, b;
41*4882a593Smuzhiyun } rgb_t;
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun typedef struct {
44*4882a593Smuzhiyun unsigned char b, g, r;
45*4882a593Smuzhiyun } bgr_t;
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun typedef struct {
48*4882a593Smuzhiyun unsigned char Cb, y1, Cr, y2;
49*4882a593Smuzhiyun } yuyv_t;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun typedef struct {
52*4882a593Smuzhiyun void *data, *palette;
53*4882a593Smuzhiyun int width, height, pixels, bpp, pixel_size, size, palette_size, yuyv;
54*4882a593Smuzhiyun } image_t;
55*4882a593Smuzhiyun
xmalloc(size_t size)56*4882a593Smuzhiyun void *xmalloc (size_t size)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun void *ret = malloc (size);
59*4882a593Smuzhiyun if (!ret) {
60*4882a593Smuzhiyun fprintf (stderr, "\nerror: malloc(%zu) failed: %s",
61*4882a593Smuzhiyun size, strerror(errno));
62*4882a593Smuzhiyun exit (1);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun return ret;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun
StringUpperCase(char * str)67*4882a593Smuzhiyun void StringUpperCase (char *str)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun int count = strlen (str);
70*4882a593Smuzhiyun char c;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun while (count--) {
73*4882a593Smuzhiyun c = *str;
74*4882a593Smuzhiyun if ((c >= 'a') && (c <= 'z'))
75*4882a593Smuzhiyun *str = 'A' + (c - 'a');
76*4882a593Smuzhiyun str++;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun
StringLowerCase(char * str)80*4882a593Smuzhiyun void StringLowerCase (char *str)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun int count = strlen (str);
83*4882a593Smuzhiyun char c;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun while (count--) {
86*4882a593Smuzhiyun c = *str;
87*4882a593Smuzhiyun if ((c >= 'A') && (c <= 'Z'))
88*4882a593Smuzhiyun *str = 'a' + (c - 'A');
89*4882a593Smuzhiyun str++;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun }
pixel_rgb_to_yuyv(rgb_t * rgb_pixel,yuyv_t * yuyv_pixel)92*4882a593Smuzhiyun void pixel_rgb_to_yuyv (rgb_t * rgb_pixel, yuyv_t * yuyv_pixel)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun unsigned int pR, pG, pB;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /* Transform (0-255) components to (0-100) */
97*4882a593Smuzhiyun pR = rgb_pixel->r * 100 / 255;
98*4882a593Smuzhiyun pG = rgb_pixel->g * 100 / 255;
99*4882a593Smuzhiyun pB = rgb_pixel->b * 100 / 255;
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun /* Calculate YUV values (0-255) from RGB beetween 0-100 */
102*4882a593Smuzhiyun yuyv_pixel->y1 = yuyv_pixel->y2 = 209 * (pR + pG + pB) / 300 + 16;
103*4882a593Smuzhiyun yuyv_pixel->Cb = pB - (pR / 4) - (pG * 3 / 4) + 128;
104*4882a593Smuzhiyun yuyv_pixel->Cr = pR - (pG * 3 / 4) - (pB / 4) + 128;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun return;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
printlogo_rgb(rgb_t * data,int w,int h)109*4882a593Smuzhiyun void printlogo_rgb (rgb_t * data, int w, int h)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun int x, y;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun for (y = 0; y < h; y++) {
114*4882a593Smuzhiyun for (x = 0; x < w; x++, data++)
115*4882a593Smuzhiyun if ((data->r <
116*4882a593Smuzhiyun 30) /*&&(data->g == 0)&&(data->b == 0) */ )
117*4882a593Smuzhiyun printf (" ");
118*4882a593Smuzhiyun else
119*4882a593Smuzhiyun printf ("X");
120*4882a593Smuzhiyun printf ("\n");
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
printlogo_yuyv(unsigned short * data,int w,int h)124*4882a593Smuzhiyun void printlogo_yuyv (unsigned short *data, int w, int h)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun int x, y;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun for (y = 0; y < h; y++) {
129*4882a593Smuzhiyun for (x = 0; x < w; x++, data++)
130*4882a593Smuzhiyun if (*data == 0x1080) /* Because of inverted on i386! */
131*4882a593Smuzhiyun printf (" ");
132*4882a593Smuzhiyun else
133*4882a593Smuzhiyun printf ("X");
134*4882a593Smuzhiyun printf ("\n");
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
le16_to_cpu(unsigned short val)138*4882a593Smuzhiyun static inline unsigned short le16_to_cpu (unsigned short val)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun union {
141*4882a593Smuzhiyun unsigned char pval[2];
142*4882a593Smuzhiyun unsigned short val;
143*4882a593Smuzhiyun } swapped;
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun swapped.val = val;
146*4882a593Smuzhiyun return (swapped.pval[1] << 8) + swapped.pval[0];
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
image_load_tga(image_t * image,char * filename)149*4882a593Smuzhiyun int image_load_tga (image_t * image, char *filename)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun FILE *file;
152*4882a593Smuzhiyun tga_header_t header;
153*4882a593Smuzhiyun int i;
154*4882a593Smuzhiyun unsigned char app;
155*4882a593Smuzhiyun rgb_t *p;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun if ((file = fopen (filename, "rb")) == NULL)
158*4882a593Smuzhiyun return -1;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun fread (&header, sizeof (header), 1, file);
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun /* byte swap: tga is little endian, host is ??? */
163*4882a593Smuzhiyun header.ColorMapOrigin = le16_to_cpu (header.ColorMapOrigin);
164*4882a593Smuzhiyun header.ColorMapLenght = le16_to_cpu (header.ColorMapLenght);
165*4882a593Smuzhiyun header.ImageXOrigin = le16_to_cpu (header.ImageXOrigin);
166*4882a593Smuzhiyun header.ImageYOrigin = le16_to_cpu (header.ImageYOrigin);
167*4882a593Smuzhiyun header.ImageWidth = le16_to_cpu (header.ImageWidth);
168*4882a593Smuzhiyun header.ImageHeight = le16_to_cpu (header.ImageHeight);
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun image->width = header.ImageWidth;
171*4882a593Smuzhiyun image->height = header.ImageHeight;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun switch (header.ImageTypeCode) {
174*4882a593Smuzhiyun case 2: /* Uncompressed RGB */
175*4882a593Smuzhiyun image->yuyv = 0;
176*4882a593Smuzhiyun image->palette_size = 0;
177*4882a593Smuzhiyun image->palette = NULL;
178*4882a593Smuzhiyun break;
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun default:
181*4882a593Smuzhiyun printf ("Format not supported!\n");
182*4882a593Smuzhiyun return -1;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun image->bpp = header.ImagePixelSize;
186*4882a593Smuzhiyun image->pixel_size = ((image->bpp - 1) / 8) + 1;
187*4882a593Smuzhiyun image->pixels = image->width * image->height;
188*4882a593Smuzhiyun image->size = image->pixels * image->pixel_size;
189*4882a593Smuzhiyun image->data = xmalloc (image->size);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun if (image->bpp != 24) {
192*4882a593Smuzhiyun printf ("Bpp not supported: %d!\n", image->bpp);
193*4882a593Smuzhiyun return -1;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun fread (image->data, image->size, 1, file);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun /* Swapping R and B values */
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun p = image->data;
201*4882a593Smuzhiyun for (i = 0; i < image->pixels; i++, p++) {
202*4882a593Smuzhiyun app = p->r;
203*4882a593Smuzhiyun p->r = p->b;
204*4882a593Smuzhiyun p->b = app;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun /* Swapping image */
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun if (!(header.ImageDescriptorByte & 0x20)) {
210*4882a593Smuzhiyun unsigned char *temp = xmalloc (image->size);
211*4882a593Smuzhiyun int linesize = image->pixel_size * image->width;
212*4882a593Smuzhiyun void *dest = image->data,
213*4882a593Smuzhiyun *source = temp + image->size - linesize;
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun printf ("S");
216*4882a593Smuzhiyun if (temp == NULL) {
217*4882a593Smuzhiyun printf ("Cannot alloc temp buffer!\n");
218*4882a593Smuzhiyun return -1;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun memcpy (temp, image->data, image->size);
222*4882a593Smuzhiyun for (i = 0; i < image->height;
223*4882a593Smuzhiyun i++, dest += linesize, source -= linesize)
224*4882a593Smuzhiyun memcpy (dest, source, linesize);
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun free (temp);
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun #ifdef ENABLE_ASCII_BANNERS
229*4882a593Smuzhiyun printlogo_rgb (image->data, image->width, image->height);
230*4882a593Smuzhiyun #endif
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun fclose (file);
233*4882a593Smuzhiyun return 0;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
image_free(image_t * image)236*4882a593Smuzhiyun void image_free (image_t * image)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun free (image->data);
239*4882a593Smuzhiyun free (image->palette);
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
image_rgb_to_yuyv(image_t * rgb_image,image_t * yuyv_image)242*4882a593Smuzhiyun int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun rgb_t *rgb_ptr = (rgb_t *) rgb_image->data;
245*4882a593Smuzhiyun yuyv_t yuyv;
246*4882a593Smuzhiyun unsigned short *dest;
247*4882a593Smuzhiyun int count = 0;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun yuyv_image->pixel_size = 2;
250*4882a593Smuzhiyun yuyv_image->bpp = 16;
251*4882a593Smuzhiyun yuyv_image->yuyv = 1;
252*4882a593Smuzhiyun yuyv_image->width = rgb_image->width;
253*4882a593Smuzhiyun yuyv_image->height = rgb_image->height;
254*4882a593Smuzhiyun yuyv_image->pixels = yuyv_image->width * yuyv_image->height;
255*4882a593Smuzhiyun yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size;
256*4882a593Smuzhiyun dest = (unsigned short *) (yuyv_image->data =
257*4882a593Smuzhiyun xmalloc (yuyv_image->size));
258*4882a593Smuzhiyun yuyv_image->palette = 0;
259*4882a593Smuzhiyun yuyv_image->palette_size = 0;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun while ((count++) < rgb_image->pixels) {
262*4882a593Smuzhiyun pixel_rgb_to_yuyv (rgb_ptr++, &yuyv);
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun if ((count & 1) == 0) /* Was == 0 */
265*4882a593Smuzhiyun memcpy (dest, ((void *) &yuyv) + 2, sizeof (short));
266*4882a593Smuzhiyun else
267*4882a593Smuzhiyun memcpy (dest, (void *) &yuyv, sizeof (short));
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun dest++;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun #ifdef ENABLE_ASCII_BANNERS
273*4882a593Smuzhiyun printlogo_yuyv (yuyv_image->data, yuyv_image->width,
274*4882a593Smuzhiyun yuyv_image->height);
275*4882a593Smuzhiyun #endif
276*4882a593Smuzhiyun return 0;
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
image_rgb888_to_rgb565(image_t * rgb888_image,image_t * rgb565_image)279*4882a593Smuzhiyun int image_rgb888_to_rgb565(image_t *rgb888_image, image_t *rgb565_image)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun rgb_t *rgb_ptr = (rgb_t *) rgb888_image->data;
282*4882a593Smuzhiyun unsigned short *dest;
283*4882a593Smuzhiyun int count = 0;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun rgb565_image->pixel_size = 2;
286*4882a593Smuzhiyun rgb565_image->bpp = 16;
287*4882a593Smuzhiyun rgb565_image->yuyv = 0;
288*4882a593Smuzhiyun rgb565_image->width = rgb888_image->width;
289*4882a593Smuzhiyun rgb565_image->height = rgb888_image->height;
290*4882a593Smuzhiyun rgb565_image->pixels = rgb565_image->width * rgb565_image->height;
291*4882a593Smuzhiyun rgb565_image->size = rgb565_image->pixels * rgb565_image->pixel_size;
292*4882a593Smuzhiyun dest = (unsigned short *) (rgb565_image->data =
293*4882a593Smuzhiyun xmalloc(rgb565_image->size));
294*4882a593Smuzhiyun rgb565_image->palette = 0;
295*4882a593Smuzhiyun rgb565_image->palette_size = 0;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun while ((count++) < rgb888_image->pixels) {
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun *dest++ = ((rgb_ptr->b & 0xF8) << 8) |
300*4882a593Smuzhiyun ((rgb_ptr->g & 0xFC) << 3) |
301*4882a593Smuzhiyun (rgb_ptr->r >> 3);
302*4882a593Smuzhiyun rgb_ptr++;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun return 0;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun enum comp_t {
309*4882a593Smuzhiyun COMP_NONE,
310*4882a593Smuzhiyun COMP_GZIP,
311*4882a593Smuzhiyun COMP_LZMA,
312*4882a593Smuzhiyun };
313*4882a593Smuzhiyun static enum comp_t compression = COMP_NONE;
314*4882a593Smuzhiyun static bool bss_storage = false;
315*4882a593Smuzhiyun
image_save_header(image_t * image,char * filename,char * varname)316*4882a593Smuzhiyun int image_save_header (image_t * image, char *filename, char *varname)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun FILE *file = fopen (filename, "w");
319*4882a593Smuzhiyun char app[256], str[256] = "", def_name[64];
320*4882a593Smuzhiyun int count = image->size, col = 0;
321*4882a593Smuzhiyun unsigned char *dataptr = image->data;
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun if (file == NULL)
324*4882a593Smuzhiyun return -1;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun /* Author information */
327*4882a593Smuzhiyun fprintf (file,
328*4882a593Smuzhiyun "/*\n * Generated by EasyLogo, (C) 2000 by Paolo Scaffardi\n *\n");
329*4882a593Smuzhiyun fprintf (file,
330*4882a593Smuzhiyun " * To use this, include it and call: easylogo_plot(screen,&%s, width,x,y)\n *\n",
331*4882a593Smuzhiyun varname);
332*4882a593Smuzhiyun fprintf (file,
333*4882a593Smuzhiyun " * Where:\t'screen'\tis the pointer to the frame buffer\n");
334*4882a593Smuzhiyun fprintf (file, " *\t\t'width'\tis the screen width\n");
335*4882a593Smuzhiyun fprintf (file, " *\t\t'x'\t\tis the horizontal position\n");
336*4882a593Smuzhiyun fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun /* image compress */
339*4882a593Smuzhiyun if (compression != COMP_NONE) {
340*4882a593Smuzhiyun const char *errstr = NULL;
341*4882a593Smuzhiyun unsigned char *compressed;
342*4882a593Smuzhiyun const char *comp_name;
343*4882a593Smuzhiyun struct stat st;
344*4882a593Smuzhiyun FILE *compfp;
345*4882a593Smuzhiyun size_t filename_len = strlen(filename);
346*4882a593Smuzhiyun char *compfilename = xmalloc(filename_len + 20);
347*4882a593Smuzhiyun char *compcmd = xmalloc(filename_len + 50);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun sprintf(compfilename, "%s.bin", filename);
350*4882a593Smuzhiyun switch (compression) {
351*4882a593Smuzhiyun case COMP_GZIP:
352*4882a593Smuzhiyun strcpy(compcmd, "gzip");
353*4882a593Smuzhiyun comp_name = "GZIP";
354*4882a593Smuzhiyun break;
355*4882a593Smuzhiyun case COMP_LZMA:
356*4882a593Smuzhiyun strcpy(compcmd, "lzma");
357*4882a593Smuzhiyun comp_name = "LZMA";
358*4882a593Smuzhiyun break;
359*4882a593Smuzhiyun default:
360*4882a593Smuzhiyun errstr = "\nerror: unknown compression method";
361*4882a593Smuzhiyun goto done;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun strcat(compcmd, " > ");
364*4882a593Smuzhiyun strcat(compcmd, compfilename);
365*4882a593Smuzhiyun compfp = popen(compcmd, "w");
366*4882a593Smuzhiyun if (!compfp) {
367*4882a593Smuzhiyun errstr = "\nerror: popen() failed";
368*4882a593Smuzhiyun goto done;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun if (fwrite(image->data, image->size, 1, compfp) != 1) {
371*4882a593Smuzhiyun errstr = "\nerror: writing data to gzip failed";
372*4882a593Smuzhiyun goto done;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun if (pclose(compfp)) {
375*4882a593Smuzhiyun errstr = "\nerror: gzip process failed";
376*4882a593Smuzhiyun goto done;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun compfp = fopen(compfilename, "r");
380*4882a593Smuzhiyun if (!compfp) {
381*4882a593Smuzhiyun errstr = "\nerror: open() on gzip data failed";
382*4882a593Smuzhiyun goto done;
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun if (stat(compfilename, &st)) {
385*4882a593Smuzhiyun errstr = "\nerror: stat() on gzip file failed";
386*4882a593Smuzhiyun goto done;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun compressed = xmalloc(st.st_size);
389*4882a593Smuzhiyun if (fread(compressed, st.st_size, 1, compfp) != 1) {
390*4882a593Smuzhiyun errstr = "\nerror: reading gzip data failed";
391*4882a593Smuzhiyun goto done;
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun fclose(compfp);
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun unlink(compfilename);
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun dataptr = compressed;
398*4882a593Smuzhiyun count = st.st_size;
399*4882a593Smuzhiyun fprintf(file, "#define EASYLOGO_ENABLE_%s %i\n\n", comp_name, count);
400*4882a593Smuzhiyun if (bss_storage)
401*4882a593Smuzhiyun fprintf (file, "static unsigned char EASYLOGO_DECOMP_BUFFER[%i];\n\n", image->size);
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun done:
404*4882a593Smuzhiyun free(compfilename);
405*4882a593Smuzhiyun free(compcmd);
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun if (errstr) {
408*4882a593Smuzhiyun perror (errstr);
409*4882a593Smuzhiyun return -1;
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun /* Headers */
414*4882a593Smuzhiyun fprintf (file, "#include <video_easylogo.h>\n\n");
415*4882a593Smuzhiyun /* Macros */
416*4882a593Smuzhiyun strcpy (def_name, varname);
417*4882a593Smuzhiyun StringUpperCase (def_name);
418*4882a593Smuzhiyun fprintf (file, "#define DEF_%s_WIDTH\t\t%d\n", def_name,
419*4882a593Smuzhiyun image->width);
420*4882a593Smuzhiyun fprintf (file, "#define DEF_%s_HEIGHT\t\t%d\n", def_name,
421*4882a593Smuzhiyun image->height);
422*4882a593Smuzhiyun fprintf (file, "#define DEF_%s_PIXELS\t\t%d\n", def_name,
423*4882a593Smuzhiyun image->pixels);
424*4882a593Smuzhiyun fprintf (file, "#define DEF_%s_BPP\t\t%d\n", def_name, image->bpp);
425*4882a593Smuzhiyun fprintf (file, "#define DEF_%s_PIXEL_SIZE\t%d\n", def_name,
426*4882a593Smuzhiyun image->pixel_size);
427*4882a593Smuzhiyun fprintf (file, "#define DEF_%s_SIZE\t\t%d\n\n", def_name,
428*4882a593Smuzhiyun image->size);
429*4882a593Smuzhiyun /* Declaration */
430*4882a593Smuzhiyun fprintf (file, "unsigned char DEF_%s_DATA[] = {\n",
431*4882a593Smuzhiyun def_name);
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun /* Data */
434*4882a593Smuzhiyun while (count)
435*4882a593Smuzhiyun switch (col) {
436*4882a593Smuzhiyun case 0:
437*4882a593Smuzhiyun sprintf (str, " 0x%02x", *dataptr++);
438*4882a593Smuzhiyun col++;
439*4882a593Smuzhiyun count--;
440*4882a593Smuzhiyun break;
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun case 16:
443*4882a593Smuzhiyun fprintf (file, "%s", str);
444*4882a593Smuzhiyun if (count > 0)
445*4882a593Smuzhiyun fprintf (file, ",");
446*4882a593Smuzhiyun fprintf (file, "\n");
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun col = 0;
449*4882a593Smuzhiyun break;
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun default:
452*4882a593Smuzhiyun strcpy (app, str);
453*4882a593Smuzhiyun sprintf (str, "%s, 0x%02x", app, *dataptr++);
454*4882a593Smuzhiyun col++;
455*4882a593Smuzhiyun count--;
456*4882a593Smuzhiyun break;
457*4882a593Smuzhiyun }
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun if (col)
460*4882a593Smuzhiyun fprintf (file, "%s\n", str);
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun /* End of declaration */
463*4882a593Smuzhiyun fprintf (file, "};\n\n");
464*4882a593Smuzhiyun /* Variable */
465*4882a593Smuzhiyun fprintf (file, "fastimage_t %s = {\n", varname);
466*4882a593Smuzhiyun fprintf (file, " DEF_%s_DATA,\n", def_name);
467*4882a593Smuzhiyun fprintf (file, " DEF_%s_WIDTH,\n", def_name);
468*4882a593Smuzhiyun fprintf (file, " DEF_%s_HEIGHT,\n", def_name);
469*4882a593Smuzhiyun fprintf (file, " DEF_%s_BPP,\n", def_name);
470*4882a593Smuzhiyun fprintf (file, " DEF_%s_PIXEL_SIZE,\n", def_name);
471*4882a593Smuzhiyun fprintf (file, " DEF_%s_SIZE\n};\n", def_name);
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun fclose (file);
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun return 0;
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun #define DEF_FILELEN 256
479*4882a593Smuzhiyun
usage(int exit_status)480*4882a593Smuzhiyun static void usage (int exit_status)
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun puts (
483*4882a593Smuzhiyun "EasyLogo 1.0 (C) 2000 by Paolo Scaffardi\n"
484*4882a593Smuzhiyun "\n"
485*4882a593Smuzhiyun "Syntax: easylogo [options] inputfile [outputvar [outputfile]]\n"
486*4882a593Smuzhiyun "\n"
487*4882a593Smuzhiyun "Options:\n"
488*4882a593Smuzhiyun " -r Output RGB888 instead of YUYV\n"
489*4882a593Smuzhiyun " -s Output RGB565 instead of YUYV\n"
490*4882a593Smuzhiyun " -g Compress with gzip\n"
491*4882a593Smuzhiyun " -l Compress with lzma\n"
492*4882a593Smuzhiyun " -b Preallocate space in bss for decompressing image\n"
493*4882a593Smuzhiyun " -h Help output\n"
494*4882a593Smuzhiyun "\n"
495*4882a593Smuzhiyun "Where: 'inputfile' is the TGA image to load\n"
496*4882a593Smuzhiyun " 'outputvar' is the variable name to create\n"
497*4882a593Smuzhiyun " 'outputfile' is the output header file (default is 'inputfile.h')"
498*4882a593Smuzhiyun );
499*4882a593Smuzhiyun exit (exit_status);
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun
main(int argc,char * argv[])502*4882a593Smuzhiyun int main (int argc, char *argv[])
503*4882a593Smuzhiyun {
504*4882a593Smuzhiyun int c;
505*4882a593Smuzhiyun bool use_rgb888 = false;
506*4882a593Smuzhiyun bool use_rgb565 = false;
507*4882a593Smuzhiyun char inputfile[DEF_FILELEN],
508*4882a593Smuzhiyun outputfile[DEF_FILELEN], varname[DEF_FILELEN];
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun image_t rgb888_logo, rgb565_logo, yuyv_logo;
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun while ((c = getopt(argc, argv, "hrsglb")) > 0) {
513*4882a593Smuzhiyun switch (c) {
514*4882a593Smuzhiyun case 'h':
515*4882a593Smuzhiyun usage (0);
516*4882a593Smuzhiyun break;
517*4882a593Smuzhiyun case 'r':
518*4882a593Smuzhiyun use_rgb888 = true;
519*4882a593Smuzhiyun puts("Using 24-bit RGB888 Output Fromat");
520*4882a593Smuzhiyun break;
521*4882a593Smuzhiyun case 's':
522*4882a593Smuzhiyun use_rgb565 = true;
523*4882a593Smuzhiyun puts("Using 16-bit RGB565 Output Fromat");
524*4882a593Smuzhiyun break;
525*4882a593Smuzhiyun case 'g':
526*4882a593Smuzhiyun compression = COMP_GZIP;
527*4882a593Smuzhiyun puts("Compressing with gzip");
528*4882a593Smuzhiyun break;
529*4882a593Smuzhiyun case 'l':
530*4882a593Smuzhiyun compression = COMP_LZMA;
531*4882a593Smuzhiyun puts("Compressing with lzma");
532*4882a593Smuzhiyun break;
533*4882a593Smuzhiyun case 'b':
534*4882a593Smuzhiyun bss_storage = true;
535*4882a593Smuzhiyun puts("Preallocating bss space for decompressing image");
536*4882a593Smuzhiyun break;
537*4882a593Smuzhiyun default:
538*4882a593Smuzhiyun usage (1);
539*4882a593Smuzhiyun break;
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun c = argc - optind;
544*4882a593Smuzhiyun if (c > 4 || c < 1)
545*4882a593Smuzhiyun usage (1);
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun strcpy (inputfile, argv[optind]);
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun if (c > 1)
550*4882a593Smuzhiyun strcpy (varname, argv[optind + 1]);
551*4882a593Smuzhiyun else {
552*4882a593Smuzhiyun /* transform "input.tga" to just "input" */
553*4882a593Smuzhiyun char *dot;
554*4882a593Smuzhiyun strcpy (varname, inputfile);
555*4882a593Smuzhiyun dot = strchr (varname, '.');
556*4882a593Smuzhiyun if (dot)
557*4882a593Smuzhiyun *dot = '\0';
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun if (c > 2)
561*4882a593Smuzhiyun strcpy (outputfile, argv[optind + 2]);
562*4882a593Smuzhiyun else {
563*4882a593Smuzhiyun /* just append ".h" to input file name */
564*4882a593Smuzhiyun strcpy (outputfile, inputfile);
565*4882a593Smuzhiyun strcat (outputfile, ".h");
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun /* Make sure the output is sent as soon as we printf() */
569*4882a593Smuzhiyun setbuf(stdout, NULL);
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun printf ("Doing '%s' (%s) from '%s'...",
572*4882a593Smuzhiyun outputfile, varname, inputfile);
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun /* Import TGA logo */
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun printf ("L");
577*4882a593Smuzhiyun if (image_load_tga(&rgb888_logo, inputfile) < 0) {
578*4882a593Smuzhiyun printf ("input file not found!\n");
579*4882a593Smuzhiyun exit (1);
580*4882a593Smuzhiyun }
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun /* Convert, save, and free the image */
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun if (!use_rgb888 && !use_rgb565) {
585*4882a593Smuzhiyun printf ("C");
586*4882a593Smuzhiyun image_rgb_to_yuyv(&rgb888_logo, &yuyv_logo);
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun printf("S");
589*4882a593Smuzhiyun image_save_header(&yuyv_logo, outputfile, varname);
590*4882a593Smuzhiyun image_free(&yuyv_logo);
591*4882a593Smuzhiyun } else if (use_rgb565) {
592*4882a593Smuzhiyun printf("C");
593*4882a593Smuzhiyun image_rgb888_to_rgb565(&rgb888_logo, &rgb565_logo);
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun printf("S");
596*4882a593Smuzhiyun image_save_header(&rgb565_logo, outputfile, varname);
597*4882a593Smuzhiyun image_free(&rgb565_logo);
598*4882a593Smuzhiyun } else {
599*4882a593Smuzhiyun printf("S");
600*4882a593Smuzhiyun image_save_header(&rgb888_logo, outputfile, varname);
601*4882a593Smuzhiyun }
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun /* Free original image and copy */
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun image_free(&rgb888_logo);
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun printf ("\n");
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun return 0;
610*4882a593Smuzhiyun }
611