From 290997538590d54387602a37879ad4cffbc311da Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Thu, 30 Apr 2015 12:10:58 +0200 Subject: Fix T44541 aka gigapixel image render support in blender. Moral of the story: Make sure that size_t is used whenever pointer arithmetic is involved. For images, that basically means whenever any squared dimensions are involved. Casting an operand to size_t early in the operation is usually sufficient to force the entire operation to size_t. There might still be places lurking where we don't support this correctly. This has been tested with render pipeline, quite a few image functions (meaning we can paint on such images now, albeit somewhat slowly ;) ) and export to jpeg. Too many places in code to check so I guess we'll be handling cases as they come. Don't try this at home unless you have an immense ammount of RAM. First GPixel render of suzanne in the multiverse can be found here: http://download.blender.org/demo/test/suzanne-billion-pixel.jpg Can be viewed from blender (takes about 3.3 GB after loading but may take more during loading so 8GB might be more safe to try this). --- source/blender/imbuf/intern/imageprocess.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/imbuf/intern/imageprocess.c') diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 8234b01992b..90219461772 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -343,7 +343,7 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_ void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]) { - int a = x * y; + size_t a = ((size_t)x) * y; float *fp = rect_float; while (a--) { @@ -366,7 +366,7 @@ void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[ void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]) { - int a = x * y; + size_t a = ((size_t)x) * y; unsigned char *cp = rect; while (a--) { -- cgit v1.2.3 From 2f2f7c0e875b2cfcd7b5caa0af532401deac67be Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Fri, 29 May 2015 13:38:20 +0200 Subject: Fix T44882, color picker in texpainting doing linear interpolation even when mipmap is off. We used to always have nearest interpolation for texpaint but at least make this work with mipmap off correctly. Also added conversion casts to avoid integer overflow in filtering code --- source/blender/imbuf/intern/imageprocess.c | 59 ++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'source/blender/imbuf/intern/imageprocess.c') diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 90219461772..d44f0dc86f4 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -51,7 +51,7 @@ /* Only this one is used liberally here, and in imbuf */ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) { - int size; + size_t size; unsigned char rt, *cp = (unsigned char *)ibuf->rect; float rtf, *cpf = ibuf->rect_float; @@ -86,7 +86,7 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y) { - int offset = ibuf->x * y * 4 + 4 * x; + size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x; if (ibuf->rect) *outI = (unsigned char *)ibuf->rect + offset; @@ -172,10 +172,10 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], if (outF) { /* sample including outside of edges of image */ - row1 = in->rect_float + in->x * y1 * 4 + 4 * x1; - row2 = in->rect_float + in->x * y2 * 4 + 4 * x1; - row3 = in->rect_float + in->x * y1 * 4 + 4 * x2; - row4 = in->rect_float + in->x * y2 * 4 + 4 * x2; + row1 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1; + row2 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x1; + row3 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x2; + row4 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x2; outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0]; outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1]; @@ -190,10 +190,10 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], } if (outI) { /* sample including outside of edges of image */ - row1I = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x1; - row2I = (unsigned char *)in->rect + in->x * y2 * 4 + 4 * x1; - row3I = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x2; - row4I = (unsigned char *)in->rect + in->x * y2 * 4 + 4 * x2; + row1I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1; + row2I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x1; + row3I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x2; + row4I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x2; /* need to add 0.5 to avoid rounding down (causes darken with the smear brush) * tested with white images and this should not wrap back to zero */ @@ -256,14 +256,14 @@ void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float } } else { - dataI = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x1; + dataI = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1; if (outI) { outI[0] = dataI[0]; outI[1] = dataI[1]; outI[2] = dataI[2]; outI[3] = dataI[3]; } - dataF = in->rect_float + in->x * y1 * 4 + 4 * x1; + dataF = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1; if (outF) { outF[0] = dataF[0]; outF[1] = dataF[1]; @@ -273,6 +273,41 @@ void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float } } + +void nearest_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) +{ + const float *dataF; + unsigned char *dataI; + int y, x; + + /* ImBuf in must have a valid rect or rect_float, assume this is already checked */ + + x = (int) floor(u); + y = (int) floor(v); + + x = x % in->x; + y = y % in->y; + + /* wrap interpolation pixels - main difference from nearest_interpolation_color */ + if (x < 0) x += in->x; + if (y < 0) y += in->y; + + dataI = (unsigned char *)in->rect + ((size_t)in->x) * y * 4 + 4 * x; + if (outI) { + outI[0] = dataI[0]; + outI[1] = dataI[1]; + outI[2] = dataI[2]; + outI[3] = dataI[3]; + } + dataF = in->rect_float + ((size_t)in->x) * y * 4 + 4 * x; + if (outF) { + outF[0] = dataF[0]; + outF[1] = dataF[1]; + outF[2] = dataF[2]; + outF[3] = dataF[3]; + } +} + void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) { unsigned char *outI = NULL; -- cgit v1.2.3