Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / gst / videoscale / vs_image.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 <string.h>
29
30 #include "vs_scanline.h"
31 #include "vs_image.h"
32
33 #include "gstvideoscaleorc.h"
34 #include <gst/gst.h>
35
36 #define ROUND_UP_2(x)  (((x)+1)&~1)
37 #define ROUND_UP_4(x)  (((x)+3)&~3)
38 #define ROUND_UP_8(x)  (((x)+7)&~7)
39
40 void
41 vs_image_scale_nearest_RGBA (const VSImage * dest, const VSImage * src,
42     uint8_t * tmpbuf)
43 {
44   int acc;
45   int y_increment;
46   int x_increment;
47   int i;
48   int j;
49   int prev_j;
50
51   if (dest->height == 1)
52     y_increment = 0;
53   else
54     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
55
56   if (dest->width == 1)
57     x_increment = 0;
58   else
59     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
60
61
62   acc = 0;
63   prev_j = -1;
64   for (i = 0; i < dest->height; i++) {
65     j = acc >> 16;
66
67     if (j == prev_j) {
68       memcpy (dest->pixels + i * dest->stride,
69           dest->pixels + (i - 1) * dest->stride, dest->width * 4);
70     } else {
71       gst_videoscale_orc_resample_nearest_u32 (dest->pixels + i * dest->stride,
72           src->pixels + j * src->stride, 0, x_increment, dest->width);
73     }
74
75     prev_j = j;
76     acc += y_increment;
77   }
78 }
79
80 void
81 vs_image_scale_linear_RGBA (const VSImage * dest, const VSImage * src,
82     uint8_t * tmpbuf)
83 {
84   int acc;
85   int y_increment;
86   int x_increment;
87   int y1;
88   int i;
89   int j;
90   int x;
91   int dest_size;
92
93   if (dest->height == 1)
94     y_increment = 0;
95   else
96     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
97
98   if (dest->width == 1)
99     x_increment = 0;
100   else
101     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
102
103   dest_size = dest->width * 4;
104
105 #define LINE(x) ((tmpbuf) + (dest_size)*((x)&1))
106
107   acc = 0;
108   gst_videoscale_orc_resample_bilinear_u32 (LINE (0), src->pixels,
109       0, x_increment, dest->width);
110   y1 = 0;
111   for (i = 0; i < dest->height; i++) {
112     j = acc >> 16;
113     x = acc & 0xffff;
114
115     if (x == 0) {
116       memcpy (dest->pixels + i * dest->stride, LINE (j), dest_size);
117     } else {
118       if (j > y1) {
119         gst_videoscale_orc_resample_bilinear_u32 (LINE (j),
120             src->pixels + j * src->stride, 0, x_increment, dest->width);
121         y1++;
122       }
123       if (j >= y1) {
124         gst_videoscale_orc_resample_bilinear_u32 (LINE (j + 1),
125             src->pixels + (j + 1) * src->stride, 0, x_increment, dest->width);
126         y1++;
127       }
128       orc_merge_linear_u8 (dest->pixels + i * dest->stride,
129           LINE (j), LINE (j + 1), (x >> 8), dest->width * 4);
130     }
131
132     acc += y_increment;
133   }
134 }
135
136
137 void
138 vs_image_scale_nearest_RGB (const VSImage * dest, const VSImage * src,
139     uint8_t * tmpbuf)
140 {
141   int acc;
142   int y_increment;
143   int x_increment;
144   int i;
145   int j;
146   int xacc;
147
148   if (dest->height == 1)
149     y_increment = 0;
150   else
151     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
152
153   if (dest->width == 1)
154     x_increment = 0;
155   else
156     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
157
158   acc = 0;
159   for (i = 0; i < dest->height; i++) {
160     j = acc >> 16;
161
162     xacc = 0;
163     vs_scanline_resample_nearest_RGB (dest->pixels + i * dest->stride,
164         src->pixels + j * src->stride, src->width, dest->width, &xacc,
165         x_increment);
166
167     acc += y_increment;
168   }
169 }
170
171 void
172 vs_image_scale_linear_RGB (const VSImage * dest, const VSImage * src,
173     uint8_t * tmpbuf)
174 {
175   int acc;
176   int y_increment;
177   int x_increment;
178   uint8_t *tmp1;
179   uint8_t *tmp2;
180   int y1;
181   int y2;
182   int i;
183   int j;
184   int x;
185   int dest_size;
186   int xacc;
187
188   if (dest->height == 1)
189     y_increment = 0;
190   else
191     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
192
193   if (dest->width == 1)
194     x_increment = 0;
195   else
196     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
197
198   dest_size = dest->width * 3;
199
200   tmp1 = tmpbuf;
201   tmp2 = tmpbuf + dest_size;
202
203   acc = 0;
204   xacc = 0;
205   y2 = -1;
206   vs_scanline_resample_linear_RGB (tmp1, src->pixels, src->width, dest->width,
207       &xacc, x_increment);
208   y1 = 0;
209   for (i = 0; i < dest->height; i++) {
210     j = acc >> 16;
211     x = acc & 0xffff;
212
213     if (x == 0) {
214       if (j == y1) {
215         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
216       } else if (j == y2) {
217         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
218       } else {
219         xacc = 0;
220         vs_scanline_resample_linear_RGB (tmp1, src->pixels + j * src->stride,
221             src->width, dest->width, &xacc, x_increment);
222         y1 = j;
223         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
224       }
225     } else {
226       if (j == y1) {
227         if (j + 1 != y2) {
228           xacc = 0;
229           vs_scanline_resample_linear_RGB (tmp2,
230               src->pixels + (j + 1) * src->stride, src->width, dest->width,
231               &xacc, x_increment);
232           y2 = j + 1;
233         }
234         vs_scanline_merge_linear_RGB (dest->pixels + i * dest->stride,
235             tmp1, tmp2, dest->width, x);
236       } else if (j == y2) {
237         if (j + 1 != y1) {
238           xacc = 0;
239           vs_scanline_resample_linear_RGB (tmp1,
240               src->pixels + (j + 1) * src->stride, src->width, dest->width,
241               &xacc, x_increment);
242           y1 = j + 1;
243         }
244         vs_scanline_merge_linear_RGB (dest->pixels + i * dest->stride,
245             tmp2, tmp1, dest->width, x);
246       } else {
247         xacc = 0;
248         vs_scanline_resample_linear_RGB (tmp1, src->pixels + j * src->stride,
249             src->width, dest->width, &xacc, x_increment);
250         y1 = j;
251         xacc = 0;
252         vs_scanline_resample_linear_RGB (tmp2,
253             src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc,
254             x_increment);
255         y2 = (j + 1);
256         vs_scanline_merge_linear_RGB (dest->pixels + i * dest->stride,
257             tmp1, tmp2, dest->width, x);
258       }
259     }
260
261     acc += y_increment;
262   }
263 }
264
265 /* YUYV */
266
267 void
268 vs_image_scale_nearest_YUYV (const VSImage * dest, const VSImage * src,
269     uint8_t * tmpbuf)
270 {
271   int acc;
272   int y_increment;
273   int x_increment;
274   int i;
275   int j;
276   int xacc;
277
278   if (dest->height == 1)
279     y_increment = 0;
280   else
281     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
282
283   if (dest->width == 1)
284     x_increment = 0;
285   else
286     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
287
288   acc = 0;
289   for (i = 0; i < dest->height; i++) {
290     j = acc >> 16;
291
292     xacc = 0;
293     vs_scanline_resample_nearest_YUYV (dest->pixels + i * dest->stride,
294         src->pixels + j * src->stride, src->width, dest->width, &xacc,
295         x_increment);
296
297     acc += y_increment;
298   }
299 }
300
301 void
302 vs_image_scale_linear_YUYV (const VSImage * dest, const VSImage * src,
303     uint8_t * tmpbuf)
304 {
305   int acc;
306   int y_increment;
307   int x_increment;
308   uint8_t *tmp1;
309   uint8_t *tmp2;
310   int y1;
311   int y2;
312   int i;
313   int j;
314   int x;
315   int dest_size;
316   int xacc;
317
318   if (dest->height == 1)
319     y_increment = 0;
320   else
321     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
322
323   if (dest->width == 1)
324     x_increment = 0;
325   else
326     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
327
328   dest_size = ROUND_UP_4 (dest->width * 2);
329
330   tmp1 = tmpbuf;
331   tmp2 = tmpbuf + dest_size;
332
333   acc = 0;
334   xacc = 0;
335   y2 = -1;
336   vs_scanline_resample_linear_YUYV (tmp1, src->pixels, src->width, dest->width,
337       &xacc, x_increment);
338   y1 = 0;
339   for (i = 0; i < dest->height; i++) {
340     j = acc >> 16;
341     x = acc & 0xffff;
342
343     if (x == 0) {
344       if (j == y1) {
345         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
346       } else if (j == y2) {
347         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
348       } else {
349         xacc = 0;
350         vs_scanline_resample_linear_YUYV (tmp1, src->pixels + j * src->stride,
351             src->width, dest->width, &xacc, x_increment);
352         y1 = j;
353         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
354       }
355     } else {
356       if (j == y1) {
357         if (j + 1 != y2) {
358           xacc = 0;
359           vs_scanline_resample_linear_YUYV (tmp2,
360               src->pixels + (j + 1) * src->stride, src->width, dest->width,
361               &xacc, x_increment);
362           y2 = j + 1;
363         }
364         vs_scanline_merge_linear_YUYV (dest->pixels + i * dest->stride,
365             tmp1, tmp2, dest->width, x);
366       } else if (j == y2) {
367         if (j + 1 != y1) {
368           xacc = 0;
369           vs_scanline_resample_linear_YUYV (tmp1,
370               src->pixels + (j + 1) * src->stride, src->width, dest->width,
371               &xacc, x_increment);
372           y1 = j + 1;
373         }
374         vs_scanline_merge_linear_YUYV (dest->pixels + i * dest->stride,
375             tmp2, tmp1, dest->width, x);
376       } else {
377         xacc = 0;
378         vs_scanline_resample_linear_YUYV (tmp1, src->pixels + j * src->stride,
379             src->width, dest->width, &xacc, x_increment);
380         y1 = j;
381         xacc = 0;
382         vs_scanline_resample_linear_YUYV (tmp2,
383             src->pixels + (j + 1) * src->stride, src->width, dest->width,
384             &xacc, x_increment);
385         y2 = (j + 1);
386         vs_scanline_merge_linear_YUYV (dest->pixels + i * dest->stride,
387             tmp1, tmp2, dest->width, x);
388       }
389     }
390
391     acc += y_increment;
392   }
393 }
394
395 /* UYVY */
396
397 void
398 vs_image_scale_nearest_UYVY (const VSImage * dest, const VSImage * src,
399     uint8_t * tmpbuf)
400 {
401   int acc;
402   int y_increment;
403   int x_increment;
404   int i;
405   int j;
406   int xacc;
407
408   if (dest->height == 1)
409     y_increment = 0;
410   else
411     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
412
413   if (dest->width == 1)
414     x_increment = 0;
415   else
416     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
417
418   acc = 0;
419   for (i = 0; i < dest->height; i++) {
420     j = acc >> 16;
421
422     xacc = 0;
423     vs_scanline_resample_nearest_UYVY (dest->pixels + i * dest->stride,
424         src->pixels + j * src->stride, src->width, dest->width, &xacc,
425         x_increment);
426
427     acc += y_increment;
428   }
429 }
430
431 void
432 vs_image_scale_linear_UYVY (const VSImage * dest, const VSImage * src,
433     uint8_t * tmpbuf)
434 {
435   int acc;
436   int y_increment;
437   int x_increment;
438   uint8_t *tmp1;
439   uint8_t *tmp2;
440   int y1;
441   int y2;
442   int i;
443   int j;
444   int x;
445   int dest_size;
446   int xacc;
447
448   if (dest->height == 1)
449     y_increment = 0;
450   else
451     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
452
453   if (dest->width == 1)
454     x_increment = 0;
455   else
456     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
457
458   dest_size = ROUND_UP_4 (dest->width * 2);
459
460   tmp1 = tmpbuf;
461   tmp2 = tmpbuf + dest_size;
462
463   acc = 0;
464   xacc = 0;
465   y2 = -1;
466   vs_scanline_resample_linear_UYVY (tmp1, src->pixels, src->width, dest->width,
467       &xacc, x_increment);
468   y1 = 0;
469   for (i = 0; i < dest->height; i++) {
470     j = acc >> 16;
471     x = acc & 0xffff;
472
473     if (x == 0) {
474       if (j == y1) {
475         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
476       } else if (j == y2) {
477         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
478       } else {
479         xacc = 0;
480         vs_scanline_resample_linear_UYVY (tmp1, src->pixels + j * src->stride,
481             src->width, dest->width, &xacc, x_increment);
482         y1 = j;
483         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
484       }
485     } else {
486       if (j == y1) {
487         if (j + 1 != y2) {
488           xacc = 0;
489           vs_scanline_resample_linear_UYVY (tmp2,
490               src->pixels + (j + 1) * src->stride, src->width, dest->width,
491               &xacc, x_increment);
492           y2 = j + 1;
493         }
494         vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride,
495             tmp1, tmp2, dest->width, x);
496       } else if (j == y2) {
497         if (j + 1 != y1) {
498           xacc = 0;
499           vs_scanline_resample_linear_UYVY (tmp1,
500               src->pixels + (j + 1) * src->stride, src->width, dest->width,
501               &xacc, x_increment);
502           y1 = j + 1;
503         }
504         vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride,
505             tmp2, tmp1, dest->width, x);
506       } else {
507         xacc = 0;
508         vs_scanline_resample_linear_UYVY (tmp1, src->pixels + j * src->stride,
509             src->width, dest->width, &xacc, x_increment);
510         y1 = j;
511         xacc = 0;
512         vs_scanline_resample_linear_UYVY (tmp2,
513             src->pixels + (j + 1) * src->stride, src->width, dest->width,
514             &xacc, x_increment);
515         y2 = (j + 1);
516         vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride,
517             tmp1, tmp2, dest->width, x);
518       }
519     }
520
521     acc += y_increment;
522   }
523 }
524
525 /* greyscale */
526
527 void
528 vs_image_scale_nearest_Y (const VSImage * dest, const VSImage * src,
529     uint8_t * tmpbuf)
530 {
531   int acc;
532   int y_increment;
533   int x_increment;
534   int i;
535   int j;
536
537   if (dest->height == 1)
538     y_increment = 0;
539   else
540     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
541
542   if (dest->width == 1)
543     x_increment = 0;
544   else
545     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
546
547   acc = 0;
548   for (i = 0; i < dest->height; i++) {
549     j = acc >> 16;
550
551     gst_videoscale_orc_resample_nearest_u8 (dest->pixels + i * dest->stride,
552         src->pixels + j * src->stride, 0, x_increment, dest->width);
553     acc += y_increment;
554   }
555 }
556
557 void
558 vs_image_scale_linear_Y (const VSImage * dest, const VSImage * src,
559     uint8_t * tmpbuf)
560 {
561   int acc;
562   int y_increment;
563   int x_increment;
564   uint8_t *tmp1;
565   uint8_t *tmp2;
566   int y1;
567   int y2;
568   int i;
569   int j;
570   int x;
571   int dest_size;
572
573   if (dest->height == 1)
574     y_increment = 0;
575   else
576     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
577
578   if (dest->width == 1)
579     x_increment = 0;
580   else
581     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
582
583   dest_size = dest->width;
584
585   tmp1 = tmpbuf;
586   tmp2 = tmpbuf + dest_size;
587
588   acc = 0;
589   y2 = -1;
590   gst_videoscale_orc_resample_bilinear_u8 (tmp1, src->pixels,
591       0, x_increment, dest->width);
592   y1 = 0;
593   for (i = 0; i < dest->height; i++) {
594     j = acc >> 16;
595     x = acc & 0xffff;
596
597     if (x == 0) {
598       if (j == y1) {
599         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
600       } else if (j == y2) {
601         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
602       } else {
603         gst_videoscale_orc_resample_bilinear_u8 (tmp1,
604             src->pixels + j * src->stride, 0, x_increment, dest->width);
605         y1 = j;
606         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
607       }
608     } else {
609       if (j == y1) {
610         if (j + 1 != y2) {
611           gst_videoscale_orc_resample_bilinear_u8 (tmp2,
612               src->pixels + (j + 1) * src->stride, 0, x_increment, dest->width);
613           y2 = j + 1;
614         }
615         if ((x >> 8) == 0) {
616           memcpy (dest->pixels + i * dest->stride, tmp1, dest->width);
617         } else {
618           orc_merge_linear_u8 (dest->pixels + i * dest->stride,
619               tmp1, tmp2, (x >> 8), dest->width);
620         }
621       } else if (j == y2) {
622         if (j + 1 != y1) {
623           gst_videoscale_orc_resample_bilinear_u8 (tmp1,
624               src->pixels + (j + 1) * src->stride, 0, x_increment, dest->width);
625           y1 = j + 1;
626         }
627         if ((x >> 8) == 0) {
628           memcpy (dest->pixels + i * dest->stride, tmp2, dest->width);
629         } else {
630           orc_merge_linear_u8 (dest->pixels + i * dest->stride,
631               tmp2, tmp1, (x >> 8), dest->width);
632         }
633       } else {
634         gst_videoscale_orc_resample_bilinear_u8 (tmp1,
635             src->pixels + j * src->stride, 0, x_increment, dest->width);
636         y1 = j;
637         gst_videoscale_orc_resample_bilinear_u8 (tmp2,
638             src->pixels + (j + 1) * src->stride, 0, x_increment, dest->width);
639         y2 = (j + 1);
640         if ((x >> 8) == 0) {
641           memcpy (dest->pixels + i * dest->stride, tmp1, dest->width);
642         } else {
643           orc_merge_linear_u8 (dest->pixels + i * dest->stride,
644               tmp1, tmp2, (x >> 8), dest->width);
645         }
646       }
647     }
648
649     acc += y_increment;
650   }
651 }
652
653 void
654 vs_image_scale_nearest_Y16 (const VSImage * dest, const VSImage * src,
655     uint8_t * tmpbuf)
656 {
657   int acc;
658   int y_increment;
659   int x_increment;
660   int i;
661   int j;
662   int xacc;
663
664   if (dest->height == 1)
665     y_increment = 0;
666   else
667     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
668
669   if (dest->width == 1)
670     x_increment = 0;
671   else
672     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
673
674   acc = 0;
675   for (i = 0; i < dest->height; i++) {
676     j = acc >> 16;
677
678     xacc = 0;
679     vs_scanline_resample_nearest_Y16 (dest->pixels + i * dest->stride,
680         src->pixels + j * src->stride, src->width, dest->width, &xacc,
681         x_increment);
682
683     acc += y_increment;
684   }
685 }
686
687 void
688 vs_image_scale_linear_Y16 (const VSImage * dest, const VSImage * src,
689     uint8_t * tmpbuf)
690 {
691   int acc;
692   int y_increment;
693   int x_increment;
694   uint8_t *tmp1;
695   uint8_t *tmp2;
696   int y1;
697   int y2;
698   int i;
699   int j;
700   int x;
701   int dest_size;
702   int xacc;
703
704   if (dest->height == 1)
705     y_increment = 0;
706   else
707     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
708
709   if (dest->width == 1)
710     x_increment = 0;
711   else
712     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
713
714   dest_size = 2 * dest->width;
715
716   tmp1 = tmpbuf;
717   tmp2 = tmpbuf + dest_size;
718
719   acc = 0;
720   xacc = 0;
721   y2 = -1;
722   vs_scanline_resample_linear_Y16 (tmp1, src->pixels, src->width, dest->width,
723       &xacc, x_increment);
724   y1 = 0;
725   for (i = 0; i < dest->height; i++) {
726     j = acc >> 16;
727     x = acc & 0xffff;
728
729     if (x == 0) {
730       if (j == y1) {
731         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
732       } else if (j == y2) {
733         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
734       } else {
735         xacc = 0;
736         vs_scanline_resample_linear_Y16 (tmp1, src->pixels + j * src->stride,
737             src->width, dest->width, &xacc, x_increment);
738         y1 = j;
739         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
740       }
741     } else {
742       if (j == y1) {
743         if (j + 1 != y2) {
744           xacc = 0;
745           vs_scanline_resample_linear_Y16 (tmp2,
746               src->pixels + (j + 1) * src->stride, src->width, dest->width,
747               &xacc, x_increment);
748           y2 = j + 1;
749         }
750         vs_scanline_merge_linear_Y16 (dest->pixels + i * dest->stride,
751             tmp1, tmp2, dest->width, x);
752       } else if (j == y2) {
753         if (j + 1 != y1) {
754           xacc = 0;
755           vs_scanline_resample_linear_Y16 (tmp1,
756               src->pixels + (j + 1) * src->stride, src->width, dest->width,
757               &xacc, x_increment);
758           y1 = j + 1;
759         }
760         vs_scanline_merge_linear_Y16 (dest->pixels + i * dest->stride,
761             tmp2, tmp1, dest->width, x);
762       } else {
763         xacc = 0;
764         vs_scanline_resample_linear_Y16 (tmp1, src->pixels + j * src->stride,
765             src->width, dest->width, &xacc, x_increment);
766         y1 = j;
767         xacc = 0;
768         vs_scanline_resample_linear_Y16 (tmp2,
769             src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc,
770             x_increment);
771         y2 = (j + 1);
772         vs_scanline_merge_linear_Y16 (dest->pixels + i * dest->stride,
773             tmp1, tmp2, dest->width, x);
774       }
775     }
776
777     acc += y_increment;
778   }
779 }
780
781 /* RGB565 */
782
783 void
784 vs_image_scale_nearest_RGB565 (const VSImage * dest, const VSImage * src,
785     uint8_t * tmpbuf)
786 {
787   int acc;
788   int y_increment;
789   int x_increment;
790   int i;
791   int j;
792   int xacc;
793
794   if (dest->height == 1)
795     y_increment = 0;
796   else
797     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
798
799   if (dest->width == 1)
800     x_increment = 0;
801   else
802     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
803
804   acc = 0;
805   for (i = 0; i < dest->height; i++) {
806     j = acc >> 16;
807
808     xacc = 0;
809     vs_scanline_resample_nearest_RGB565 (dest->pixels + i * dest->stride,
810         src->pixels + j * src->stride, src->width, dest->width, &xacc,
811         x_increment);
812
813     acc += y_increment;
814   }
815 }
816
817 void
818 vs_image_scale_linear_RGB565 (const VSImage * dest, const VSImage * src,
819     uint8_t * tmpbuf)
820 {
821   int acc;
822   int y_increment;
823   int x_increment;
824   uint8_t *tmp1;
825   uint8_t *tmp2;
826   int y1;
827   int y2;
828   int i;
829   int j;
830   int x;
831   int dest_size;
832   int xacc;
833
834   if (dest->height == 1)
835     y_increment = 0;
836   else
837     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
838
839   if (dest->width == 1)
840     x_increment = 0;
841   else
842     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
843
844   dest_size = dest->width * 2;
845
846   tmp1 = tmpbuf;
847   tmp2 = tmpbuf + dest_size;
848
849   acc = 0;
850   xacc = 0;
851   y2 = -1;
852   vs_scanline_resample_linear_RGB565 (tmp1, src->pixels, src->width,
853       dest->width, &xacc, x_increment);
854   y1 = 0;
855   for (i = 0; i < dest->height; i++) {
856     j = acc >> 16;
857     x = acc & 0xffff;
858
859     if (x == 0) {
860       if (j == y1) {
861         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
862       } else if (j == y2) {
863         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
864       } else {
865         xacc = 0;
866         vs_scanline_resample_linear_RGB565 (tmp1, src->pixels + j * src->stride,
867             src->width, dest->width, &xacc, x_increment);
868         y1 = j;
869         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
870       }
871     } else {
872       if (j == y1) {
873         if (j + 1 != y2) {
874           xacc = 0;
875           vs_scanline_resample_linear_RGB565 (tmp2,
876               src->pixels + (j + 1) * src->stride, src->width, dest->width,
877               &xacc, x_increment);
878           y2 = j + 1;
879         }
880         vs_scanline_merge_linear_RGB565 (dest->pixels + i * dest->stride,
881             tmp1, tmp2, dest->width, x);
882       } else if (j == y2) {
883         if (j + 1 != y1) {
884           xacc = 0;
885           vs_scanline_resample_linear_RGB565 (tmp1,
886               src->pixels + (j + 1) * src->stride, src->width, dest->width,
887               &xacc, x_increment);
888           y1 = j + 1;
889         }
890         vs_scanline_merge_linear_RGB565 (dest->pixels + i * dest->stride,
891             tmp2, tmp1, dest->width, x);
892       } else {
893         xacc = 0;
894         vs_scanline_resample_linear_RGB565 (tmp1, src->pixels + j * src->stride,
895             src->width, dest->width, &xacc, x_increment);
896         y1 = j;
897         xacc = 0;
898         vs_scanline_resample_linear_RGB565 (tmp2,
899             src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc,
900             x_increment);
901         y2 = (j + 1);
902         vs_scanline_merge_linear_RGB565 (dest->pixels + i * dest->stride,
903             tmp1, tmp2, dest->width, x);
904       }
905     }
906
907     acc += y_increment;
908   }
909 }
910
911 /* RGB555 */
912
913 void
914 vs_image_scale_nearest_RGB555 (const VSImage * dest, const VSImage * src,
915     uint8_t * tmpbuf)
916 {
917   int acc;
918   int y_increment;
919   int x_increment;
920   int i;
921   int j;
922   int xacc;
923
924   if (dest->height == 1)
925     y_increment = 0;
926   else
927     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
928
929   if (dest->width == 1)
930     x_increment = 0;
931   else
932     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
933
934   acc = 0;
935   for (i = 0; i < dest->height; i++) {
936     j = acc >> 16;
937
938     xacc = 0;
939     vs_scanline_resample_nearest_RGB555 (dest->pixels + i * dest->stride,
940         src->pixels + j * src->stride, src->width, dest->width, &xacc,
941         x_increment);
942
943     acc += y_increment;
944   }
945 }
946
947 void
948 vs_image_scale_linear_RGB555 (const VSImage * dest, const VSImage * src,
949     uint8_t * tmpbuf)
950 {
951   int acc;
952   int y_increment;
953   int x_increment;
954   uint8_t *tmp1;
955   uint8_t *tmp2;
956   int y1;
957   int y2;
958   int i;
959   int j;
960   int x;
961   int dest_size;
962   int xacc;
963
964   if (dest->height == 1)
965     y_increment = 0;
966   else
967     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
968
969   if (dest->width == 1)
970     x_increment = 0;
971   else
972     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
973
974   dest_size = dest->width * 2;
975
976   tmp1 = tmpbuf;
977   tmp2 = tmpbuf + dest_size;
978
979   acc = 0;
980   xacc = 0;
981   y2 = -1;
982   vs_scanline_resample_linear_RGB555 (tmp1, src->pixels, src->width,
983       dest->width, &xacc, x_increment);
984   y1 = 0;
985   for (i = 0; i < dest->height; i++) {
986     j = acc >> 16;
987     x = acc & 0xffff;
988
989     if (x == 0) {
990       if (j == y1) {
991         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
992       } else if (j == y2) {
993         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
994       } else {
995         xacc = 0;
996         vs_scanline_resample_linear_RGB555 (tmp1, src->pixels + j * src->stride,
997             src->width, dest->width, &xacc, x_increment);
998         y1 = j;
999         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
1000       }
1001     } else {
1002       if (j == y1) {
1003         if (j + 1 != y2) {
1004           xacc = 0;
1005           vs_scanline_resample_linear_RGB555 (tmp2,
1006               src->pixels + (j + 1) * src->stride, src->width, dest->width,
1007               &xacc, x_increment);
1008           y2 = j + 1;
1009         }
1010         vs_scanline_merge_linear_RGB555 (dest->pixels + i * dest->stride,
1011             tmp1, tmp2, dest->width, x);
1012       } else if (j == y2) {
1013         if (j + 1 != y1) {
1014           xacc = 0;
1015           vs_scanline_resample_linear_RGB555 (tmp1,
1016               src->pixels + (j + 1) * src->stride, src->width, dest->width,
1017               &xacc, x_increment);
1018           y1 = j + 1;
1019         }
1020         vs_scanline_merge_linear_RGB555 (dest->pixels + i * dest->stride,
1021             tmp2, tmp1, dest->width, x);
1022       } else {
1023         xacc = 0;
1024         vs_scanline_resample_linear_RGB555 (tmp1, src->pixels + j * src->stride,
1025             src->width, dest->width, &xacc, x_increment);
1026         y1 = j;
1027         xacc = 0;
1028         vs_scanline_resample_linear_RGB555 (tmp2,
1029             src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc,
1030             x_increment);
1031         y2 = (j + 1);
1032         vs_scanline_merge_linear_RGB555 (dest->pixels + i * dest->stride,
1033             tmp1, tmp2, dest->width, x);
1034       }
1035     }
1036
1037     acc += y_increment;
1038   }
1039 }
1040
1041 void
1042 vs_image_scale_nearest_AYUV64 (const VSImage * dest, const VSImage * src,
1043     uint8_t * tmpbuf8)
1044 {
1045   int acc;
1046   int y_increment;
1047   int x_increment;
1048   int i;
1049   int j;
1050   int prev_j;
1051
1052   if (dest->height == 1)
1053     y_increment = 0;
1054   else
1055     y_increment = ((src->height - 1) << 16) / (dest->height - 1);
1056
1057   if (dest->width == 1)
1058     x_increment = 0;
1059   else
1060     x_increment = ((src->width - 1) << 16) / (dest->width - 1);
1061
1062
1063   acc = 0;
1064   prev_j = -1;
1065   for (i = 0; i < dest->height; i++) {
1066     j = acc >> 16;
1067
1068     if (j == prev_j) {
1069       memcpy (dest->pixels + i * dest->stride,
1070           dest->pixels + (i - 1) * dest->stride, dest->width * 8);
1071     } else {
1072       int xacc = 0;
1073       vs_scanline_resample_nearest_AYUV64 (dest->pixels + i * dest->stride,
1074           src->pixels + j * src->stride, src->width, dest->width, &xacc,
1075           x_increment);
1076     }
1077
1078     prev_j = j;
1079     acc += y_increment;
1080   }
1081 }
1082
1083 void
1084 vs_image_scale_linear_AYUV64 (const VSImage * dest, const VSImage * src,
1085     uint8_t * tmpbuf)
1086 {
1087   int acc;
1088   int y_increment;
1089   int x_increment;
1090   int y1;
1091   int i;
1092   int j;
1093   int x;
1094   int dest_size;
1095   int xacc;
1096
1097   if (dest->height == 1)
1098     y_increment = 0;
1099   else
1100     y_increment = ((src->height - 1) << 16) / (dest->height - 1) - 1;
1101
1102   if (dest->width == 1)
1103     x_increment = 0;
1104   else
1105     x_increment = ((src->width - 1) << 16) / (dest->width - 1) - 1;
1106
1107   dest_size = dest->width * 8;
1108
1109 #undef LINE
1110 #define LINE(x) ((guint16 *)((tmpbuf) + (dest_size)*((x)&1)))
1111
1112   acc = 0;
1113   //gst_videoscale_orc_resample_bilinear_u64 (LINE (0), src->pixels,
1114   //    0, x_increment, dest->width);
1115   xacc = 0;
1116   vs_scanline_resample_linear_AYUV64 ((guint8 *) LINE (0),
1117       src->pixels, src->width, dest->width, &xacc, x_increment);
1118   y1 = 0;
1119   for (i = 0; i < dest->height; i++) {
1120     j = acc >> 16;
1121     x = acc & 0xffff;
1122
1123     if (x == 0) {
1124       memcpy (dest->pixels + i * dest->stride, LINE (j), dest_size);
1125     } else {
1126       if (j > y1) {
1127         xacc = 0;
1128         vs_scanline_resample_linear_AYUV64 ((guint8 *) LINE (j),
1129             src->pixels + j * src->stride, src->width, dest->width, &xacc,
1130             x_increment);
1131         //gst_videoscale_orc_resample_bilinear_u64 (LINE (j),
1132         //    src->pixels + j * src->stride, 0, x_increment, dest->width);
1133         y1++;
1134       }
1135       if (j >= y1) {
1136         xacc = 0;
1137         vs_scanline_resample_linear_AYUV64 ((guint8 *) LINE (j + 1),
1138             src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc,
1139             x_increment);
1140         orc_merge_linear_u16 ((guint16 *) (dest->pixels + i * dest->stride),
1141             LINE (j), LINE (j + 1), 65536 - x, x, dest->width * 4);
1142         //gst_videoscale_orc_resample_merge_bilinear_u64 (dest->pixels +
1143         //    i * dest->stride, LINE (j + 1), LINE (j),
1144         //    src->pixels + (j + 1) * src->stride, (x >> 8), 0, x_increment,
1145         //    dest->width);
1146         y1++;
1147       } else {
1148         orc_merge_linear_u16 ((guint16 *) (dest->pixels + i * dest->stride),
1149             LINE (j), LINE (j + 1), 65536 - x, x, dest->width * 4);
1150       }
1151     }
1152
1153     acc += y_increment;
1154   }
1155 }