media/libvpx/vpx_scale/generic/vpx_scale.c

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /*
     2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
     3  *
     4  *  Use of this source code is governed by a BSD-style license
     5  *  that can be found in the LICENSE file in the root of the source
     6  *  tree. An additional intellectual property rights grant can be found
     7  *  in the file PATENTS.  All contributing project authors may
     8  *  be found in the AUTHORS file in the root of the source tree.
     9  */
    12 /****************************************************************************
    13  *
    14  *   Module Title :     scale.c
    15  *
    16  *   Description  :     Image scaling functions.
    17  *
    18  ***************************************************************************/
    20 /****************************************************************************
    21 *  Header Files
    22 ****************************************************************************/
    23 #include "./vpx_scale_rtcd.h"
    24 #include "vpx_mem/vpx_mem.h"
    25 #include "vpx_scale/yv12config.h"
    27 typedef struct {
    28   int     expanded_frame_width;
    29   int     expanded_frame_height;
    31   int HScale;
    32   int HRatio;
    33   int VScale;
    34   int VRatio;
    36   YV12_BUFFER_CONFIG *src_yuv_config;
    37   YV12_BUFFER_CONFIG *dst_yuv_config;
    39 } SCALE_VARS;
    41 /****************************************************************************
    42  *
    43  *  ROUTINE       : scale1d_2t1_i
    44  *
    45  *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
    46  *                  int source_step              : Number of pixels to step on in source.
    47  *                  unsigned int source_scale    : Scale for source (UNUSED).
    48  *                  unsigned int source_length   : Length of source (UNUSED).
    49  *                  unsigned char *dest         : Pointer to output data array.
    50  *                  int dest_step                : Number of pixels to step on in destination.
    51  *                  unsigned int dest_scale      : Scale for destination (UNUSED).
    52  *                  unsigned int dest_length     : Length of destination.
    53  *
    54  *  OUTPUTS       : None.
    55  *
    56  *  RETURNS       : void
    57  *
    58  *  FUNCTION      : Performs 2-to-1 interpolated scaling.
    59  *
    60  *  SPECIAL NOTES : None.
    61  *
    62  ****************************************************************************/
    63 static
    64 void scale1d_2t1_i
    65 (
    66   const unsigned char *source,
    67   int source_step,
    68   unsigned int source_scale,
    69   unsigned int source_length,
    70   unsigned char *dest,
    71   int dest_step,
    72   unsigned int dest_scale,
    73   unsigned int dest_length
    74 ) {
    75   unsigned int i, j;
    76   unsigned int temp;
    77   int source_pitch = source_step;
    78   (void) source_length;
    79   (void) source_scale;
    80   (void) dest_scale;
    82   source_step *= 2;
    83   dest[0] = source[0];
    85   for (i = dest_step, j = source_step; i < dest_length * dest_step; i += dest_step, j += source_step) {
    86     temp = 8;
    87     temp += 3 * source[j - source_pitch];
    88     temp += 10 * source[j];
    89     temp += 3 * source[j + source_pitch];
    90     temp >>= 4;
    91     dest[i] = (char)(temp);
    92   }
    93 }
    95 /****************************************************************************
    96  *
    97  *  ROUTINE       : scale1d_2t1_ps
    98  *
    99  *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
   100  *                  int source_step              : Number of pixels to step on in source.
   101  *                  unsigned int source_scale    : Scale for source (UNUSED).
   102  *                  unsigned int source_length   : Length of source (UNUSED).
   103  *                  unsigned char *dest         : Pointer to output data array.
   104  *                  int dest_step                : Number of pixels to step on in destination.
   105  *                  unsigned int dest_scale      : Scale for destination (UNUSED).
   106  *                  unsigned int dest_length     : Length of destination.
   107  *
   108  *  OUTPUTS       : None.
   109  *
   110  *  RETURNS       : void
   111  *
   112  *  FUNCTION      : Performs 2-to-1 point subsampled scaling.
   113  *
   114  *  SPECIAL NOTES : None.
   115  *
   116  ****************************************************************************/
   117 static
   118 void scale1d_2t1_ps
   119 (
   120   const unsigned char *source,
   121   int source_step,
   122   unsigned int source_scale,
   123   unsigned int source_length,
   124   unsigned char *dest,
   125   int dest_step,
   126   unsigned int dest_scale,
   127   unsigned int dest_length
   128 ) {
   129   unsigned int i, j;
   131   (void) source_length;
   132   (void) source_scale;
   133   (void) dest_scale;
   135   source_step *= 2;
   136   j = 0;
   138   for (i = 0; i < dest_length * dest_step; i += dest_step, j += source_step)
   139     dest[i] = source[j];
   140 }
   141 /****************************************************************************
   142  *
   143  *  ROUTINE       : scale1d_c
   144  *
   145  *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
   146  *                  int source_step              : Number of pixels to step on in source.
   147  *                  unsigned int source_scale    : Scale for source.
   148  *                  unsigned int source_length   : Length of source (UNUSED).
   149  *                  unsigned char *dest         : Pointer to output data array.
   150  *                  int dest_step                : Number of pixels to step on in destination.
   151  *                  unsigned int dest_scale      : Scale for destination.
   152  *                  unsigned int dest_length     : Length of destination.
   153  *
   154  *  OUTPUTS       : None.
   155  *
   156  *  RETURNS       : void
   157  *
   158  *  FUNCTION      : Performs linear interpolation in one dimension.
   159  *
   160  *  SPECIAL NOTES : None.
   161  *
   162  ****************************************************************************/
   163 static
   164 void scale1d_c
   165 (
   166   const unsigned char *source,
   167   int source_step,
   168   unsigned int source_scale,
   169   unsigned int source_length,
   170   unsigned char *dest,
   171   int dest_step,
   172   unsigned int dest_scale,
   173   unsigned int dest_length
   174 ) {
   175   unsigned int i;
   176   unsigned int round_value = dest_scale / 2;
   177   unsigned int left_modifier = dest_scale;
   178   unsigned int right_modifier = 0;
   179   unsigned char left_pixel = *source;
   180   unsigned char right_pixel = *(source + source_step);
   182   (void) source_length;
   184   /* These asserts are needed if there are boundary issues... */
   185   /*assert ( dest_scale > source_scale );*/
   186   /*assert ( (source_length-1) * dest_scale >= (dest_length-1) * source_scale );*/
   188   for (i = 0; i < dest_length * dest_step; i += dest_step) {
   189     dest[i] = (char)((left_modifier * left_pixel + right_modifier * right_pixel + round_value) / dest_scale);
   191     right_modifier += source_scale;
   193     while (right_modifier > dest_scale) {
   194       right_modifier -= dest_scale;
   195       source += source_step;
   196       left_pixel = *source;
   197       right_pixel = *(source + source_step);
   198     }
   200     left_modifier = dest_scale - right_modifier;
   201   }
   202 }
   204 /****************************************************************************
   205  *
   206  *  ROUTINE       : Scale2D
   207  *
   208  *  INPUTS        : const unsigned char *source  : Pointer to data to be scaled.
   209  *                  int source_pitch              : Stride of source image.
   210  *                  unsigned int source_width     : Width of input image.
   211  *                  unsigned int source_height    : Height of input image.
   212  *                  unsigned char *dest          : Pointer to output data array.
   213  *                  int dest_pitch                : Stride of destination image.
   214  *                  unsigned int dest_width       : Width of destination image.
   215  *                  unsigned int dest_height      : Height of destination image.
   216  *                  unsigned char *temp_area      : Pointer to temp work area.
   217  *                  unsigned char temp_area_height : Height of temp work area.
   218  *                  unsigned int hscale          : Horizontal scale factor numerator.
   219  *                  unsigned int hratio          : Horizontal scale factor denominator.
   220  *                  unsigned int vscale          : Vertical scale factor numerator.
   221  *                  unsigned int vratio          : Vertical scale factor denominator.
   222  *                  unsigned int interlaced      : Interlace flag.
   223  *
   224  *  OUTPUTS       : None.
   225  *
   226  *  RETURNS       : void
   227  *
   228  *  FUNCTION      : Performs 2-tap linear interpolation in two dimensions.
   229  *
   230  *  SPECIAL NOTES : Expansion is performed one band at a time to help with
   231  *                  caching.
   232  *
   233  ****************************************************************************/
   234 static
   235 void Scale2D
   236 (
   237   /*const*/
   238   unsigned char *source,
   239   int source_pitch,
   240   unsigned int source_width,
   241   unsigned int source_height,
   242   unsigned char *dest,
   243   int dest_pitch,
   244   unsigned int dest_width,
   245   unsigned int dest_height,
   246   unsigned char *temp_area,
   247   unsigned char temp_area_height,
   248   unsigned int hscale,
   249   unsigned int hratio,
   250   unsigned int vscale,
   251   unsigned int vratio,
   252   unsigned int interlaced
   253 ) {
   254   /*unsigned*/
   255   int i, j, k;
   256   int bands;
   257   int dest_band_height;
   258   int source_band_height;
   260   typedef void (*Scale1D)(const unsigned char * source, int source_step, unsigned int source_scale, unsigned int source_length,
   261                           unsigned char * dest, int dest_step, unsigned int dest_scale, unsigned int dest_length);
   263   Scale1D Scale1Dv = scale1d_c;
   264   Scale1D Scale1Dh = scale1d_c;
   266   void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL;
   267   void (*vert_band_scale)(unsigned char *, unsigned int, unsigned char *, unsigned int, unsigned int) = NULL;
   269   int ratio_scalable = 1;
   270   int interpolation = 0;
   272   unsigned char *source_base; /* = (unsigned char *) ((source_pitch >= 0) ? source : (source + ((source_height-1) * source_pitch))); */
   273   unsigned char *line_src;
   276   source_base = (unsigned char *)source;
   278   if (source_pitch < 0) {
   279     int offset;
   281     offset = (source_height - 1);
   282     offset *= source_pitch;
   284     source_base += offset;
   285   }
   287   /* find out the ratio for each direction */
   288   switch (hratio * 10 / hscale) {
   289     case 8:
   290       /* 4-5 Scale in Width direction */
   291       horiz_line_scale = vp8_horizontal_line_5_4_scale;
   292       break;
   293     case 6:
   294       /* 3-5 Scale in Width direction */
   295       horiz_line_scale = vp8_horizontal_line_5_3_scale;
   296       break;
   297     case 5:
   298       /* 1-2 Scale in Width direction */
   299       horiz_line_scale = vp8_horizontal_line_2_1_scale;
   300       break;
   301     default:
   302       /* The ratio is not acceptable now */
   303       /* throw("The ratio is not acceptable for now!"); */
   304       ratio_scalable = 0;
   305       break;
   306   }
   308   switch (vratio * 10 / vscale) {
   309     case 8:
   310       /* 4-5 Scale in vertical direction */
   311       vert_band_scale     = vp8_vertical_band_5_4_scale;
   312       source_band_height  = 5;
   313       dest_band_height    = 4;
   314       break;
   315     case 6:
   316       /* 3-5 Scale in vertical direction */
   317       vert_band_scale     = vp8_vertical_band_5_3_scale;
   318       source_band_height  = 5;
   319       dest_band_height    = 3;
   320       break;
   321     case 5:
   322       /* 1-2 Scale in vertical direction */
   324       if (interlaced) {
   325         /* if the content is interlaced, point sampling is used */
   326         vert_band_scale     = vp8_vertical_band_2_1_scale;
   327       } else {
   329         interpolation = 1;
   330         /* if the content is progressive, interplo */
   331         vert_band_scale     = vp8_vertical_band_2_1_scale_i;
   333       }
   335       source_band_height  = 2;
   336       dest_band_height    = 1;
   337       break;
   338     default:
   339       /* The ratio is not acceptable now */
   340       /* throw("The ratio is not acceptable for now!"); */
   341       ratio_scalable = 0;
   342       break;
   343   }
   345   if (ratio_scalable) {
   346     if (source_height == dest_height) {
   347       /* for each band of the image */
   348       for (k = 0; k < (int)dest_height; k++) {
   349         horiz_line_scale(source, source_width, dest, dest_width);
   350         source += source_pitch;
   351         dest   += dest_pitch;
   352       }
   354       return;
   355     }
   357     if (interpolation) {
   358       if (source < source_base)
   359         source = source_base;
   361       horiz_line_scale(source, source_width, temp_area, dest_width);
   362     }
   364     for (k = 0; k < (int)(dest_height + dest_band_height - 1) / dest_band_height; k++) {
   365       /* scale one band horizontally */
   366       for (i = 0; i < source_band_height; i++) {
   367         /* Trap case where we could read off the base of the source buffer */
   369         line_src = (unsigned char *)source + i * source_pitch;
   371         if (line_src < source_base)
   372           line_src = source_base;
   374         horiz_line_scale(line_src, source_width,
   375                          temp_area + (i + 1)*dest_pitch, dest_width);
   376       }
   378       /* Vertical scaling is in place */
   379       vert_band_scale(temp_area + dest_pitch, dest_pitch, dest, dest_pitch, dest_width);
   381       if (interpolation)
   382         vpx_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_width);
   384       /* Next band... */
   385       source += (unsigned long) source_band_height  * source_pitch;
   386       dest   += (unsigned long) dest_band_height * dest_pitch;
   387     }
   389     return;
   390   }
   392   if (hscale == 2 && hratio == 1)
   393     Scale1Dh = scale1d_2t1_ps;
   395   if (vscale == 2 && vratio == 1) {
   396     if (interlaced)
   397       Scale1Dv = scale1d_2t1_ps;
   398     else
   399       Scale1Dv = scale1d_2t1_i;
   400   }
   402   if (source_height == dest_height) {
   403     /* for each band of the image */
   404     for (k = 0; k < (int)dest_height; k++) {
   405       Scale1Dh(source, 1, hscale, source_width + 1, dest, 1, hratio, dest_width);
   406       source += source_pitch;
   407       dest   += dest_pitch;
   408     }
   410     return;
   411   }
   413   if (dest_height > source_height) {
   414     dest_band_height   = temp_area_height - 1;
   415     source_band_height = dest_band_height * source_height / dest_height;
   416   } else {
   417     source_band_height = temp_area_height - 1;
   418     dest_band_height   = source_band_height * vratio / vscale;
   419   }
   421   /* first row needs to be done so that we can stay one row ahead for vertical zoom */
   422   Scale1Dh(source, 1, hscale, source_width + 1, temp_area, 1, hratio, dest_width);
   424   /* for each band of the image */
   425   bands = (dest_height + dest_band_height - 1) / dest_band_height;
   427   for (k = 0; k < bands; k++) {
   428     /* scale one band horizontally */
   429     for (i = 1; i < source_band_height + 1; i++) {
   430       if (k * source_band_height + i < (int) source_height) {
   431         Scale1Dh(source + i * source_pitch, 1, hscale, source_width + 1,
   432                  temp_area + i * dest_pitch, 1, hratio, dest_width);
   433       } else { /*  Duplicate the last row */
   434         /* copy temp_area row 0 over from last row in the past */
   435         vpx_memcpy(temp_area + i * dest_pitch, temp_area + (i - 1)*dest_pitch, dest_pitch);
   436       }
   437     }
   439     /* scale one band vertically */
   440     for (j = 0; j < (int)dest_width; j++) {
   441       Scale1Dv(&temp_area[j], dest_pitch, vscale, source_band_height + 1,
   442                &dest[j], dest_pitch, vratio, dest_band_height);
   443     }
   445     /* copy temp_area row 0 over from last row in the past */
   446     vpx_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_pitch);
   448     /* move to the next band */
   449     source += source_band_height * source_pitch;
   450     dest   += dest_band_height * dest_pitch;
   451   }
   452 }
   454 /****************************************************************************
   455  *
   456  *  ROUTINE       : vpx_scale_frame
   457  *
   458  *  INPUTS        : YV12_BUFFER_CONFIG *src       : Pointer to frame to be scaled.
   459  *                  YV12_BUFFER_CONFIG *dst       : Pointer to buffer to hold scaled frame.
   460  *                  unsigned char *temp_area      : Pointer to temp work area.
   461  *                  unsigned char temp_area_height : Height of temp work area.
   462  *                  unsigned int hscale          : Horizontal scale factor numerator.
   463  *                  unsigned int hratio          : Horizontal scale factor denominator.
   464  *                  unsigned int vscale          : Vertical scale factor numerator.
   465  *                  unsigned int vratio          : Vertical scale factor denominator.
   466  *                  unsigned int interlaced      : Interlace flag.
   467  *
   468  *  OUTPUTS       : None.
   469  *
   470  *  RETURNS       : void
   471  *
   472  *  FUNCTION      : Performs 2-tap linear interpolation in two dimensions.
   473  *
   474  *  SPECIAL NOTES : Expansion is performed one band at a time to help with
   475  *                  caching.
   476  *
   477  ****************************************************************************/
   478 void vpx_scale_frame
   479 (
   480   YV12_BUFFER_CONFIG *src,
   481   YV12_BUFFER_CONFIG *dst,
   482   unsigned char *temp_area,
   483   unsigned char temp_height,
   484   unsigned int hscale,
   485   unsigned int hratio,
   486   unsigned int vscale,
   487   unsigned int vratio,
   488   unsigned int interlaced
   489 ) {
   490   int i;
   491   int dw = (hscale - 1 + src->y_width * hratio) / hscale;
   492   int dh = (vscale - 1 + src->y_height * vratio) / vscale;
   494   /* call our internal scaling routines!! */
   495   Scale2D((unsigned char *) src->y_buffer, src->y_stride, src->y_width, src->y_height,
   496           (unsigned char *) dst->y_buffer, dst->y_stride, dw, dh,
   497           temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
   499   if (dw < (int)dst->y_width)
   500     for (i = 0; i < dh; i++)
   501       vpx_memset(dst->y_buffer + i * dst->y_stride + dw - 1, dst->y_buffer[i * dst->y_stride + dw - 2], dst->y_width - dw + 1);
   503   if (dh < (int)dst->y_height)
   504     for (i = dh - 1; i < (int)dst->y_height; i++)
   505       vpx_memcpy(dst->y_buffer + i * dst->y_stride, dst->y_buffer + (dh - 2) * dst->y_stride, dst->y_width + 1);
   507   Scale2D((unsigned char *) src->u_buffer, src->uv_stride, src->uv_width, src->uv_height,
   508           (unsigned char *) dst->u_buffer, dst->uv_stride, dw / 2, dh / 2,
   509           temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
   511   if (dw / 2 < (int)dst->uv_width)
   512     for (i = 0; i < dst->uv_height; i++)
   513       vpx_memset(dst->u_buffer + i * dst->uv_stride + dw / 2 - 1, dst->u_buffer[i * dst->uv_stride + dw / 2 - 2], dst->uv_width - dw / 2 + 1);
   515   if (dh / 2 < (int)dst->uv_height)
   516     for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
   517       vpx_memcpy(dst->u_buffer + i * dst->uv_stride, dst->u_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
   519   Scale2D((unsigned char *) src->v_buffer, src->uv_stride, src->uv_width, src->uv_height,
   520           (unsigned char *) dst->v_buffer, dst->uv_stride, dw / 2, dh / 2,
   521           temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
   523   if (dw / 2 < (int)dst->uv_width)
   524     for (i = 0; i < dst->uv_height; i++)
   525       vpx_memset(dst->v_buffer + i * dst->uv_stride + dw / 2 - 1, dst->v_buffer[i * dst->uv_stride + dw / 2 - 2], dst->uv_width - dw / 2 + 1);
   527   if (dh / 2 < (int) dst->uv_height)
   528     for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
   529       vpx_memcpy(dst->v_buffer + i * dst->uv_stride, dst->v_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
   530 }

mercurial