595
596
y_counter = 65536;
596
597
for (y_src = 0; y_src < src_height; y_src++) {
597
598
unsigned char* line = src + y_src * 4 * src_width;
598
uintptr_t weight1y = 65536 - (y_dst & 0xffff);
599
uintptr_t weight2y = 65536 - weight1y;
599
uintptr_t weight1y = 65535 - (y_dst & 0xffff);
600
uintptr_t weight2y = 65535 - weight1y;
601
602
for (x_src = 0; x_src < src_width; x_src++) {
602
uintptr_t weight1x = 65536 - (x_dst & 0xffff);
603
uintptr_t weight2x = 65536 - weight1x;
603
uintptr_t weight1x = 65535 - (x_dst & 0xffff);
604
uintptr_t weight2x = 65535 - weight1x;
605
606
uintptr_t x = x_dst >> 16;
609
610
w = (weight1y * weight1x) >> 16;
611
dst_line1[x].r += (line[0] * w) >> 16;
612
dst_line1[x].g += (line[1] * w) >> 16;
613
dst_line1[x].b += (line[2] * w) >> 16;
614
dst_line1[x].a += (line[3] * w) >> 16;
612
/* ensure correct rounding, without this you get ugly banding, or too low color values (ton) */
613
dst_line1[x].r += (line[0] * w + 32767) >> 16;
614
dst_line1[x].g += (line[1] * w + 32767) >> 16;
615
dst_line1[x].b += (line[2] * w + 32767) >> 16;
616
dst_line1[x].a += (line[3] * w + 32767) >> 16;
615
617
dst_line1[x].weight += w;
617
619
w = (weight2y * weight1x) >> 16;
619
dst_line2[x].r += (line[0] * w) >> 16;
620
dst_line2[x].g += (line[1] * w) >> 16;
621
dst_line2[x].b += (line[2] * w) >> 16;
622
dst_line2[x].a += (line[3] * w) >> 16;
621
dst_line2[x].r += (line[0] * w + 32767) >> 16;
622
dst_line2[x].g += (line[1] * w + 32767) >> 16;
623
dst_line2[x].b += (line[2] * w + 32767) >> 16;
624
dst_line2[x].a += (line[3] * w + 32767) >> 16;
623
625
dst_line2[x].weight += w;
625
627
w = (weight1y * weight2x) >> 16;
627
dst_line1[x+1].r += (line[0] * w) >> 16;
628
dst_line1[x+1].g += (line[1] * w) >> 16;
629
dst_line1[x+1].b += (line[2] * w) >> 16;
630
dst_line1[x+1].a += (line[3] * w) >> 16;
629
dst_line1[x+1].r += (line[0] * w + 32767) >> 16;
630
dst_line1[x+1].g += (line[1] * w + 32767) >> 16;
631
dst_line1[x+1].b += (line[2] * w + 32767) >> 16;
632
dst_line1[x+1].a += (line[3] * w + 32767) >> 16;
631
633
dst_line1[x+1].weight += w;
633
635
w = (weight2y * weight2x) >> 16;
635
dst_line2[x+1].r += (line[0] * w) >> 16;
636
dst_line2[x+1].g += (line[1] * w) >> 16;
637
dst_line2[x+1].b += (line[2] * w) >> 16;
638
dst_line2[x+1].a += (line[3] * w) >> 16;
637
dst_line2[x+1].r += (line[0] * w + 32767) >> 16;
638
dst_line2[x+1].g += (line[1] * w + 32767) >> 16;
639
dst_line2[x+1].b += (line[2] * w + 32767) >> 16;
640
dst_line2[x+1].a += (line[3] * w + 32767) >> 16;
639
641
dst_line2[x+1].weight += w;
646
648
y_counter -= dy_dst;
647
649
if (y_counter < 0) {
649
652
struct scale_outpix_byte * temp;
651
654
y_counter += 65536;
653
656
for (x=0; x < dst_width; x++) {
654
uintptr_t f = 0x80000000UL
655
/ dst_line1[x].weight;
656
*dst++ = (dst_line1[x].r * f) >> 15;
657
*dst++ = (dst_line1[x].g * f) >> 15;
658
*dst++ = (dst_line1[x].b * f) >> 15;
659
*dst++ = (dst_line1[x].a * f) >> 15;
657
uintptr_t f = 0x80000000UL / dst_line1[x].weight;
658
*dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val;
659
*dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val;
660
*dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val;
661
*dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val;
661
663
memset(dst_line1, 0, dst_width *
662
664
sizeof(struct scale_outpix_byte));
668
670
if (dst - dst_begin < dst_width * dst_height * 4) {
670
673
for (x = 0; x < dst_width; x++) {
671
674
uintptr_t f = 0x80000000UL / dst_line1[x].weight;
672
*dst++ = (dst_line1[x].r * f) >> 15;
673
*dst++ = (dst_line1[x].g * f) >> 15;
674
*dst++ = (dst_line1[x].b * f) >> 15;
675
*dst++ = (dst_line1[x].a * f) >> 15;
675
*dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val;
676
*dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val;
677
*dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val;
678
*dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val;
678
681
MEM_freeN(dst_line1);
910
913
Should be comparable in speed to the ImBuf ..._fast functions at least
911
914
for byte-buffers.
916
NOTE: disabled, due to inacceptable inaccuracy and quality loss, see bug #18609 (ton)
914
919
static int q_scale_linear_interpolation(
915
920
struct ImBuf *ibuf, int newx, int newy)
1582
1587
scalefast_Z_ImBuf(ibuf, newx, newy);
1584
1589
/* try to scale common cases in a fast way */
1585
if (q_scale_linear_interpolation(ibuf, newx, newy)) {
1590
/* disabled, quality loss is inacceptable, see report #18609 (ton) */
1591
if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) {