[U-Boot] [PATCH] easylogo: add optional gzip support

Some images can be quite large, so add an option to compress the image data with gzip in the U-Boot image. Then at runtime, the board can decompress it with the normal zlib functions.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- tools/easylogo/easylogo.c | 47 ++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/tools/easylogo/easylogo.c b/tools/easylogo/easylogo.c index 00a1e4e..05214aa 100644 --- a/tools/easylogo/easylogo.c +++ b/tools/easylogo/easylogo.c @@ -12,6 +12,8 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <sys/stat.h>
#pragma pack(1)
@@ -261,6 +263,8 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) return 0; }
+int use_gzip = 0; + int image_save_header (image_t * image, char *filename, char *varname) { FILE *file = fopen (filename, "w"); @@ -283,6 +287,33 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, " *\t\t'x'\t\tis the horizontal position\n"); fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
+ /* gzip compress */ + if (use_gzip & 0x1) { + unsigned char *compressed; + struct stat st; + FILE *gz; + + sprintf (str, "%s.gz", filename); + sprintf (app, "gzip > %s", str); + gz = popen (app, "w"); + fwrite (image->data, image->size, 1, gz); + pclose (gz); + + gz = fopen (str, "r"); + stat (str, &st); + compressed = malloc (st.st_size); + fread (compressed, st.st_size, 1, gz); + fclose (gz); + + unlink (str); + + dataptr = compressed; + count = st.st_size; + fprintf (file, "#define EASYLOGO_ENABLE_GZIP %i\n\n", count); + if (use_gzip & 0x2) + fprintf (file, "static unsigned char EASYLOGO_DECOMP_BUFFER[%i];\n\n", image->size); + } + /* Headers */ fprintf (file, "#include <video_easylogo.h>\n\n"); /* Macros */ @@ -300,8 +331,8 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, "#define DEF_%s_SIZE\t\t%d\n\n", def_name, image->size); /* Declaration */ - fprintf (file, "unsigned char DEF_%s_DATA[DEF_%s_SIZE] = {\n", - def_name, def_name); + fprintf (file, "unsigned char DEF_%s_DATA[] = {\n", + def_name);
/* Data */ while (count) @@ -359,6 +390,8 @@ static void usage (int exit_status) "\n" "Options:\n" " -r Output RGB instead of YUYV\n" + " -g Compress with gzip\n" + " -b Preallocate space in bss for decompressing image\n" " -h Help output\n" "\n" "Where: 'inputfile' is the TGA image to load\n" @@ -377,7 +410,7 @@ int main (int argc, char *argv[])
image_t rgb_logo, yuyv_logo;
- while ((c = getopt(argc, argv, "hr")) > 0) { + while ((c = getopt(argc, argv, "hrgb")) > 0) { switch (c) { case 'h': usage (0); @@ -386,6 +419,14 @@ int main (int argc, char *argv[]) use_rgb = true; puts ("Using 24-bit RGB Output Fromat"); break; + case 'g': + use_gzip |= 0x1; + puts ("Compressing with gzip"); + break; + case 'b': + use_gzip |= 0x2; + puts ("Preallocating bss space for decompressing image"); + break; default: usage (1); break;

Dear Mike Frysinger,
In message 1228882838-14437-1-git-send-email-vapier@gentoo.org you wrote:
Some images can be quite large, so add an option to compress the image data with gzip in the U-Boot image. Then at runtime, the board can decompress it with the normal zlib functions.
Good idea.
FILE *gz;
sprintf (str, "%s.gz", filename);
Lenght checking?
sprintf (app, "gzip > %s", str);
Lenght checking?
gz = popen (app, "w");
Erorr checking?
fwrite (image->data, image->size, 1, gz);
Erorr checking?
pclose (gz);
Erorr checking?
And so on...
Best regards,
Wolfgang Denk

Some images can be quite large, so add an option to compress the image data with gzip in the U-Boot image. Then at runtime, the board can decompress it with the normal zlib functions.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- v2: - add error checking
tools/easylogo/easylogo.c | 91 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/tools/easylogo/easylogo.c b/tools/easylogo/easylogo.c index 00a1e4e..c7e146f 100644 --- a/tools/easylogo/easylogo.c +++ b/tools/easylogo/easylogo.c @@ -2,16 +2,20 @@ ** Easylogo TGA->header converter ** ============================== ** (C) 2000 by Paolo Scaffardi (arsenio@tin.it) +** (C) 2007-2008 Mike Frysinger vapier@gentoo.org ** AIRVENT SAM s.p.a - RIMINI(ITALY) ** ** This is still under construction! */
+#include <errno.h> #include <getopt.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <sys/stat.h>
#pragma pack(1)
@@ -49,6 +53,17 @@ typedef struct { int width, height, pixels, bpp, pixel_size, size, palette_size, yuyv; } image_t;
+void *xmalloc (size_t size) +{ + void *ret = malloc (size); + if (!ret) { + fprintf (stderr, "\nerror: malloc(%zu) failed: %s", + size, strerror(errno)); + exit(1); + } + return ret; +} + void StringUpperCase (char *str) { int count = strlen (str); @@ -171,7 +186,7 @@ int image_load_tga (image_t * image, char *filename) image->pixel_size = ((image->bpp - 1) / 8) + 1; image->pixels = image->width * image->height; image->size = image->pixels * image->pixel_size; - image->data = malloc (image->size); + image->data = xmalloc (image->size);
if (image->bpp != 24) { printf ("Bpp not supported: %d!\n", image->bpp); @@ -192,7 +207,7 @@ int image_load_tga (image_t * image, char *filename) /* Swapping image */
if (!(header.ImageDescriptorByte & 0x20)) { - unsigned char *temp = malloc (image->size); + unsigned char *temp = xmalloc (image->size); int linesize = image->pixel_size * image->width; void *dest = image->data, *source = temp + image->size - linesize; @@ -239,7 +254,7 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) yuyv_image->pixels = yuyv_image->width * yuyv_image->height; yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size; dest = (unsigned short *) (yuyv_image->data = - malloc (yuyv_image->size)); + xmalloc (yuyv_image->size)); yuyv_image->palette = 0; yuyv_image->palette_size = 0;
@@ -261,6 +276,8 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) return 0; }
+int use_gzip = 0; + int image_save_header (image_t * image, char *filename, char *varname) { FILE *file = fopen (filename, "w"); @@ -283,6 +300,58 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, " *\t\t'x'\t\tis the horizontal position\n"); fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
+ /* gzip compress */ + if (use_gzip & 0x1) { + unsigned char *compressed; + struct stat st; + FILE *gz; + char *gzfilename = xmalloc(strlen (filename) + 20); + char *gzcmd = xmalloc(strlen (filename) + 20); + + sprintf (gzfilename, "%s.gz", filename); + sprintf (gzcmd, "gzip > %s", gzfilename); + gz = popen (gzcmd, "w"); + if (!gz) { + perror ("\nerror: popen() failed"); + return -1; + } + if (fwrite (image->data, image->size, 1, gz) != 1) { + perror ("\nerror: writing data to gzip failed"); + return -1; + } + if (pclose (gz)) { + perror ("\nerror: gzip process failed"); + return -1; + } + + gz = fopen (gzfilename, "r"); + if (!gz) { + perror ("\nerror: open() on gzip data failed"); + return -1; + } + if (stat (gzfilename, &st)) { + perror ("\nerror: stat() on gzip file failed"); + return -1; + } + compressed = xmalloc (st.st_size); + if (fread (compressed, st.st_size, 1, gz) != 1) { + perror ("\nerror: reading gzip data failed"); + return -1; + } + fclose (gz); + + unlink (gzfilename); + + dataptr = compressed; + count = st.st_size; + fprintf (file, "#define EASYLOGO_ENABLE_GZIP %i\n\n", count); + if (use_gzip & 0x2) + fprintf (file, "static unsigned char EASYLOGO_DECOMP_BUFFER[%i];\n\n", image->size); + + free (gzfilename); + free (gzcmd); + } + /* Headers */ fprintf (file, "#include <video_easylogo.h>\n\n"); /* Macros */ @@ -300,8 +369,8 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, "#define DEF_%s_SIZE\t\t%d\n\n", def_name, image->size); /* Declaration */ - fprintf (file, "unsigned char DEF_%s_DATA[DEF_%s_SIZE] = {\n", - def_name, def_name); + fprintf (file, "unsigned char DEF_%s_DATA[] = {\n", + def_name);
/* Data */ while (count) @@ -359,6 +428,8 @@ static void usage (int exit_status) "\n" "Options:\n" " -r Output RGB instead of YUYV\n" + " -g Compress with gzip\n" + " -b Preallocate space in bss for decompressing image\n" " -h Help output\n" "\n" "Where: 'inputfile' is the TGA image to load\n" @@ -377,7 +448,7 @@ int main (int argc, char *argv[])
image_t rgb_logo, yuyv_logo;
- while ((c = getopt(argc, argv, "hr")) > 0) { + while ((c = getopt(argc, argv, "hrgb")) > 0) { switch (c) { case 'h': usage (0); @@ -386,6 +457,14 @@ int main (int argc, char *argv[]) use_rgb = true; puts ("Using 24-bit RGB Output Fromat"); break; + case 'g': + use_gzip |= 0x1; + puts ("Compressing with gzip"); + break; + case 'b': + use_gzip |= 0x2; + puts ("Preallocating bss space for decompressing image"); + break; default: usage (1); break;

Dear Mike Frysinger,
In message 1228934668-20992-1-git-send-email-vapier@gentoo.org you wrote:
Some images can be quite large, so add an option to compress the image data with gzip in the U-Boot image. Then at runtime, the board can decompress it with the normal zlib functions.
Signed-off-by: Mike Frysinger vapier@gentoo.org
v2:
- add error checking
tools/easylogo/easylogo.c | 91 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/tools/easylogo/easylogo.c b/tools/easylogo/easylogo.c index 00a1e4e..c7e146f 100644 --- a/tools/easylogo/easylogo.c +++ b/tools/easylogo/easylogo.c @@ -2,16 +2,20 @@ ** Easylogo TGA->header converter ** ============================== ** (C) 2000 by Paolo Scaffardi (arsenio@tin.it) +** (C) 2007-2008 Mike Frysinger vapier@gentoo.org ** AIRVENT SAM s.p.a - RIMINI(ITALY)
This is a bad place to add your copyright - splitting Paolo's entry.
** This is still under construction! */
+#include <errno.h> #include <getopt.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <sys/stat.h>
#pragma pack(1)
@@ -49,6 +53,17 @@ typedef struct { int width, height, pixels, bpp, pixel_size, size, palette_size, yuyv; } image_t;
+void *xmalloc (size_t size) +{
- void *ret = malloc (size);
- if (!ret) {
fprintf (stderr, "\nerror: malloc(%zu) failed: %s",
size, strerror(errno));
exit(1);
- }
- return ret;
+}
void StringUpperCase (char *str) { int count = strlen (str); @@ -171,7 +186,7 @@ int image_load_tga (image_t * image, char *filename) image->pixel_size = ((image->bpp - 1) / 8) + 1; image->pixels = image->width * image->height; image->size = image->pixels * image->pixel_size;
- image->data = malloc (image->size);
image->data = xmalloc (image->size);
if (image->bpp != 24) { printf ("Bpp not supported: %d!\n", image->bpp);
@@ -192,7 +207,7 @@ int image_load_tga (image_t * image, char *filename) /* Swapping image */
if (!(header.ImageDescriptorByte & 0x20)) {
unsigned char *temp = malloc (image->size);
int linesize = image->pixel_size * image->width; void *dest = image->data, *source = temp + image->size - linesize;unsigned char *temp = xmalloc (image->size);
@@ -239,7 +254,7 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) yuyv_image->pixels = yuyv_image->width * yuyv_image->height; yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size; dest = (unsigned short *) (yuyv_image->data =
malloc (yuyv_image->size));
yuyv_image->palette = 0; yuyv_image->palette_size = 0;xmalloc (yuyv_image->size));
@@ -261,6 +276,8 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) return 0; }
+int use_gzip = 0;
int image_save_header (image_t * image, char *filename, char *varname) { FILE *file = fopen (filename, "w"); @@ -283,6 +300,58 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, " *\t\t'x'\t\tis the horizontal position\n"); fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
- /* gzip compress */
- if (use_gzip & 0x1) {
unsigned char *compressed;
struct stat st;
FILE *gz;
char *gzfilename = xmalloc(strlen (filename) + 20);
char *gzcmd = xmalloc(strlen (filename) + 20);
sprintf (gzfilename, "%s.gz", filename);
sprintf (gzcmd, "gzip > %s", gzfilename);
gz = popen (gzcmd, "w");
if (!gz) {
perror ("\nerror: popen() failed");
return -1;
}
if (fwrite (image->data, image->size, 1, gz) != 1) {
perror ("\nerror: writing data to gzip failed");
return -1;
}
if (pclose (gz)) {
perror ("\nerror: gzip process failed");
return -1;
}
gz = fopen (gzfilename, "r");
if (!gz) {
perror ("\nerror: open() on gzip data failed");
return -1;
}
if (stat (gzfilename, &st)) {
perror ("\nerror: stat() on gzip file failed");
return -1;
}
compressed = xmalloc (st.st_size);
if (fread (compressed, st.st_size, 1, gz) != 1) {
perror ("\nerror: reading gzip data failed");
return -1;
}
All the returns above leak the gzfilename and gzcmd memory. Not that it really matters, but it's not clean. Also, please omit the "\n" at the begin of the perror strings.
Best regards,
Wolfgang Denk

On Wednesday 10 December 2008 14:57:27 Wolfgang Denk wrote:
In message ... you wrote:
diff --git a/tools/easylogo/easylogo.c b/tools/easylogo/easylogo.c index 00a1e4e..c7e146f 100644 --- a/tools/easylogo/easylogo.c +++ b/tools/easylogo/easylogo.c @@ -2,16 +2,20 @@ ** Easylogo TGA->header converter ** ============================== ** (C) 2000 by Paolo Scaffardi (arsenio@tin.it) +** (C) 2007-2008 Mike Frysinger vapier@gentoo.org ** AIRVENT SAM s.p.a - RIMINI(ITALY)
This is a bad place to add your copyright - splitting Paolo's entry.
oops, i didnt notice
if (fread (compressed, st.st_size, 1, gz) != 1) {
perror ("\nerror: reading gzip data failed");
return -1;
}
All the returns above leak the gzfilename and gzcmd memory. Not that it really matters, but it's not clean.
ok
Also, please omit the "\n" at the begin of the perror strings.
easylogo's output is byte by byte, so no \n means the error message and the normal output run together -mike

Some images can be quite large, so add an option to compress the image data with gzip in the U-Boot image. Then at runtime, the board can decompress it with the normal zlib functions.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- v3 - fix copyright - free buffers on error
v2 - add error checking
tools/easylogo/easylogo.c | 94 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 88 insertions(+), 6 deletions(-)
diff --git a/tools/easylogo/easylogo.c b/tools/easylogo/easylogo.c index 00a1e4e..4129827 100644 --- a/tools/easylogo/easylogo.c +++ b/tools/easylogo/easylogo.c @@ -3,15 +3,19 @@ ** ============================== ** (C) 2000 by Paolo Scaffardi (arsenio@tin.it) ** AIRVENT SAM s.p.a - RIMINI(ITALY) +** (C) 2007-2008 Mike Frysinger vapier@gentoo.org ** ** This is still under construction! */
+#include <errno.h> #include <getopt.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <sys/stat.h>
#pragma pack(1)
@@ -49,6 +53,17 @@ typedef struct { int width, height, pixels, bpp, pixel_size, size, palette_size, yuyv; } image_t;
+void *xmalloc (size_t size) +{ + void *ret = malloc (size); + if (!ret) { + fprintf (stderr, "\nerror: malloc(%zu) failed: %s", + size, strerror(errno)); + exit(1); + } + return ret; +} + void StringUpperCase (char *str) { int count = strlen (str); @@ -171,7 +186,7 @@ int image_load_tga (image_t * image, char *filename) image->pixel_size = ((image->bpp - 1) / 8) + 1; image->pixels = image->width * image->height; image->size = image->pixels * image->pixel_size; - image->data = malloc (image->size); + image->data = xmalloc (image->size);
if (image->bpp != 24) { printf ("Bpp not supported: %d!\n", image->bpp); @@ -192,7 +207,7 @@ int image_load_tga (image_t * image, char *filename) /* Swapping image */
if (!(header.ImageDescriptorByte & 0x20)) { - unsigned char *temp = malloc (image->size); + unsigned char *temp = xmalloc (image->size); int linesize = image->pixel_size * image->width; void *dest = image->data, *source = temp + image->size - linesize; @@ -239,7 +254,7 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) yuyv_image->pixels = yuyv_image->width * yuyv_image->height; yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size; dest = (unsigned short *) (yuyv_image->data = - malloc (yuyv_image->size)); + xmalloc (yuyv_image->size)); yuyv_image->palette = 0; yuyv_image->palette_size = 0;
@@ -261,6 +276,8 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) return 0; }
+int use_gzip = 0; + int image_save_header (image_t * image, char *filename, char *varname) { FILE *file = fopen (filename, "w"); @@ -283,6 +300,61 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, " *\t\t'x'\t\tis the horizontal position\n"); fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
+ /* gzip compress */ + if (use_gzip & 0x1) { + unsigned char *compressed; + struct stat st; + FILE *gz; + char *gzfilename = xmalloc(strlen (filename) + 20); + char *gzcmd = xmalloc(strlen (filename) + 20); + + sprintf (gzfilename, "%s.gz", filename); + sprintf (gzcmd, "gzip > %s", gzfilename); + gz = popen (gzcmd, "w"); + if (!gz) { + perror ("\nerror: popen() failed"); + gzerr: + free (gzfilename); + free (gzcmd); + return -1; + } + if (fwrite (image->data, image->size, 1, gz) != 1) { + perror ("\nerror: writing data to gzip failed"); + goto gzerr; + } + if (pclose (gz)) { + perror ("\nerror: gzip process failed"); + goto gzerr; + } + + gz = fopen (gzfilename, "r"); + if (!gz) { + perror ("\nerror: open() on gzip data failed"); + goto gzerr; + } + if (stat (gzfilename, &st)) { + perror ("\nerror: stat() on gzip file failed"); + goto gzerr; + } + compressed = xmalloc (st.st_size); + if (fread (compressed, st.st_size, 1, gz) != 1) { + perror ("\nerror: reading gzip data failed"); + goto gzerr; + } + fclose (gz); + + unlink (gzfilename); + + dataptr = compressed; + count = st.st_size; + fprintf (file, "#define EASYLOGO_ENABLE_GZIP %i\n\n", count); + if (use_gzip & 0x2) + fprintf (file, "static unsigned char EASYLOGO_DECOMP_BUFFER[%i];\n\n", image->size); + + free (gzfilename); + free (gzcmd); + } + /* Headers */ fprintf (file, "#include <video_easylogo.h>\n\n"); /* Macros */ @@ -300,8 +372,8 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, "#define DEF_%s_SIZE\t\t%d\n\n", def_name, image->size); /* Declaration */ - fprintf (file, "unsigned char DEF_%s_DATA[DEF_%s_SIZE] = {\n", - def_name, def_name); + fprintf (file, "unsigned char DEF_%s_DATA[] = {\n", + def_name);
/* Data */ while (count) @@ -359,6 +431,8 @@ static void usage (int exit_status) "\n" "Options:\n" " -r Output RGB instead of YUYV\n" + " -g Compress with gzip\n" + " -b Preallocate space in bss for decompressing image\n" " -h Help output\n" "\n" "Where: 'inputfile' is the TGA image to load\n" @@ -377,7 +451,7 @@ int main (int argc, char *argv[])
image_t rgb_logo, yuyv_logo;
- while ((c = getopt(argc, argv, "hr")) > 0) { + while ((c = getopt(argc, argv, "hrgb")) > 0) { switch (c) { case 'h': usage (0); @@ -386,6 +460,14 @@ int main (int argc, char *argv[]) use_rgb = true; puts ("Using 24-bit RGB Output Fromat"); break; + case 'g': + use_gzip |= 0x1; + puts ("Compressing with gzip"); + break; + case 'b': + use_gzip |= 0x2; + puts ("Preallocating bss space for decompressing image"); + break; default: usage (1); break;

Dear Mike Frysinger,
In message 1228941641-27682-1-git-send-email-vapier@gentoo.org you wrote:
Some images can be quite large, so add an option to compress the image data with gzip in the U-Boot image. Then at runtime, the board can decompress it with the normal zlib functions.
...
gz = popen (gzcmd, "w");
if (!gz) {
perror ("\nerror: popen() failed");
- gzerr:
free (gzfilename);
free (gzcmd);
return -1;
}
if (fwrite (image->data, image->size, 1, gz) != 1) {
perror ("\nerror: writing data to gzip failed");
goto gzerr;
}
if (pclose (gz)) {
perror ("\nerror: gzip process failed");
goto gzerr;
}
gz = fopen (gzfilename, "r");
if (!gz) {
perror ("\nerror: open() on gzip data failed");
goto gzerr;
}
if (stat (gzfilename, &st)) {
perror ("\nerror: stat() on gzip file failed");
goto gzerr;
}
compressed = xmalloc (st.st_size);
if (fread (compressed, st.st_size, 1, gz) != 1) {
perror ("\nerror: reading gzip data failed");
goto gzerr;
}
fclose (gz);
unlink (gzfilename);
dataptr = compressed;
count = st.st_size;
fprintf (file, "#define EASYLOGO_ENABLE_GZIP %i\n\n", count);
if (use_gzip & 0x2)
fprintf (file, "static unsigned char EASYLOGO_DECOMP_BUFFER[%i];\n\n", image->size);
free (gzfilename);
free (gzcmd);
Umm... no. Jumping back to a random place upward in the code just to get an error exit is ugly, and you duplicate code (the 2 x free() calls).
How about something like this:
char *errstr = NULL;
... gz = popen (gzcmd, "w"); if (!gz) { errstr = "\nerror: popen() failed"; goto out; } if (fwrite (image->data, image->size, 1, gz) != 1) { errstr = "\nerror: writing data to gzip failed"; goto out; } if (pclose (gz)) { errstr = "\nerror: gzip process failed"; goto out; }
gz = fopen (gzfilename, "r"); if (!gz) { errstr = "\nerror: open() on gzip data failed"; goto out; } if (stat (gzfilename, &st)) { errstr = "\nerror: stat() on gzip file failed"; goto out; } compressed = xmalloc (st.st_size); if (fread (compressed, st.st_size, 1, gz) != 1) { errstr = "\nerror: reading gzip data failed"; goto out; } fclose (gz);
unlink (gzfilename);
dataptr = compressed; count = st.st_size; fprintf (file, "#define EASYLOGO_ENABLE_GZIP %i\n\n", count); if (use_gzip & 0x2) fprintf (file, "static unsigned char EASYLOGO_DECOMP_BUFFER[%i];\n\n", image->size);
out: if (errstr) perror (errstr); free (gzfilename); free (gzcmd); if (errstr) return -1; ...
Best regards,
Wolfgang Denk

Some images can be quite large, so add an option to compress the image data with gzip in the U-Boot image. Then at runtime, the board can decompress it with the normal zlib functions.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- v4 - redo error handling
v3 - fix copyright - free buffers on error
v2 - add error checking
tools/easylogo/easylogo.c | 98 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/tools/easylogo/easylogo.c b/tools/easylogo/easylogo.c index 00a1e4e..41e5838 100644 --- a/tools/easylogo/easylogo.c +++ b/tools/easylogo/easylogo.c @@ -3,15 +3,19 @@ ** ============================== ** (C) 2000 by Paolo Scaffardi (arsenio@tin.it) ** AIRVENT SAM s.p.a - RIMINI(ITALY) +** (C) 2007-2008 Mike Frysinger vapier@gentoo.org ** ** This is still under construction! */
+#include <errno.h> #include <getopt.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <sys/stat.h>
#pragma pack(1)
@@ -49,6 +53,17 @@ typedef struct { int width, height, pixels, bpp, pixel_size, size, palette_size, yuyv; } image_t;
+void *xmalloc (size_t size) +{ + void *ret = malloc (size); + if (!ret) { + fprintf (stderr, "\nerror: malloc(%zu) failed: %s", + size, strerror(errno)); + exit (1); + } + return ret; +} + void StringUpperCase (char *str) { int count = strlen (str); @@ -171,7 +186,7 @@ int image_load_tga (image_t * image, char *filename) image->pixel_size = ((image->bpp - 1) / 8) + 1; image->pixels = image->width * image->height; image->size = image->pixels * image->pixel_size; - image->data = malloc (image->size); + image->data = xmalloc (image->size);
if (image->bpp != 24) { printf ("Bpp not supported: %d!\n", image->bpp); @@ -192,7 +207,7 @@ int image_load_tga (image_t * image, char *filename) /* Swapping image */
if (!(header.ImageDescriptorByte & 0x20)) { - unsigned char *temp = malloc (image->size); + unsigned char *temp = xmalloc (image->size); int linesize = image->pixel_size * image->width; void *dest = image->data, *source = temp + image->size - linesize; @@ -239,7 +254,7 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) yuyv_image->pixels = yuyv_image->width * yuyv_image->height; yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size; dest = (unsigned short *) (yuyv_image->data = - malloc (yuyv_image->size)); + xmalloc (yuyv_image->size)); yuyv_image->palette = 0; yuyv_image->palette_size = 0;
@@ -261,6 +276,8 @@ int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image) return 0; }
+int use_gzip = 0; + int image_save_header (image_t * image, char *filename, char *varname) { FILE *file = fopen (filename, "w"); @@ -283,6 +300,65 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, " *\t\t'x'\t\tis the horizontal position\n"); fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
+ /* gzip compress */ + if (use_gzip & 0x1) { + const char *errstr = NULL; + unsigned char *compressed; + struct stat st; + FILE *gz; + char *gzfilename = xmalloc(strlen (filename) + 20); + char *gzcmd = xmalloc(strlen (filename) + 20); + + sprintf (gzfilename, "%s.gz", filename); + sprintf (gzcmd, "gzip > %s", gzfilename); + gz = popen (gzcmd, "w"); + if (!gz) { + errstr = "\nerror: popen() failed"; + goto done; + } + if (fwrite (image->data, image->size, 1, gz) != 1) { + errstr = "\nerror: writing data to gzip failed"; + goto done; + } + if (pclose (gz)) { + errstr = "\nerror: gzip process failed"; + goto done; + } + + gz = fopen (gzfilename, "r"); + if (!gz) { + errstr = "\nerror: open() on gzip data failed"; + goto done; + } + if (stat (gzfilename, &st)) { + errstr = "\nerror: stat() on gzip file failed"; + goto done; + } + compressed = xmalloc (st.st_size); + if (fread (compressed, st.st_size, 1, gz) != 1) { + errstr = "\nerror: reading gzip data failed"; + goto done; + } + fclose (gz); + + unlink (gzfilename); + + dataptr = compressed; + count = st.st_size; + fprintf (file, "#define EASYLOGO_ENABLE_GZIP %i\n\n", count); + if (use_gzip & 0x2) + fprintf (file, "static unsigned char EASYLOGO_DECOMP_BUFFER[%i];\n\n", image->size); + + done: + free (gzfilename); + free (gzcmd); + + if (errstr) { + perror (errstr); + return -1; + } + } + /* Headers */ fprintf (file, "#include <video_easylogo.h>\n\n"); /* Macros */ @@ -300,8 +376,8 @@ int image_save_header (image_t * image, char *filename, char *varname) fprintf (file, "#define DEF_%s_SIZE\t\t%d\n\n", def_name, image->size); /* Declaration */ - fprintf (file, "unsigned char DEF_%s_DATA[DEF_%s_SIZE] = {\n", - def_name, def_name); + fprintf (file, "unsigned char DEF_%s_DATA[] = {\n", + def_name);
/* Data */ while (count) @@ -359,6 +435,8 @@ static void usage (int exit_status) "\n" "Options:\n" " -r Output RGB instead of YUYV\n" + " -g Compress with gzip\n" + " -b Preallocate space in bss for decompressing image\n" " -h Help output\n" "\n" "Where: 'inputfile' is the TGA image to load\n" @@ -377,7 +455,7 @@ int main (int argc, char *argv[])
image_t rgb_logo, yuyv_logo;
- while ((c = getopt(argc, argv, "hr")) > 0) { + while ((c = getopt(argc, argv, "hrgb")) > 0) { switch (c) { case 'h': usage (0); @@ -386,6 +464,14 @@ int main (int argc, char *argv[]) use_rgb = true; puts ("Using 24-bit RGB Output Fromat"); break; + case 'g': + use_gzip |= 0x1; + puts ("Compressing with gzip"); + break; + case 'b': + use_gzip |= 0x2; + puts ("Preallocating bss space for decompressing image"); + break; default: usage (1); break;

Dear Mike Frysinger,
In message 1230624938-17360-1-git-send-email-vapier@gentoo.org you wrote:
Some images can be quite large, so add an option to compress the image data with gzip in the U-Boot image. Then at runtime, the board can decompress it with the normal zlib functions.
Signed-off-by: Mike Frysinger vapier@gentoo.org
v4
- redo error handling
v3
- fix copyright
- free buffers on error
v2
- add error checking
tools/easylogo/easylogo.c | 98 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 92 insertions(+), 6 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk
participants (2)
-
Mike Frysinger
-
Wolfgang Denk