fix incorrect img_n variable for interlaced files, caused files to be totally incorrect if forcing channel count

This commit is contained in:
Sean Barrett 2014-12-13 23:35:55 -08:00
parent ff2d5473c5
commit 8679ce08b7
2 changed files with 32 additions and 20 deletions

View File

@ -2530,9 +2530,9 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
else {
// unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
// png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
in = line8;
stbi_uc* decode_out = line8;
stbi_uc * decode_out = line8;
stbi_uc scale = (color == 0) ? 0xFF/((1<<depth)-1) : 1; // scale grayscale values to 0..255 range
in = line8;
if (depth == 4) {
for (k=x*img_n; k >= 1; k-=2, raw++) {
*decode_out++ = scale * ((*raw >> 4) );
@ -2617,12 +2617,12 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
return 1;
}
static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, int depth, int color, int interlaced)
static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced)
{
stbi_uc *final;
int p;
if (!interlaced)
return stbi__create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y, depth, color);
return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color);
// de-interlacing
final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n);
@ -2636,18 +2636,22 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_l
x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p];
y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p];
if (x && y) {
stbi__uint32 img_len = ((((out_n * x * depth) + 7) >> 3) + 1) * y;
if (!stbi__create_png_image_raw(a, raw, raw_len, out_n, x, y, depth, color)) {
stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y;
if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) {
free(final);
return 0;
}
for (j=0; j < y; ++j)
for (i=0; i < x; ++i)
memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n,
for (j=0; j < y; ++j) {
for (i=0; i < x; ++i) {
int out_y = j*yspc[p]+yorig[p];
int out_x = i*xspc[p]+xorig[p];
memcpy(final + out_y*a->s->img_x*out_n + out_x*out_n,
a->out + (j*x+i)*out_n, out_n);
}
}
free(a->out);
raw += img_len;
raw_len -= img_len;
image_data += img_len;
image_data_len -= img_len;
}
}
a->out = final;

View File

@ -32,24 +32,32 @@ int main(int argc, char **argv)
}
} else {
int i;
char **files = stb_readdir_files("images");
char **files = stb_readdir_files("pngsuite/part1");
for (i=0; i < stb_arr_len(files); ++i) {
int n;
char **failed = NULL;
unsigned char *data;
printf("%s\n", files[i]);
data = stbi_load(files[i], &w, &h, &n, 4); if (data) free(data); else printf("Failed &n\n");
data = stbi_load(files[i], &w, &h, 0, 1); if (data) free(data); else printf("Failed 1\n");
data = stbi_load(files[i], &w, &h, 0, 2); if (data) free(data); else printf("Failed 2\n");
data = stbi_load(files[i], &w, &h, 0, 3); if (data) free(data); else printf("Failed 3\n");
data = stbi_load(files[i], &w, &h, 0, 4);
//printf("%s\n", files[i]);
data = stbi_load(files[i], &w, &h, &n, 0); if (data) free(data); else stb_arr_push(failed, "&n");
data = stbi_load(files[i], &w, &h, 0, 1); if (data) free(data); else stb_arr_push(failed, "1");
data = stbi_load(files[i], &w, &h, 0, 2); if (data) free(data); else stb_arr_push(failed, "2");
data = stbi_load(files[i], &w, &h, 0, 3); if (data) free(data); else stb_arr_push(failed, "3");
data = stbi_load(files[i], &w, &h, 0, 4); if (data) ; else stb_arr_push(failed, "4");
if (data) {
char fname[512];
stb_splitpath(fname, files[i], STB_FILE);
stbi_write_png(stb_sprintf("output/%s.png", fname), w, h, 4, data, w*4);
free(data);
} else
printf("FAILED\n");
}
if (failed) {
int j;
printf("FAILED: ");
for (j=0; j < stb_arr_len(failed); ++j)
printf("%s ", failed[j]);
printf(" -- %s\n", files[i]);
}
}
printf("Tested %d files\n", i);
}
return 0;
}