gst_plugins_base/gst/videoscale/vs_image.c
changeset 0 0e761a78d257
child 8 4a7fac7dd34a
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     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 #define ROUND_UP_2(x)  (((x)+1)&~1)
       
    34 #define ROUND_UP_4(x)  (((x)+3)&~3)
       
    35 #define ROUND_UP_8(x)  (((x)+7)&~7)
       
    36 
       
    37 #ifdef __SYMBIAN32__
       
    38 EXPORT_C
       
    39 #endif
       
    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 x;
       
    50   int xacc;
       
    51 
       
    52   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
    53   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
    54 
       
    55   acc = 0;
       
    56   for (i = 0; i < dest->height; i++) {
       
    57     j = acc >> 16;
       
    58     x = acc & 0xffff;
       
    59 
       
    60     xacc = 0;
       
    61     vs_scanline_resample_nearest_RGBA (dest->pixels + i * dest->stride,
       
    62         src->pixels + j * src->stride, dest->width, &xacc, x_increment);
       
    63 
       
    64     acc += y_increment;
       
    65   }
       
    66 }
       
    67 #ifdef __SYMBIAN32__
       
    68 EXPORT_C
       
    69 #endif
       
    70 
       
    71 
       
    72 void
       
    73 vs_image_scale_linear_RGBA (const VSImage * dest, const VSImage * src,
       
    74     uint8_t * tmpbuf)
       
    75 {
       
    76   int acc;
       
    77   int y_increment;
       
    78   int x_increment;
       
    79   uint8_t *tmp1;
       
    80   uint8_t *tmp2;
       
    81   int y1;
       
    82   int y2;
       
    83   int i;
       
    84   int j;
       
    85   int x;
       
    86   int dest_size;
       
    87   int xacc;
       
    88 
       
    89   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
    90   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
    91 
       
    92   dest_size = dest->width * 4;
       
    93 
       
    94   tmp1 = tmpbuf;
       
    95   tmp2 = tmpbuf + dest_size;
       
    96 
       
    97   acc = 0;
       
    98   xacc = 0;
       
    99   y2 = -1;
       
   100   vs_scanline_resample_linear_RGBA (tmp1, src->pixels, dest->width, &xacc,
       
   101       x_increment);
       
   102   y1 = 0;
       
   103   for (i = 0; i < dest->height; i++) {
       
   104     j = acc >> 16;
       
   105     x = acc & 0xffff;
       
   106 
       
   107     if (x == 0) {
       
   108       if (j == y1) {
       
   109         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   110       } else if (j == y2) {
       
   111         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
       
   112       } else {
       
   113         xacc = 0;
       
   114         vs_scanline_resample_linear_RGBA (tmp1, src->pixels + j * src->stride,
       
   115             dest->width, &xacc, x_increment);
       
   116         y1 = j;
       
   117         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   118       }
       
   119     } else {
       
   120       if (j == y1) {
       
   121         if (j + 1 != y2) {
       
   122           xacc = 0;
       
   123           vs_scanline_resample_linear_RGBA (tmp2,
       
   124               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   125               x_increment);
       
   126           y2 = j + 1;
       
   127         }
       
   128         vs_scanline_merge_linear_RGBA (dest->pixels + i * dest->stride,
       
   129             tmp1, tmp2, dest->width, x);
       
   130       } else if (j == y2) {
       
   131         if (j + 1 != y1) {
       
   132           xacc = 0;
       
   133           vs_scanline_resample_linear_RGBA (tmp1,
       
   134               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   135               x_increment);
       
   136           y1 = j + 1;
       
   137         }
       
   138         vs_scanline_merge_linear_RGBA (dest->pixels + i * dest->stride,
       
   139             tmp2, tmp1, dest->width, x);
       
   140       } else {
       
   141         xacc = 0;
       
   142         vs_scanline_resample_linear_RGBA (tmp1, src->pixels + j * src->stride,
       
   143             dest->width, &xacc, x_increment);
       
   144         y1 = j;
       
   145         xacc = 0;
       
   146         vs_scanline_resample_linear_RGBA (tmp2,
       
   147             src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   148             x_increment);
       
   149         y2 = (j + 1);
       
   150         vs_scanline_merge_linear_RGBA (dest->pixels + i * dest->stride,
       
   151             tmp1, tmp2, dest->width, x);
       
   152       }
       
   153     }
       
   154 
       
   155     acc += y_increment;
       
   156   }
       
   157 }
       
   158 #ifdef __SYMBIAN32__
       
   159 EXPORT_C
       
   160 #endif
       
   161 
       
   162 
       
   163 
       
   164 void
       
   165 vs_image_scale_nearest_RGB (const VSImage * dest, const VSImage * src,
       
   166     uint8_t * tmpbuf)
       
   167 {
       
   168   int acc;
       
   169   int y_increment;
       
   170   int x_increment;
       
   171   int i;
       
   172   int j;
       
   173   int x;
       
   174   int xacc;
       
   175 
       
   176   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   177   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   178 
       
   179   acc = 0;
       
   180   for (i = 0; i < dest->height; i++) {
       
   181     j = acc >> 16;
       
   182     x = acc & 0xffff;
       
   183 
       
   184     xacc = 0;
       
   185     vs_scanline_resample_nearest_RGB (dest->pixels + i * dest->stride,
       
   186         src->pixels + j * src->stride, dest->width, &xacc, x_increment);
       
   187 
       
   188     acc += y_increment;
       
   189   }
       
   190 }
       
   191 #ifdef __SYMBIAN32__
       
   192 EXPORT_C
       
   193 #endif
       
   194 
       
   195 
       
   196 void
       
   197 vs_image_scale_linear_RGB (const VSImage * dest, const VSImage * src,
       
   198     uint8_t * tmpbuf)
       
   199 {
       
   200   int acc;
       
   201   int y_increment;
       
   202   int x_increment;
       
   203   uint8_t *tmp1;
       
   204   uint8_t *tmp2;
       
   205   int y1;
       
   206   int y2;
       
   207   int i;
       
   208   int j;
       
   209   int x;
       
   210   int dest_size;
       
   211   int xacc;
       
   212 
       
   213   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   214   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   215 
       
   216   dest_size = dest->width * 3;
       
   217 
       
   218   tmp1 = tmpbuf;
       
   219   tmp2 = tmpbuf + dest_size;
       
   220 
       
   221   acc = 0;
       
   222   xacc = 0;
       
   223   y2 = -1;
       
   224   vs_scanline_resample_linear_RGB (tmp1, src->pixels, dest->width, &xacc,
       
   225       x_increment);
       
   226   y1 = 0;
       
   227   for (i = 0; i < dest->height; i++) {
       
   228     j = acc >> 16;
       
   229     x = acc & 0xffff;
       
   230 
       
   231     if (x == 0) {
       
   232       if (j == y1) {
       
   233         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   234       } else if (j == y2) {
       
   235         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
       
   236       } else {
       
   237         xacc = 0;
       
   238         vs_scanline_resample_linear_RGB (tmp1, src->pixels + j * src->stride,
       
   239             dest->width, &xacc, x_increment);
       
   240         y1 = j;
       
   241         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   242       }
       
   243     } else {
       
   244       if (j == y1) {
       
   245         if (j + 1 != y2) {
       
   246           xacc = 0;
       
   247           vs_scanline_resample_linear_RGB (tmp2,
       
   248               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   249               x_increment);
       
   250           y2 = j + 1;
       
   251         }
       
   252         vs_scanline_merge_linear_RGB (dest->pixels + i * dest->stride,
       
   253             tmp1, tmp2, dest->width, x);
       
   254       } else if (j == y2) {
       
   255         if (j + 1 != y1) {
       
   256           xacc = 0;
       
   257           vs_scanline_resample_linear_RGB (tmp1,
       
   258               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   259               x_increment);
       
   260           y1 = j + 1;
       
   261         }
       
   262         vs_scanline_merge_linear_RGB (dest->pixels + i * dest->stride,
       
   263             tmp2, tmp1, dest->width, x);
       
   264       } else {
       
   265         xacc = 0;
       
   266         vs_scanline_resample_linear_RGB (tmp1, src->pixels + j * src->stride,
       
   267             dest->width, &xacc, x_increment);
       
   268         y1 = j;
       
   269         xacc = 0;
       
   270         vs_scanline_resample_linear_RGB (tmp2,
       
   271             src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   272             x_increment);
       
   273         y2 = (j + 1);
       
   274         vs_scanline_merge_linear_RGB (dest->pixels + i * dest->stride,
       
   275             tmp1, tmp2, dest->width, x);
       
   276       }
       
   277     }
       
   278 
       
   279     acc += y_increment;
       
   280   }
       
   281 }
       
   282 
       
   283 /* YUYV */
       
   284 #ifdef __SYMBIAN32__
       
   285 EXPORT_C
       
   286 #endif
       
   287 
       
   288 
       
   289 void
       
   290 vs_image_scale_nearest_YUYV (const VSImage * dest, const VSImage * src,
       
   291     uint8_t * tmpbuf)
       
   292 {
       
   293   int acc;
       
   294   int y_increment;
       
   295   int x_increment;
       
   296   int i;
       
   297   int j;
       
   298   int x;
       
   299   int xacc;
       
   300   int n_quads;
       
   301 
       
   302   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   303   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   304 
       
   305   n_quads = ROUND_UP_2 (dest->width) / 2;
       
   306   acc = 0;
       
   307   for (i = 0; i < dest->height; i++) {
       
   308     j = acc >> 16;
       
   309     x = acc & 0xffff;
       
   310 
       
   311     xacc = 0;
       
   312     vs_scanline_resample_nearest_YUYV (dest->pixels + i * dest->stride,
       
   313         src->pixels + j * src->stride, n_quads, &xacc, x_increment);
       
   314 
       
   315     acc += y_increment;
       
   316   }
       
   317 }
       
   318 #ifdef __SYMBIAN32__
       
   319 EXPORT_C
       
   320 #endif
       
   321 
       
   322 
       
   323 void
       
   324 vs_image_scale_linear_YUYV (const VSImage * dest, const VSImage * src,
       
   325     uint8_t * tmpbuf)
       
   326 {
       
   327   int acc;
       
   328   int y_increment;
       
   329   int x_increment;
       
   330   uint8_t *tmp1;
       
   331   uint8_t *tmp2;
       
   332   int y1;
       
   333   int y2;
       
   334   int i;
       
   335   int j;
       
   336   int x;
       
   337   int dest_size;
       
   338   int n_quads;
       
   339   int xacc;
       
   340 
       
   341   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   342   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   343 
       
   344   dest_size = ROUND_UP_4 (dest->width * 2);
       
   345   n_quads = ROUND_UP_2 (dest->width) / 2;
       
   346 
       
   347   tmp1 = tmpbuf;
       
   348   tmp2 = tmpbuf + dest_size;
       
   349 
       
   350   acc = 0;
       
   351   xacc = 0;
       
   352   y2 = -1;
       
   353   vs_scanline_resample_linear_YUYV (tmp1, src->pixels, n_quads, &xacc,
       
   354       x_increment);
       
   355   y1 = 0;
       
   356   for (i = 0; i < dest->height; i++) {
       
   357     j = acc >> 16;
       
   358     x = acc & 0xffff;
       
   359 
       
   360     if (x == 0) {
       
   361       if (j == y1) {
       
   362         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   363       } else if (j == y2) {
       
   364         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
       
   365       } else {
       
   366         xacc = 0;
       
   367         vs_scanline_resample_linear_YUYV (tmp1, src->pixels + j * src->stride,
       
   368             n_quads, &xacc, x_increment);
       
   369         y1 = j;
       
   370         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   371       }
       
   372     } else {
       
   373       if (j == y1) {
       
   374         if (j + 1 != y2) {
       
   375           xacc = 0;
       
   376           vs_scanline_resample_linear_YUYV (tmp2,
       
   377               src->pixels + (j + 1) * src->stride, n_quads, &xacc, x_increment);
       
   378           y2 = j + 1;
       
   379         }
       
   380         vs_scanline_merge_linear_YUYV (dest->pixels + i * dest->stride,
       
   381             tmp1, tmp2, n_quads, x);
       
   382       } else if (j == y2) {
       
   383         if (j + 1 != y1) {
       
   384           xacc = 0;
       
   385           vs_scanline_resample_linear_YUYV (tmp1,
       
   386               src->pixels + (j + 1) * src->stride, n_quads, &xacc, x_increment);
       
   387           y1 = j + 1;
       
   388         }
       
   389         vs_scanline_merge_linear_YUYV (dest->pixels + i * dest->stride,
       
   390             tmp2, tmp1, n_quads, x);
       
   391       } else {
       
   392         xacc = 0;
       
   393         vs_scanline_resample_linear_YUYV (tmp1, src->pixels + j * src->stride,
       
   394             n_quads, &xacc, x_increment);
       
   395         y1 = j;
       
   396         xacc = 0;
       
   397         vs_scanline_resample_linear_YUYV (tmp2,
       
   398             src->pixels + (j + 1) * src->stride, n_quads, &xacc, x_increment);
       
   399         y2 = (j + 1);
       
   400         vs_scanline_merge_linear_YUYV (dest->pixels + i * dest->stride,
       
   401             tmp1, tmp2, n_quads, x);
       
   402       }
       
   403     }
       
   404 
       
   405     acc += y_increment;
       
   406   }
       
   407 }
       
   408 
       
   409 /* UYVY */
       
   410 #ifdef __SYMBIAN32__
       
   411 EXPORT_C
       
   412 #endif
       
   413 
       
   414 
       
   415 void
       
   416 vs_image_scale_nearest_UYVY (const VSImage * dest, const VSImage * src,
       
   417     uint8_t * tmpbuf)
       
   418 {
       
   419   int acc;
       
   420   int y_increment;
       
   421   int x_increment;
       
   422   int i;
       
   423   int j;
       
   424   int x;
       
   425   int xacc;
       
   426   int n_quads;
       
   427 
       
   428   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   429   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   430 
       
   431   n_quads = (dest->width + 1) / 2;
       
   432   acc = 0;
       
   433   for (i = 0; i < dest->height; i++) {
       
   434     j = acc >> 16;
       
   435     x = acc & 0xffff;
       
   436 
       
   437     xacc = 0;
       
   438     vs_scanline_resample_nearest_UYVY (dest->pixels + i * dest->stride,
       
   439         src->pixels + j * src->stride, n_quads, &xacc, x_increment);
       
   440 
       
   441     acc += y_increment;
       
   442   }
       
   443 }
       
   444 #ifdef __SYMBIAN32__
       
   445 EXPORT_C
       
   446 #endif
       
   447 
       
   448 
       
   449 void
       
   450 vs_image_scale_linear_UYVY (const VSImage * dest, const VSImage * src,
       
   451     uint8_t * tmpbuf)
       
   452 {
       
   453   int acc;
       
   454   int y_increment;
       
   455   int x_increment;
       
   456   uint8_t *tmp1;
       
   457   uint8_t *tmp2;
       
   458   int y1;
       
   459   int y2;
       
   460   int i;
       
   461   int j;
       
   462   int x;
       
   463   int dest_size;
       
   464   int n_quads;
       
   465   int xacc;
       
   466 
       
   467   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   468   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   469 
       
   470   dest_size = ROUND_UP_4 (dest->width * 2);
       
   471   n_quads = ROUND_UP_2 (dest->width) / 2;
       
   472 
       
   473   tmp1 = tmpbuf;
       
   474   tmp2 = tmpbuf + dest_size;
       
   475 
       
   476   acc = 0;
       
   477   xacc = 0;
       
   478   y2 = -1;
       
   479   vs_scanline_resample_linear_UYVY (tmp1, src->pixels, n_quads, &xacc,
       
   480       x_increment);
       
   481   y1 = 0;
       
   482   for (i = 0; i < dest->height; i++) {
       
   483     j = acc >> 16;
       
   484     x = acc & 0xffff;
       
   485 
       
   486     if (x == 0) {
       
   487       if (j == y1) {
       
   488         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   489       } else if (j == y2) {
       
   490         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
       
   491       } else {
       
   492         xacc = 0;
       
   493         vs_scanline_resample_linear_UYVY (tmp1, src->pixels + j * src->stride,
       
   494             n_quads, &xacc, x_increment);
       
   495         y1 = j;
       
   496         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   497       }
       
   498     } else {
       
   499       if (j == y1) {
       
   500         if (j + 1 != y2) {
       
   501           xacc = 0;
       
   502           vs_scanline_resample_linear_UYVY (tmp2,
       
   503               src->pixels + (j + 1) * src->stride, n_quads, &xacc, x_increment);
       
   504           y2 = j + 1;
       
   505         }
       
   506         vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride,
       
   507             tmp1, tmp2, n_quads, x);
       
   508       } else if (j == y2) {
       
   509         if (j + 1 != y1) {
       
   510           xacc = 0;
       
   511           vs_scanline_resample_linear_UYVY (tmp1,
       
   512               src->pixels + (j + 1) * src->stride, n_quads, &xacc, x_increment);
       
   513           y1 = j + 1;
       
   514         }
       
   515         vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride,
       
   516             tmp2, tmp1, n_quads, x);
       
   517       } else {
       
   518         xacc = 0;
       
   519         vs_scanline_resample_linear_UYVY (tmp1, src->pixels + j * src->stride,
       
   520             n_quads, &xacc, x_increment);
       
   521         y1 = j;
       
   522         xacc = 0;
       
   523         vs_scanline_resample_linear_UYVY (tmp2,
       
   524             src->pixels + (j + 1) * src->stride, n_quads, &xacc, x_increment);
       
   525         y2 = (j + 1);
       
   526         vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride,
       
   527             tmp1, tmp2, n_quads, x);
       
   528       }
       
   529     }
       
   530 
       
   531     acc += y_increment;
       
   532   }
       
   533 }
       
   534 
       
   535 /* greyscale */
       
   536 #ifdef __SYMBIAN32__
       
   537 EXPORT_C
       
   538 #endif
       
   539 
       
   540 
       
   541 void
       
   542 vs_image_scale_nearest_Y (const VSImage * dest, const VSImage * src,
       
   543     uint8_t * tmpbuf)
       
   544 {
       
   545   int acc;
       
   546   int y_increment;
       
   547   int x_increment;
       
   548   int i;
       
   549   int j;
       
   550   int x;
       
   551   int xacc;
       
   552 
       
   553   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   554   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   555 
       
   556   acc = 0;
       
   557   for (i = 0; i < dest->height; i++) {
       
   558     j = acc >> 16;
       
   559     x = acc & 0xffff;
       
   560 
       
   561     xacc = 0;
       
   562     vs_scanline_resample_nearest_Y (dest->pixels + i * dest->stride,
       
   563         src->pixels + j * src->stride, dest->width, &xacc, x_increment);
       
   564 
       
   565     acc += y_increment;
       
   566   }
       
   567 }
       
   568 #ifdef __SYMBIAN32__
       
   569 EXPORT_C
       
   570 #endif
       
   571 
       
   572 
       
   573 void
       
   574 vs_image_scale_linear_Y (const VSImage * dest, const VSImage * src,
       
   575     uint8_t * tmpbuf)
       
   576 {
       
   577   int acc;
       
   578   int y_increment;
       
   579   int x_increment;
       
   580   uint8_t *tmp1;
       
   581   uint8_t *tmp2;
       
   582   int y1;
       
   583   int y2;
       
   584   int i;
       
   585   int j;
       
   586   int x;
       
   587   int dest_size;
       
   588   int xacc;
       
   589 
       
   590   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   591   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   592 
       
   593   dest_size = dest->width;
       
   594 
       
   595   tmp1 = tmpbuf;
       
   596   tmp2 = tmpbuf + dest_size;
       
   597 
       
   598   acc = 0;
       
   599   xacc = 0;
       
   600   y2 = -1;
       
   601   vs_scanline_resample_linear_Y (tmp1, src->pixels, dest->width, &xacc,
       
   602       x_increment);
       
   603   y1 = 0;
       
   604   for (i = 0; i < dest->height; i++) {
       
   605     j = acc >> 16;
       
   606     x = acc & 0xffff;
       
   607 
       
   608     if (x == 0) {
       
   609       if (j == y1) {
       
   610         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   611       } else if (j == y2) {
       
   612         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
       
   613       } else {
       
   614         xacc = 0;
       
   615         vs_scanline_resample_linear_Y (tmp1, src->pixels + j * src->stride,
       
   616             dest->width, &xacc, x_increment);
       
   617         y1 = j;
       
   618         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   619       }
       
   620     } else {
       
   621       if (j == y1) {
       
   622         if (j + 1 != y2) {
       
   623           xacc = 0;
       
   624           vs_scanline_resample_linear_Y (tmp2,
       
   625               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   626               x_increment);
       
   627           y2 = j + 1;
       
   628         }
       
   629         vs_scanline_merge_linear_Y (dest->pixels + i * dest->stride,
       
   630             tmp1, tmp2, dest->width, x);
       
   631       } else if (j == y2) {
       
   632         if (j + 1 != y1) {
       
   633           xacc = 0;
       
   634           vs_scanline_resample_linear_Y (tmp1,
       
   635               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   636               x_increment);
       
   637           y1 = j + 1;
       
   638         }
       
   639         vs_scanline_merge_linear_Y (dest->pixels + i * dest->stride,
       
   640             tmp2, tmp1, dest->width, x);
       
   641       } else {
       
   642         xacc = 0;
       
   643         vs_scanline_resample_linear_Y (tmp1, src->pixels + j * src->stride,
       
   644             dest->width, &xacc, x_increment);
       
   645         y1 = j;
       
   646         xacc = 0;
       
   647         vs_scanline_resample_linear_Y (tmp2,
       
   648             src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   649             x_increment);
       
   650         y2 = (j + 1);
       
   651         vs_scanline_merge_linear_Y (dest->pixels + i * dest->stride,
       
   652             tmp1, tmp2, dest->width, x);
       
   653       }
       
   654     }
       
   655 
       
   656     acc += y_increment;
       
   657   }
       
   658 }
       
   659 
       
   660 /* RGB565 */
       
   661 #ifdef __SYMBIAN32__
       
   662 EXPORT_C
       
   663 #endif
       
   664 
       
   665 
       
   666 void
       
   667 vs_image_scale_nearest_RGB565 (const VSImage * dest, const VSImage * src,
       
   668     uint8_t * tmpbuf)
       
   669 {
       
   670   int acc;
       
   671   int y_increment;
       
   672   int x_increment;
       
   673   int i;
       
   674   int j;
       
   675   int x;
       
   676   int xacc;
       
   677 
       
   678   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   679   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   680 
       
   681   acc = 0;
       
   682   for (i = 0; i < dest->height; i++) {
       
   683     j = acc >> 16;
       
   684     x = acc & 0xffff;
       
   685 
       
   686     xacc = 0;
       
   687     vs_scanline_resample_nearest_RGB565 (dest->pixels + i * dest->stride,
       
   688         src->pixels + j * src->stride, dest->width, &xacc, x_increment);
       
   689 
       
   690     acc += y_increment;
       
   691   }
       
   692 }
       
   693 #ifdef __SYMBIAN32__
       
   694 EXPORT_C
       
   695 #endif
       
   696 
       
   697 
       
   698 void
       
   699 vs_image_scale_linear_RGB565 (const VSImage * dest, const VSImage * src,
       
   700     uint8_t * tmpbuf)
       
   701 {
       
   702   int acc;
       
   703   int y_increment;
       
   704   int x_increment;
       
   705   uint8_t *tmp1;
       
   706   uint8_t *tmp2;
       
   707   int y1;
       
   708   int y2;
       
   709   int i;
       
   710   int j;
       
   711   int x;
       
   712   int dest_size;
       
   713   int xacc;
       
   714 
       
   715   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   716   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   717 
       
   718   dest_size = dest->width * 2;
       
   719 
       
   720   tmp1 = tmpbuf;
       
   721   tmp2 = tmpbuf + dest_size;
       
   722 
       
   723   acc = 0;
       
   724   xacc = 0;
       
   725   y2 = -1;
       
   726   vs_scanline_resample_linear_RGB565 (tmp1, src->pixels, dest->width, &xacc,
       
   727       x_increment);
       
   728   y1 = 0;
       
   729   for (i = 0; i < dest->height; i++) {
       
   730     j = acc >> 16;
       
   731     x = acc & 0xffff;
       
   732 
       
   733     if (x == 0) {
       
   734       if (j == y1) {
       
   735         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   736       } else if (j == y2) {
       
   737         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
       
   738       } else {
       
   739         xacc = 0;
       
   740         vs_scanline_resample_linear_RGB565 (tmp1, src->pixels + j * src->stride,
       
   741             dest->width, &xacc, x_increment);
       
   742         y1 = j;
       
   743         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   744       }
       
   745     } else {
       
   746       if (j == y1) {
       
   747         if (j + 1 != y2) {
       
   748           xacc = 0;
       
   749           vs_scanline_resample_linear_RGB565 (tmp2,
       
   750               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   751               x_increment);
       
   752           y2 = j + 1;
       
   753         }
       
   754         vs_scanline_merge_linear_RGB565 (dest->pixels + i * dest->stride,
       
   755             tmp1, tmp2, dest->width, x);
       
   756       } else if (j == y2) {
       
   757         if (j + 1 != y1) {
       
   758           xacc = 0;
       
   759           vs_scanline_resample_linear_RGB565 (tmp1,
       
   760               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   761               x_increment);
       
   762           y1 = j + 1;
       
   763         }
       
   764         vs_scanline_merge_linear_RGB565 (dest->pixels + i * dest->stride,
       
   765             tmp2, tmp1, dest->width, x);
       
   766       } else {
       
   767         xacc = 0;
       
   768         vs_scanline_resample_linear_RGB565 (tmp1, src->pixels + j * src->stride,
       
   769             dest->width, &xacc, x_increment);
       
   770         y1 = j;
       
   771         xacc = 0;
       
   772         vs_scanline_resample_linear_RGB565 (tmp2,
       
   773             src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   774             x_increment);
       
   775         y2 = (j + 1);
       
   776         vs_scanline_merge_linear_RGB565 (dest->pixels + i * dest->stride,
       
   777             tmp1, tmp2, dest->width, x);
       
   778       }
       
   779     }
       
   780 
       
   781     acc += y_increment;
       
   782   }
       
   783 }
       
   784 
       
   785 /* RGB555 */
       
   786 #ifdef __SYMBIAN32__
       
   787 EXPORT_C
       
   788 #endif
       
   789 
       
   790 
       
   791 void
       
   792 vs_image_scale_nearest_RGB555 (const VSImage * dest, const VSImage * src,
       
   793     uint8_t * tmpbuf)
       
   794 {
       
   795   int acc;
       
   796   int y_increment;
       
   797   int x_increment;
       
   798   int i;
       
   799   int j;
       
   800   int x;
       
   801   int xacc;
       
   802 
       
   803   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   804   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   805 
       
   806   acc = 0;
       
   807   for (i = 0; i < dest->height; i++) {
       
   808     j = acc >> 16;
       
   809     x = acc & 0xffff;
       
   810 
       
   811     xacc = 0;
       
   812     vs_scanline_resample_nearest_RGB555 (dest->pixels + i * dest->stride,
       
   813         src->pixels + j * src->stride, dest->width, &xacc, x_increment);
       
   814 
       
   815     acc += y_increment;
       
   816   }
       
   817 }
       
   818 #ifdef __SYMBIAN32__
       
   819 EXPORT_C
       
   820 #endif
       
   821 
       
   822 
       
   823 void
       
   824 vs_image_scale_linear_RGB555 (const VSImage * dest, const VSImage * src,
       
   825     uint8_t * tmpbuf)
       
   826 {
       
   827   int acc;
       
   828   int y_increment;
       
   829   int x_increment;
       
   830   uint8_t *tmp1;
       
   831   uint8_t *tmp2;
       
   832   int y1;
       
   833   int y2;
       
   834   int i;
       
   835   int j;
       
   836   int x;
       
   837   int dest_size;
       
   838   int xacc;
       
   839 
       
   840   y_increment = ((src->height - 1) << 16) / (dest->height - 1);
       
   841   x_increment = ((src->width - 1) << 16) / (dest->width - 1);
       
   842 
       
   843   dest_size = dest->width * 2;
       
   844 
       
   845   tmp1 = tmpbuf;
       
   846   tmp2 = tmpbuf + dest_size;
       
   847 
       
   848   acc = 0;
       
   849   xacc = 0;
       
   850   y2 = -1;
       
   851   vs_scanline_resample_linear_RGB555 (tmp1, src->pixels, dest->width, &xacc,
       
   852       x_increment);
       
   853   y1 = 0;
       
   854   for (i = 0; i < dest->height; i++) {
       
   855     j = acc >> 16;
       
   856     x = acc & 0xffff;
       
   857 
       
   858     if (x == 0) {
       
   859       if (j == y1) {
       
   860         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   861       } else if (j == y2) {
       
   862         memcpy (dest->pixels + i * dest->stride, tmp2, dest_size);
       
   863       } else {
       
   864         xacc = 0;
       
   865         vs_scanline_resample_linear_RGB555 (tmp1, src->pixels + j * src->stride,
       
   866             dest->width, &xacc, x_increment);
       
   867         y1 = j;
       
   868         memcpy (dest->pixels + i * dest->stride, tmp1, dest_size);
       
   869       }
       
   870     } else {
       
   871       if (j == y1) {
       
   872         if (j + 1 != y2) {
       
   873           xacc = 0;
       
   874           vs_scanline_resample_linear_RGB555 (tmp2,
       
   875               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   876               x_increment);
       
   877           y2 = j + 1;
       
   878         }
       
   879         vs_scanline_merge_linear_RGB555 (dest->pixels + i * dest->stride,
       
   880             tmp1, tmp2, dest->width, x);
       
   881       } else if (j == y2) {
       
   882         if (j + 1 != y1) {
       
   883           xacc = 0;
       
   884           vs_scanline_resample_linear_RGB555 (tmp1,
       
   885               src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   886               x_increment);
       
   887           y1 = j + 1;
       
   888         }
       
   889         vs_scanline_merge_linear_RGB555 (dest->pixels + i * dest->stride,
       
   890             tmp2, tmp1, dest->width, x);
       
   891       } else {
       
   892         xacc = 0;
       
   893         vs_scanline_resample_linear_RGB555 (tmp1, src->pixels + j * src->stride,
       
   894             dest->width, &xacc, x_increment);
       
   895         y1 = j;
       
   896         xacc = 0;
       
   897         vs_scanline_resample_linear_RGB555 (tmp2,
       
   898             src->pixels + (j + 1) * src->stride, dest->width, &xacc,
       
   899             x_increment);
       
   900         y2 = (j + 1);
       
   901         vs_scanline_merge_linear_RGB555 (dest->pixels + i * dest->stride,
       
   902             tmp1, tmp2, dest->width, x);
       
   903       }
       
   904     }
       
   905 
       
   906     acc += y_increment;
       
   907   }
       
   908 }