[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20257] trunk/blender/source/blender/imbuf /intern/scaling.c: Bugfix #18733 & #18609 (revisited)

Ton Roosendaal ton at blender.org
Mon May 18 12:34:26 CEST 2009


Revision: 20257
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20257
Author:   ton
Date:     2009-05-18 12:34:26 +0200 (Mon, 18 May 2009)

Log Message:
-----------
Bugfix #18733 & #18609 (revisited)

New imbuf scaling code, advertised as "quick and quality" gave
inacceptable noise and rounding errors. 

Check this bugreport for images that show it well:
http://projects.blender.org/tracker/?func=detail&atid=125&aid=18609&group_id=9

For release, better disable this code and fall back on perfectly
working old code. :)

Modified Paths:
--------------
    trunk/blender/source/blender/imbuf/intern/scaling.c

Modified: trunk/blender/source/blender/imbuf/intern/scaling.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/scaling.c	2009-05-18 10:29:37 UTC (rev 20256)
+++ trunk/blender/source/blender/imbuf/intern/scaling.c	2009-05-18 10:34:26 UTC (rev 20257)
@@ -596,12 +596,12 @@
 	y_counter = 65536;
 	for (y_src = 0; y_src < src_height; y_src++) {
 		unsigned char* line = src + y_src * 4 * src_width;
-		uintptr_t weight1y = 65536 - (y_dst & 0xffff);
-		uintptr_t weight2y = 65536 - weight1y;
+		uintptr_t weight1y = 65535 - (y_dst & 0xffff);
+		uintptr_t weight2y = 65535 - weight1y;
 		x_dst = 0;
 		for (x_src = 0; x_src < src_width; x_src++) {
-			uintptr_t weight1x = 65536 - (x_dst & 0xffff);
-			uintptr_t weight2x = 65536 - weight1x;
+			uintptr_t weight1x = 65535 - (x_dst & 0xffff);
+			uintptr_t weight2x = 65535 - weight1x;
 
 			uintptr_t x = x_dst >> 16;
 
@@ -609,7 +609,7 @@
 
 			w = (weight1y * weight1x) >> 16;
 
-			/* ensure correct rounding, without this you get ugly banding (ton) */
+			/* ensure correct rounding, without this you get ugly banding, or too low color values (ton) */
 			dst_line1[x].r += (line[0] * w + 32767) >> 16;
 			dst_line1[x].g += (line[1] * w + 32767) >> 16;
 			dst_line1[x].b += (line[2] * w + 32767) >> 16;
@@ -647,18 +647,18 @@
 		y_dst += dy_dst;
 		y_counter -= dy_dst;
 		if (y_counter < 0) {
+			int val;
 			uintptr_t x;
 			struct scale_outpix_byte * temp;
 
 			y_counter += 65536;
 			
 			for (x=0; x < dst_width; x++) {
-				uintptr_t f = 0x80000000UL
-					/ dst_line1[x].weight;
-				*dst++ = (dst_line1[x].r * f) >> 15;
-				*dst++ = (dst_line1[x].g * f) >> 15;
-				*dst++ = (dst_line1[x].b * f) >> 15;
-				*dst++ = (dst_line1[x].a * f) >> 15;
+				uintptr_t f =  0x80000000UL / dst_line1[x].weight;
+				*dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val;
+				*dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val;
+				*dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val;
+				*dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val;
 			}
 			memset(dst_line1, 0, dst_width *
 			       sizeof(struct scale_outpix_byte));
@@ -668,13 +668,14 @@
 		}
 	}
 	if (dst - dst_begin < dst_width * dst_height * 4) {
+		int val;
 		uintptr_t x;
 		for (x = 0; x < dst_width; x++) {
 			uintptr_t f = 0x80000000UL / dst_line1[x].weight;
-			*dst++ = (dst_line1[x].r * f) >> 15;
-			*dst++ = (dst_line1[x].g * f) >> 15;
-			*dst++ = (dst_line1[x].b * f) >> 15;
-			*dst++ = (dst_line1[x].a * f) >> 15;
+			*dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val;
+			*dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val;
+			*dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val;
+			*dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val;
 		}
 	}
 	MEM_freeN(dst_line1);
@@ -912,6 +913,8 @@
    Should be comparable in speed to the ImBuf ..._fast functions at least 
    for byte-buffers.
 
+   NOTE: disabled, due to inacceptable inaccuracy and quality loss, see bug #18609 (ton)
+
 */
 static int q_scale_linear_interpolation(
 	struct ImBuf *ibuf, int newx, int newy)
@@ -1584,7 +1587,8 @@
 	scalefast_Z_ImBuf(ibuf, newx, newy);
 
 	/* try to scale common cases in a fast way */
-	if (q_scale_linear_interpolation(ibuf, newx, newy)) {
+	/* disabled, quality loss is inacceptable, see report #18609  (ton) */
+	if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) {
 		return ibuf;
 	}
 





More information about the Bf-blender-cvs mailing list