xref: /openbmc/u-boot/tools/easylogo/easylogo.c (revision 2146cf56)
1 /*
2 ** Easylogo TGA->header converter
3 ** ==============================
4 ** (C) 2000 by Paolo Scaffardi (arsenio@tin.it)
5 ** AIRVENT SAM s.p.a - RIMINI(ITALY)
6 **
7 ** This is still under construction!
8 */
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #pragma pack(1)
15 
16 /*#define ENABLE_ASCII_BANNERS */
17 
18 typedef struct {
19 	unsigned char id;
20 	unsigned char ColorMapType;
21 	unsigned char ImageTypeCode;
22 	unsigned short ColorMapOrigin;
23 	unsigned short ColorMapLenght;
24 	unsigned char ColorMapEntrySize;
25 	unsigned short ImageXOrigin;
26 	unsigned short ImageYOrigin;
27 	unsigned short ImageWidth;
28 	unsigned short ImageHeight;
29 	unsigned char ImagePixelSize;
30 	unsigned char ImageDescriptorByte;
31 } tga_header_t;
32 
33 typedef struct {
34 	unsigned char r, g, b;
35 } rgb_t;
36 
37 typedef struct {
38 	unsigned char b, g, r;
39 } bgr_t;
40 
41 typedef struct {
42 	unsigned char Cb, y1, Cr, y2;
43 } yuyv_t;
44 
45 typedef struct {
46 	void *data, *palette;
47 	int width, height, pixels, bpp, pixel_size, size, palette_size, yuyv;
48 } image_t;
49 
50 void StringUpperCase (char *str)
51 {
52 	int count = strlen (str);
53 	char c;
54 
55 	while (count--) {
56 		c = *str;
57 		if ((c >= 'a') && (c <= 'z'))
58 			*str = 'A' + (c - 'a');
59 		str++;
60 	}
61 }
62 
63 void StringLowerCase (char *str)
64 {
65 	int count = strlen (str);
66 	char c;
67 
68 	while (count--) {
69 		c = *str;
70 		if ((c >= 'A') && (c <= 'Z'))
71 			*str = 'a' + (c - 'A');
72 		str++;
73 	}
74 }
75 void pixel_rgb_to_yuyv (rgb_t * rgb_pixel, yuyv_t * yuyv_pixel)
76 {
77 	unsigned int pR, pG, pB;
78 
79 	/* Transform (0-255) components to (0-100) */
80 	pR = rgb_pixel->r * 100 / 255;
81 	pG = rgb_pixel->g * 100 / 255;
82 	pB = rgb_pixel->b * 100 / 255;
83 
84 	/* Calculate YUV values (0-255) from RGB beetween 0-100 */
85 	yuyv_pixel->y1 = yuyv_pixel->y2 = 209 * (pR + pG + pB) / 300 + 16;
86 	yuyv_pixel->Cb = pB - (pR / 4) - (pG * 3 / 4) + 128;
87 	yuyv_pixel->Cr = pR - (pG * 3 / 4) - (pB / 4) + 128;
88 
89 	return;
90 }
91 
92 void printlogo_rgb (rgb_t * data, int w, int h)
93 {
94 	int x, y;
95 
96 	for (y = 0; y < h; y++) {
97 		for (x = 0; x < w; x++, data++)
98 			if ((data->r <
99 			     30) /*&&(data->g == 0)&&(data->b == 0) */ )
100 				printf (" ");
101 			else
102 				printf ("X");
103 		printf ("\n");
104 	}
105 }
106 
107 void printlogo_yuyv (unsigned short *data, int w, int h)
108 {
109 	int x, y;
110 
111 	for (y = 0; y < h; y++) {
112 		for (x = 0; x < w; x++, data++)
113 			if (*data == 0x1080)	/* Because of inverted on i386! */
114 				printf (" ");
115 			else
116 				printf ("X");
117 		printf ("\n");
118 	}
119 }
120 
121 static inline unsigned short le16_to_cpu (unsigned short val)
122 {
123 	union {
124 		unsigned char pval[2];
125 		unsigned short val;
126 	} swapped;
127 
128 	swapped.val = val;
129 	return (swapped.pval[1] << 8) + swapped.pval[0];
130 }
131 
132 int image_load_tga (image_t * image, char *filename)
133 {
134 	FILE *file;
135 	tga_header_t header;
136 	int i;
137 	unsigned char app;
138 	rgb_t *p;
139 
140 	if ((file = fopen (filename, "rb")) == NULL)
141 		return -1;
142 
143 	fread (&header, sizeof (header), 1, file);
144 
145 	/* byte swap: tga is little endian, host is ??? */
146 	header.ColorMapOrigin = le16_to_cpu (header.ColorMapOrigin);
147 	header.ColorMapLenght = le16_to_cpu (header.ColorMapLenght);
148 	header.ImageXOrigin = le16_to_cpu (header.ImageXOrigin);
149 	header.ImageYOrigin = le16_to_cpu (header.ImageYOrigin);
150 	header.ImageWidth = le16_to_cpu (header.ImageWidth);
151 	header.ImageHeight = le16_to_cpu (header.ImageHeight);
152 
153 	image->width = header.ImageWidth;
154 	image->height = header.ImageHeight;
155 
156 	switch (header.ImageTypeCode) {
157 	case 2:		/* Uncompressed RGB */
158 		image->yuyv = 0;
159 		image->palette_size = 0;
160 		image->palette = NULL;
161 		break;
162 
163 	default:
164 		printf ("Format not supported!\n");
165 		return -1;
166 	}
167 
168 	image->bpp = header.ImagePixelSize;
169 	image->pixel_size = ((image->bpp - 1) / 8) + 1;
170 	image->pixels = image->width * image->height;
171 	image->size = image->pixels * image->pixel_size;
172 	image->data = malloc (image->size);
173 
174 	if (image->bpp != 24) {
175 		printf ("Bpp not supported: %d!\n", image->bpp);
176 		return -1;
177 	}
178 
179 	fread (image->data, image->size, 1, file);
180 
181 /* Swapping R and B values */
182 
183 	p = image->data;
184 	for (i = 0; i < image->pixels; i++, p++) {
185 		app = p->r;
186 		p->r = p->b;
187 		p->b = app;
188 	}
189 
190 /* Swapping image */
191 
192 	if (!(header.ImageDescriptorByte & 0x20)) {
193 		unsigned char *temp = malloc (image->size);
194 		int linesize = image->pixel_size * image->width;
195 		void *dest = image->data,
196 			*source = temp + image->size - linesize;
197 
198 		printf ("S");
199 		if (temp == NULL) {
200 			printf ("Cannot alloc temp buffer!\n");
201 			return -1;
202 		}
203 
204 		memcpy (temp, image->data, image->size);
205 		for (i = 0; i < image->height;
206 		     i++, dest += linesize, source -= linesize)
207 			memcpy (dest, source, linesize);
208 
209 		free (temp);
210 	}
211 #ifdef ENABLE_ASCII_BANNERS
212 	printlogo_rgb (image->data, image->width, image->height);
213 #endif
214 
215 	fclose (file);
216 	return 0;
217 }
218 
219 int image_free (image_t * image)
220 {
221 	if (image->data != NULL)
222 		free (image->data);
223 
224 	if (image->palette != NULL)
225 		free (image->palette);
226 
227 	return 0;
228 }
229 
230 int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image)
231 {
232 	rgb_t *rgb_ptr = (rgb_t *) rgb_image->data;
233 	yuyv_t yuyv;
234 	unsigned short *dest;
235 	int count = 0;
236 
237 	yuyv_image->pixel_size = 2;
238 	yuyv_image->bpp = 16;
239 	yuyv_image->yuyv = 1;
240 	yuyv_image->width = rgb_image->width;
241 	yuyv_image->height = rgb_image->height;
242 	yuyv_image->pixels = yuyv_image->width * yuyv_image->height;
243 	yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size;
244 	dest = (unsigned short *) (yuyv_image->data =
245 				   malloc (yuyv_image->size));
246 	yuyv_image->palette = 0;
247 	yuyv_image->palette_size = 0;
248 
249 	while ((count++) < rgb_image->pixels) {
250 		pixel_rgb_to_yuyv (rgb_ptr++, &yuyv);
251 
252 		if ((count & 1) == 0)	/* Was == 0 */
253 			memcpy (dest, ((void *) &yuyv) + 2, sizeof (short));
254 		else
255 			memcpy (dest, (void *) &yuyv, sizeof (short));
256 
257 		dest++;
258 	}
259 
260 #ifdef ENABLE_ASCII_BANNERS
261 	printlogo_yuyv (yuyv_image->data, yuyv_image->width,
262 			yuyv_image->height);
263 #endif
264 	return 0;
265 }
266 
267 int image_save_header (image_t * image, char *filename, char *varname)
268 {
269 	FILE *file = fopen (filename, "w");
270 	char app[256], str[256] = "", def_name[64];
271 	int count = image->size, col = 0;
272 	unsigned char *dataptr = image->data;
273 
274 	if (file == NULL)
275 		return -1;
276 
277 	/*  Author information */
278 	fprintf (file,
279 		 "/*\n * Generated by EasyLogo, (C) 2000 by Paolo Scaffardi\n *\n");
280 	fprintf (file,
281 		 " * To use this, include it and call: easylogo_plot(screen,&%s, width,x,y)\n *\n",
282 		 varname);
283 	fprintf (file,
284 		 " * Where:\t'screen'\tis the pointer to the frame buffer\n");
285 	fprintf (file, " *\t\t'width'\tis the screen width\n");
286 	fprintf (file, " *\t\t'x'\t\tis the horizontal position\n");
287 	fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
288 
289 	/*	Headers */
290 	fprintf (file, "#include <video_easylogo.h>\n\n");
291 	/*	Macros */
292 	strcpy (def_name, varname);
293 	StringUpperCase (def_name);
294 	fprintf (file, "#define	DEF_%s_WIDTH\t\t%d\n", def_name,
295 		 image->width);
296 	fprintf (file, "#define	DEF_%s_HEIGHT\t\t%d\n", def_name,
297 		 image->height);
298 	fprintf (file, "#define	DEF_%s_PIXELS\t\t%d\n", def_name,
299 		 image->pixels);
300 	fprintf (file, "#define	DEF_%s_BPP\t\t%d\n", def_name, image->bpp);
301 	fprintf (file, "#define	DEF_%s_PIXEL_SIZE\t%d\n", def_name,
302 		 image->pixel_size);
303 	fprintf (file, "#define	DEF_%s_SIZE\t\t%d\n\n", def_name,
304 		 image->size);
305 	/*  Declaration */
306 	fprintf (file, "unsigned char DEF_%s_DATA[DEF_%s_SIZE] = {\n",
307 		 def_name, def_name);
308 
309 	/*	Data */
310 	while (count)
311 		switch (col) {
312 		case 0:
313 			sprintf (str, " 0x%02x", *dataptr++);
314 			col++;
315 			count--;
316 			break;
317 
318 		case 16:
319 			fprintf (file, "%s", str);
320 			if (count > 0)
321 				fprintf (file, ",");
322 			fprintf (file, "\n");
323 
324 			col = 0;
325 			break;
326 
327 		default:
328 			strcpy (app, str);
329 			sprintf (str, "%s, 0x%02x", app, *dataptr++);
330 			col++;
331 			count--;
332 			break;
333 		}
334 
335 	if (col)
336 		fprintf (file, "%s\n", str);
337 
338 	/* 	End of declaration */
339 	fprintf (file, "};\n\n");
340 	/*	Variable */
341 	fprintf (file, "fastimage_t %s = {\n", varname);
342 	fprintf (file, "		DEF_%s_DATA,\n", def_name);
343 	fprintf (file, "		DEF_%s_WIDTH,\n", def_name);
344 	fprintf (file, "		DEF_%s_HEIGHT,\n", def_name);
345 	fprintf (file, "		DEF_%s_BPP,\n", def_name);
346 	fprintf (file, "		DEF_%s_PIXEL_SIZE,\n", def_name);
347 	fprintf (file, "		DEF_%s_SIZE\n};\n", def_name);
348 
349 	fclose (file);
350 
351 	return 0;
352 }
353 
354 #define DEF_FILELEN	256
355 
356 int main (int argc, char *argv[])
357 {
358 	char inputfile[DEF_FILELEN],
359 		outputfile[DEF_FILELEN], varname[DEF_FILELEN];
360 
361 	image_t rgb_logo, yuyv_logo;
362 
363 	switch (argc) {
364 	case 2:
365 	case 3:
366 	case 4:
367 		strcpy (inputfile, argv[1]);
368 
369 		if (argc > 2)
370 			strcpy (varname, argv[2]);
371 		else {
372 			char *dot = strchr (inputfile, '.');
373 			int pos = dot - inputfile;
374 
375 			if (dot) {
376 				strncpy (varname, inputfile, pos);
377 				varname[pos] = 0;
378 			}
379 		}
380 
381 		if (argc > 3)
382 			strcpy (outputfile, argv[3]);
383 		else {
384 			char *dot = strchr (varname, '.');
385 			int pos = dot - varname;
386 
387 			if (dot) {
388 				char app[DEF_FILELEN];
389 
390 				strncpy (app, varname, pos);
391 				app[pos] = 0;
392 				sprintf (outputfile, "%s.h", app);
393 			}
394 		}
395 		break;
396 
397 	default:
398 		printf ("EasyLogo 1.0 (C) 2000 by Paolo Scaffardi\n\n");
399 
400 		printf("Syntax:	easylogo inputfile [outputvar {outputfile}] \n");
401 		printf("\n");
402 		printf("Where:	'inputfile' 	is the TGA image to load\n");
403 		printf("      	'outputvar' 	is the variable name to create\n");
404 		printf("       	'outputfile' 	is the output header file (default is 'inputfile.h')\n");
405 
406 		return -1;
407 	}
408 
409 	printf ("Doing '%s' (%s) from '%s'...",
410 		outputfile, varname, inputfile);
411 
412 	/* Import TGA logo */
413 
414 	printf ("L");
415 	if (image_load_tga (&rgb_logo, inputfile) < 0) {
416 		printf ("input file not found!\n");
417 		exit (1);
418 	}
419 
420 	/* Convert it to YUYV format */
421 
422 	printf ("C");
423 	image_rgb_to_yuyv (&rgb_logo, &yuyv_logo);
424 
425 	/* Save it into a header format */
426 
427 	printf ("S");
428 	image_save_header (&yuyv_logo, outputfile, varname);
429 
430 	/* Free original image and copy */
431 
432 	image_free (&rgb_logo);
433 	image_free (&yuyv_logo);
434 
435 	printf ("\n");
436 
437 	return 0;
438 }
439