[Bf-blender-cvs] [2909975] master: Fix T44541 aka gigapixel image render support in blender.

Antony Riakiotakis noreply at git.blender.org
Thu Apr 30 12:11:38 CEST 2015


Commit: 290997538590d54387602a37879ad4cffbc311da
Author: Antony Riakiotakis
Date:   Thu Apr 30 12:10:58 2015 +0200
Branches: master
https://developer.blender.org/rB290997538590d54387602a37879ad4cffbc311da

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).

===================================================================

M	source/blender/editors/screen/glutil.c
M	source/blender/imbuf/intern/allocimbuf.c
M	source/blender/imbuf/intern/colormanagement.c
M	source/blender/imbuf/intern/divers.c
M	source/blender/imbuf/intern/imageprocess.c
M	source/blender/imbuf/intern/rectop.c
M	source/blender/render/intern/source/render_result.c

===================================================================

diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index c7421aa..8a8b61e 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -579,25 +579,25 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
 				continue;
 			
 			if (type == GL_FLOAT) {
-				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_FLOAT, &f_rect[subpart_y * offset_y * img_w * components + subpart_x * offset_x * components]);
+				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]);
 				
 				/* add an extra border of pixels so linear looks ok at edges of full image. */
 				if (subpart_w < tex_w)
-					glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_FLOAT, &f_rect[subpart_y * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
+					glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
 				if (subpart_h < tex_h)
-					glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_FLOAT, &f_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]);
+					glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_FLOAT, &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]);
 				if (subpart_w < tex_w && subpart_h < tex_h)
-					glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_FLOAT, &f_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
+					glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_FLOAT, &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
 			}
 			else {
-				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[subpart_y * offset_y * img_w * components + subpart_x * offset_x * components]);
+				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]);
 				
 				if (subpart_w < tex_w)
-					glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[subpart_y * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
+					glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
 				if (subpart_h < tex_h)
-					glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]);
+					glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]);
 				if (subpart_w < tex_w && subpart_h < tex_h)
-					glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
+					glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
 			}
 
 			glEnable(GL_TEXTURE_2D);
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index b28d19e..18c3aeb 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -465,10 +465,10 @@ ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
 	if (ibuf2 == NULL) return NULL;
 
 	if (flags & IB_rect)
-		memcpy(ibuf2->rect, ibuf1->rect, x * y * sizeof(int));
+		memcpy(ibuf2->rect, ibuf1->rect, ((size_t)x) * y * sizeof(int));
 	
 	if (flags & IB_rectfloat)
-		memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels * x * y * sizeof(float));
+		memcpy(ibuf2->rect_float, ibuf1->rect_float, ((size_t)ibuf1->channels) * x * y * sizeof(float));
 
 	if (ibuf1->encodedbuffer) {
 		ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 20baa16..d6fdcad 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -1306,8 +1306,8 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
 	float dither = ibuf->dither;
 	bool is_data = (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) != 0;
 
-	int offset = channels * start_line * ibuf->x;
-	int display_buffer_byte_offset = DISPLAY_BUFFER_CHANNELS * start_line * ibuf->x;
+	size_t offset = ((size_t)channels) * start_line * ibuf->x;
+	size_t display_buffer_byte_offset = ((size_t)DISPLAY_BUFFER_CHANNELS) * start_line * ibuf->x;
 
 	memset(handle, 0, sizeof(DisplayBufferThread));
 
@@ -1344,7 +1344,7 @@ static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle,
 	int channels = handle->channels;
 	int width = handle->width;
 
-	int buffer_size = channels * width * height;
+	size_t buffer_size = ((size_t)channels) * width * height;
 
 	bool is_data = handle->is_data;
 	bool is_data_display = handle->cm_processor->is_data_result;
@@ -1357,11 +1357,11 @@ static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle,
 
 		float *fp;
 		unsigned char *cp;
-		int i;
+		size_t i;
 
 		/* first convert byte buffer to float, keep in image space */
 		for (i = 0, fp = linear_buffer, cp = byte_buffer;
-		     i < width * height;
+		     i < ((size_t)width) * height;
 		     i++, fp += channels, cp += channels)
 		{
 			if (channels == 3) {
@@ -1440,7 +1440,7 @@ static void *do_display_buffer_apply_thread(void *handle_v)
 	}
 	else {
 		bool is_straight_alpha, predivide;
-		float *linear_buffer = MEM_mallocN(channels * width * height * sizeof(float),
+		float *linear_buffer = MEM_mallocN(((size_t)channels) * width * height * sizeof(float),
 		                                   "color conversion linear buffer");
 
 		display_buffer_apply_get_linear_buffer(handle, height, linear_buffer, &is_straight_alpha);
@@ -1467,14 +1467,14 @@ static void *do_display_buffer_apply_thread(void *handle_v)
 		}
 
 		if (display_buffer) {
-			memcpy(display_buffer, linear_buffer, width * height * channels * sizeof(float));
+			memcpy(display_buffer, linear_buffer, ((size_t)width) * height * channels * sizeof(float));
 
 			if (is_straight_alpha && channels == 4) {
-				int i;
+				size_t i;
 				float *fp;
 
 				for (i = 0, fp = display_buffer;
-				     i < width * height;
+				     i < ((size_t)width) * height;
 				     i++, fp += channels)
 				{
 					straight_to_premul_v4(fp);
@@ -2959,7 +2959,7 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo
 
 		for (y = 0; y < height; y++) {
 			for (x = 0; x < width; x++) {
-				float *pixel = buffer + channels * (y * width + x);
+				float *pixel = buffer + channels * (((size_t)y) * width + x);
 
 				curve_mapping_apply_pixel(cm_processor->curve_mapping, pixel, channels);
 			}
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 3417fe2..455b78b 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -184,16 +184,16 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
 
 		if (channels_from == 1) {
 			/* single channel input */
-			const float *from = rect_from + stride_from * y;
-			uchar *to = rect_to + stride_to * y * 4;
+			const float *from = rect_from + ((size_t)stride_from) * y;
+			uchar *to = rect_to + ((size_t)stride_to) * y * 4;
 
 			for (x = 0; x < width; x++, from++, to += 4)
 				to[0] = to[1] = to[2] = to[3] = FTOCHAR(from[0]);
 		}
 		else if (channels_from == 3) {
 			/* RGB input */
-			const float *from = rect_from + stride_from * y * 3;
-			uchar *to = rect_to + stride_to * y * 4;
+			const float *from = rect_from + ((size_t)stride_from) * y * 3;
+			uchar *to = rect_to + ((size_t)stride_to) * y * 4;
 
 			if (profile_to == profile_from) {
 				/* no color space conversion */
@@ -221,8 +221,8 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
 		}
 		else if (channels_from == 4) {
 			/* RGBA input */
-			const float *from = rect_from + stride_from * y * 4;
-			uchar *to = rect_to + stride_to * y * 4;
+			const float *from = rect_from + ((size_t)stride_from) * y * 4;
+			uchar *to = rect_to + ((size_t)stride_to) * y * 4;
 
 			if (profile_to == profile_from) {
 				float straight[4];
@@ -334,8 +334,8 @@ void IMB_buffer_byte_from_float_mask(uchar *rect_to, const float *rect_from,
 
 		if (channels_from == 1) {
 			/* single channel input */
-			const float *from = rect_from + stride_from * y;
-			uchar *to = rect_to + stride_to * y * 4;
+			const float *from = rect_from + ((size_t)stride_from) * y;
+			uchar *to = rect_to + ((size_t)stride_to) * y * 4;
 
 			for (x = 0; x < width; x++, from++, to += 4)
 				if (*mask++ == FILTER_MASK_USED)
@@ -343,8 +343,8 @@ void IMB_buffer_byte_from_float_mask(uchar *rect_to, const float *rect_from,
 		}
 		else if (channels_from == 3) {
 			/* RGB input */
-			const float *from = rect_from + stride_from * y * 3;
-			uchar *to = rect_to + stride_to * y * 4;
+			const float *from = rect_from + ((size_t)stride_from) * y * 3;
+			uchar *to = rect_to + ((size_t)stride_to) * y * 4;
 
 			for (x = 0; x < width; x++, from += 3, to += 4) {
 				if (*mask++ == FILTER_MASK_USED) {
@@ -355,8 +355,8 @@ void IMB_buffer_byte_from_float_mask(uchar *rec

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list