[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56966] trunk/blender/source/blender: Fix #35469: image editor smear and soften paint tools not working correct for

Brecht Van Lommel brechtvanlommel at pandora.be
Wed May 22 22:06:52 CEST 2013


Revision: 56966
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56966
Author:   blendix
Date:     2013-05-22 20:06:50 +0000 (Wed, 22 May 2013)
Log Message:
-----------
Fix #35469: image editor smear and soften paint tools not working correct for
float images, was not taking premul/straight convention into account properly.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c
    trunk/blender/source/blender/imbuf/intern/rectop.c

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c	2013-05-22 19:21:42 UTC (rev 56965)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c	2013-05-22 20:06:50 UTC (rev 56966)
@@ -68,25 +68,7 @@
 /* Brush Painting for 2D image editor */
 
 /* Defines and Structs */
-/* FTOCHAR as inline function */
-BLI_INLINE unsigned char f_to_char(const float val)
-{
-	return FTOCHAR(val);
-}
-#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f)  {                                   \
-	(c)[0] = f_to_char((f)[0]);                                               \
-	(c)[1] = f_to_char((f)[1]);                                               \
-	(c)[2] = f_to_char((f)[2]);                                               \
-} (void)0
 
-#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c)  {                                   \
-	(f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]);                                  \
-	(f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]);                                  \
-	(f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]);                                  \
-} (void)0
-
-#define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
-
 typedef struct BrushPainterCache {
 	int size;                    /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
 
@@ -662,7 +644,7 @@
 }
 
 /* keep these functions in sync */
-static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_torus, float r_rgb[3])
+static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_torus, float r_rgb[4])
 {
 	if (is_torus) {
 		x %= ibuf->x;
@@ -673,14 +655,14 @@
 
 	if (ibuf->rect_float) {
 		float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
-		IMAPAINT_FLOAT_RGB_COPY(r_rgb, rrgbf);
+		copy_v4_v4(r_rgb, rrgbf);
 	}
 	else {
-		char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
-		IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb);
+		unsigned char *rrgb = (unsigned char *)ibuf->rect + (ibuf->x * y + x) * 4;
+		straight_uchar_to_premul_float(r_rgb, rrgb);
 	}
 }
-static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3])
+static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[4])
 {
 	if (is_torus) {
 		x %= ibuf->x;
@@ -691,17 +673,24 @@
 
 	if (ibuf->rect_float) {
 		float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
-		IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
+		float map_alpha = (rgb[3] == 0.0f)? rrgbf[3] : rrgbf[3] / rgb[3];
+
+		mul_v3_v3fl(rrgbf, rgb, map_alpha);
 	}
 	else {
-		char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
-		IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb);
+		unsigned char straight[4];
+		unsigned char *rrgb = (unsigned char *)ibuf->rect + (ibuf->x * y + x) * 4;
+
+		premul_float_to_straight_uchar(straight, rgb);
+		rrgb[0] = straight[0];
+		rrgb[1] = straight[1];
+		rrgb[2] = straight[2];
 	}
 }
 
 static int paint_2d_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, float *outrgb, short torus)
 {
-	float inrgb[3];
+	float inrgb[4];
 
 	// XXX: signed unsigned mismatch
 	if ((x >= (unsigned int)(ibuf->x)) || (y >= (unsigned int)(ibuf->y))) {
@@ -712,9 +701,7 @@
 		paint_2d_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
 	}
 
-	outrgb[0] += inrgb[0];
-	outrgb[1] += inrgb[1];
-	outrgb[2] += inrgb[2];
+	add_v4_v4(outrgb, inrgb);
 
 	return 1;
 }
@@ -723,7 +710,7 @@
 {
 	int x, y, count, xi, yi, xo, yo;
 	int out_off[2], in_off[2], dim[2];
-	float outrgb[3];
+	float outrgb[4];
 
 	dim[0] = ibufb->x;
 	dim[1] = ibufb->y;
@@ -759,7 +746,7 @@
 			count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi, outrgb, is_torus);
 			count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi + 1, outrgb, is_torus);
 
-			mul_v3_fl(outrgb, 1.0f / (float)count);
+			mul_v4_fl(outrgb, 1.0f / (float)count);
 
 			/* write into brush buffer */
 			xo = out_off[0] + x;
@@ -842,10 +829,10 @@
 	ImBuf *clonebuf = IMB_allocImBuf(w, h, ibufb->planes, ibufb->flags);
 
 	IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
-	IMB_rectblend(clonebuf, clonebuf, ibuf, NULL, NULL, 0, destx, desty, destx, desty, srcx, srcy, w, h,
-	              IMB_BLEND_COPY_RGB);
 	IMB_rectblend(clonebuf, clonebuf, ibufb, NULL, NULL, 0, destx, desty, destx, desty, destx, desty, w, h,
 	              IMB_BLEND_COPY_ALPHA);
+	IMB_rectblend(clonebuf, clonebuf, ibuf, NULL, NULL, 0, destx, desty, destx, desty, srcx, srcy, w, h,
+	              IMB_BLEND_COPY_RGB);
 
 	return clonebuf;
 }

Modified: trunk/blender/source/blender/imbuf/intern/rectop.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/rectop.c	2013-05-22 19:21:42 UTC (rev 56965)
+++ trunk/blender/source/blender/imbuf/intern/rectop.c	2013-05-22 20:06:50 UTC (rev 56966)
@@ -321,9 +321,11 @@
 				drf = drectf;
 				srf = srectf;
 				for (x = width; x > 0; x--, drf += 4, srf += 4) {
-					drf[0] = srf[0];
-					drf[1] = srf[1];
-					drf[2] = srf[2];
+					float map_alpha = (srf[3] == 0.0f)? drf[3] : drf[3] / srf[3];
+
+					drf[0] = srf[0] * map_alpha;
+					drf[1] = srf[1] * map_alpha;
+					drf[2] = srf[2] * map_alpha;
 				}
 				drectf += destskip * 4;
 				srectf += srcskip * 4;




More information about the Bf-blender-cvs mailing list