From b1a393e8156d9020aaefb25cf5cf8fb4103cea75 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 18 May 2009 10:34:26 +0000 Subject: 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. :) --- source/blender/imbuf/intern/scaling.c | 36 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'source/blender/imbuf') diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index b308915cd62..1ccdad05deb 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -596,12 +596,12 @@ static void shrink_picture_byte( 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 @@ static void shrink_picture_byte( 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 @@ static void shrink_picture_byte( 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 @@ static void shrink_picture_byte( } } 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 @@ static void q_scale_float(float* in, float* out, int in_width, 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 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy) 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; } -- cgit v1.2.3