PNM loader: Refactor around progress and exits.

SVN revision: 58520
This commit is contained in:
Kim Woelders 2011-04-09 09:24:51 +00:00
parent de93dc7e22
commit 4b12b9e154
1 changed files with 128 additions and 346 deletions

View File

@ -1,10 +1,36 @@
#include "loader_common.h" #include "loader_common.h"
#include <ctype.h> #include <ctype.h>
int
do_progress(ImlibImage * im, ImlibProgressFunction progress,
char progress_granularity, char *pper, int *py, int y)
{
int rc = 0;
int h = 0;
char per;
per = (char)((100 * y) / im->h);
if (((per - *pper) >= progress_granularity) || (y == (im->h - 1)))
{
h = y - *py;
/* fix off by one in case of the last line */
if (y == (im->h - 1))
h++;
rc = !progress(im, per, 0, *py, im->w, h);
*pper = per;
*py = y;
}
return rc;
}
char char
load(ImlibImage * im, ImlibProgressFunction progress, load(ImlibImage * im, ImlibProgressFunction progress,
char progress_granularity, char immediate_load) char progress_granularity, char immediate_load)
{ {
int rc;
char p = ' ', numbers = 3, count = 0; char p = ' ', numbers = 3, count = 0;
int w = 0, h = 0, v = 255, c = 0; int w = 0, h = 0, v = 255, c = 0;
char buf[256]; char buf[256];
@ -25,32 +51,26 @@ load(ImlibImage * im, ImlibProgressFunction progress,
/* read the header info */ /* read the header info */
rc = 0; /* Error */
c = fgetc(f); c = fgetc(f);
if (c != 'P') if (c != 'P')
{ goto quit;
fclose(f);
return 0;
}
p = fgetc(f); p = fgetc(f);
if (p == '1' || p == '4') if (p == '1' || p == '4')
numbers = 2; /* bitimages don't have max value */ numbers = 2; /* bitimages don't have max value */
if ((p < '1') || (p > '8')) if ((p < '1') || (p > '8'))
{ goto quit;
fclose(f);
return 0;
}
count = 0; count = 0;
while (count < numbers) while (count < numbers)
{ {
c = fgetc(f); c = fgetc(f);
if (c == EOF) if (c == EOF)
{ goto quit;
fclose(f);
return 0;
}
/* eat whitespace */ /* eat whitespace */
while (isspace(c)) while (isspace(c))
@ -96,18 +116,13 @@ load(ImlibImage * im, ImlibProgressFunction progress,
} }
} }
if ((v < 0) || (v > 255)) if ((v < 0) || (v > 255))
{ goto quit;
fclose(f);
return 0;
}
im->w = w; im->w = w;
im->h = h; im->h = h;
if (!IMAGE_DIMENSIONS_OK(w, h)) if (!IMAGE_DIMENSIONS_OK(w, h))
{ goto quit;
fclose(f);
return 0;
}
if (!im->format) if (!im->format)
{ {
if (p == '8') if (p == '8')
@ -117,6 +132,8 @@ load(ImlibImage * im, ImlibProgressFunction progress,
im->format = strdup("pnm"); im->format = strdup("pnm");
} }
rc = 1; /* Ok */
if (((!im->data) && (im->loader)) || (immediate_load) || (progress)) if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
{ {
DATA8 *data = NULL; /* for the binary versions */ DATA8 *data = NULL; /* for the binary versions */
@ -131,10 +148,8 @@ load(ImlibImage * im, ImlibProgressFunction progress,
/* must set the im->data member before callign progress function */ /* must set the im->data member before callign progress function */
ptr2 = im->data = malloc(w * h * sizeof(DATA32)); ptr2 = im->data = malloc(w * h * sizeof(DATA32));
if (!im->data) if (!im->data)
{ goto quit_error;
fclose(f);
return 0;
}
/* start reading the data */ /* start reading the data */
switch (p) switch (p)
{ {
@ -149,10 +164,7 @@ load(ImlibImage * im, ImlibProgressFunction progress,
if (!buf[i]) /* fill buffer */ if (!buf[i]) /* fill buffer */
{ {
if (!fgets(buf, 255, f)) if (!fgets(buf, 255, f))
{ goto quit_error;
fclose(f);
return 0;
}
i = 0; i = 0;
} }
while (buf[i] && isspace(buf[i])) while (buf[i] && isspace(buf[i]))
@ -164,48 +176,22 @@ load(ImlibImage * im, ImlibProgressFunction progress,
else if (buf[i] == '0') else if (buf[i] == '0')
*ptr2 = 0xffffffff; *ptr2 = 0xffffffff;
else else
{ goto quit_error;
fclose(f);
return 0;
}
ptr2++; ptr2++;
i++; i++;
} }
} }
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity,
char per; &pper, &pl, y))
int l; goto quit_progress;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
l = y - pl;
/* fix off by one in case of the last line */
if (y == (im->h - 1))
l++;
if (!progress(im, per, 0, pl, im->w, l))
{
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
break; break;
case '2': /* ASCII greyscale */ case '2': /* ASCII greyscale */
idata = malloc(sizeof(int) * w); idata = malloc(sizeof(int) * w);
if (!idata) if (!idata)
{ goto quit_error;
fclose(f);
return 0;
}
buf[0] = 0; buf[0] = 0;
i = 0; i = 0;
j = 0; j = 0;
@ -225,11 +211,7 @@ load(ImlibImage * im, ImlibProgressFunction progress,
{ {
if (fseek(f, -k, SEEK_CUR) == -1 || if (fseek(f, -k, SEEK_CUR) == -1 ||
!fgets(buf, 255, f)) !fgets(buf, 255, f))
{ goto quit_error;
free(idata);
fclose(f);
return 0;
}
i = 0; i = 0;
break; break;
} }
@ -271,42 +253,17 @@ load(ImlibImage * im, ImlibProgressFunction progress,
iptr++; iptr++;
} }
} }
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity,
char per; &pper, &pl, y))
int l; goto quit_progress;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
l = y - pl;
/* fix off by one in case of the last line */
if (y == (im->h - 1))
l++;
if (!progress(im, per, 0, pl, im->w, l))
{
free(idata);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
break; break;
case '3': /* ASCII RGB */ case '3': /* ASCII RGB */
idata = malloc(3 * sizeof(int) * w); idata = malloc(3 * sizeof(int) * w);
if (!idata) if (!idata)
{ goto quit_error;
fclose(f);
return 0;
}
buf[0] = 0; buf[0] = 0;
i = 0; i = 0;
j = 0; j = 0;
@ -328,11 +285,7 @@ load(ImlibImage * im, ImlibProgressFunction progress,
{ {
if (fseek(f, -k, SEEK_CUR) == -1 || if (fseek(f, -k, SEEK_CUR) == -1 ||
!fgets(buf, 255, f)) !fgets(buf, 255, f))
{ goto quit_error;
free(idata);
fclose(f);
return 0;
}
i = 0; i = 0;
break; break;
} }
@ -374,49 +327,23 @@ load(ImlibImage * im, ImlibProgressFunction progress,
iptr += 3; iptr += 3;
} }
} }
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity,
char per; &pper, &pl, y))
int l; goto quit_progress;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
l = y - pl;
/* fix off by one in case of the last line */
if (y == (im->h - 1))
l++;
if (!progress(im, per, 0, pl, im->w, l))
{
free(idata);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
break; break;
case '4': /* binary 1bit monochrome */ case '4': /* binary 1bit monochrome */
data = malloc((w + 7) / 8 * sizeof(DATA8)); data = malloc((w + 7) / 8 * sizeof(DATA8));
if (!data) if (!data)
{ goto quit_error;
fclose(f);
return 0;
}
ptr2 = im->data; ptr2 = im->data;
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (!fread(data, (w + 7) / 8, 1, f)) if (!fread(data, (w + 7) / 8, 1, f))
{ goto quit_error;
free(data);
fclose(f);
return 0;
}
ptr = data; ptr = data;
for (x = 0; x < w; x += 8) for (x = 0; x < w; x += 8)
{ {
@ -431,49 +358,23 @@ load(ImlibImage * im, ImlibProgressFunction progress,
} }
ptr++; ptr++;
} }
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity,
char per; &pper, &pl, y))
int l; goto quit_progress;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
l = y - pl;
/* fix off by one in case of the last line */
if (y == (im->h - 1))
l++;
if (!progress(im, per, 0, pl, im->w, l))
{
free(idata);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
break; break;
case '5': /* binary 8bit grayscale GGGGGGGG */ case '5': /* binary 8bit grayscale GGGGGGGG */
data = malloc(1 * sizeof(DATA8) * w); data = malloc(1 * sizeof(DATA8) * w);
if (!data) if (!data)
{ goto quit_error;
fclose(f);
return 0;
}
ptr2 = im->data; ptr2 = im->data;
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (!fread(data, w * 1, 1, f)) if (!fread(data, w * 1, 1, f))
{ break;
free(data);
fclose(f);
return 1;
}
ptr = data; ptr = data;
if (v == 255) if (v == 255)
{ {
@ -499,49 +400,23 @@ load(ImlibImage * im, ImlibProgressFunction progress,
ptr++; ptr++;
} }
} }
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity,
char per; &pper, &pl, y))
int l; goto quit_progress;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
l = y - pl;
/* fix off by one in case of the last line */
if (y == (im->h - 1))
l++;
if (!progress(im, per, 0, pl, im->w, l))
{
free(data);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
break; break;
case '6': /* 24bit binary RGBRGBRGB */ case '6': /* 24bit binary RGBRGBRGB */
data = malloc(3 * sizeof(DATA8) * w); data = malloc(3 * sizeof(DATA8) * w);
if (!data) if (!data)
{ goto quit_error;
fclose(f);
return 0;
}
ptr2 = im->data; ptr2 = im->data;
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (!fread(data, w * 3, 1, f)) if (!fread(data, w * 3, 1, f))
{ break;
free(data);
fclose(f);
return 1;
}
ptr = data; ptr = data;
if (v == 255) if (v == 255)
{ {
@ -567,49 +442,23 @@ load(ImlibImage * im, ImlibProgressFunction progress,
ptr += 3; ptr += 3;
} }
} }
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity,
char per; &pper, &pl, y))
int l; goto quit_progress;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
l = y - pl;
/* fix off by one in case of the last line */
if (y == (im->h - 1))
l++;
if (!progress(im, per, 0, pl, im->w, l))
{
free(data);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
break; break;
case '7': /* XV's 8bit 332 format */ case '7': /* XV's 8bit 332 format */
data = malloc(1 * sizeof(DATA8) * w); data = malloc(1 * sizeof(DATA8) * w);
if (!data) if (!data)
{ goto quit_error;
fclose(f);
return 0;
}
ptr2 = im->data; ptr2 = im->data;
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (!fread(data, w * 1, 1, f)) if (!fread(data, w * 1, 1, f))
{ break;
free(data);
fclose(f);
return 1;
}
ptr = data; ptr = data;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
@ -626,47 +475,23 @@ load(ImlibImage * im, ImlibProgressFunction progress,
ptr2++; ptr2++;
ptr++; ptr++;
} }
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity,
char per; &pper, &pl, y))
int l = 0; goto quit_progress;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
/* fix off by one in case of the last line */
if (y == (im->h - 1))
l++;
if (!progress(im, per, 0, pl, im->w, l))
{
free(data);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
break; break;
case '8': /* 24bit binary RGBARGBARGBA */ case '8': /* 24bit binary RGBARGBARGBA */
data = malloc(4 * sizeof(DATA8) * w); data = malloc(4 * sizeof(DATA8) * w);
if (!data) if (!data)
{ goto quit_error;
fclose(f);
return 0;
}
ptr2 = im->data; ptr2 = im->data;
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (!fread(data, w * 4, 1, f)) if (!fread(data, w * 4, 1, f))
{ break;
free(data);
fclose(f);
return 1;
}
ptr = data; ptr = data;
if (v == 255) if (v == 255)
{ {
@ -692,34 +517,18 @@ load(ImlibImage * im, ImlibProgressFunction progress,
ptr += 4; ptr += 4;
} }
} }
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity,
char per; &pper, &pl, y))
int l = 0; goto quit_progress;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
/* fix off by one in case of the last line */
if (y == (im->h - 1))
l++;
if (!progress(im, per, 0, pl, im->w, l))
{
free(data);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
break; break;
default: default:
fclose(f); quit_error:
return 0; rc = 0;
break;
quit_progress:
rc = 2;
break; break;
} }
if (idata) if (idata)
@ -727,13 +536,15 @@ load(ImlibImage * im, ImlibProgressFunction progress,
if (data) if (data)
free(data); free(data);
} }
quit:
fclose(f); fclose(f);
return 1; return rc;
} }
char char
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity) save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
{ {
int rc;
FILE *f; FILE *f;
DATA8 *buf, *bptr; DATA8 *buf, *bptr;
DATA32 *ptr; DATA32 *ptr;
@ -746,16 +557,17 @@ save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
f = fopen(im->real_file, "wb"); f = fopen(im->real_file, "wb");
if (!f) if (!f)
return 0; return 0;
rc = 0; /* Error */
/* if the image has a useful alpha channel */ /* if the image has a useful alpha channel */
if (im->flags & F_HAS_ALPHA) if (im->flags & F_HAS_ALPHA)
{ {
/* allocate a small buffer to convert image data */ /* allocate a small buffer to convert image data */
buf = malloc(im->w * 4 * sizeof(DATA8)); buf = malloc(im->w * 4 * sizeof(DATA8));
if (!buf) if (!buf)
{ goto quit;
fclose(f);
return 0;
}
ptr = im->data; ptr = im->data;
fprintf(f, "P8\n" "# PNM File written by Imlib2\n" "%i %i\n" "255\n", fprintf(f, "P8\n" "# PNM File written by Imlib2\n" "%i %i\n" "255\n",
im->w, im->h); im->w, im->h);
@ -772,26 +584,9 @@ save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
ptr++; ptr++;
} }
fwrite(buf, im->w * 4, 1, f); fwrite(buf, im->w * 4, 1, f);
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity, &pper, &pl, y))
char per; goto quit_progress;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
l = y - pl;
if (!progress(im, per, 0, (y - l), im->w, l))
{
free(buf);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
} }
else else
@ -799,10 +594,8 @@ save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
/* allocate a small buffer to convert image data */ /* allocate a small buffer to convert image data */
buf = malloc(im->w * 3 * sizeof(DATA8)); buf = malloc(im->w * 3 * sizeof(DATA8));
if (!buf) if (!buf)
{ goto quit;
fclose(f);
return 0;
}
ptr = im->data; ptr = im->data;
fprintf(f, "P6\n" "# PNM File written by Imlib2\n" "%i %i\n" "255\n", fprintf(f, "P6\n" "# PNM File written by Imlib2\n" "%i %i\n" "255\n",
im->w, im->h); im->w, im->h);
@ -818,33 +611,22 @@ save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
ptr++; ptr++;
} }
fwrite(buf, im->w * 3, 1, f); fwrite(buf, im->w * 3, 1, f);
if (progress) if (progress &&
{ do_progress(im, progress, progress_granularity, &pper, &pl, y))
char per; goto quit_progress;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity)
|| (y == (im->h - 1)))
{
l = y - pl;
if (!progress(im, per, 0, (y - l), im->w, l))
{
free(buf);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
} }
} }
rc = 1; /* Ok */
/* finish off */ /* finish off */
free(buf); free(buf);
quit:
fclose(f); fclose(f);
return 1; return rc;
progress = NULL; quit_progress:
rc = 2;
goto quit;
} }
void void