[Bf-blender-cvs] [2f2f7c0] master: Fix T44882, color picker in texpainting doing linear interpolation even when mipmap is off.

Antony Riakiotakis noreply at git.blender.org
Fri May 29 13:38:35 CEST 2015


Commit: 2f2f7c0e875b2cfcd7b5caa0af532401deac67be
Author: Antony Riakiotakis
Date:   Fri May 29 13:38:20 2015 +0200
Branches: master
https://developer.blender.org/rB2f2f7c0e875b2cfcd7b5caa0af532401deac67be

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

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

M	source/blender/editors/sculpt_paint/paint_utils.c
M	source/blender/imbuf/IMB_imbuf.h
M	source/blender/imbuf/intern/imageprocess.c

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

diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index f1edf8a..bdf11de 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -487,12 +487,15 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
 							if (u < 0.0f) u += 1.0f;
 							if (v < 0.0f) v += 1.0f;
 							
-							u = u * ibuf->x - 0.5f;
-							v = v * ibuf->y - 0.5f;
+							u = u * ibuf->x;
+							v = v * ibuf->y;
 							
 							if (ibuf->rect_float) {
 								float rgba_f[4];
-								bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v);
+								if (U.gameflags & USER_DISABLE_MIPMAP)
+									nearest_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v);
+								else
+									bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v);
 								straight_to_premul_v4(rgba_f);
 								if (use_palette) {
 									linearrgb_to_srgb_v3_v3(color->rgb, rgba_f);
@@ -504,7 +507,10 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
 							}
 							else {
 								unsigned char rgba[4];
-								bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v);
+								if (U.gameflags & USER_DISABLE_MIPMAP)
+									nearest_interpolation_color_wrap(ibuf, rgba, NULL, u, v);
+								else
+									bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v);
 								if (use_palette) {
 									rgb_uchar_to_float(color->rgb, rgba);
 								}
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 4a2d05b..ed16c67 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -467,6 +467,7 @@ void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float
 
 void bicubic_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
 void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void nearest_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
 void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
 void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
 
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 9021946..d44f0dc 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;




More information about the Bf-blender-cvs mailing list