xref: /OK3568_Linux_fs/u-boot/tools/easylogo/easylogo.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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