blob: 00a1e4ed1675ccedbee5a203e1ad68c6610c672a [file] [log] [blame]
wdenkfe8c2802002-11-03 00:38:21 +00001/*
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
Mike Frysingeredfed1d2008-02-16 02:40:18 -050010#include <getopt.h>
11#include <stdbool.h>
wdenkfe8c2802002-11-03 00:38:21 +000012#include <stdio.h>
Mike Frysinger38d299c2007-12-18 03:23:25 -050013#include <stdlib.h>
14#include <string.h>
wdenkfe8c2802002-11-03 00:38:21 +000015
16#pragma pack(1)
17
18/*#define ENABLE_ASCII_BANNERS */
19
20typedef struct {
Wolfgang Denk6007f322008-01-09 15:14:46 +010021 unsigned char id;
22 unsigned char ColorMapType;
23 unsigned char ImageTypeCode;
24 unsigned short ColorMapOrigin;
25 unsigned short ColorMapLenght;
26 unsigned char ColorMapEntrySize;
27 unsigned short ImageXOrigin;
28 unsigned short ImageYOrigin;
29 unsigned short ImageWidth;
30 unsigned short ImageHeight;
31 unsigned char ImagePixelSize;
32 unsigned char ImageDescriptorByte;
wdenkfe8c2802002-11-03 00:38:21 +000033} tga_header_t;
34
35typedef struct {
Wolfgang Denk6007f322008-01-09 15:14:46 +010036 unsigned char r, g, b;
37} rgb_t;
wdenkfe8c2802002-11-03 00:38:21 +000038
39typedef struct {
Wolfgang Denk6007f322008-01-09 15:14:46 +010040 unsigned char b, g, r;
41} bgr_t;
wdenkfe8c2802002-11-03 00:38:21 +000042
43typedef struct {
Wolfgang Denk6007f322008-01-09 15:14:46 +010044 unsigned char Cb, y1, Cr, y2;
45} yuyv_t;
wdenkfe8c2802002-11-03 00:38:21 +000046
47typedef struct {
Wolfgang Denk6007f322008-01-09 15:14:46 +010048 void *data, *palette;
49 int width, height, pixels, bpp, pixel_size, size, palette_size, yuyv;
50} image_t;
wdenkfe8c2802002-11-03 00:38:21 +000051
52void StringUpperCase (char *str)
53{
Wolfgang Denk6007f322008-01-09 15:14:46 +010054 int count = strlen (str);
55 char c;
wdenkfe8c2802002-11-03 00:38:21 +000056
Wolfgang Denk6007f322008-01-09 15:14:46 +010057 while (count--) {
58 c = *str;
59 if ((c >= 'a') && (c <= 'z'))
60 *str = 'A' + (c - 'a');
61 str++;
62 }
wdenkfe8c2802002-11-03 00:38:21 +000063}
64
65void StringLowerCase (char *str)
66{
Wolfgang Denk6007f322008-01-09 15:14:46 +010067 int count = strlen (str);
68 char c;
wdenkfe8c2802002-11-03 00:38:21 +000069
Wolfgang Denk6007f322008-01-09 15:14:46 +010070 while (count--) {
71 c = *str;
72 if ((c >= 'A') && (c <= 'Z'))
73 *str = 'a' + (c - 'A');
74 str++;
75 }
wdenkfe8c2802002-11-03 00:38:21 +000076}
Wolfgang Denk6007f322008-01-09 15:14:46 +010077void pixel_rgb_to_yuyv (rgb_t * rgb_pixel, yuyv_t * yuyv_pixel)
wdenkfe8c2802002-11-03 00:38:21 +000078{
Wolfgang Denk6007f322008-01-09 15:14:46 +010079 unsigned int pR, pG, pB;
wdenkfe8c2802002-11-03 00:38:21 +000080
Wolfgang Denk6007f322008-01-09 15:14:46 +010081 /* Transform (0-255) components to (0-100) */
82 pR = rgb_pixel->r * 100 / 255;
83 pG = rgb_pixel->g * 100 / 255;
84 pB = rgb_pixel->b * 100 / 255;
wdenkfe8c2802002-11-03 00:38:21 +000085
Wolfgang Denk6007f322008-01-09 15:14:46 +010086 /* Calculate YUV values (0-255) from RGB beetween 0-100 */
87 yuyv_pixel->y1 = yuyv_pixel->y2 = 209 * (pR + pG + pB) / 300 + 16;
88 yuyv_pixel->Cb = pB - (pR / 4) - (pG * 3 / 4) + 128;
89 yuyv_pixel->Cr = pR - (pG * 3 / 4) - (pB / 4) + 128;
wdenkfe8c2802002-11-03 00:38:21 +000090
Wolfgang Denk6007f322008-01-09 15:14:46 +010091 return;
wdenkfe8c2802002-11-03 00:38:21 +000092}
93
Wolfgang Denk6007f322008-01-09 15:14:46 +010094void printlogo_rgb (rgb_t * data, int w, int h)
wdenkfe8c2802002-11-03 00:38:21 +000095{
Wolfgang Denk6007f322008-01-09 15:14:46 +010096 int x, y;
97
98 for (y = 0; y < h; y++) {
99 for (x = 0; x < w; x++, data++)
100 if ((data->r <
101 30) /*&&(data->g == 0)&&(data->b == 0) */ )
102 printf (" ");
103 else
104 printf ("X");
105 printf ("\n");
106 }
wdenkfe8c2802002-11-03 00:38:21 +0000107}
108
109void printlogo_yuyv (unsigned short *data, int w, int h)
110{
Wolfgang Denk6007f322008-01-09 15:14:46 +0100111 int x, y;
112
113 for (y = 0; y < h; y++) {
114 for (x = 0; x < w; x++, data++)
115 if (*data == 0x1080) /* Because of inverted on i386! */
116 printf (" ");
117 else
118 printf ("X");
119 printf ("\n");
120 }
wdenkfe8c2802002-11-03 00:38:21 +0000121}
122
Mike Frysingerfc6414e2007-12-18 04:29:55 -0500123static inline unsigned short le16_to_cpu (unsigned short val)
124{
Wolfgang Denk6007f322008-01-09 15:14:46 +0100125 union {
126 unsigned char pval[2];
127 unsigned short val;
128 } swapped;
129
130 swapped.val = val;
131 return (swapped.pval[1] << 8) + swapped.pval[0];
Mike Frysingerfc6414e2007-12-18 04:29:55 -0500132}
133
Wolfgang Denk6007f322008-01-09 15:14:46 +0100134int image_load_tga (image_t * image, char *filename)
wdenkfe8c2802002-11-03 00:38:21 +0000135{
Wolfgang Denk6007f322008-01-09 15:14:46 +0100136 FILE *file;
137 tga_header_t header;
138 int i;
139 unsigned char app;
140 rgb_t *p;
wdenkfe8c2802002-11-03 00:38:21 +0000141
Wolfgang Denk6007f322008-01-09 15:14:46 +0100142 if ((file = fopen (filename, "rb")) == NULL)
143 return -1;
wdenkfe8c2802002-11-03 00:38:21 +0000144
Wolfgang Denk6007f322008-01-09 15:14:46 +0100145 fread (&header, sizeof (header), 1, file);
wdenkfe8c2802002-11-03 00:38:21 +0000146
Wolfgang Denk6007f322008-01-09 15:14:46 +0100147 /* byte swap: tga is little endian, host is ??? */
148 header.ColorMapOrigin = le16_to_cpu (header.ColorMapOrigin);
149 header.ColorMapLenght = le16_to_cpu (header.ColorMapLenght);
150 header.ImageXOrigin = le16_to_cpu (header.ImageXOrigin);
151 header.ImageYOrigin = le16_to_cpu (header.ImageYOrigin);
152 header.ImageWidth = le16_to_cpu (header.ImageWidth);
153 header.ImageHeight = le16_to_cpu (header.ImageHeight);
Mike Frysingerfc6414e2007-12-18 04:29:55 -0500154
Wolfgang Denk6007f322008-01-09 15:14:46 +0100155 image->width = header.ImageWidth;
156 image->height = header.ImageHeight;
wdenkfe8c2802002-11-03 00:38:21 +0000157
Wolfgang Denk6007f322008-01-09 15:14:46 +0100158 switch (header.ImageTypeCode) {
159 case 2: /* Uncompressed RGB */
160 image->yuyv = 0;
161 image->palette_size = 0;
162 image->palette = NULL;
163 break;
wdenkfe8c2802002-11-03 00:38:21 +0000164
165 default:
Wolfgang Denk6007f322008-01-09 15:14:46 +0100166 printf ("Format not supported!\n");
167 return -1;
168 }
wdenkfe8c2802002-11-03 00:38:21 +0000169
Wolfgang Denk6007f322008-01-09 15:14:46 +0100170 image->bpp = header.ImagePixelSize;
171 image->pixel_size = ((image->bpp - 1) / 8) + 1;
172 image->pixels = image->width * image->height;
173 image->size = image->pixels * image->pixel_size;
174 image->data = malloc (image->size);
wdenkfe8c2802002-11-03 00:38:21 +0000175
Wolfgang Denk6007f322008-01-09 15:14:46 +0100176 if (image->bpp != 24) {
177 printf ("Bpp not supported: %d!\n", image->bpp);
178 return -1;
179 }
wdenkfe8c2802002-11-03 00:38:21 +0000180
Wolfgang Denk6007f322008-01-09 15:14:46 +0100181 fread (image->data, image->size, 1, file);
wdenkfe8c2802002-11-03 00:38:21 +0000182
183/* Swapping R and B values */
184
Wolfgang Denk6007f322008-01-09 15:14:46 +0100185 p = image->data;
186 for (i = 0; i < image->pixels; i++, p++) {
187 app = p->r;
188 p->r = p->b;
189 p->b = app;
190 }
wdenkfe8c2802002-11-03 00:38:21 +0000191
192/* Swapping image */
193
Wolfgang Denk6007f322008-01-09 15:14:46 +0100194 if (!(header.ImageDescriptorByte & 0x20)) {
195 unsigned char *temp = malloc (image->size);
196 int linesize = image->pixel_size * image->width;
197 void *dest = image->data,
198 *source = temp + image->size - linesize;
wdenkfe8c2802002-11-03 00:38:21 +0000199
Wolfgang Denk6007f322008-01-09 15:14:46 +0100200 printf ("S");
201 if (temp == NULL) {
202 printf ("Cannot alloc temp buffer!\n");
203 return -1;
204 }
205
206 memcpy (temp, image->data, image->size);
207 for (i = 0; i < image->height;
208 i++, dest += linesize, source -= linesize)
209 memcpy (dest, source, linesize);
210
211 free (temp);
wdenkfe8c2802002-11-03 00:38:21 +0000212 }
wdenkfe8c2802002-11-03 00:38:21 +0000213#ifdef ENABLE_ASCII_BANNERS
Wolfgang Denk6007f322008-01-09 15:14:46 +0100214 printlogo_rgb (image->data, image->width, image->height);
wdenkfe8c2802002-11-03 00:38:21 +0000215#endif
216
Wolfgang Denk6007f322008-01-09 15:14:46 +0100217 fclose (file);
218 return 0;
wdenkfe8c2802002-11-03 00:38:21 +0000219}
220
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500221void image_free (image_t * image)
wdenkfe8c2802002-11-03 00:38:21 +0000222{
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500223 free (image->data);
224 free (image->palette);
wdenkfe8c2802002-11-03 00:38:21 +0000225}
226
Wolfgang Denk6007f322008-01-09 15:14:46 +0100227int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image)
wdenkfe8c2802002-11-03 00:38:21 +0000228{
Wolfgang Denk6007f322008-01-09 15:14:46 +0100229 rgb_t *rgb_ptr = (rgb_t *) rgb_image->data;
230 yuyv_t yuyv;
231 unsigned short *dest;
232 int count = 0;
wdenkfe8c2802002-11-03 00:38:21 +0000233
Wolfgang Denk6007f322008-01-09 15:14:46 +0100234 yuyv_image->pixel_size = 2;
235 yuyv_image->bpp = 16;
236 yuyv_image->yuyv = 1;
237 yuyv_image->width = rgb_image->width;
238 yuyv_image->height = rgb_image->height;
239 yuyv_image->pixels = yuyv_image->width * yuyv_image->height;
240 yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size;
241 dest = (unsigned short *) (yuyv_image->data =
242 malloc (yuyv_image->size));
243 yuyv_image->palette = 0;
244 yuyv_image->palette_size = 0;
wdenkfe8c2802002-11-03 00:38:21 +0000245
Wolfgang Denk6007f322008-01-09 15:14:46 +0100246 while ((count++) < rgb_image->pixels) {
wdenkfe8c2802002-11-03 00:38:21 +0000247 pixel_rgb_to_yuyv (rgb_ptr++, &yuyv);
248
Wolfgang Denk6007f322008-01-09 15:14:46 +0100249 if ((count & 1) == 0) /* Was == 0 */
250 memcpy (dest, ((void *) &yuyv) + 2, sizeof (short));
wdenkfe8c2802002-11-03 00:38:21 +0000251 else
Wolfgang Denk6007f322008-01-09 15:14:46 +0100252 memcpy (dest, (void *) &yuyv, sizeof (short));
wdenkfe8c2802002-11-03 00:38:21 +0000253
Wolfgang Denk6007f322008-01-09 15:14:46 +0100254 dest++;
wdenkfe8c2802002-11-03 00:38:21 +0000255 }
256
257#ifdef ENABLE_ASCII_BANNERS
Wolfgang Denk6007f322008-01-09 15:14:46 +0100258 printlogo_yuyv (yuyv_image->data, yuyv_image->width,
259 yuyv_image->height);
wdenkfe8c2802002-11-03 00:38:21 +0000260#endif
Wolfgang Denk6007f322008-01-09 15:14:46 +0100261 return 0;
wdenkfe8c2802002-11-03 00:38:21 +0000262}
263
Wolfgang Denk6007f322008-01-09 15:14:46 +0100264int image_save_header (image_t * image, char *filename, char *varname)
wdenkfe8c2802002-11-03 00:38:21 +0000265{
Wolfgang Denk6007f322008-01-09 15:14:46 +0100266 FILE *file = fopen (filename, "w");
267 char app[256], str[256] = "", def_name[64];
268 int count = image->size, col = 0;
269 unsigned char *dataptr = image->data;
wdenkfe8c2802002-11-03 00:38:21 +0000270
Wolfgang Denk6007f322008-01-09 15:14:46 +0100271 if (file == NULL)
272 return -1;
wdenkfe8c2802002-11-03 00:38:21 +0000273
Wolfgang Denk6007f322008-01-09 15:14:46 +0100274 /* Author information */
275 fprintf (file,
276 "/*\n * Generated by EasyLogo, (C) 2000 by Paolo Scaffardi\n *\n");
277 fprintf (file,
278 " * To use this, include it and call: easylogo_plot(screen,&%s, width,x,y)\n *\n",
279 varname);
280 fprintf (file,
281 " * Where:\t'screen'\tis the pointer to the frame buffer\n");
282 fprintf (file, " *\t\t'width'\tis the screen width\n");
283 fprintf (file, " *\t\t'x'\t\tis the horizontal position\n");
284 fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
285
286 /* Headers */
287 fprintf (file, "#include <video_easylogo.h>\n\n");
288 /* Macros */
289 strcpy (def_name, varname);
wdenkfe8c2802002-11-03 00:38:21 +0000290 StringUpperCase (def_name);
Wolfgang Denk6007f322008-01-09 15:14:46 +0100291 fprintf (file, "#define DEF_%s_WIDTH\t\t%d\n", def_name,
292 image->width);
293 fprintf (file, "#define DEF_%s_HEIGHT\t\t%d\n", def_name,
294 image->height);
295 fprintf (file, "#define DEF_%s_PIXELS\t\t%d\n", def_name,
296 image->pixels);
297 fprintf (file, "#define DEF_%s_BPP\t\t%d\n", def_name, image->bpp);
298 fprintf (file, "#define DEF_%s_PIXEL_SIZE\t%d\n", def_name,
299 image->pixel_size);
300 fprintf (file, "#define DEF_%s_SIZE\t\t%d\n\n", def_name,
301 image->size);
302 /* Declaration */
303 fprintf (file, "unsigned char DEF_%s_DATA[DEF_%s_SIZE] = {\n",
304 def_name, def_name);
wdenkfe8c2802002-11-03 00:38:21 +0000305
Wolfgang Denk6007f322008-01-09 15:14:46 +0100306 /* Data */
307 while (count)
308 switch (col) {
309 case 0:
310 sprintf (str, " 0x%02x", *dataptr++);
311 col++;
312 count--;
313 break;
wdenkfe8c2802002-11-03 00:38:21 +0000314
Wolfgang Denk6007f322008-01-09 15:14:46 +0100315 case 16:
316 fprintf (file, "%s", str);
317 if (count > 0)
318 fprintf (file, ",");
319 fprintf (file, "\n");
wdenkfe8c2802002-11-03 00:38:21 +0000320
Wolfgang Denk6007f322008-01-09 15:14:46 +0100321 col = 0;
322 break;
wdenkfe8c2802002-11-03 00:38:21 +0000323
Wolfgang Denk6007f322008-01-09 15:14:46 +0100324 default:
325 strcpy (app, str);
326 sprintf (str, "%s, 0x%02x", app, *dataptr++);
327 col++;
328 count--;
329 break;
wdenkfe8c2802002-11-03 00:38:21 +0000330 }
331
332 if (col)
Wolfgang Denk6007f322008-01-09 15:14:46 +0100333 fprintf (file, "%s\n", str);
wdenkfe8c2802002-11-03 00:38:21 +0000334
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200335 /* End of declaration */
Wolfgang Denk6007f322008-01-09 15:14:46 +0100336 fprintf (file, "};\n\n");
337 /* Variable */
338 fprintf (file, "fastimage_t %s = {\n", varname);
339 fprintf (file, " DEF_%s_DATA,\n", def_name);
340 fprintf (file, " DEF_%s_WIDTH,\n", def_name);
341 fprintf (file, " DEF_%s_HEIGHT,\n", def_name);
342 fprintf (file, " DEF_%s_BPP,\n", def_name);
343 fprintf (file, " DEF_%s_PIXEL_SIZE,\n", def_name);
344 fprintf (file, " DEF_%s_SIZE\n};\n", def_name);
wdenkfe8c2802002-11-03 00:38:21 +0000345
346 fclose (file);
347
Wolfgang Denk6007f322008-01-09 15:14:46 +0100348 return 0;
wdenkfe8c2802002-11-03 00:38:21 +0000349}
350
351#define DEF_FILELEN 256
352
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500353static void usage (int exit_status)
354{
355 puts (
356 "EasyLogo 1.0 (C) 2000 by Paolo Scaffardi\n"
357 "\n"
358 "Syntax: easylogo [options] inputfile [outputvar [outputfile]]\n"
359 "\n"
360 "Options:\n"
361 " -r Output RGB instead of YUYV\n"
362 " -h Help output\n"
363 "\n"
364 "Where: 'inputfile' is the TGA image to load\n"
365 " 'outputvar' is the variable name to create\n"
366 " 'outputfile' is the output header file (default is 'inputfile.h')"
367 );
368 exit (exit_status);
369}
370
wdenkfe8c2802002-11-03 00:38:21 +0000371int main (int argc, char *argv[])
372{
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500373 int c;
374 bool use_rgb = false;
Wolfgang Denk6007f322008-01-09 15:14:46 +0100375 char inputfile[DEF_FILELEN],
376 outputfile[DEF_FILELEN], varname[DEF_FILELEN];
wdenkfe8c2802002-11-03 00:38:21 +0000377
Wolfgang Denk6007f322008-01-09 15:14:46 +0100378 image_t rgb_logo, yuyv_logo;
wdenkfe8c2802002-11-03 00:38:21 +0000379
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500380 while ((c = getopt(argc, argv, "hr")) > 0) {
381 switch (c) {
382 case 'h':
383 usage (0);
384 break;
385 case 'r':
386 use_rgb = true;
387 puts ("Using 24-bit RGB Output Fromat");
388 break;
389 default:
390 usage (1);
391 break;
Wolfgang Denk6007f322008-01-09 15:14:46 +0100392 }
wdenkfe8c2802002-11-03 00:38:21 +0000393 }
394
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500395 c = argc - optind;
396 if (c > 4 || c < 1)
397 usage (1);
398
399 strcpy (inputfile, argv[optind]);
400
401 if (c > 1)
402 strcpy (varname, argv[optind + 1]);
403 else {
404 /* transform "input.tga" to just "input" */
405 char *dot;
406 strcpy (varname, inputfile);
407 dot = strchr (varname, '.');
408 if (dot)
409 *dot = '\0';
410 }
411
412 if (c > 2)
413 strcpy (outputfile, argv[optind + 2]);
414 else {
415 /* just append ".h" to input file name */
416 strcpy (outputfile, inputfile);
417 strcat (outputfile, ".h");
418 }
419
420 /* Make sure the output is sent as soon as we printf() */
421 setbuf(stdout, NULL);
422
Wolfgang Denk6007f322008-01-09 15:14:46 +0100423 printf ("Doing '%s' (%s) from '%s'...",
424 outputfile, varname, inputfile);
wdenkfe8c2802002-11-03 00:38:21 +0000425
Wolfgang Denk6007f322008-01-09 15:14:46 +0100426 /* Import TGA logo */
wdenkfe8c2802002-11-03 00:38:21 +0000427
Wolfgang Denk6007f322008-01-09 15:14:46 +0100428 printf ("L");
429 if (image_load_tga (&rgb_logo, inputfile) < 0) {
430 printf ("input file not found!\n");
431 exit (1);
wdenkfe8c2802002-11-03 00:38:21 +0000432 }
wdenkfe8c2802002-11-03 00:38:21 +0000433
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500434 /* Convert it to YUYV format if wanted */
wdenkfe8c2802002-11-03 00:38:21 +0000435
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500436 if (!use_rgb) {
437 printf ("C");
438 image_rgb_to_yuyv (&rgb_logo, &yuyv_logo);
439 }
wdenkfe8c2802002-11-03 00:38:21 +0000440
Wolfgang Denk6007f322008-01-09 15:14:46 +0100441 /* Save it into a header format */
wdenkfe8c2802002-11-03 00:38:21 +0000442
Wolfgang Denk6007f322008-01-09 15:14:46 +0100443 printf ("S");
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500444 image_save_header (use_rgb ? &rgb_logo : &yuyv_logo, outputfile, varname);
wdenkfe8c2802002-11-03 00:38:21 +0000445
Wolfgang Denk6007f322008-01-09 15:14:46 +0100446 /* Free original image and copy */
wdenkfe8c2802002-11-03 00:38:21 +0000447
Wolfgang Denk6007f322008-01-09 15:14:46 +0100448 image_free (&rgb_logo);
Mike Frysingeredfed1d2008-02-16 02:40:18 -0500449 if (!use_rgb)
450 image_free (&yuyv_logo);
wdenkfe8c2802002-11-03 00:38:21 +0000451
Wolfgang Denk6007f322008-01-09 15:14:46 +0100452 printf ("\n");
wdenkfe8c2802002-11-03 00:38:21 +0000453
Wolfgang Denk6007f322008-01-09 15:14:46 +0100454 return 0;
wdenkfe8c2802002-11-03 00:38:21 +0000455}