diff --git a/test/correctness/image_io.cpp b/test/correctness/image_io.cpp index e24bccb9091b..858ffb28a54e 100644 --- a/test/correctness/image_io.cpp +++ b/test/correctness/image_io.cpp @@ -268,6 +268,32 @@ void test_mat_header() { } } +// read_big_endian_row must honor a nonzero channel-dimension min. It used to +// index channel (c + cmin), which writes past the channel bounds (and out of +// the allocation) for any buffer whose channel min is nonzero. +void test_read_big_endian_row_channel_offset() { + const int W = 4, H = 1, C = 3, CMIN = 2; + Halide::Runtime::Buffer im(W, H, C); + im.translate(2, CMIN); // channel dim: min = 2, max = 4 + im.fill(0); + std::vector src(W * C); + for (int i = 0; i < W * C; i++) { + src[i] = (uint8_t)(i + 1); + } + Tools::Internal::read_big_endian_row(src.data(), im.dim(1).min(), &im); + int idx = 0; + for (int x = im.dim(0).min(); x <= im.dim(0).max(); x++) { + for (int c = im.dim(2).min(); c <= im.dim(2).max(); c++) { + if (im(x, im.dim(1).min(), c) != src[idx]) { + printf("read_big_endian_row wrote wrong value at (%d, %d): got %d expected %d\n", + x, c, (int)im(x, im.dim(1).min(), c), (int)src[idx]); + exit(1); + } + idx++; + } + } +} + int main(int argc, char **argv) { do_test(); do_test(); @@ -283,6 +309,7 @@ int main(int argc, char **argv) { #endif do_test(); test_mat_header(); + test_read_big_endian_row_channel_offset(); printf("Success!\n"); return 0; } diff --git a/tools/halide_image_io.h b/tools/halide_image_io.h index 1f3f8dd01f99..ff28aa50996d 100644 --- a/tools/halide_image_io.h +++ b/tools/halide_image_io.h @@ -831,7 +831,7 @@ void read_big_endian_row(const uint8_t *src, int y, ImageType *im) { const int cmax = im_typed.dim(2).max(); for (int x = xmin; x <= xmax; x++) { for (int c = cmin; c <= cmax; c++) { - im_typed(x, y, c + cmin) = read_big_endian(src); + im_typed(x, y, c) = read_big_endian(src); src += sizeof(ElemType); } }