From 8679ce08b78c96a74f0e0d7efb54b9abac24dda2 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 13 Dec 2014 23:35:55 -0800 Subject: [PATCH] fix incorrect img_n variable for interlaced files, caused files to be totally incorrect if forcing channel count --- stb_image.h | 26 +++++++++++++++----------- tests/image_test.c | 26 +++++++++++++++++--------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/stb_image.h b/stb_image.h index 5ab9c58..771ba15 100644 --- a/stb_image.h +++ b/stb_image.h @@ -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<= 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; diff --git a/tests/image_test.c b/tests/image_test.c index c17c766..47c5c68 100644 --- a/tests/image_test.c +++ b/tests/image_test.c @@ -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; }