This fixes a commit from Peter, revision 12931, Dec 17 2007
He added quick image scaling code, derived from ppmqscale, 
http://libdv.sf.net

This implementation gave ugly banding. especially visible on
dark colors or byte images with very close colors.

Solution is to add correct rounding, seems to me normal for such
fixed point magic. Optimizing code and keeping quality is tricky
dudes! Results for scaling down in sequencer were bad for over a
year (2.47 and 2.48 both wrong).
This commit is contained in:
Ton Roosendaal 2009-04-29 11:20:07 +00:00
parent 32b70e333f
commit 988fbb88dc
1 changed files with 17 additions and 16 deletions

View File

@ -609,34 +609,35 @@ static void shrink_picture_byte(
w = (weight1y * weight1x) >> 16;
dst_line1[x].r += (line[0] * w) >> 16;
dst_line1[x].g += (line[1] * w) >> 16;
dst_line1[x].b += (line[2] * w) >> 16;
dst_line1[x].a += (line[3] * w) >> 16;
/* ensure correct rounding, without this you get ugly banding (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;
dst_line1[x].a += (line[3] * w + 32767) >> 16;
dst_line1[x].weight += w;
w = (weight2y * weight1x) >> 16;
dst_line2[x].r += (line[0] * w) >> 16;
dst_line2[x].g += (line[1] * w) >> 16;
dst_line2[x].b += (line[2] * w) >> 16;
dst_line2[x].a += (line[3] * w) >> 16;
dst_line2[x].r += (line[0] * w + 32767) >> 16;
dst_line2[x].g += (line[1] * w + 32767) >> 16;
dst_line2[x].b += (line[2] * w + 32767) >> 16;
dst_line2[x].a += (line[3] * w + 32767) >> 16;
dst_line2[x].weight += w;
w = (weight1y * weight2x) >> 16;
dst_line1[x+1].r += (line[0] * w) >> 16;
dst_line1[x+1].g += (line[1] * w) >> 16;
dst_line1[x+1].b += (line[2] * w) >> 16;
dst_line1[x+1].a += (line[3] * w) >> 16;
dst_line1[x+1].r += (line[0] * w + 32767) >> 16;
dst_line1[x+1].g += (line[1] * w + 32767) >> 16;
dst_line1[x+1].b += (line[2] * w + 32767) >> 16;
dst_line1[x+1].a += (line[3] * w + 32767) >> 16;
dst_line1[x+1].weight += w;
w = (weight2y * weight2x) >> 16;
dst_line2[x+1].r += (line[0] * w) >> 16;
dst_line2[x+1].g += (line[1] * w) >> 16;
dst_line2[x+1].b += (line[2] * w) >> 16;
dst_line2[x+1].a += (line[3] * w) >> 16;
dst_line2[x+1].r += (line[0] * w + 32767) >> 16;
dst_line2[x+1].g += (line[1] * w + 32767) >> 16;
dst_line2[x+1].b += (line[2] * w + 32767) >> 16;
dst_line2[x+1].a += (line[3] * w + 32767) >> 16;
dst_line2[x+1].weight += w;
x_dst += dx_dst;