Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / gst / videoscale / vs_scanline.c
1 /*
2  * Image Scaling Functions
3  * Copyright (c) 2005 David A. Schleef <ds@schleef.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "vs_scanline.h"
29
30 #include "gstvideoscaleorc.h"
31 #include <gst/gst.h>
32
33 #include <string.h>
34
35 /* greyscale, i.e., single componenet */
36
37 void
38 vs_scanline_downsample_Y (uint8_t * dest, uint8_t * src, int n)
39 {
40   orc_downsample_u8 (dest, src, n);
41 }
42
43 void
44 vs_scanline_resample_nearest_Y (uint8_t * dest, uint8_t * src, int src_width,
45     int n, int *accumulator, int increment)
46 {
47   gst_videoscale_orc_resample_nearest_u8 (dest, src,
48       *accumulator, increment, n);
49
50   *accumulator += n * increment;
51 }
52
53 #include <glib.h>
54 void
55 vs_scanline_resample_linear_Y (uint8_t * dest, uint8_t * src, int src_width,
56     int n, int *accumulator, int increment)
57 {
58   gst_videoscale_orc_resample_bilinear_u8 (dest, src,
59       *accumulator, increment, n);
60
61   *accumulator += n * increment;
62 }
63
64 void
65 vs_scanline_merge_linear_Y (uint8_t * dest, uint8_t * src1, uint8_t * src2,
66     int n, int x)
67 {
68   uint32_t value = x >> 8;
69
70   if (value == 0) {
71     memcpy (dest, src1, n);
72   } else {
73     orc_merge_linear_u8 (dest, src1, src2, value, n);
74   }
75 }
76
77 void
78 vs_scanline_downsample_Y16 (uint8_t * dest, uint8_t * src, int n)
79 {
80   orc_downsample_u16 ((uint16_t *) dest, (uint16_t *) src, n);
81 }
82
83 void
84 vs_scanline_resample_nearest_Y16 (uint8_t * dest, uint8_t * src, int src_width,
85     int n, int *accumulator, int increment)
86 {
87   int acc = *accumulator;
88   int i;
89   int j;
90   int x;
91   uint16_t *d = (uint16_t *) dest, *s = (uint16_t *) src;
92
93   for (i = 0; i < n; i++) {
94     j = acc >> 16;
95     x = acc & 0xffff;
96     d[i] = (x < 32768 || j + 1 >= src_width) ? s[j] : s[j + 1];
97
98     acc += increment;
99   }
100
101   *accumulator = acc;
102 }
103
104 void
105 vs_scanline_resample_linear_Y16 (uint8_t * dest, uint8_t * src, int src_width,
106     int n, int *accumulator, int increment)
107 {
108   int acc = *accumulator;
109   int i;
110   int j;
111   int x;
112   uint16_t *d = (uint16_t *) dest, *s = (uint16_t *) src;
113
114   for (i = 0; i < n; i++) {
115     j = acc >> 16;
116     x = acc & 0xffff;
117
118     if (j + 1 < src_width)
119       d[i] = (s[j] * (65536 - x) + s[j + 1] * x) >> 16;
120     else
121       d[i] = s[j];
122
123     acc += increment;
124   }
125
126   *accumulator = acc;
127 }
128
129 void
130 vs_scanline_merge_linear_Y16 (uint8_t * dest, uint8_t * src1, uint8_t * src2,
131     int n, int x)
132 {
133   uint16_t *d = (uint16_t *) dest;
134   const uint16_t *s1 = (const uint16_t *) src1;
135   const uint16_t *s2 = (const uint16_t *) src2;
136
137   if (x == 0) {
138     memcpy (d, s1, n * 2);
139   } else {
140     orc_merge_linear_u16 (d, s1, s2, 65536 - x, x, n);
141   }
142 }
143
144 /* RGBA */
145
146 void
147 vs_scanline_downsample_RGBA (uint8_t * dest, uint8_t * src, int n)
148 {
149   gst_videoscale_orc_downsample_u32 (dest, src, n);
150 }
151
152 void
153 vs_scanline_resample_nearest_RGBA (uint8_t * dest, uint8_t * src, int src_width,
154     int n, int *accumulator, int increment)
155 {
156   gst_videoscale_orc_resample_nearest_u32 (dest, src,
157       *accumulator, increment, n);
158
159   *accumulator += n * increment;
160 }
161
162 void
163 vs_scanline_resample_linear_RGBA (uint8_t * dest, uint8_t * src, int src_width,
164     int n, int *accumulator, int increment)
165 {
166   gst_videoscale_orc_resample_bilinear_u32 (dest, src,
167       *accumulator, increment, n);
168
169   *accumulator += n * increment;
170 }
171
172 void
173 vs_scanline_merge_linear_RGBA (uint8_t * dest, uint8_t * src1, uint8_t * src2,
174     int n, int x)
175 {
176   uint32_t value = x >> 8;
177
178   if (value == 0) {
179     memcpy (dest, src1, n * 4);
180   } else {
181     orc_merge_linear_u8 (dest, src1, src2, value, n * 4);
182   }
183 }
184
185
186 /* RGB */
187
188 void
189 vs_scanline_downsample_RGB (uint8_t * dest, uint8_t * src, int n)
190 {
191   int i;
192
193   for (i = 0; i < n; i++) {
194     dest[i * 3 + 0] = (src[i * 6 + 0] + src[i * 6 + 3]) / 2;
195     dest[i * 3 + 1] = (src[i * 6 + 1] + src[i * 6 + 4]) / 2;
196     dest[i * 3 + 2] = (src[i * 6 + 2] + src[i * 6 + 5]) / 2;
197   }
198 }
199
200 void
201 vs_scanline_resample_nearest_RGB (uint8_t * dest, uint8_t * src, int src_width,
202     int n, int *accumulator, int increment)
203 {
204   int acc = *accumulator;
205   int i;
206   int j;
207   int x;
208
209   for (i = 0; i < n; i++) {
210     j = acc >> 16;
211     x = acc & 0xffff;
212     dest[i * 3 + 0] = (x < 32768
213         || j + 1 >= src_width) ? src[j * 3 + 0] : src[j * 3 + 3];
214     dest[i * 3 + 1] = (x < 32768
215         || j + 1 >= src_width) ? src[j * 3 + 1] : src[j * 3 + 4];
216     dest[i * 3 + 2] = (x < 32768
217         || j + 1 >= src_width) ? src[j * 3 + 2] : src[j * 3 + 5];
218
219     acc += increment;
220   }
221
222   *accumulator = acc;
223 }
224
225 void
226 vs_scanline_resample_linear_RGB (uint8_t * dest, uint8_t * src, int src_width,
227     int n, int *accumulator, int increment)
228 {
229   int acc = *accumulator;
230   int i;
231   int j;
232   int x;
233
234   for (i = 0; i < n; i++) {
235     j = acc >> 16;
236     x = acc & 0xffff;
237
238     if (j + 1 < src_width) {
239       dest[i * 3 + 0] =
240           (src[j * 3 + 0] * (65536 - x) + src[j * 3 + 3] * x) >> 16;
241       dest[i * 3 + 1] =
242           (src[j * 3 + 1] * (65536 - x) + src[j * 3 + 4] * x) >> 16;
243       dest[i * 3 + 2] =
244           (src[j * 3 + 2] * (65536 - x) + src[j * 3 + 5] * x) >> 16;
245     } else {
246       dest[i * 3 + 0] = src[j * 3 + 0];
247       dest[i * 3 + 1] = src[j * 3 + 1];
248       dest[i * 3 + 2] = src[j * 3 + 2];
249     }
250
251     acc += increment;
252   }
253
254   *accumulator = acc;
255 }
256
257 void
258 vs_scanline_merge_linear_RGB (uint8_t * dest, uint8_t * src1, uint8_t * src2,
259     int n, int x)
260 {
261   uint32_t value = x >> 8;
262
263   if (value == 0) {
264     memcpy (dest, src1, n * 3);
265   } else {
266     orc_merge_linear_u8 (dest, src1, src2, value, n * 3);
267   }
268 }
269
270
271 /* YUYV */
272
273 /* n is the number of pixels */
274 /* increment is per Y pixel */
275
276 void
277 vs_scanline_downsample_YUYV (uint8_t * dest, uint8_t * src, int n)
278 {
279   gst_videoscale_orc_downsample_yuyv (dest, src, n);
280 }
281
282 void
283 vs_scanline_resample_nearest_YUYV (uint8_t * dest, uint8_t * src, int src_width,
284     int n, int *accumulator, int increment)
285 {
286   int acc = *accumulator;
287   int i;
288   int j;
289   int x;
290   int quads = (n + 1) / 2;
291
292   for (i = 0; i < quads; i++) {
293     j = acc >> 16;
294     x = acc & 0xffff;
295     dest[i * 4 + 0] = (x < 32768
296         || j + 1 >= src_width) ? src[j * 2 + 0] : src[j * 2 + 2];
297
298     j = acc >> 17;
299     x = acc & 0x1ffff;
300     dest[i * 4 + 1] = (x < 65536
301         || 2 * j + 2 >= src_width) ? src[j * 4 + 1] : src[j * 4 + 5];
302
303     if (2 * i + 1 < n && 2 * j + 1 < src_width)
304       dest[i * 4 + 3] = (x < 65536
305           || 2 * j + 3 >= src_width) ? src[j * 4 + 3] : src[j * 4 + 7];
306
307     acc += increment;
308
309     j = acc >> 16;
310     x = acc & 0xffff;
311
312     if (2 * i + 1 < n && j < src_width) {
313       dest[i * 4 + 2] = (x < 32768
314           || j + 1 >= src_width) ? src[j * 2 + 0] : src[j * 2 + 2];
315       acc += increment;
316     }
317   }
318
319   *accumulator = acc;
320 }
321
322 void
323 vs_scanline_resample_linear_YUYV (uint8_t * dest, uint8_t * src, int src_width,
324     int n, int *accumulator, int increment)
325 {
326   int acc = *accumulator;
327   int i;
328   int j;
329   int x;
330   int quads = (n + 1) / 2;
331
332   for (i = 0; i < quads; i++) {
333     j = acc >> 16;
334     x = acc & 0xffff;
335
336     if (j + 1 < src_width)
337       dest[i * 4 + 0] =
338           (src[j * 2 + 0] * (65536 - x) + src[j * 2 + 2] * x) >> 16;
339     else
340       dest[i * 4 + 0] = src[j * 2 + 0];
341
342     j = acc >> 17;
343     x = acc & 0x1ffff;
344
345     if (2 * j + 2 < src_width)
346       dest[i * 4 + 1] =
347           (src[j * 4 + 1] * (131072 - x) + src[j * 4 + 5] * x) >> 17;
348     else
349       dest[i * 4 + 1] = src[j * 4 + 1];
350
351     if (2 * i + 1 < n && 2 * j + 1 < src_width) {
352       if (2 * j + 3 < src_width)
353         dest[i * 4 + 3] =
354             (src[j * 4 + 3] * (131072 - x) + src[j * 4 + 7] * x) >> 17;
355       else
356         dest[i * 4 + 3] = src[j * 4 + 3];
357     }
358
359     acc += increment;
360
361     j = acc >> 16;
362     x = acc & 0xffff;
363
364     if (2 * i + 1 < n && j < src_width) {
365       if (j + 1 < src_width)
366         dest[i * 4 + 2] =
367             (src[j * 2 + 0] * (65536 - x) + src[j * 2 + 2] * x) >> 16;
368       else
369         dest[i * 4 + 2] = src[j * 2 + 0];
370       acc += increment;
371     }
372   }
373
374
375   *accumulator = acc;
376 }
377
378 void
379 vs_scanline_merge_linear_YUYV (uint8_t * dest, uint8_t * src1, uint8_t * src2,
380     int n, int x)
381 {
382   int quads = (n + 1) / 2;
383   uint32_t value = x >> 8;
384
385   if (value == 0) {
386     memcpy (dest, src1, quads * 4);
387   } else {
388     orc_merge_linear_u8 (dest, src1, src2, value, quads * 4);
389   }
390 }
391
392
393 /* UYVY */
394
395 /* n is the number of bi-pixels */
396 /* increment is per Y pixel */
397
398 void
399 vs_scanline_downsample_UYVY (uint8_t * dest, uint8_t * src, int n)
400 {
401   int i;
402
403   for (i = 0; i < n; i++) {
404     dest[i * 4 + 0] = (src[i * 8 + 0] + src[i * 8 + 4]) / 2;
405     dest[i * 4 + 1] = (src[i * 8 + 1] + src[i * 8 + 3]) / 2;
406     dest[i * 4 + 2] = (src[i * 8 + 2] + src[i * 8 + 6]) / 2;
407     dest[i * 4 + 3] = (src[i * 8 + 5] + src[i * 8 + 7]) / 2;
408   }
409 }
410
411 void
412 vs_scanline_resample_nearest_UYVY (uint8_t * dest, uint8_t * src, int src_width,
413     int n, int *accumulator, int increment)
414 {
415   int acc = *accumulator;
416   int i;
417   int j;
418   int x;
419   int quads = (n + 1) / 2;
420
421   for (i = 0; i < quads; i++) {
422     j = acc >> 16;
423     x = acc & 0xffff;
424
425     dest[i * 4 + 1] = (x < 32768
426         || j + 1 >= src_width) ? src[j * 2 + 1] : src[j * 2 + 3];
427
428     j = acc >> 17;
429     x = acc & 0x1ffff;
430
431     dest[i * 4 + 0] = (x < 65536
432         || 2 * j + 2 >= src_width) ? src[j * 4 + 0] : src[j * 4 + 4];
433
434     if (2 * i + 1 < n && 2 * j + 1 < src_width)
435       dest[i * 4 + 2] = (x < 65536
436           || 2 * j + 3 >= src_width) ? src[j * 4 + 2] : src[j * 4 + 6];
437
438     acc += increment;
439
440     j = acc >> 16;
441     x = acc & 0xffff;
442
443     if (2 * i + 1 < n && j < src_width) {
444       dest[i * 4 + 3] = (x < 32768
445           || j + 1 >= src_width) ? src[j * 2 + 1] : src[j * 2 + 3];
446       acc += increment;
447     }
448   }
449
450   *accumulator = acc;
451 }
452
453 void
454 vs_scanline_resample_linear_UYVY (uint8_t * dest, uint8_t * src, int src_width,
455     int n, int *accumulator, int increment)
456 {
457   int acc = *accumulator;
458   int i;
459   int j;
460   int x;
461   int quads = (n + 1) / 2;
462
463   for (i = 0; i < quads; i++) {
464     j = acc >> 16;
465     x = acc & 0xffff;
466
467     if (j + 1 < src_width)
468       dest[i * 4 + 1] =
469           (src[j * 2 + 1] * (65536 - x) + src[j * 2 + 3] * x) >> 16;
470     else
471       dest[i * 4 + 1] = src[j * 2 + 1];
472
473     j = acc >> 17;
474     x = acc & 0x1ffff;
475     if (2 * j + 2 < src_width)
476       dest[i * 4 + 0] =
477           (src[j * 4 + 0] * (131072 - x) + src[j * 4 + 4] * x) >> 17;
478     else
479       dest[i * 4 + 0] = src[j * 4 + 0];
480
481     if (i * 2 + 1 < n && 2 * j + 1 < src_width) {
482       if (2 * j + 3 < src_width)
483         dest[i * 4 + 2] =
484             (src[j * 4 + 2] * (131072 - x) + src[j * 4 + 6] * x) >> 17;
485       else
486         dest[i * 4 + 2] = src[j * 4 + 2];
487     }
488
489     acc += increment;
490
491     j = acc >> 16;
492     x = acc & 0xffff;
493
494     if (2 * i + 1 < n && j < src_width) {
495       if (j + 1 < src_width)
496         dest[i * 4 + 3] =
497             (src[j * 2 + 1] * (65536 - x) + src[j * 2 + 3] * x) >> 16;
498       else
499         dest[i * 4 + 3] = src[j * 2 + 1];
500       acc += increment;
501     }
502   }
503
504   *accumulator = acc;
505 }
506
507 void
508 vs_scanline_merge_linear_UYVY (uint8_t * dest, uint8_t * src1,
509     uint8_t * src2, int n, int x)
510 {
511   int quads = (n + 1) / 2;
512   uint32_t value = x >> 8;
513
514   if (value == 0) {
515     memcpy (dest, src1, quads * 4);
516   } else {
517     orc_merge_linear_u8 (dest, src1, src2, value, quads * 4);
518   }
519 }
520
521
522 /* RGB565 */
523
524 /* note that src and dest are uint16_t, and thus endian dependent */
525
526 #define RGB565_R(x) (((x)&0xf800)>>8 | ((x)&0xf800)>>13)
527 #define RGB565_G(x) (((x)&0x07e0)>>3 | ((x)&0x07e0)>>9)
528 #define RGB565_B(x) (((x)&0x001f)<<3 | ((x)&0x001f)>>2)
529
530 #define RGB565(r,g,b) \
531   ((((r)<<8)&0xf800) | (((g)<<3)&0x07e0) | (((b)>>3)&0x001f))
532
533
534 void
535 vs_scanline_downsample_RGB565 (uint8_t * dest_u8, uint8_t * src_u8, int n)
536 {
537   uint16_t *dest = (uint16_t *) dest_u8;
538   uint16_t *src = (uint16_t *) src_u8;
539   int i;
540
541   for (i = 0; i < n; i++) {
542     dest[i] = RGB565 (
543         (RGB565_R (src[i * 2]) + RGB565_R (src[i * 2 + 1])) / 2,
544         (RGB565_G (src[i * 2]) + RGB565_G (src[i * 2 + 1])) / 2,
545         (RGB565_B (src[i * 2]) + RGB565_B (src[i * 2 + 1])) / 2);
546   }
547 }
548
549 void
550 vs_scanline_resample_nearest_RGB565 (uint8_t * dest_u8, uint8_t * src_u8,
551     int src_width, int n, int *accumulator, int increment)
552 {
553   uint16_t *dest = (uint16_t *) dest_u8;
554   uint16_t *src = (uint16_t *) src_u8;
555   int acc = *accumulator;
556   int i;
557   int j;
558   int x;
559
560   for (i = 0; i < n; i++) {
561     j = acc >> 16;
562     x = acc & 0xffff;
563     dest[i] = (x < 32768 || j + 1 >= src_width) ? src[j] : src[j + 1];
564
565     acc += increment;
566   }
567
568   *accumulator = acc;
569 }
570
571 void
572 vs_scanline_resample_linear_RGB565 (uint8_t * dest_u8, uint8_t * src_u8,
573     int src_width, int n, int *accumulator, int increment)
574 {
575   uint16_t *dest = (uint16_t *) dest_u8;
576   uint16_t *src = (uint16_t *) src_u8;
577   int acc = *accumulator;
578   int i;
579   int j;
580   int x;
581
582   for (i = 0; i < n; i++) {
583     j = acc >> 16;
584     x = acc & 0xffff;
585
586     if (j + 1 < src_width) {
587       dest[i] = RGB565 (
588           (RGB565_R (src[j]) * (65536 - x) + RGB565_R (src[j + 1]) * x) >> 16,
589           (RGB565_G (src[j]) * (65536 - x) + RGB565_G (src[j + 1]) * x) >> 16,
590           (RGB565_B (src[j]) * (65536 - x) + RGB565_B (src[j + 1]) * x) >> 16);
591     } else {
592       dest[i] = RGB565 (RGB565_R (src[j]),
593           RGB565_G (src[j]), RGB565_B (src[j]));
594     }
595
596     acc += increment;
597   }
598
599   *accumulator = acc;
600 }
601
602 void
603 vs_scanline_merge_linear_RGB565 (uint8_t * dest_u8, uint8_t * src1_u8,
604     uint8_t * src2_u8, int n, int x)
605 {
606   uint16_t *dest = (uint16_t *) dest_u8;
607   uint16_t *src1 = (uint16_t *) src1_u8;
608   uint16_t *src2 = (uint16_t *) src2_u8;
609   int i;
610
611   for (i = 0; i < n; i++) {
612     dest[i] = RGB565 (
613         (RGB565_R (src1[i]) * (65536 - x) + RGB565_R (src2[i]) * x) >> 16,
614         (RGB565_G (src1[i]) * (65536 - x) + RGB565_G (src2[i]) * x) >> 16,
615         (RGB565_B (src1[i]) * (65536 - x) + RGB565_B (src2[i]) * x) >> 16);
616   }
617 }
618
619
620 /* RGB555 */
621
622 /* note that src and dest are uint16_t, and thus endian dependent */
623
624 #define RGB555_R(x) (((x)&0x7c00)>>8 | ((x)&0x7c00)>>13)
625 #define RGB555_G(x) (((x)&0x03e0)>>3 | ((x)&0x03e0)>>9)
626 #define RGB555_B(x) (((x)&0x001f)<<3 | ((x)&0x001f)>>2)
627
628 #define RGB555(r,g,b) \
629   ((((r)<<7)&0x7c00) | (((g)<<3)&0x03e0) | (((b)>>3)&0x001f))
630
631
632 void
633 vs_scanline_downsample_RGB555 (uint8_t * dest_u8, uint8_t * src_u8, int n)
634 {
635   uint16_t *dest = (uint16_t *) dest_u8;
636   uint16_t *src = (uint16_t *) src_u8;
637   int i;
638
639   for (i = 0; i < n; i++) {
640     dest[i] = RGB555 (
641         (RGB555_R (src[i * 2]) + RGB555_R (src[i * 2 + 1])) / 2,
642         (RGB555_G (src[i * 2]) + RGB555_G (src[i * 2 + 1])) / 2,
643         (RGB555_B (src[i * 2]) + RGB555_B (src[i * 2 + 1])) / 2);
644   }
645 }
646
647 void
648 vs_scanline_resample_nearest_RGB555 (uint8_t * dest_u8, uint8_t * src_u8,
649     int src_width, int n, int *accumulator, int increment)
650 {
651   uint16_t *dest = (uint16_t *) dest_u8;
652   uint16_t *src = (uint16_t *) src_u8;
653   int acc = *accumulator;
654   int i;
655   int j;
656   int x;
657
658   for (i = 0; i < n; i++) {
659     j = acc >> 16;
660     x = acc & 0xffff;
661     dest[i] = (x < 32768 || j + 1 >= src_width) ? src[j] : src[j + 1];
662
663     acc += increment;
664   }
665
666   *accumulator = acc;
667 }
668
669 void
670 vs_scanline_resample_linear_RGB555 (uint8_t * dest_u8, uint8_t * src_u8,
671     int src_width, int n, int *accumulator, int increment)
672 {
673   uint16_t *dest = (uint16_t *) dest_u8;
674   uint16_t *src = (uint16_t *) src_u8;
675   int acc = *accumulator;
676   int i;
677   int j;
678   int x;
679
680   for (i = 0; i < n; i++) {
681     j = acc >> 16;
682     x = acc & 0xffff;
683
684     if (j + 1 < src_width) {
685       dest[i] = RGB555 (
686           (RGB555_R (src[j]) * (65536 - x) + RGB555_R (src[j + 1]) * x) >> 16,
687           (RGB555_G (src[j]) * (65536 - x) + RGB555_G (src[j + 1]) * x) >> 16,
688           (RGB555_B (src[j]) * (65536 - x) + RGB555_B (src[j + 1]) * x) >> 16);
689     } else {
690       dest[i] = RGB555 (RGB555_R (src[j]),
691           RGB555_G (src[j]), RGB555_B (src[j]));
692     }
693
694     acc += increment;
695   }
696
697   *accumulator = acc;
698 }
699
700 void
701 vs_scanline_merge_linear_RGB555 (uint8_t * dest_u8, uint8_t * src1_u8,
702     uint8_t * src2_u8, int n, int x)
703 {
704   uint16_t *dest = (uint16_t *) dest_u8;
705   uint16_t *src1 = (uint16_t *) src1_u8;
706   uint16_t *src2 = (uint16_t *) src2_u8;
707   int i;
708
709   for (i = 0; i < n; i++) {
710     dest[i] = RGB555 (
711         (RGB555_R (src1[i]) * (65536 - x) + RGB555_R (src2[i]) * x) >> 16,
712         (RGB555_G (src1[i]) * (65536 - x) + RGB555_G (src2[i]) * x) >> 16,
713         (RGB555_B (src1[i]) * (65536 - x) + RGB555_B (src2[i]) * x) >> 16);
714   }
715 }
716
717 void
718 vs_scanline_resample_nearest_AYUV64 (uint8_t * dest8, uint8_t * src8,
719     int src_width, int n, int *accumulator, int increment)
720 {
721   guint16 *dest = (guint16 *) dest8;
722   guint16 *src = (guint16 *) src8;
723   int acc = *accumulator;
724   int i;
725   int j;
726   int x;
727
728   for (i = 0; i < n; i++) {
729     j = acc >> 16;
730     x = acc & 0xffff;
731     dest[i * 4 + 0] = (x < 32768
732         || j + 1 >= src_width) ? src[j * 4 + 0] : src[j * 4 + 4];
733     dest[i * 4 + 1] = (x < 32768
734         || j + 1 >= src_width) ? src[j * 4 + 1] : src[j * 4 + 5];
735     dest[i * 4 + 2] = (x < 32768
736         || j + 1 >= src_width) ? src[j * 4 + 2] : src[j * 4 + 6];
737     dest[i * 4 + 3] = (x < 32768
738         || j + 1 >= src_width) ? src[j * 4 + 3] : src[j * 4 + 7];
739
740     acc += increment;
741   }
742
743   *accumulator = acc;
744 }
745
746 void
747 vs_scanline_resample_linear_AYUV64 (uint8_t * dest8, uint8_t * src8,
748     int src_width, int n, int *accumulator, int increment)
749 {
750   guint16 *dest = (guint16 *) dest8;
751   guint16 *src = (guint16 *) src8;
752   int acc = *accumulator;
753   int i;
754   int j;
755   int x;
756
757   for (i = 0; i < n; i++) {
758     j = acc >> 16;
759     x = (acc & 0xffff) >> 1;
760
761     if (j + 1 < src_width) {
762       dest[i * 4 + 0] =
763           (src[j * 3 + 0] * (32768 - x) + src[j * 4 + 4] * x) >> 15;
764       dest[i * 4 + 1] =
765           (src[j * 4 + 1] * (32768 - x) + src[j * 4 + 5] * x) >> 15;
766       dest[i * 4 + 2] =
767           (src[j * 4 + 2] * (32768 - x) + src[j * 4 + 6] * x) >> 15;
768       dest[i * 4 + 3] =
769           (src[j * 4 + 3] * (32768 - x) + src[j * 4 + 7] * x) >> 15;
770     } else {
771       dest[i * 4 + 0] = src[j * 4 + 0];
772       dest[i * 4 + 1] = src[j * 4 + 1];
773       dest[i * 4 + 2] = src[j * 4 + 2];
774       dest[i * 4 + 3] = src[j * 4 + 3];
775     }
776
777     acc += increment;
778   }
779
780   *accumulator = acc;
781 }