From: Christophe CURIS <[email protected]> - re-add PPM to the list of supported format, because legacy apps may expect to find it from the list;
- revert changes related to image format detection because it is not related to PPM and will be added through a dedicated patch; - add the copyright notice related to the code that have been borrowed from Netpbm; - imported the fixes related to returning properly on error, that was part of the "future" WebP patch (and is not related to webp) - fixed a small error in PPM format check in the loading procedure; - reverted changes to the test code, they are not related and will be part of a dedicated patch - and a few minor code improvements Signed-off-by: Christophe CURIS <[email protected]> --- wrlib/load.c | 22 ++++++++---- wrlib/load_ppm.c | 93 +++++++++++++++++++++++++++++++++---------------- wrlib/tests/Makefile.am | 2 +- wrlib/tests/testdraw.c | 1 - wrlib/tests/view.c | 6 ++-- 5 files changed, 81 insertions(+), 43 deletions(-) diff --git a/wrlib/load.c b/wrlib/load.c index 061a50d..8c76373 100644 --- a/wrlib/load.c +++ b/wrlib/load.c @@ -73,13 +73,19 @@ static WRImgFormat identFile(const char *path); char **RSupportedFileFormats(void) { - static char *tmp[IM_TYPES + 1]; + static char *tmp[IM_TYPES + 2]; int i = 0; /* built-in */ tmp[i++] = "XPM"; /* built-in PNM here refers to anymap format: PPM, PGM, PBM */ tmp[i++] = "PNM"; + /* + * PPM is a just a sub-type of PNM, but it has to be in the list + * for compatibility with legacy programs that may expect it but + * not the new PNM type + */ + tmp[i++] = "PPM"; #ifdef USE_TIFF tmp[i++] = "TIFF"; #endif @@ -275,7 +281,7 @@ char *RGetImageFileFormat(const char *file) static WRImgFormat identFile(const char *path) { FILE *file; - unsigned char buffer[7]; + unsigned char buffer[32]; size_t nread; assert(path != NULL); @@ -295,7 +301,7 @@ static WRImgFormat identFile(const char *path) RETRY( fclose(file) ) /* check for XPM */ - if (strncmp((char *)buffer, "/* XPM", 6) == 0) + if (strncmp((char *)buffer, "/* XPM */", 9) == 0) return IM_XPM; /* check for TIFF */ @@ -303,12 +309,14 @@ static WRImgFormat identFile(const char *path) || (buffer[0] == 'M' && buffer[1] == 'M' && buffer[2] == 0 && buffer[3] == '*')) return IM_TIFF; +#ifdef USE_PNG /* check for PNG */ - if (buffer[0] == 0x89 && buffer[1] == 'P' && buffer[2] == 'N' && buffer[3] == 'G') + if (!png_sig_cmp(buffer, 0, 8)) return IM_PNG; +#endif - /* check for PBM or PGM or PPM */ - if (buffer[0] == 'P' && (buffer[1] > '0' && buffer[1] < '7') && (buffer[2] == 0x0a || buffer[2] == 0x20 || buffer[2] == 0x09 || buffer[2] == 0x0d)) + /* check for raw PPM or PGM */ + if (buffer[0] == 'P' && (buffer[1] == '5' || buffer[1] == '6')) return IM_PPM; /* check for JPEG */ @@ -316,7 +324,7 @@ static WRImgFormat identFile(const char *path) return IM_JPEG; /* check for GIF */ - if (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F' && buffer[3] == '8') + if (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F') return IM_GIF; return IM_UNKNOWN; diff --git a/wrlib/load_ppm.c b/wrlib/load_ppm.c index b45d0f0..8d1ab72 100644 --- a/wrlib/load_ppm.c +++ b/wrlib/load_ppm.c @@ -32,10 +32,18 @@ #include "wraster.h" #include "imgformat.h" -/* fileio.c - routines to read elements based on Netpbm -** -** Copyright (C) 1988 by Jef Poskanzer. -*/ +/* + * fileio.c - routines to read elements based on Netpbm + * + * Copyright (C) 1988 by Jef Poskanzer. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. This software is provided "as is" without express or + * implied warranty. + */ char pm_getc(FILE * const fileP) { @@ -103,6 +111,7 @@ int pm_getuint(FILE * const ifP) return i; } +/* end of fileio.c re-used code */ /******************************************************************************************/ /* PGM: support for portable graymap ascii and binary encoding */ @@ -112,23 +121,29 @@ static RImage *load_graymap(FILE * file, int w, int h, int max, int raw) unsigned char *ptr; int x, y; - image = RCreateImage(w, h, 0); - if (!image) + if (raw != '2' && raw != '5') { + RErrorCode = RERR_BADFORMAT; return NULL; + } - if (raw != '2' && raw != '5') - return image; + image = RCreateImage(w, h, 0); + if (!image) { + RErrorCode = RERR_NOMEMORY; + return NULL; + } if (max < 256) { ptr = image->data; if (raw == '2') { int val; + for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { val = pm_getuint(file); if (val > max || val < 0) { RErrorCode = RERR_BADIMAGEFILE; + RReleaseImage(image); return NULL; } @@ -141,13 +156,18 @@ static RImage *load_graymap(FILE * file, int w, int h, int max, int raw) } else { if (raw == '5') { char *buf; + buf = malloc(w + 1); - if (!buf) + if (!buf) { + RErrorCode = RERR_NOMEMORY; + RReleaseImage(image); return NULL; + } for (y = 0; y < h; y++) { if (!fread(buf, w, 1, file)) { free(buf); RErrorCode = RERR_BADIMAGEFILE; + RReleaseImage(image); return NULL; } @@ -168,20 +188,25 @@ static RImage *load_graymap(FILE * file, int w, int h, int max, int raw) static RImage *load_pixmap(FILE * file, int w, int h, int max, int raw) { RImage *image; + int i; unsigned char *ptr; - int i = 0; - image = RCreateImage(w, h, 0); - if (!image) + if (raw != '3' && raw != '6') { + RErrorCode = RERR_BADFORMAT; return NULL; + } - if (raw != '3' && raw != '6') - return image; + image = RCreateImage(w, h, 0); + if (!image) { + RErrorCode = RERR_NOMEMORY; + return NULL; + } ptr = image->data; if (max < 256) { if (raw == '3') { int x, y, val; + for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { for (i = 0; i < 3; i++) { @@ -189,6 +214,7 @@ static RImage *load_pixmap(FILE * file, int w, int h, int max, int raw) if (val > max || val < 0) { RErrorCode = RERR_BADIMAGEFILE; + RReleaseImage(image); return NULL; } @@ -199,9 +225,12 @@ static RImage *load_pixmap(FILE * file, int w, int h, int max, int raw) } } else if (raw == '6') { char buf[3]; + + i = 0; while (i < w * h) { if (fread(buf, 1, 3, file) != 3) { RErrorCode = RERR_BADIMAGEFILE; + RReleaseImage(image); return NULL; } @@ -222,21 +251,27 @@ static RImage *load_bitmap(FILE * file, int w, int h, int max, int raw) int val; unsigned char *ptr; - image = RCreateImage(w, h, 0); - if (!image) + if (raw != '1' && raw != '4') { + RErrorCode = RERR_BADFORMAT; return NULL; + } - if (raw != '1' && raw != '4') - return image; + image = RCreateImage(w, h, 0); + if (!image) { + RErrorCode = RERR_NOMEMORY; + return NULL; + } ptr = image->data; if (raw == '1') { int i = 0; + while (i < w * h) { val = pm_getuint(file); if (val > max || val < 0) { RErrorCode = RERR_BADIMAGEFILE; + RReleaseImage(image); return NULL; } @@ -293,8 +328,8 @@ RImage *RLoadPPM(const char *file_name) return NULL; } - /* accept bitmaps, pixmaps or graymaps */ - if (buffer[0] != 'P' || (buffer[1] < '1' && buffer[1] > '6')) { + /* accept bitmaps, pixmaps or graymaps */ + if (buffer[0] != 'P' || (buffer[1] < '1' || buffer[1] > '6')) { RErrorCode = RERR_BADFORMAT; fclose(file); return NULL; @@ -339,17 +374,15 @@ RImage *RLoadPPM(const char *file_name) m = 1; } - /* check portable bitmap type, ascii = 1 and binary = 4 */ - if (type == '1' || type == '4') + if (type == '1' || type == '4') { + /* Portable Bit Map: P1 is for 'plain' (ascii, rare), P4 for 'regular' (binary) */ image = load_bitmap(file, w, h, m, type); - else { - /* check portable graymap type, ascii = 2 and binary = 5 */ - if (type == '2' || type == '5') - image = load_graymap(file, w, h, m, type); - else - /* check portable pixmap type, ascii = 3 and binary = 6 */ - if (type == '3' || type == '6') - image = load_pixmap(file, w, h, m, type); + } else if (type == '2' || type == '5') { + /* Portable Gray Map: P2 is for 'plain' (ascii, rare), P5 for 'regular' (binary) */ + image = load_graymap(file, w, h, m, type); + } else if (type == '3' || type == '6') { + /* Portable Pix Map: P3 is for 'plain' (ascii, rare), P6 for 'regular' (binary) */ + image = load_pixmap(file, w, h, m, type); } fclose(file); diff --git a/wrlib/tests/Makefile.am b/wrlib/tests/Makefile.am index 76c9872..e447e97 100644 --- a/wrlib/tests/Makefile.am +++ b/wrlib/tests/Makefile.am @@ -8,7 +8,7 @@ EXTRA_DIST = test.png tile.xpm ballot_box.xpm AM_CPPFLAGS = -I$(srcdir)/.. $(DFLAGS) @HEADER_SEARCH_PATH@ -LIBLIST = $(top_builddir)/wrlib/libwraster.la @XLIBS@ +LIBLIST = $(top_builddir)/wrlib/libwraster.la testdraw_SOURCES = testdraw.c testdraw_LDADD = $(LIBLIST) diff --git a/wrlib/tests/testdraw.c b/wrlib/tests/testdraw.c index 2b209f5..8d416bb 100644 --- a/wrlib/tests/testdraw.c +++ b/wrlib/tests/testdraw.c @@ -561,7 +561,6 @@ int main(int argc, char **argv) { RContextAttributes attr; int visualID = -1; - (void) argc; ProgName = strrchr(argv[0], '/'); if (!ProgName) diff --git a/wrlib/tests/view.c b/wrlib/tests/view.c index 52c3ade..6b107af 100644 --- a/wrlib/tests/view.c +++ b/wrlib/tests/view.c @@ -24,10 +24,8 @@ int main(int argc, char **argv) attr.colors_per_channel = 4; ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr); - if (argc < 2) { - printf("using default image as none was provided\n"); + if (argc < 2) img = RGetImageFromXPMData(ctx, image_name); - } else img = RLoadImage(ctx, argv[1], 0); @@ -72,7 +70,7 @@ int main(int argc, char **argv) exit(1); } - printf("size is %ix%i\n", img->width, img->height); + printf("%ix%i\n", img->width, img->height); win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10, img->width, img->height, 0, 0, 0); XSetWindowBackgroundPixmap(dpy, win, pix); -- 1.9.1 -- To unsubscribe, send mail to [email protected].
