2 * Image Scaling Functions (4 tap)
3 * Copyright (c) 2005 David A. Schleef <ds@schleef.org>
4 * Copyright (c) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
30 #include "vs_scanline.h"
34 #include <gst/math-compat.h>
38 static int16_t vs_4tap_taps[256][4];
41 vs_4tap_func (double x)
55 return sin (G_PI * x) / (G_PI * x) * (1 - 0.25 * x * x);
60 return sin (G_PI * x) / (G_PI * x);
71 for (i = 0; i < 256; i++) {
72 a = vs_4tap_func (-1 - i / 256.0);
73 b = vs_4tap_func (0 - i / 256.0);
74 c = vs_4tap_func (1 - i / 256.0);
75 d = vs_4tap_func (2 - i / 256.0);
78 vs_4tap_taps[i][0] = rint ((1 << SHIFT) * (a / sum));
79 vs_4tap_taps[i][1] = rint ((1 << SHIFT) * (b / sum));
80 vs_4tap_taps[i][2] = rint ((1 << SHIFT) * (c / sum));
81 vs_4tap_taps[i][3] = rint ((1 << SHIFT) * (d / sum));
87 vs_scanline_resample_4tap_Y (uint8_t * dest, uint8_t * src,
88 int n, int src_width, int *xacc, int increment)
97 for (i = 0; i < n; i++) {
99 x = (acc & 0xff00) >> 8;
100 if (j - 1 >= 0 && j + 2 < src_width) {
101 y = vs_4tap_taps[x][0] * src[MAX (j - 1, 0)];
102 y += vs_4tap_taps[x][1] * src[j];
103 y += vs_4tap_taps[x][2] * src[j + 1];
104 y += vs_4tap_taps[x][3] * src[j + 2];
106 y = vs_4tap_taps[x][0] * src[CLAMP (j - 1, 0, src_width - 1)];
107 y += vs_4tap_taps[x][1] * src[CLAMP (j, 0, src_width - 1)];
108 y += vs_4tap_taps[x][2] * src[CLAMP (j + 1, 0, src_width - 1)];
109 y += vs_4tap_taps[x][3] * src[CLAMP (j + 2, 0, src_width - 1)];
111 y += (1 << (SHIFT - 1));
112 dest[i] = CLAMP (y >> SHIFT, 0, 255);
119 vs_scanline_merge_4tap_Y (uint8_t * dest, uint8_t * src1, uint8_t * src2,
120 uint8_t * src3, uint8_t * src4, int n, int acc)
126 acc = (acc >> 8) & 0xff;
127 a = vs_4tap_taps[acc][0];
128 b = vs_4tap_taps[acc][1];
129 c = vs_4tap_taps[acc][2];
130 d = vs_4tap_taps[acc][3];
131 for (i = 0; i < n; i++) {
136 y += (1 << (SHIFT - 1));
137 dest[i] = CLAMP (y >> SHIFT, 0, 255);
143 vs_image_scale_4tap_Y (const VSImage * dest, const VSImage * src,
154 if (dest->height == 1)
157 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
159 if (dest->width == 1)
162 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
165 for (i = 0; i < 4; i++) {
167 vs_scanline_resample_4tap_Y (tmpbuf + i * dest->width,
168 src->pixels + CLAMP (i, 0, src->height - 1) * src->stride, dest->width,
169 src->width, &xacc, x_increment);
173 for (i = 0; i < dest->height; i++) {
174 uint8_t *t0, *t1, *t2, *t3;
180 if (k + 3 < src->height) {
182 vs_scanline_resample_4tap_Y (tmpbuf + ((k + 3) & 3) * dest->width,
183 src->pixels + (k + 3) * src->stride,
184 dest->width, src->width, &xacc, x_increment);
188 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->width;
189 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->width;
190 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->width;
191 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->width;
192 vs_scanline_merge_4tap_Y (dest->pixels + i * dest->stride,
193 t0, t1, t2, t3, dest->width, yacc & 0xffff);
200 vs_scanline_resample_4tap_Y16 (uint8_t * dest, uint8_t * src,
201 int n, int src_width, int *xacc, int increment)
208 uint16_t *d = (uint16_t *) dest, *s = (uint16_t *) src;
211 for (i = 0; i < n; i++) {
213 x = (acc & 0xff00) >> 8;
214 if (j - 1 >= 0 && j + 2 < src_width) {
215 y = vs_4tap_taps[x][0] * s[MAX (j - 1, 0)];
216 y += vs_4tap_taps[x][1] * s[j];
217 y += vs_4tap_taps[x][2] * s[j + 1];
218 y += vs_4tap_taps[x][3] * s[j + 2];
220 y = vs_4tap_taps[x][0] * s[CLAMP (j - 1, 0, src_width - 1)];
221 y += vs_4tap_taps[x][1] * s[CLAMP (j, 0, src_width - 1)];
222 y += vs_4tap_taps[x][2] * s[CLAMP (j + 1, 0, src_width - 1)];
223 y += vs_4tap_taps[x][3] * s[CLAMP (j + 2, 0, src_width - 1)];
225 y += (1 << (SHIFT - 1));
226 d[i] = CLAMP (y >> SHIFT, 0, 65535);
233 vs_scanline_merge_4tap_Y16 (uint8_t * dest, uint8_t * src1, uint8_t * src2,
234 uint8_t * src3, uint8_t * src4, int n, int acc)
239 uint16_t *de = (uint16_t *) dest, *s1 = (uint16_t *) src1;
240 uint16_t *s2 = (uint16_t *) src2, *s3 = (uint16_t *) src3;
241 uint16_t *s4 = (uint16_t *) src4;
243 acc = (acc >> 8) & 0xff;
244 a = vs_4tap_taps[acc][0];
245 b = vs_4tap_taps[acc][1];
246 c = vs_4tap_taps[acc][2];
247 d = vs_4tap_taps[acc][3];
248 for (i = 0; i < n; i++) {
253 y += (1 << (SHIFT - 1));
254 de[i] = CLAMP (y >> SHIFT, 0, 65535);
260 vs_image_scale_4tap_Y16 (const VSImage * dest, const VSImage * src,
271 if (dest->height == 1)
274 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
276 if (dest->width == 1)
279 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
282 for (i = 0; i < 4; i++) {
284 vs_scanline_resample_4tap_Y16 (tmpbuf + i * dest->stride,
285 src->pixels + CLAMP (i, 0, src->height - 1) * src->stride, dest->width,
286 src->width, &xacc, x_increment);
290 for (i = 0; i < dest->height; i++) {
291 uint8_t *t0, *t1, *t2, *t3;
297 if (k + 3 < src->height) {
299 vs_scanline_resample_4tap_Y16 (tmpbuf + ((k + 3) & 3) * dest->stride,
300 src->pixels + (k + 3) * src->stride,
301 dest->width, src->width, &xacc, x_increment);
305 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride;
306 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride;
307 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride;
308 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride;
309 vs_scanline_merge_4tap_Y16 (dest->pixels + i * dest->stride,
310 t0, t1, t2, t3, dest->width, yacc & 0xffff);
317 vs_scanline_resample_4tap_RGBA (uint8_t * dest, uint8_t * src,
318 int n, int src_width, int *xacc, int increment)
328 for (i = 0; i < n; i++) {
330 x = (acc & 0xffff) >> 8;
332 for (off = 0; off < 4; off++) {
333 if (j - 1 >= 0 && j + 2 < src_width) {
334 y = vs_4tap_taps[x][0] * src[MAX ((j - 1) * 4 + off, 0)];
335 y += vs_4tap_taps[x][1] * src[j * 4 + off];
336 y += vs_4tap_taps[x][2] * src[(j + 1) * 4 + off];
337 y += vs_4tap_taps[x][3] * src[(j + 2) * 4 + off];
339 y = vs_4tap_taps[x][0] *
340 src[CLAMP ((j - 1), 0, src_width - 1) * 4 + off];
341 y += vs_4tap_taps[x][1] *
342 src[CLAMP ((j + 0), 0, src_width - 1) * 4 + off];
343 y += vs_4tap_taps[x][2] *
344 src[CLAMP ((j + 1), 0, src_width - 1) * 4 + off];
345 y += vs_4tap_taps[x][3] *
346 src[CLAMP ((j + 2), 0, src_width - 1) * 4 + off];
348 y += (1 << (SHIFT - 1));
349 dest[i * 4 + off] = CLAMP (y >> SHIFT, 0, 255);
357 vs_scanline_merge_4tap_RGBA (uint8_t * dest, uint8_t * src1, uint8_t * src2,
358 uint8_t * src3, uint8_t * src4, int n, int acc)
365 acc = (acc >> 8) & 0xff;
366 a = vs_4tap_taps[acc][0];
367 b = vs_4tap_taps[acc][1];
368 c = vs_4tap_taps[acc][2];
369 d = vs_4tap_taps[acc][3];
370 for (i = 0; i < n; i++) {
371 for (off = 0; off < 4; off++) {
372 y = a * src1[i * 4 + off];
373 y += b * src2[i * 4 + off];
374 y += c * src3[i * 4 + off];
375 y += d * src4[i * 4 + off];
376 y += (1 << (SHIFT - 1));
377 dest[i * 4 + off] = CLAMP (y >> SHIFT, 0, 255);
383 vs_image_scale_4tap_RGBA (const VSImage * dest, const VSImage * src,
394 if (dest->height == 1)
397 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
399 if (dest->width == 1)
402 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
405 for (i = 0; i < 4; i++) {
407 vs_scanline_resample_4tap_RGBA (tmpbuf + i * dest->stride,
408 src->pixels + CLAMP (i, 0, src->height) * src->stride,
409 dest->width, src->width, &xacc, x_increment);
413 for (i = 0; i < dest->height; i++) {
414 uint8_t *t0, *t1, *t2, *t3;
420 if (k + 3 < src->height) {
422 vs_scanline_resample_4tap_RGBA (tmpbuf + ((k + 3) & 3) * dest->stride,
423 src->pixels + (k + 3) * src->stride,
424 dest->width, src->width, &xacc, x_increment);
428 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride;
429 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride;
430 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride;
431 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride;
432 vs_scanline_merge_4tap_RGBA (dest->pixels + i * dest->stride,
433 t0, t1, t2, t3, dest->width, yacc & 0xffff);
440 vs_scanline_resample_4tap_RGB (uint8_t * dest, uint8_t * src,
441 int n, int src_width, int *xacc, int increment)
451 for (i = 0; i < n; i++) {
453 x = (acc & 0xffff) >> 8;
455 for (off = 0; off < 3; off++) {
456 if (j - 1 >= 0 && j + 2 < src_width) {
457 y = vs_4tap_taps[x][0] * src[MAX ((j - 1) * 3 + off, 0)];
458 y += vs_4tap_taps[x][1] * src[j * 3 + off];
459 y += vs_4tap_taps[x][2] * src[(j + 1) * 3 + off];
460 y += vs_4tap_taps[x][3] * src[(j + 2) * 3 + off];
462 y = vs_4tap_taps[x][0] * src[CLAMP ((j - 1) * 3 + off, 0,
463 3 * (src_width - 1) + off)];
464 y += vs_4tap_taps[x][1] * src[CLAMP (j * 3 + off, 0,
465 3 * (src_width - 1) + off)];
466 y += vs_4tap_taps[x][2] * src[CLAMP ((j + 1) * 3 + off, 0,
467 3 * (src_width - 1) + off)];
468 y += vs_4tap_taps[x][3] * src[CLAMP ((j + 2) * 3 + off, 0,
469 3 * (src_width - 1) + off)];
471 y += (1 << (SHIFT - 1));
472 dest[i * 3 + off] = CLAMP (y >> SHIFT, 0, 255);
480 vs_scanline_merge_4tap_RGB (uint8_t * dest, uint8_t * src1, uint8_t * src2,
481 uint8_t * src3, uint8_t * src4, int n, int acc)
488 acc = (acc >> 8) & 0xff;
489 a = vs_4tap_taps[acc][0];
490 b = vs_4tap_taps[acc][1];
491 c = vs_4tap_taps[acc][2];
492 d = vs_4tap_taps[acc][3];
493 for (i = 0; i < n; i++) {
494 for (off = 0; off < 3; off++) {
495 y = a * src1[i * 3 + off];
496 y += b * src2[i * 3 + off];
497 y += c * src3[i * 3 + off];
498 y += d * src4[i * 3 + off];
499 y += (1 << (SHIFT - 1));
500 dest[i * 3 + off] = CLAMP (y >> SHIFT, 0, 255);
506 vs_image_scale_4tap_RGB (const VSImage * dest, const VSImage * src,
517 if (dest->height == 1)
520 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
522 if (dest->width == 1)
525 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
528 for (i = 0; i < 4; i++) {
530 vs_scanline_resample_4tap_RGB (tmpbuf + i * dest->stride,
531 src->pixels + CLAMP (i, 0, src->height - 1) * src->stride, dest->width,
532 src->width, &xacc, x_increment);
536 for (i = 0; i < dest->height; i++) {
537 uint8_t *t0, *t1, *t2, *t3;
543 if (k + 3 < src->height) {
545 vs_scanline_resample_4tap_RGB (tmpbuf + ((k + 3) & 3) * dest->stride,
546 src->pixels + (k + 3) * src->stride,
547 dest->width, src->width, &xacc, x_increment);
551 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride;
552 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride;
553 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride;
554 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride;
555 vs_scanline_merge_4tap_RGB (dest->pixels + i * dest->stride,
556 t0, t1, t2, t3, dest->width, yacc & 0xffff);
563 vs_scanline_resample_4tap_YUYV (uint8_t * dest, uint8_t * src,
564 int n, int src_width, int *xacc, int increment)
571 int quads = (n + 1) / 2;
572 int last_y = 2 * (src_width - 1);
574 MAX ((2 * (src_width - 1) % 4 ==
575 0) ? 2 * (src_width - 1) + 1 : 2 * (src_width - 1) - 1, 1);
577 MAX ((2 * (src_width - 1) % 4 ==
578 2) ? 2 * (src_width - 1) + 1 : 2 * (src_width - 1) - 1, 1);
581 for (i = 0; i < quads; i++) {
583 x = (acc & 0xffff) >> 8;
585 if (j - 1 >= 0 && j + 2 < src_width) {
586 y = vs_4tap_taps[x][0] * src[MAX (j * 2 + 0 - 2, 0)];
587 y += vs_4tap_taps[x][1] * src[j * 2 + 0];
588 y += vs_4tap_taps[x][2] * src[j * 2 + 0 + 2];
589 y += vs_4tap_taps[x][3] * src[j * 2 + 0 + 4];
591 y = vs_4tap_taps[x][0] * src[CLAMP (j * 2 + 0 - 2, 0, last_y)];
592 y += vs_4tap_taps[x][1] * src[CLAMP (j * 2 + 0, 0, last_y)];
593 y += vs_4tap_taps[x][2] * src[CLAMP (j * 2 + 0 + 2, 0, last_y)];
594 y += vs_4tap_taps[x][3] * src[CLAMP (j * 2 + 0 + 4, 0, last_y)];
596 y += (1 << (SHIFT - 1));
597 dest[i * 4 + 0] = CLAMP (y >> SHIFT, 0, 255);
600 x = (acc & 0x1ffff) >> 9;
602 if (2 * j - 1 >= 0 && 2 * j + 4 < src_width) {
603 y = vs_4tap_taps[x][0] * src[MAX (j * 4 + 1 - 4, 1)];
604 y += vs_4tap_taps[x][1] * src[j * 4 + 1];
605 y += vs_4tap_taps[x][2] * src[j * 4 + 1 + 4];
606 y += vs_4tap_taps[x][3] * src[j * 4 + 1 + 8];
608 y = vs_4tap_taps[x][0] * src[CLAMP (j * 4 + 1 - 4, 1, last_u)];
609 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + 1, 1, last_u)];
610 y += vs_4tap_taps[x][2] * src[CLAMP (j * 4 + 1 + 4, 1, last_u)];
611 y += vs_4tap_taps[x][3] * src[CLAMP (j * 4 + 1 + 8, 1, last_u)];
613 y += (1 << (SHIFT - 1));
614 dest[i * 4 + 1] = CLAMP (y >> SHIFT, 0, 255);
617 if (2 * j - 1 >= 0 && 2 * j + 4 < src_width) {
618 y = vs_4tap_taps[x][0] * src[MAX (j * 4 + 3 - 4, 3)];
619 y += vs_4tap_taps[x][1] * src[j * 4 + 3];
620 y += vs_4tap_taps[x][2] * src[j * 4 + 3 + 4];
621 y += vs_4tap_taps[x][3] * src[j * 4 + 3 + 8];
623 y = vs_4tap_taps[x][0] * src[CLAMP (j * 4 + 3 - 4, 3, last_v)];
624 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + 3, 3, last_v)];
625 y += vs_4tap_taps[x][2] * src[CLAMP (j * 4 + 3 + 4, 3, last_v)];
626 y += vs_4tap_taps[x][3] * src[CLAMP (j * 4 + 3 + 8, 3, last_v)];
628 y += (1 << (SHIFT - 1));
629 dest[i * 4 + 3] = CLAMP (y >> SHIFT, 0, 255);
634 x = (acc & 0xffff) >> 8;
637 if (j - 1 >= 0 && j + 2 < src_width) {
638 y = vs_4tap_taps[x][0] * src[MAX (j * 2 + 0 - 2, 0)];
639 y += vs_4tap_taps[x][1] * src[j * 2 + 0];
640 y += vs_4tap_taps[x][2] * src[j * 2 + 0 + 2];
641 y += vs_4tap_taps[x][3] * src[j * 2 + 0 + 4];
643 y = vs_4tap_taps[x][0] * src[CLAMP (j * 2 + 0 - 2, 0, last_y)];
644 y += vs_4tap_taps[x][1] * src[CLAMP (j * 2 + 0, 0, last_y)];
645 y += vs_4tap_taps[x][2] * src[CLAMP (j * 2 + 0 + 2, 0, last_y)];
646 y += vs_4tap_taps[x][3] * src[CLAMP (j * 2 + 0 + 4, 0, last_y)];
648 y += (1 << (SHIFT - 1));
649 dest[i * 4 + 2] = CLAMP (y >> SHIFT, 0, 255);
657 vs_scanline_merge_4tap_YUYV (uint8_t * dest, uint8_t * src1, uint8_t * src2,
658 uint8_t * src3, uint8_t * src4, int n, int acc)
663 int quads = (n + 1) / 2;
665 acc = (acc >> 8) & 0xff;
666 a = vs_4tap_taps[acc][0];
667 b = vs_4tap_taps[acc][1];
668 c = vs_4tap_taps[acc][2];
669 d = vs_4tap_taps[acc][3];
670 for (i = 0; i < quads; i++) {
671 y = a * src1[i * 4 + 0];
672 y += b * src2[i * 4 + 0];
673 y += c * src3[i * 4 + 0];
674 y += d * src4[i * 4 + 0];
675 y += (1 << (SHIFT - 1));
676 dest[i * 4 + 0] = CLAMP (y >> SHIFT, 0, 255);
678 y = a * src1[i * 4 + 1];
679 y += b * src2[i * 4 + 1];
680 y += c * src3[i * 4 + 1];
681 y += d * src4[i * 4 + 1];
682 y += (1 << (SHIFT - 1));
683 dest[i * 4 + 1] = CLAMP (y >> SHIFT, 0, 255);
686 y = a * src1[i * 4 + 2];
687 y += b * src2[i * 4 + 2];
688 y += c * src3[i * 4 + 2];
689 y += d * src4[i * 4 + 2];
690 y += (1 << (SHIFT - 1));
691 dest[i * 4 + 2] = CLAMP (y >> SHIFT, 0, 255);
693 y = a * src1[i * 4 + 3];
694 y += b * src2[i * 4 + 3];
695 y += c * src3[i * 4 + 3];
696 y += d * src4[i * 4 + 3];
697 y += (1 << (SHIFT - 1));
698 dest[i * 4 + 3] = CLAMP (y >> SHIFT, 0, 255);
704 vs_image_scale_4tap_YUYV (const VSImage * dest, const VSImage * src,
715 if (dest->height == 1)
718 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
720 if (dest->width == 1)
723 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
726 for (i = 0; i < 4; i++) {
728 vs_scanline_resample_4tap_YUYV (tmpbuf + i * dest->stride,
729 src->pixels + CLAMP (i, 0, src->height - 1) * src->stride, dest->width,
730 src->width, &xacc, x_increment);
734 for (i = 0; i < dest->height; i++) {
735 uint8_t *t0, *t1, *t2, *t3;
741 if (k + 3 < src->height) {
743 vs_scanline_resample_4tap_YUYV (tmpbuf + ((k + 3) & 3) * dest->stride,
744 src->pixels + (k + 3) * src->stride,
745 dest->width, src->width, &xacc, x_increment);
749 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride;
750 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride;
751 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride;
752 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride;
753 vs_scanline_merge_4tap_YUYV (dest->pixels + i * dest->stride,
754 t0, t1, t2, t3, dest->width, yacc & 0xffff);
761 vs_scanline_resample_4tap_UYVY (uint8_t * dest, uint8_t * src,
762 int n, int src_width, int *xacc, int increment)
769 int quads = (n + 1) / 2;
770 int last_y = 2 * (src_width - 1) + 1;
772 MAX ((2 * (src_width - 1) % 4 ==
773 0) ? 2 * (src_width - 1) : 2 * (src_width - 1) - 2, 0);
775 MAX ((2 * (src_width - 1) % 4 ==
776 2) ? 2 * (src_width - 1) : 2 * (src_width - 1) - 2, 0);
779 for (i = 0; i < quads; i++) {
781 x = (acc & 0xffff) >> 8;
783 if (j - 1 >= 0 && j + 2 < src_width) {
784 y = vs_4tap_taps[x][0] * src[MAX (j * 2 + 1 - 2, 1)];
785 y += vs_4tap_taps[x][1] * src[j * 2 + 1];
786 y += vs_4tap_taps[x][2] * src[j * 2 + 1 + 2];
787 y += vs_4tap_taps[x][3] * src[j * 2 + 1 + 4];
789 y = vs_4tap_taps[x][0] * src[CLAMP (j * 2 + 1 - 2, 1, last_y)];
790 y += vs_4tap_taps[x][1] * src[CLAMP (j * 2 + 1, 1, last_y)];
791 y += vs_4tap_taps[x][2] * src[CLAMP (j * 2 + 1 + 2, 1, last_y)];
792 y += vs_4tap_taps[x][3] * src[CLAMP (j * 2 + 1 + 4, 1, last_y)];
794 y += (1 << (SHIFT - 1));
795 dest[i * 4 + 1] = CLAMP (y >> SHIFT, 0, 255);
798 x = (acc & 0x1ffff) >> 9;
800 if (2 * j - 2 >= 0 && 2 * j + 4 < src_width) {
801 y = vs_4tap_taps[x][0] * src[MAX (j * 4 + 0 - 4, 0)];
802 y += vs_4tap_taps[x][1] * src[j * 4 + 0];
803 y += vs_4tap_taps[x][2] * src[j * 4 + 0 + 4];
804 y += vs_4tap_taps[x][3] * src[j * 4 + 0 + 8];
806 y = vs_4tap_taps[x][0] * src[CLAMP (j * 4 + 0 - 4, 0, last_u)];
807 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + 0, 0, last_u)];
808 y += vs_4tap_taps[x][2] * src[CLAMP (j * 4 + 0 + 4, 0, last_u)];
809 y += vs_4tap_taps[x][3] * src[CLAMP (j * 4 + 0 + 8, 0, last_u)];
811 y += (1 << (SHIFT - 1));
812 dest[i * 4 + 0] = CLAMP (y >> SHIFT, 0, 255);
815 if (2 * j - 1 >= 0 && 2 * j + 4 < src_width) {
816 y = vs_4tap_taps[x][0] * src[MAX (j * 4 + 2 - 4, 2)];
817 y += vs_4tap_taps[x][1] * src[j * 4 + 2];
818 y += vs_4tap_taps[x][2] * src[j * 4 + 2 + 4];
819 y += vs_4tap_taps[x][3] * src[j * 4 + 2 + 8];
821 y = vs_4tap_taps[x][0] * src[CLAMP (j * 4 + 2 - 4, 2, last_v)];
822 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + 2, 2, last_v)];
823 y += vs_4tap_taps[x][2] * src[CLAMP (j * 4 + 2 + 4, 2, last_v)];
824 y += vs_4tap_taps[x][3] * src[CLAMP (j * 4 + 2 + 8, 2, last_v)];
826 y += (1 << (SHIFT - 1));
827 dest[i * 4 + 2] = CLAMP (y >> SHIFT, 0, 255);
832 x = (acc & 0xffff) >> 8;
835 if (j - 1 >= 0 && j + 2 < src_width) {
836 y = vs_4tap_taps[x][0] * src[MAX (j * 2 + 1 - 2, 0)];
837 y += vs_4tap_taps[x][1] * src[j * 2 + 1];
838 y += vs_4tap_taps[x][2] * src[j * 2 + 1 + 2];
839 y += vs_4tap_taps[x][3] * src[j * 2 + 1 + 4];
841 y = vs_4tap_taps[x][0] * src[CLAMP (j * 2 + 1 - 2, 1, last_y)];
842 y += vs_4tap_taps[x][1] * src[CLAMP (j * 2 + 1, 1, last_y)];
843 y += vs_4tap_taps[x][2] * src[CLAMP (j * 2 + 1 + 2, 1, last_y)];
844 y += vs_4tap_taps[x][3] * src[CLAMP (j * 2 + 1 + 4, 1, last_y)];
846 y += (1 << (SHIFT - 1));
847 dest[i * 4 + 3] = CLAMP (y >> SHIFT, 0, 255);
855 vs_scanline_merge_4tap_UYVY (uint8_t * dest, uint8_t * src1, uint8_t * src2,
856 uint8_t * src3, uint8_t * src4, int n, int acc)
861 int quads = (n + 1) / 2;
863 acc = (acc >> 8) & 0xff;
864 a = vs_4tap_taps[acc][0];
865 b = vs_4tap_taps[acc][1];
866 c = vs_4tap_taps[acc][2];
867 d = vs_4tap_taps[acc][3];
868 for (i = 0; i < quads; i++) {
869 y = a * src1[i * 4 + 0];
870 y += b * src2[i * 4 + 0];
871 y += c * src3[i * 4 + 0];
872 y += d * src4[i * 4 + 0];
873 y += (1 << (SHIFT - 1));
874 dest[i * 4 + 0] = CLAMP (y >> SHIFT, 0, 255);
876 y = a * src1[i * 4 + 1];
877 y += b * src2[i * 4 + 1];
878 y += c * src3[i * 4 + 1];
879 y += d * src4[i * 4 + 1];
880 y += (1 << (SHIFT - 1));
881 dest[i * 4 + 1] = CLAMP (y >> SHIFT, 0, 255);
884 y = a * src1[i * 4 + 2];
885 y += b * src2[i * 4 + 2];
886 y += c * src3[i * 4 + 2];
887 y += d * src4[i * 4 + 2];
888 y += (1 << (SHIFT - 1));
889 dest[i * 4 + 2] = CLAMP (y >> SHIFT, 0, 255);
891 y = a * src1[i * 4 + 3];
892 y += b * src2[i * 4 + 3];
893 y += c * src3[i * 4 + 3];
894 y += d * src4[i * 4 + 3];
895 y += (1 << (SHIFT - 1));
896 dest[i * 4 + 3] = CLAMP (y >> SHIFT, 0, 255);
902 vs_image_scale_4tap_UYVY (const VSImage * dest, const VSImage * src,
913 if (dest->height == 1)
916 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
918 if (dest->width == 1)
921 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
924 for (i = 0; i < 4; i++) {
926 vs_scanline_resample_4tap_UYVY (tmpbuf + i * dest->stride,
927 src->pixels + CLAMP (i, 0, src->height - 1) * src->stride, dest->width,
928 src->width, &xacc, x_increment);
932 for (i = 0; i < dest->height; i++) {
933 uint8_t *t0, *t1, *t2, *t3;
939 if (k + 3 < src->height) {
941 vs_scanline_resample_4tap_UYVY (tmpbuf + ((k + 3) & 3) * dest->stride,
942 src->pixels + (k + 3) * src->stride,
943 dest->width, src->width, &xacc, x_increment);
947 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride;
948 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride;
949 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride;
950 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride;
951 vs_scanline_merge_4tap_UYVY (dest->pixels + i * dest->stride,
952 t0, t1, t2, t3, dest->width, yacc & 0xffff);
958 /* note that src and dest are uint16_t, and thus endian dependent */
960 #define RGB565_R(x) (((x)&0xf800)>>8 | ((x)&0xf800)>>13)
961 #define RGB565_G(x) (((x)&0x07e0)>>3 | ((x)&0x07e0)>>9)
962 #define RGB565_B(x) (((x)&0x001f)<<3 | ((x)&0x001f)>>2)
964 #define RGB565(r,g,b) \
965 ((((r)<<8)&0xf800) | (((g)<<3)&0x07e0) | (((b)>>3)&0x001f))
968 vs_scanline_resample_4tap_RGB565 (uint8_t * dest_u8, uint8_t * src_u8,
969 int n, int src_width, int *xacc, int increment)
975 int y, y_r, y_b, y_g;
976 uint16_t *dest = (uint16_t *) dest_u8;
977 uint16_t *src = (uint16_t *) src_u8;
980 for (i = 0; i < n; i++) {
982 x = acc & 0xffff >> 8;
984 if (j - 1 >= 0 && j + 2 < src_width) {
985 y = vs_4tap_taps[x][0] * RGB565_R (src[MAX ((j - 1), 0)]);
986 y += vs_4tap_taps[x][1] * RGB565_R (src[j]);
987 y += vs_4tap_taps[x][2] * RGB565_R (src[(j + 1)]);
988 y += vs_4tap_taps[x][3] * RGB565_R (src[(j + 2)]);
990 y = vs_4tap_taps[x][0] * RGB565_R (src[CLAMP ((j - 1), 0,
992 y += vs_4tap_taps[x][1] * RGB565_R (src[CLAMP (j, 0, src_width - 1)]);
993 y += vs_4tap_taps[x][2] * RGB565_R (src[CLAMP ((j + 1), 0,
995 y += vs_4tap_taps[x][3] * RGB565_R (src[CLAMP ((j + 2), 0,
998 y += (1 << (SHIFT - 1));
999 y_r = CLAMP (y >> SHIFT, 0, 255);
1001 if (j - 1 >= 0 && j + 2 < src_width) {
1002 y = vs_4tap_taps[x][0] * RGB565_G (src[MAX ((j - 1), 0)]);
1003 y += vs_4tap_taps[x][1] * RGB565_G (src[j]);
1004 y += vs_4tap_taps[x][2] * RGB565_G (src[(j + 1)]);
1005 y += vs_4tap_taps[x][3] * RGB565_G (src[(j + 2)]);
1007 y = vs_4tap_taps[x][0] * RGB565_G (src[CLAMP ((j - 1), 0,
1009 y += vs_4tap_taps[x][1] * RGB565_G (src[CLAMP (j, 0, src_width - 1)]);
1010 y += vs_4tap_taps[x][2] * RGB565_G (src[CLAMP ((j + 1), 0,
1012 y += vs_4tap_taps[x][3] * RGB565_G (src[CLAMP ((j + 2), 0,
1015 y += (1 << (SHIFT - 1));
1016 y_g = CLAMP (y >> SHIFT, 0, 255);
1018 if (j - 1 >= 0 && j + 2 < src_width) {
1019 y = vs_4tap_taps[x][0] * RGB565_B (src[MAX ((j - 1), 0)]);
1020 y += vs_4tap_taps[x][1] * RGB565_B (src[j]);
1021 y += vs_4tap_taps[x][2] * RGB565_B (src[(j + 1)]);
1022 y += vs_4tap_taps[x][3] * RGB565_B (src[(j + 2)]);
1024 y = vs_4tap_taps[x][0] * RGB565_B (src[CLAMP ((j - 1), 0,
1026 y += vs_4tap_taps[x][1] * RGB565_B (src[CLAMP (j, 0, src_width - 1)]);
1027 y += vs_4tap_taps[x][2] * RGB565_B (src[CLAMP ((j + 1), 0,
1029 y += vs_4tap_taps[x][3] * RGB565_B (src[CLAMP ((j + 2), 0,
1032 y += (1 << (SHIFT - 1));
1033 y_b = CLAMP (y >> SHIFT, 0, 255);
1035 dest[i] = RGB565 (y_r, y_b, y_g);
1042 vs_scanline_merge_4tap_RGB565 (uint8_t * dest_u8, uint8_t * src1_u8,
1043 uint8_t * src2_u8, uint8_t * src3_u8, uint8_t * src4_u8, int n, int acc)
1046 int y, y_r, y_b, y_g;
1048 uint16_t *dest = (uint16_t *) dest_u8;
1049 uint16_t *src1 = (uint16_t *) src1_u8;
1050 uint16_t *src2 = (uint16_t *) src2_u8;
1051 uint16_t *src3 = (uint16_t *) src3_u8;
1052 uint16_t *src4 = (uint16_t *) src4_u8;
1054 acc = (acc >> 8) & 0xff;
1055 a = vs_4tap_taps[acc][0];
1056 b = vs_4tap_taps[acc][1];
1057 c = vs_4tap_taps[acc][2];
1058 d = vs_4tap_taps[acc][3];
1060 for (i = 0; i < n; i++) {
1061 y = a * RGB565_R (src1[i]);
1062 y += b * RGB565_R (src2[i]);
1063 y += c * RGB565_R (src3[i]);
1064 y += d * RGB565_R (src4[i]);
1065 y += (1 << (SHIFT - 1));
1066 y_r = CLAMP (y >> SHIFT, 0, 255);
1068 y = a * RGB565_G (src1[i]);
1069 y += b * RGB565_G (src2[i]);
1070 y += c * RGB565_G (src3[i]);
1071 y += d * RGB565_G (src4[i]);
1072 y += (1 << (SHIFT - 1));
1073 y_g = CLAMP (y >> SHIFT, 0, 255);
1075 y = a * RGB565_B (src1[i]);
1076 y += b * RGB565_B (src2[i]);
1077 y += c * RGB565_B (src3[i]);
1078 y += d * RGB565_B (src4[i]);
1079 y += (1 << (SHIFT - 1));
1080 y_b = CLAMP (y >> SHIFT, 0, 255);
1082 dest[i] = RGB565 (y_r, y_b, y_g);
1087 vs_image_scale_4tap_RGB565 (const VSImage * dest, const VSImage * src,
1098 if (dest->height == 1)
1101 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
1103 if (dest->width == 1)
1106 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
1109 for (i = 0; i < 4; i++) {
1111 vs_scanline_resample_4tap_RGB565 (tmpbuf + i * dest->stride,
1112 src->pixels + CLAMP (i, 0, src->height - 1) * src->stride, dest->width,
1113 src->width, &xacc, x_increment);
1117 for (i = 0; i < dest->height; i++) {
1118 uint8_t *t0, *t1, *t2, *t3;
1124 if (k + 3 < src->height) {
1126 vs_scanline_resample_4tap_RGB565 (tmpbuf + ((k + 3) & 3) * dest->stride,
1127 src->pixels + (k + 3) * src->stride,
1128 dest->width, src->width, &xacc, x_increment);
1132 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride;
1133 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride;
1134 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride;
1135 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride;
1136 vs_scanline_merge_4tap_RGB565 (dest->pixels + i * dest->stride,
1137 t0, t1, t2, t3, dest->width, yacc & 0xffff);
1139 yacc += y_increment;
1143 /* note that src and dest are uint16_t, and thus endian dependent */
1145 #define RGB555_R(x) (((x)&0x7c00)>>8 | ((x)&0x7c00)>>13)
1146 #define RGB555_G(x) (((x)&0x03e0)>>3 | ((x)&0x03e0)>>9)
1147 #define RGB555_B(x) (((x)&0x001f)<<3 | ((x)&0x001f)>>2)
1149 #define RGB555(r,g,b) \
1150 ((((r)<<7)&0x7c00) | (((g)<<2)&0x03e0) | (((b)>>3)&0x001f))
1153 vs_scanline_resample_4tap_RGB555 (uint8_t * dest_u8, uint8_t * src_u8,
1154 int n, int src_width, int *xacc, int increment)
1160 int y, y_r, y_b, y_g;
1161 uint16_t *dest = (uint16_t *) dest_u8;
1162 uint16_t *src = (uint16_t *) src_u8;
1165 for (i = 0; i < n; i++) {
1167 x = acc & 0xffff >> 8;
1169 if (j - 1 >= 0 && j + 2 < src_width) {
1170 y = vs_4tap_taps[x][0] * RGB555_R (src[MAX ((j - 1), 0)]);
1171 y += vs_4tap_taps[x][1] * RGB555_R (src[j]);
1172 y += vs_4tap_taps[x][2] * RGB555_R (src[(j + 1)]);
1173 y += vs_4tap_taps[x][3] * RGB555_R (src[(j + 2)]);
1175 y = vs_4tap_taps[x][0] * RGB555_R (src[CLAMP ((j - 1), 0,
1177 y += vs_4tap_taps[x][1] * RGB555_R (src[CLAMP (j, 0, src_width - 1)]);
1178 y += vs_4tap_taps[x][2] * RGB555_R (src[CLAMP ((j + 1), 0,
1180 y += vs_4tap_taps[x][3] * RGB555_R (src[CLAMP ((j + 2), 0,
1183 y += (1 << (SHIFT - 1));
1184 y_r = CLAMP (y >> SHIFT, 0, 255);
1186 if (j - 1 >= 0 && j + 2 < src_width) {
1187 y = vs_4tap_taps[x][0] * RGB555_G (src[MAX ((j - 1), 0)]);
1188 y += vs_4tap_taps[x][1] * RGB555_G (src[j]);
1189 y += vs_4tap_taps[x][2] * RGB555_G (src[(j + 1)]);
1190 y += vs_4tap_taps[x][3] * RGB555_G (src[(j + 2)]);
1192 y = vs_4tap_taps[x][0] * RGB555_G (src[CLAMP ((j - 1), 0,
1194 y += vs_4tap_taps[x][1] * RGB555_G (src[CLAMP (j, 0, src_width - 1)]);
1195 y += vs_4tap_taps[x][2] * RGB555_G (src[CLAMP ((j + 1), 0,
1197 y += vs_4tap_taps[x][3] * RGB555_G (src[CLAMP ((j + 2), 0,
1200 y += (1 << (SHIFT - 1));
1201 y_g = CLAMP (y >> SHIFT, 0, 255);
1203 if (j - 1 >= 0 && j + 2 < src_width) {
1204 y = vs_4tap_taps[x][0] * RGB555_B (src[MAX ((j - 1), 0)]);
1205 y += vs_4tap_taps[x][1] * RGB555_B (src[j]);
1206 y += vs_4tap_taps[x][2] * RGB555_B (src[(j + 1)]);
1207 y += vs_4tap_taps[x][3] * RGB555_B (src[(j + 2)]);
1209 y = vs_4tap_taps[x][0] * RGB555_B (src[CLAMP ((j - 1), 0,
1211 y += vs_4tap_taps[x][1] * RGB555_B (src[CLAMP (j, 0, src_width - 1)]);
1212 y += vs_4tap_taps[x][2] * RGB555_B (src[CLAMP ((j + 1), 0,
1214 y += vs_4tap_taps[x][3] * RGB555_B (src[CLAMP ((j + 2), 0,
1217 y += (1 << (SHIFT - 1));
1218 y_b = CLAMP (y >> SHIFT, 0, 255);
1220 dest[i] = RGB555 (y_r, y_b, y_g);
1227 vs_scanline_merge_4tap_RGB555 (uint8_t * dest_u8, uint8_t * src1_u8,
1228 uint8_t * src2_u8, uint8_t * src3_u8, uint8_t * src4_u8, int n, int acc)
1231 int y, y_r, y_b, y_g;
1233 uint16_t *dest = (uint16_t *) dest_u8;
1234 uint16_t *src1 = (uint16_t *) src1_u8;
1235 uint16_t *src2 = (uint16_t *) src2_u8;
1236 uint16_t *src3 = (uint16_t *) src3_u8;
1237 uint16_t *src4 = (uint16_t *) src4_u8;
1239 acc = (acc >> 8) & 0xff;
1240 a = vs_4tap_taps[acc][0];
1241 b = vs_4tap_taps[acc][1];
1242 c = vs_4tap_taps[acc][2];
1243 d = vs_4tap_taps[acc][3];
1245 for (i = 0; i < n; i++) {
1246 y = a * RGB555_R (src1[i]);
1247 y += b * RGB555_R (src2[i]);
1248 y += c * RGB555_R (src3[i]);
1249 y += d * RGB555_R (src4[i]);
1250 y += (1 << (SHIFT - 1));
1251 y_r = CLAMP (y >> SHIFT, 0, 255);
1253 y = a * RGB555_G (src1[i]);
1254 y += b * RGB555_G (src2[i]);
1255 y += c * RGB555_G (src3[i]);
1256 y += d * RGB555_G (src4[i]);
1257 y += (1 << (SHIFT - 1));
1258 y_g = CLAMP (y >> SHIFT, 0, 255);
1260 y = a * RGB555_B (src1[i]);
1261 y += b * RGB555_B (src2[i]);
1262 y += c * RGB555_B (src3[i]);
1263 y += d * RGB555_B (src4[i]);
1264 y += (1 << (SHIFT - 1));
1265 y_b = CLAMP (y >> SHIFT, 0, 255);
1267 dest[i] = RGB555 (y_r, y_b, y_g);
1272 vs_image_scale_4tap_RGB555 (const VSImage * dest, const VSImage * src,
1283 if (dest->height == 1)
1286 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
1288 if (dest->width == 1)
1291 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
1294 for (i = 0; i < 4; i++) {
1296 vs_scanline_resample_4tap_RGB555 (tmpbuf + i * dest->stride,
1297 src->pixels + CLAMP (i, 0, src->height - 1) * src->stride, dest->width,
1298 src->width, &xacc, x_increment);
1302 for (i = 0; i < dest->height; i++) {
1303 uint8_t *t0, *t1, *t2, *t3;
1309 if (k + 3 < src->height) {
1311 vs_scanline_resample_4tap_RGB555 (tmpbuf + ((k + 3) & 3) * dest->stride,
1312 src->pixels + (k + 3) * src->stride,
1313 dest->width, src->width, &xacc, x_increment);
1317 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride;
1318 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride;
1319 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride;
1320 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride;
1321 vs_scanline_merge_4tap_RGB555 (dest->pixels + i * dest->stride,
1322 t0, t1, t2, t3, dest->width, yacc & 0xffff);
1324 yacc += y_increment;
1329 vs_scanline_resample_4tap_AYUV64 (uint16_t * dest, uint16_t * src,
1330 int n, int src_width, int *xacc, int increment)
1340 for (i = 0; i < n; i++) {
1342 x = (acc & 0xffff) >> 8;
1344 for (off = 0; off < 4; off++) {
1345 if (j - 1 >= 0 && j + 2 < src_width) {
1346 y = vs_4tap_taps[x][0] * src[MAX ((j - 1) * 4 + off, 0)];
1347 y += vs_4tap_taps[x][1] * src[j * 4 + off];
1348 y += vs_4tap_taps[x][2] * src[(j + 1) * 4 + off];
1349 y += vs_4tap_taps[x][3] * src[(j + 2) * 4 + off];
1351 y = vs_4tap_taps[x][0] * src[CLAMP ((j - 1) * 4 + off, 0,
1352 4 * (src_width - 1) + off)];
1353 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + off, 0,
1354 4 * (src_width - 1) + off)];
1355 y += vs_4tap_taps[x][2] * src[CLAMP ((j + 1) * 4 + off, 0,
1356 4 * (src_width - 1) + off)];
1357 y += vs_4tap_taps[x][3] * src[CLAMP ((j + 2) * 4 + off, 0,
1358 4 * (src_width - 1) + off)];
1360 y += (1 << (SHIFT - 1));
1361 dest[i * 4 + off] = CLAMP (y >> SHIFT, 0, 255);
1369 vs_scanline_merge_4tap_AYUV64 (uint16_t * dest, uint16_t * src1,
1370 uint16_t * src2, uint16_t * src3, uint16_t * src4, int n, int acc)
1377 acc = (acc >> 8) & 0xff;
1378 a = vs_4tap_taps[acc][0];
1379 b = vs_4tap_taps[acc][1];
1380 c = vs_4tap_taps[acc][2];
1381 d = vs_4tap_taps[acc][3];
1382 for (i = 0; i < n; i++) {
1383 for (off = 0; off < 4; off++) {
1384 y = a * src1[i * 4 + off];
1385 y += b * src2[i * 4 + off];
1386 y += c * src3[i * 4 + off];
1387 y += d * src4[i * 4 + off];
1388 y += (1 << (SHIFT - 1));
1389 dest[i * 4 + off] = CLAMP (y >> SHIFT, 0, 65535);
1395 vs_image_scale_4tap_AYUV64 (const VSImage * dest, const VSImage * src,
1405 guint16 *tmpbuf = (guint16 *) tmpbuf8;
1407 if (dest->height == 1)
1410 y_increment = ((src->height - 1) << 16) / (dest->height - 1);
1412 if (dest->width == 1)
1415 x_increment = ((src->width - 1) << 16) / (dest->width - 1);
1418 for (i = 0; i < 4; i++) {
1420 vs_scanline_resample_4tap_AYUV64 ((guint16 *) (tmpbuf + i * dest->stride),
1421 (guint16 *) (src->pixels + CLAMP (i, 0, src->height - 1) * src->stride),
1422 dest->width, src->width, &xacc, x_increment);
1426 for (i = 0; i < dest->height; i++) {
1427 uint16_t *t0, *t1, *t2, *t3;
1433 if (k + 3 < src->height) {
1435 vs_scanline_resample_4tap_AYUV64 ((guint16 *) (tmpbuf + ((k +
1436 3) & 3) * dest->stride),
1437 (guint16 *) (src->pixels + (k + 3) * src->stride), dest->width,
1438 src->width, &xacc, x_increment);
1442 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride;
1443 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride;
1444 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride;
1445 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride;
1446 vs_scanline_merge_4tap_AYUV64 ((guint16 *) (dest->pixels +
1447 i * dest->stride), t0, t1, t2, t3, dest->width, yacc & 0xffff);
1449 yacc += y_increment;