From: Christophe CURIS <christophe.cu...@free.fr> - keep PPM in the list of supported formats, because legacy apps may not handle well the change;
- brought the proper PPM exit code fixes that were implemented in the WEPB patch back into this one because they are not related to WEPB at all; - reverted XPM check change because the original code seems more in line with the official format specification; - make use of the official signature for PNG as defined in the spec; - extended GIF detection to match what is valid as per the spec; - added the copyright notice for the code borrowed to NetPBM, as it is not the GPL (although compatible); - fixed a small error in PPM type check before loading; - and a few minor things for code readability Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> --- wrlib/load.c | 26 +++++++++----- wrlib/load_ppm.c | 93 ++++++++++++++++++++++++++++++++++---------------- wrlib/tests/testdraw.c | 1 + 3 files changed, 82 insertions(+), 38 deletions(-) diff --git a/wrlib/load.c b/wrlib/load.c index 061a50d..05c1b01 100644 --- a/wrlib/load.c +++ b/wrlib/load.c @@ -33,10 +33,6 @@ #include <time.h> #include <assert.h> -#ifdef USE_PNG -#include <png.h> -#endif - #include "wraster.h" #include "imgformat.h" @@ -73,13 +69,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 @@ -303,8 +305,15 @@ static WRImgFormat identFile(const char *path) || (buffer[0] == 'M' && buffer[1] == 'M' && buffer[2] == 0 && buffer[3] == '*')) return IM_TIFF; - /* check for PNG */ - if (buffer[0] == 0x89 && buffer[1] == 'P' && buffer[2] == 'N' && buffer[3] == 'G') + /* + * check for PNG + * + * The signature is defined in the PNG specifiation: + * http://www.libpng.org/pub/png/spec/1.2/PNG-Structure.html + * it is valid for v1.0, v1.1, v1.2 and ISO version + */ + if (buffer[0] == 137 && buffer[1] == 80 && buffer[2] == 78 && buffer[3] == 71 && + buffer[4] == 13 && buffer[5] == 10 && buffer[6] == 26 && buffer[7] == 10) return IM_PNG; /* check for PBM or PGM or PPM */ @@ -316,7 +325,8 @@ 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' && buffer[3] == '8' && + (buffer[4] == '7' || buffer[4] == '9') && buffer[5] == 'a') 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/testdraw.c b/wrlib/tests/testdraw.c index 2b209f5..df8c27d 100644 --- a/wrlib/tests/testdraw.c +++ b/wrlib/tests/testdraw.c @@ -561,6 +561,7 @@ int main(int argc, char **argv) { RContextAttributes attr; int visualID = -1; + (void) argc; ProgName = strrchr(argv[0], '/'); -- 1.8.5.3 -- To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.