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