From dba0a3cfcb38a0596ed22cae1fbade8cc192ff8c Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Tue, 2 Nov 1999 00:24:17 +0000 Subject: [PATCH] pnm loader handles binary formats allright... :) SVN revision: 1132 --- loaders/loader_pnm.c | 282 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 266 insertions(+), 16 deletions(-) diff --git a/loaders/loader_pnm.c b/loaders/loader_pnm.c index 80d23a8..d496e11 100644 --- a/loaders/loader_pnm.c +++ b/loaders/loader_pnm.c @@ -28,9 +28,10 @@ load (ImlibImage *im, int update_w, int update_h), char progress_granularity, char immediate_load) { - char ascii = 0, alpha = 0, color = 0, mono = 0; - int w, h; - FILE *f; + char p = ' '; + int w = 0, h = 0, v = 255; + DATA8 *data = NULL; + FILE *f = NULL; if (im->data) return 0; @@ -38,23 +39,105 @@ load (ImlibImage *im, if (!f) return 0; - if ((!im->loader) && (!im->data)) + if (!im->data) { - /* red the header info */ + char buf[256], buf2[256]; + /* read the header info */ + + if (fgets(buf, 255, f)) + { + if ((buf[0] == 'P') && (isspace(buf[2]))) + { + int i, j; + char comment = 1; + + p = buf[1]; + /* skip blanks */ + while (comment) + { + comment = 0; + if (!fgets(buf, 244, f)) + { + fclose(f); + return 0; + } + if (buf[0] == '#') + comment = 1; + } + + /* get the width */ + i = 0; + j = 0; + while ((buf[i]) && (!isspace(buf[i]))) + buf2[j++] = buf[i++]; + buf2[j] = 0; + w = atoi(buf2); + + while ((buf[i]) && (isspace(buf[i]))) + i++; + if (!buf[i]) + { + i = 0; + if (!fgets(buf, 244, f)) + { + fclose(f); + return 0; + } + } + + /* get the height */ + j = 0; + while ((buf[i]) && (!isspace(buf[i]))) + buf2[j++] = buf[i++]; + buf2[j] = 0; + h = atoi(buf2); + + /* if its a color or grayscale get the max value */ + if (!((p == '4') || (p == '1'))) + { + while ((buf[i]) && (isspace(buf[i]))) + i++; + if (!buf[i]) + { + i = 0; + if (!fgets(buf, 244, f)) + { + fclose(f); + return 0; + } + } + i = 0; + j = 0; + while ((buf[i]) && (!isspace(buf[i]))) + buf2[j++] = buf[i++]; + buf2[j] = 0; + v = atoi(buf2); + } + } + else + { + fclose(f); + return 0; + } + } + else + { + fclose(f); + return 0; + } im->w = w; im->h = h; - if (!alpha) + if (p == '8') UNSET_FLAG(im->flags, F_HAS_ALPHA); im->format = strdup("pnm"); } + if (((!im->data) && (im->loader)) || (immediate_load) || (progress)) { DATA8 *ptr; DATA32 *ptr2; - int x, y, i; - - im->w = w; - im->h = h; + int i, j, x, y, pl = 0; + char pper = 0; /* must set the im->data member before callign progress function */ ptr2 = im->data = malloc(w * h * sizeof(DATA32)); @@ -63,16 +146,183 @@ load (ImlibImage *im, fclose(f); return 0; } - for (y = 0; y < h; y++) + /* start reading the data */ + switch (p) { - if (progress) + case '1': /* */ + fclose(f); + return 0; + break; + case '2': /* */ + fclose(f); + return 0; + break; + case '3': /* */ + fclose(f); + return 0; + break; + case '4': /* binary 1bit monochrome */ + data = malloc(1 * sizeof(DATA8)); + if (!data) { - int per; - - per = (y * 100) / h; - progress(im, per, 0, y, w, 1); + fclose(f); + return 0; } + ptr2 = im->data; + j = 0; + while ((fread(data, 1, 1, f)) && (j < (w * h))) + { + for (i = 7; i >= 0; i--) + { + if (j < (w * h)) + { + if (data[0] & (1 << i)) + *ptr2 = 0xff000000; + else + *ptr2 = 0xffffffff; + ptr2++; + } + j++; + } + } + break; + case '5': /* binary 8bit grayscale GGGGGGGG */ + data = malloc(1 * sizeof(DATA8) * w); + if (!data) + { + fclose(f); + return 0; + } + ptr2 = im->data; + for (y = 0; y < h; y++) + { + if (!fread(data, w * 1, 1, f)) + { + free(data); + fclose(f); + return 1; + } + ptr = data; + if (v == 255) + { + for (x = 0; x < w; x++) + { + *ptr2 = + (ptr[0] << 16) | + (ptr[0] << 8) | + ptr[0]; + ptr2++; + ptr ++; + } + } + else + { + for (x = 0; x < w; x++) + { + *ptr2 = + (((ptr[0] * 255) / v) << 16) | + (((ptr[0] * 255) / v) << 8) | + ((ptr[0] * 255) / v); + ptr2++; + ptr++; + } + } + if (progress) + { + char per; + int l; + + per = (char)((100 * y) / im->h); + if ((per - pper) >= progress_granularity) + { + l = y - pl; + progress(im, per, 0, (y - l), im->w, l); + pper = per; + pl = y; + } + } + } + break; + case '6': /* 24bit binary RGBRGBRGB */ + data = malloc(3 * sizeof(DATA8) * w); + if (!data) + { + fclose(f); + return 0; + } + ptr2 = im->data; + for (y = 0; y < h; y++) + { + if (!fread(data, w * 3, 1, f)) + { + free(data); + fclose(f); + return 1; + } + ptr = data; + if (v == 255) + { + for (x = 0; x < w; x++) + { + *ptr2 = + (ptr[0] << 16) | + (ptr[1] << 8) | + ptr[2]; + ptr2++; + ptr += 3; + } + } + else + { + for (x = 0; x < w; x++) + { + *ptr2 = + (((ptr[0] * 255) / v) << 16) | + (((ptr[1] * 255) / v) << 8) | + ((ptr[2] * 255) / v); + ptr2++; + ptr += 3; + } + } + if (progress) + { + char per; + int l; + + per = (char)((100 * y) / im->h); + if ((per - pper) >= progress_granularity) + { + l = y - pl; + progress(im, per, 0, (y - l), im->w, l); + pper = per; + pl = y; + } + } + } + break; + case '7': /* XV's 8bit 332 format */ + data = malloc(1 * sizeof(DATA8) * w); + if (!data) + { + fclose(f); + return 0; + } + break; + case '8': /* 24bit binary RGBARGBARGBA */ + data = malloc(4 * sizeof(DATA8) * w); + if (!data) + { + fclose(f); + return 0; + } + break; + default: + fclose(f); + return 0; + break; } + if (data) + free(data); } fclose(f); return 1;