xref: /aosp_15_r20/external/libvpx/tools_common.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 #include <math.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <stdarg.h>
13*fb1b10abSAndroid Build Coastguard Worker #include <stdio.h>
14*fb1b10abSAndroid Build Coastguard Worker #include <stdlib.h>
15*fb1b10abSAndroid Build Coastguard Worker #include <string.h>
16*fb1b10abSAndroid Build Coastguard Worker 
17*fb1b10abSAndroid Build Coastguard Worker #include "./tools_common.h"
18*fb1b10abSAndroid Build Coastguard Worker 
19*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
20*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vp8cx.h"
21*fb1b10abSAndroid Build Coastguard Worker #endif
22*fb1b10abSAndroid Build Coastguard Worker 
23*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
24*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vp8dx.h"
25*fb1b10abSAndroid Build Coastguard Worker #endif
26*fb1b10abSAndroid Build Coastguard Worker 
27*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_codec.h"
28*fb1b10abSAndroid Build Coastguard Worker 
29*fb1b10abSAndroid Build Coastguard Worker #if defined(_WIN32)
30*fb1b10abSAndroid Build Coastguard Worker #include <io.h>
31*fb1b10abSAndroid Build Coastguard Worker #include <fcntl.h>
32*fb1b10abSAndroid Build Coastguard Worker #endif
33*fb1b10abSAndroid Build Coastguard Worker 
34*fb1b10abSAndroid Build Coastguard Worker #define LOG_ERROR(label)               \
35*fb1b10abSAndroid Build Coastguard Worker   do {                                 \
36*fb1b10abSAndroid Build Coastguard Worker     const char *l = label;             \
37*fb1b10abSAndroid Build Coastguard Worker     va_list ap;                        \
38*fb1b10abSAndroid Build Coastguard Worker     va_start(ap, fmt);                 \
39*fb1b10abSAndroid Build Coastguard Worker     if (l) fprintf(stderr, "%s: ", l); \
40*fb1b10abSAndroid Build Coastguard Worker     vfprintf(stderr, fmt, ap);         \
41*fb1b10abSAndroid Build Coastguard Worker     fprintf(stderr, "\n");             \
42*fb1b10abSAndroid Build Coastguard Worker     va_end(ap);                        \
43*fb1b10abSAndroid Build Coastguard Worker   } while (0)
44*fb1b10abSAndroid Build Coastguard Worker 
45*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_ENCODERS
46*fb1b10abSAndroid Build Coastguard Worker /* Swallow warnings about unused results of fread/fwrite */
wrap_fread(void * ptr,size_t size,size_t nmemb,FILE * stream)47*fb1b10abSAndroid Build Coastguard Worker static size_t wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
48*fb1b10abSAndroid Build Coastguard Worker   return fread(ptr, size, nmemb, stream);
49*fb1b10abSAndroid Build Coastguard Worker }
50*fb1b10abSAndroid Build Coastguard Worker #define fread wrap_fread
51*fb1b10abSAndroid Build Coastguard Worker #endif
52*fb1b10abSAndroid Build Coastguard Worker 
set_binary_mode(FILE * stream)53*fb1b10abSAndroid Build Coastguard Worker FILE *set_binary_mode(FILE *stream) {
54*fb1b10abSAndroid Build Coastguard Worker   (void)stream;
55*fb1b10abSAndroid Build Coastguard Worker #if defined(_WIN32)
56*fb1b10abSAndroid Build Coastguard Worker   _setmode(_fileno(stream), _O_BINARY);
57*fb1b10abSAndroid Build Coastguard Worker #endif
58*fb1b10abSAndroid Build Coastguard Worker   return stream;
59*fb1b10abSAndroid Build Coastguard Worker }
60*fb1b10abSAndroid Build Coastguard Worker 
die(const char * fmt,...)61*fb1b10abSAndroid Build Coastguard Worker void die(const char *fmt, ...) {
62*fb1b10abSAndroid Build Coastguard Worker   LOG_ERROR(NULL);
63*fb1b10abSAndroid Build Coastguard Worker   usage_exit();
64*fb1b10abSAndroid Build Coastguard Worker }
65*fb1b10abSAndroid Build Coastguard Worker 
fatal(const char * fmt,...)66*fb1b10abSAndroid Build Coastguard Worker void fatal(const char *fmt, ...) {
67*fb1b10abSAndroid Build Coastguard Worker   LOG_ERROR("Fatal");
68*fb1b10abSAndroid Build Coastguard Worker   exit(EXIT_FAILURE);
69*fb1b10abSAndroid Build Coastguard Worker }
70*fb1b10abSAndroid Build Coastguard Worker 
warn(const char * fmt,...)71*fb1b10abSAndroid Build Coastguard Worker void warn(const char *fmt, ...) { LOG_ERROR("Warning"); }
72*fb1b10abSAndroid Build Coastguard Worker 
die_codec(vpx_codec_ctx_t * ctx,const char * s)73*fb1b10abSAndroid Build Coastguard Worker void die_codec(vpx_codec_ctx_t *ctx, const char *s) {
74*fb1b10abSAndroid Build Coastguard Worker   const char *detail = vpx_codec_error_detail(ctx);
75*fb1b10abSAndroid Build Coastguard Worker 
76*fb1b10abSAndroid Build Coastguard Worker   fprintf(stderr, "%s: %s\n", s, vpx_codec_error(ctx));
77*fb1b10abSAndroid Build Coastguard Worker   if (detail) fprintf(stderr, "    %s\n", detail);
78*fb1b10abSAndroid Build Coastguard Worker   exit(EXIT_FAILURE);
79*fb1b10abSAndroid Build Coastguard Worker }
80*fb1b10abSAndroid Build Coastguard Worker 
read_yuv_frame(struct VpxInputContext * input_ctx,vpx_image_t * yuv_frame)81*fb1b10abSAndroid Build Coastguard Worker int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) {
82*fb1b10abSAndroid Build Coastguard Worker   FILE *f = input_ctx->file;
83*fb1b10abSAndroid Build Coastguard Worker   struct FileTypeDetectionBuffer *detect = &input_ctx->detect;
84*fb1b10abSAndroid Build Coastguard Worker   int plane = 0;
85*fb1b10abSAndroid Build Coastguard Worker   int shortread = 0;
86*fb1b10abSAndroid Build Coastguard Worker   const int bytespp = (yuv_frame->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
87*fb1b10abSAndroid Build Coastguard Worker 
88*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; ++plane) {
89*fb1b10abSAndroid Build Coastguard Worker     uint8_t *ptr;
90*fb1b10abSAndroid Build Coastguard Worker     int w = vpx_img_plane_width(yuv_frame, plane);
91*fb1b10abSAndroid Build Coastguard Worker     const int h = vpx_img_plane_height(yuv_frame, plane);
92*fb1b10abSAndroid Build Coastguard Worker     int r;
93*fb1b10abSAndroid Build Coastguard Worker     // Assuming that for nv12 we read all chroma data at once
94*fb1b10abSAndroid Build Coastguard Worker     if (yuv_frame->fmt == VPX_IMG_FMT_NV12 && plane > 1) break;
95*fb1b10abSAndroid Build Coastguard Worker     // Fixing NV12 chroma width if it is odd
96*fb1b10abSAndroid Build Coastguard Worker     if (yuv_frame->fmt == VPX_IMG_FMT_NV12 && plane == 1) w = (w + 1) & ~1;
97*fb1b10abSAndroid Build Coastguard Worker     /* Determine the correct plane based on the image format. The for-loop
98*fb1b10abSAndroid Build Coastguard Worker      * always counts in Y,U,V order, but this may not match the order of
99*fb1b10abSAndroid Build Coastguard Worker      * the data on disk.
100*fb1b10abSAndroid Build Coastguard Worker      */
101*fb1b10abSAndroid Build Coastguard Worker     switch (plane) {
102*fb1b10abSAndroid Build Coastguard Worker       case 1:
103*fb1b10abSAndroid Build Coastguard Worker         ptr =
104*fb1b10abSAndroid Build Coastguard Worker             yuv_frame->planes[yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V
105*fb1b10abSAndroid Build Coastguard Worker                                                                  : VPX_PLANE_U];
106*fb1b10abSAndroid Build Coastguard Worker         break;
107*fb1b10abSAndroid Build Coastguard Worker       case 2:
108*fb1b10abSAndroid Build Coastguard Worker         ptr =
109*fb1b10abSAndroid Build Coastguard Worker             yuv_frame->planes[yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U
110*fb1b10abSAndroid Build Coastguard Worker                                                                  : VPX_PLANE_V];
111*fb1b10abSAndroid Build Coastguard Worker         break;
112*fb1b10abSAndroid Build Coastguard Worker       default: ptr = yuv_frame->planes[plane];
113*fb1b10abSAndroid Build Coastguard Worker     }
114*fb1b10abSAndroid Build Coastguard Worker 
115*fb1b10abSAndroid Build Coastguard Worker     for (r = 0; r < h; ++r) {
116*fb1b10abSAndroid Build Coastguard Worker       size_t needed = w * bytespp;
117*fb1b10abSAndroid Build Coastguard Worker       size_t buf_position = 0;
118*fb1b10abSAndroid Build Coastguard Worker       const size_t left = detect->buf_read - detect->position;
119*fb1b10abSAndroid Build Coastguard Worker       if (left > 0) {
120*fb1b10abSAndroid Build Coastguard Worker         const size_t more = (left < needed) ? left : needed;
121*fb1b10abSAndroid Build Coastguard Worker         memcpy(ptr, detect->buf + detect->position, more);
122*fb1b10abSAndroid Build Coastguard Worker         buf_position = more;
123*fb1b10abSAndroid Build Coastguard Worker         needed -= more;
124*fb1b10abSAndroid Build Coastguard Worker         detect->position += more;
125*fb1b10abSAndroid Build Coastguard Worker       }
126*fb1b10abSAndroid Build Coastguard Worker       if (needed > 0) {
127*fb1b10abSAndroid Build Coastguard Worker         shortread |= (fread(ptr + buf_position, 1, needed, f) < needed);
128*fb1b10abSAndroid Build Coastguard Worker       }
129*fb1b10abSAndroid Build Coastguard Worker 
130*fb1b10abSAndroid Build Coastguard Worker       ptr += yuv_frame->stride[plane];
131*fb1b10abSAndroid Build Coastguard Worker     }
132*fb1b10abSAndroid Build Coastguard Worker   }
133*fb1b10abSAndroid Build Coastguard Worker 
134*fb1b10abSAndroid Build Coastguard Worker   return shortread;
135*fb1b10abSAndroid Build Coastguard Worker }
136*fb1b10abSAndroid Build Coastguard Worker 
137*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_ENCODERS
138*fb1b10abSAndroid Build Coastguard Worker 
139*fb1b10abSAndroid Build Coastguard Worker static const VpxInterface vpx_encoders[] = {
140*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP8_ENCODER
141*fb1b10abSAndroid Build Coastguard Worker   { "vp8", VP8_FOURCC, &vpx_codec_vp8_cx },
142*fb1b10abSAndroid Build Coastguard Worker #endif
143*fb1b10abSAndroid Build Coastguard Worker 
144*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_ENCODER
145*fb1b10abSAndroid Build Coastguard Worker   { "vp9", VP9_FOURCC, &vpx_codec_vp9_cx },
146*fb1b10abSAndroid Build Coastguard Worker #endif
147*fb1b10abSAndroid Build Coastguard Worker };
148*fb1b10abSAndroid Build Coastguard Worker 
get_vpx_encoder_count(void)149*fb1b10abSAndroid Build Coastguard Worker int get_vpx_encoder_count(void) {
150*fb1b10abSAndroid Build Coastguard Worker   return sizeof(vpx_encoders) / sizeof(vpx_encoders[0]);
151*fb1b10abSAndroid Build Coastguard Worker }
152*fb1b10abSAndroid Build Coastguard Worker 
get_vpx_encoder_by_index(int i)153*fb1b10abSAndroid Build Coastguard Worker const VpxInterface *get_vpx_encoder_by_index(int i) { return &vpx_encoders[i]; }
154*fb1b10abSAndroid Build Coastguard Worker 
get_vpx_encoder_by_name(const char * name)155*fb1b10abSAndroid Build Coastguard Worker const VpxInterface *get_vpx_encoder_by_name(const char *name) {
156*fb1b10abSAndroid Build Coastguard Worker   int i;
157*fb1b10abSAndroid Build Coastguard Worker 
158*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < get_vpx_encoder_count(); ++i) {
159*fb1b10abSAndroid Build Coastguard Worker     const VpxInterface *encoder = get_vpx_encoder_by_index(i);
160*fb1b10abSAndroid Build Coastguard Worker     if (strcmp(encoder->name, name) == 0) return encoder;
161*fb1b10abSAndroid Build Coastguard Worker   }
162*fb1b10abSAndroid Build Coastguard Worker 
163*fb1b10abSAndroid Build Coastguard Worker   return NULL;
164*fb1b10abSAndroid Build Coastguard Worker }
165*fb1b10abSAndroid Build Coastguard Worker 
166*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_ENCODERS
167*fb1b10abSAndroid Build Coastguard Worker 
168*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_DECODERS
169*fb1b10abSAndroid Build Coastguard Worker 
170*fb1b10abSAndroid Build Coastguard Worker static const VpxInterface vpx_decoders[] = {
171*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP8_DECODER
172*fb1b10abSAndroid Build Coastguard Worker   { "vp8", VP8_FOURCC, &vpx_codec_vp8_dx },
173*fb1b10abSAndroid Build Coastguard Worker #endif
174*fb1b10abSAndroid Build Coastguard Worker 
175*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_DECODER
176*fb1b10abSAndroid Build Coastguard Worker   { "vp9", VP9_FOURCC, &vpx_codec_vp9_dx },
177*fb1b10abSAndroid Build Coastguard Worker #endif
178*fb1b10abSAndroid Build Coastguard Worker };
179*fb1b10abSAndroid Build Coastguard Worker 
get_vpx_decoder_count(void)180*fb1b10abSAndroid Build Coastguard Worker int get_vpx_decoder_count(void) {
181*fb1b10abSAndroid Build Coastguard Worker   return sizeof(vpx_decoders) / sizeof(vpx_decoders[0]);
182*fb1b10abSAndroid Build Coastguard Worker }
183*fb1b10abSAndroid Build Coastguard Worker 
get_vpx_decoder_by_index(int i)184*fb1b10abSAndroid Build Coastguard Worker const VpxInterface *get_vpx_decoder_by_index(int i) { return &vpx_decoders[i]; }
185*fb1b10abSAndroid Build Coastguard Worker 
get_vpx_decoder_by_name(const char * name)186*fb1b10abSAndroid Build Coastguard Worker const VpxInterface *get_vpx_decoder_by_name(const char *name) {
187*fb1b10abSAndroid Build Coastguard Worker   int i;
188*fb1b10abSAndroid Build Coastguard Worker 
189*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < get_vpx_decoder_count(); ++i) {
190*fb1b10abSAndroid Build Coastguard Worker     const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
191*fb1b10abSAndroid Build Coastguard Worker     if (strcmp(decoder->name, name) == 0) return decoder;
192*fb1b10abSAndroid Build Coastguard Worker   }
193*fb1b10abSAndroid Build Coastguard Worker 
194*fb1b10abSAndroid Build Coastguard Worker   return NULL;
195*fb1b10abSAndroid Build Coastguard Worker }
196*fb1b10abSAndroid Build Coastguard Worker 
get_vpx_decoder_by_fourcc(uint32_t fourcc)197*fb1b10abSAndroid Build Coastguard Worker const VpxInterface *get_vpx_decoder_by_fourcc(uint32_t fourcc) {
198*fb1b10abSAndroid Build Coastguard Worker   int i;
199*fb1b10abSAndroid Build Coastguard Worker 
200*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < get_vpx_decoder_count(); ++i) {
201*fb1b10abSAndroid Build Coastguard Worker     const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
202*fb1b10abSAndroid Build Coastguard Worker     if (decoder->fourcc == fourcc) return decoder;
203*fb1b10abSAndroid Build Coastguard Worker   }
204*fb1b10abSAndroid Build Coastguard Worker 
205*fb1b10abSAndroid Build Coastguard Worker   return NULL;
206*fb1b10abSAndroid Build Coastguard Worker }
207*fb1b10abSAndroid Build Coastguard Worker 
208*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_DECODERS
209*fb1b10abSAndroid Build Coastguard Worker 
vpx_img_plane_width(const vpx_image_t * img,int plane)210*fb1b10abSAndroid Build Coastguard Worker int vpx_img_plane_width(const vpx_image_t *img, int plane) {
211*fb1b10abSAndroid Build Coastguard Worker   if (plane > 0 && img->x_chroma_shift > 0)
212*fb1b10abSAndroid Build Coastguard Worker     return (img->d_w + 1) >> img->x_chroma_shift;
213*fb1b10abSAndroid Build Coastguard Worker   else
214*fb1b10abSAndroid Build Coastguard Worker     return img->d_w;
215*fb1b10abSAndroid Build Coastguard Worker }
216*fb1b10abSAndroid Build Coastguard Worker 
vpx_img_plane_height(const vpx_image_t * img,int plane)217*fb1b10abSAndroid Build Coastguard Worker int vpx_img_plane_height(const vpx_image_t *img, int plane) {
218*fb1b10abSAndroid Build Coastguard Worker   if (plane > 0 && img->y_chroma_shift > 0)
219*fb1b10abSAndroid Build Coastguard Worker     return (img->d_h + 1) >> img->y_chroma_shift;
220*fb1b10abSAndroid Build Coastguard Worker   else
221*fb1b10abSAndroid Build Coastguard Worker     return img->d_h;
222*fb1b10abSAndroid Build Coastguard Worker }
223*fb1b10abSAndroid Build Coastguard Worker 
vpx_img_write(const vpx_image_t * img,FILE * file)224*fb1b10abSAndroid Build Coastguard Worker void vpx_img_write(const vpx_image_t *img, FILE *file) {
225*fb1b10abSAndroid Build Coastguard Worker   int plane;
226*fb1b10abSAndroid Build Coastguard Worker   const int bytespp = (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
227*fb1b10abSAndroid Build Coastguard Worker 
228*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; ++plane) {
229*fb1b10abSAndroid Build Coastguard Worker     const unsigned char *buf = img->planes[plane];
230*fb1b10abSAndroid Build Coastguard Worker     const int stride = img->stride[plane];
231*fb1b10abSAndroid Build Coastguard Worker     int w = vpx_img_plane_width(img, plane);
232*fb1b10abSAndroid Build Coastguard Worker     const int h = vpx_img_plane_height(img, plane);
233*fb1b10abSAndroid Build Coastguard Worker     int y;
234*fb1b10abSAndroid Build Coastguard Worker 
235*fb1b10abSAndroid Build Coastguard Worker     // Assuming that for nv12 we write all chroma data at once
236*fb1b10abSAndroid Build Coastguard Worker     if (img->fmt == VPX_IMG_FMT_NV12 && plane > 1) break;
237*fb1b10abSAndroid Build Coastguard Worker     // Fixing NV12 chroma width if it is odd
238*fb1b10abSAndroid Build Coastguard Worker     if (img->fmt == VPX_IMG_FMT_NV12 && plane == 1) w = (w + 1) & ~1;
239*fb1b10abSAndroid Build Coastguard Worker 
240*fb1b10abSAndroid Build Coastguard Worker     for (y = 0; y < h; ++y) {
241*fb1b10abSAndroid Build Coastguard Worker       fwrite(buf, bytespp, w, file);
242*fb1b10abSAndroid Build Coastguard Worker       buf += stride;
243*fb1b10abSAndroid Build Coastguard Worker     }
244*fb1b10abSAndroid Build Coastguard Worker   }
245*fb1b10abSAndroid Build Coastguard Worker }
246*fb1b10abSAndroid Build Coastguard Worker 
vpx_img_read(vpx_image_t * img,FILE * file)247*fb1b10abSAndroid Build Coastguard Worker int vpx_img_read(vpx_image_t *img, FILE *file) {
248*fb1b10abSAndroid Build Coastguard Worker   int plane;
249*fb1b10abSAndroid Build Coastguard Worker   const int bytespp = (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
250*fb1b10abSAndroid Build Coastguard Worker 
251*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; ++plane) {
252*fb1b10abSAndroid Build Coastguard Worker     unsigned char *buf = img->planes[plane];
253*fb1b10abSAndroid Build Coastguard Worker     const int stride = img->stride[plane];
254*fb1b10abSAndroid Build Coastguard Worker     int w = vpx_img_plane_width(img, plane);
255*fb1b10abSAndroid Build Coastguard Worker     const int h = vpx_img_plane_height(img, plane);
256*fb1b10abSAndroid Build Coastguard Worker     int y;
257*fb1b10abSAndroid Build Coastguard Worker 
258*fb1b10abSAndroid Build Coastguard Worker     // Assuming that for nv12 we read all chroma data at once
259*fb1b10abSAndroid Build Coastguard Worker     if (img->fmt == VPX_IMG_FMT_NV12 && plane > 1) break;
260*fb1b10abSAndroid Build Coastguard Worker     // Fixing NV12 chroma width if it is odd
261*fb1b10abSAndroid Build Coastguard Worker     if (img->fmt == VPX_IMG_FMT_NV12 && plane == 1) w = (w + 1) & ~1;
262*fb1b10abSAndroid Build Coastguard Worker 
263*fb1b10abSAndroid Build Coastguard Worker     for (y = 0; y < h; ++y) {
264*fb1b10abSAndroid Build Coastguard Worker       if (fread(buf, bytespp, w, file) != (size_t)w) return 0;
265*fb1b10abSAndroid Build Coastguard Worker       buf += stride;
266*fb1b10abSAndroid Build Coastguard Worker     }
267*fb1b10abSAndroid Build Coastguard Worker   }
268*fb1b10abSAndroid Build Coastguard Worker 
269*fb1b10abSAndroid Build Coastguard Worker   return 1;
270*fb1b10abSAndroid Build Coastguard Worker }
271*fb1b10abSAndroid Build Coastguard Worker 
272*fb1b10abSAndroid Build Coastguard Worker // TODO(dkovalev) change sse_to_psnr signature: double -> int64_t
sse_to_psnr(double samples,double peak,double sse)273*fb1b10abSAndroid Build Coastguard Worker double sse_to_psnr(double samples, double peak, double sse) {
274*fb1b10abSAndroid Build Coastguard Worker   static const double kMaxPSNR = 100.0;
275*fb1b10abSAndroid Build Coastguard Worker 
276*fb1b10abSAndroid Build Coastguard Worker   if (sse > 0.0) {
277*fb1b10abSAndroid Build Coastguard Worker     const double psnr = 10.0 * log10(samples * peak * peak / sse);
278*fb1b10abSAndroid Build Coastguard Worker     return psnr > kMaxPSNR ? kMaxPSNR : psnr;
279*fb1b10abSAndroid Build Coastguard Worker   } else {
280*fb1b10abSAndroid Build Coastguard Worker     return kMaxPSNR;
281*fb1b10abSAndroid Build Coastguard Worker   }
282*fb1b10abSAndroid Build Coastguard Worker }
283*fb1b10abSAndroid Build Coastguard Worker 
284*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_ENCODERS
read_frame(struct VpxInputContext * input_ctx,vpx_image_t * img)285*fb1b10abSAndroid Build Coastguard Worker int read_frame(struct VpxInputContext *input_ctx, vpx_image_t *img) {
286*fb1b10abSAndroid Build Coastguard Worker   FILE *f = input_ctx->file;
287*fb1b10abSAndroid Build Coastguard Worker   y4m_input *y4m = &input_ctx->y4m;
288*fb1b10abSAndroid Build Coastguard Worker   int shortread = 0;
289*fb1b10abSAndroid Build Coastguard Worker 
290*fb1b10abSAndroid Build Coastguard Worker   if (input_ctx->file_type == FILE_TYPE_Y4M) {
291*fb1b10abSAndroid Build Coastguard Worker     if (y4m_input_fetch_frame(y4m, f, img) < 1) return 0;
292*fb1b10abSAndroid Build Coastguard Worker   } else {
293*fb1b10abSAndroid Build Coastguard Worker     shortread = read_yuv_frame(input_ctx, img);
294*fb1b10abSAndroid Build Coastguard Worker   }
295*fb1b10abSAndroid Build Coastguard Worker 
296*fb1b10abSAndroid Build Coastguard Worker   return !shortread;
297*fb1b10abSAndroid Build Coastguard Worker }
298*fb1b10abSAndroid Build Coastguard Worker 
file_is_y4m(const char detect[4])299*fb1b10abSAndroid Build Coastguard Worker int file_is_y4m(const char detect[4]) {
300*fb1b10abSAndroid Build Coastguard Worker   if (memcmp(detect, "YUV4", 4) == 0) {
301*fb1b10abSAndroid Build Coastguard Worker     return 1;
302*fb1b10abSAndroid Build Coastguard Worker   }
303*fb1b10abSAndroid Build Coastguard Worker   return 0;
304*fb1b10abSAndroid Build Coastguard Worker }
305*fb1b10abSAndroid Build Coastguard Worker 
fourcc_is_ivf(const char detect[4])306*fb1b10abSAndroid Build Coastguard Worker int fourcc_is_ivf(const char detect[4]) {
307*fb1b10abSAndroid Build Coastguard Worker   if (memcmp(detect, "DKIF", 4) == 0) {
308*fb1b10abSAndroid Build Coastguard Worker     return 1;
309*fb1b10abSAndroid Build Coastguard Worker   }
310*fb1b10abSAndroid Build Coastguard Worker   return 0;
311*fb1b10abSAndroid Build Coastguard Worker }
312*fb1b10abSAndroid Build Coastguard Worker 
open_input_file(struct VpxInputContext * input)313*fb1b10abSAndroid Build Coastguard Worker void open_input_file(struct VpxInputContext *input) {
314*fb1b10abSAndroid Build Coastguard Worker   /* Parse certain options from the input file, if possible */
315*fb1b10abSAndroid Build Coastguard Worker   input->file = strcmp(input->filename, "-") ? fopen(input->filename, "rb")
316*fb1b10abSAndroid Build Coastguard Worker                                              : set_binary_mode(stdin);
317*fb1b10abSAndroid Build Coastguard Worker 
318*fb1b10abSAndroid Build Coastguard Worker   if (!input->file) fatal("Failed to open input file");
319*fb1b10abSAndroid Build Coastguard Worker 
320*fb1b10abSAndroid Build Coastguard Worker   if (!fseeko(input->file, 0, SEEK_END)) {
321*fb1b10abSAndroid Build Coastguard Worker     /* Input file is seekable. Figure out how long it is, so we can get
322*fb1b10abSAndroid Build Coastguard Worker      * progress info.
323*fb1b10abSAndroid Build Coastguard Worker      */
324*fb1b10abSAndroid Build Coastguard Worker     input->length = ftello(input->file);
325*fb1b10abSAndroid Build Coastguard Worker     rewind(input->file);
326*fb1b10abSAndroid Build Coastguard Worker   }
327*fb1b10abSAndroid Build Coastguard Worker 
328*fb1b10abSAndroid Build Coastguard Worker   /* Default to 1:1 pixel aspect ratio. */
329*fb1b10abSAndroid Build Coastguard Worker   input->pixel_aspect_ratio.numerator = 1;
330*fb1b10abSAndroid Build Coastguard Worker   input->pixel_aspect_ratio.denominator = 1;
331*fb1b10abSAndroid Build Coastguard Worker 
332*fb1b10abSAndroid Build Coastguard Worker   /* For RAW input sources, these bytes will applied on the first frame
333*fb1b10abSAndroid Build Coastguard Worker    *  in read_frame().
334*fb1b10abSAndroid Build Coastguard Worker    */
335*fb1b10abSAndroid Build Coastguard Worker   input->detect.buf_read = fread(input->detect.buf, 1, 4, input->file);
336*fb1b10abSAndroid Build Coastguard Worker   input->detect.position = 0;
337*fb1b10abSAndroid Build Coastguard Worker 
338*fb1b10abSAndroid Build Coastguard Worker   if (input->detect.buf_read == 4 && file_is_y4m(input->detect.buf)) {
339*fb1b10abSAndroid Build Coastguard Worker     if (y4m_input_open(&input->y4m, input->file, input->detect.buf, 4,
340*fb1b10abSAndroid Build Coastguard Worker                        input->only_i420) >= 0) {
341*fb1b10abSAndroid Build Coastguard Worker       input->file_type = FILE_TYPE_Y4M;
342*fb1b10abSAndroid Build Coastguard Worker       input->width = input->y4m.pic_w;
343*fb1b10abSAndroid Build Coastguard Worker       input->height = input->y4m.pic_h;
344*fb1b10abSAndroid Build Coastguard Worker       input->pixel_aspect_ratio.numerator = input->y4m.par_n;
345*fb1b10abSAndroid Build Coastguard Worker       input->pixel_aspect_ratio.denominator = input->y4m.par_d;
346*fb1b10abSAndroid Build Coastguard Worker       input->framerate.numerator = input->y4m.fps_n;
347*fb1b10abSAndroid Build Coastguard Worker       input->framerate.denominator = input->y4m.fps_d;
348*fb1b10abSAndroid Build Coastguard Worker       input->fmt = input->y4m.vpx_fmt;
349*fb1b10abSAndroid Build Coastguard Worker       input->bit_depth = input->y4m.bit_depth;
350*fb1b10abSAndroid Build Coastguard Worker     } else {
351*fb1b10abSAndroid Build Coastguard Worker       fatal("Unsupported Y4M stream.");
352*fb1b10abSAndroid Build Coastguard Worker     }
353*fb1b10abSAndroid Build Coastguard Worker   } else if (input->detect.buf_read == 4 && fourcc_is_ivf(input->detect.buf)) {
354*fb1b10abSAndroid Build Coastguard Worker     fatal("IVF is not supported as input.");
355*fb1b10abSAndroid Build Coastguard Worker   } else {
356*fb1b10abSAndroid Build Coastguard Worker     input->file_type = FILE_TYPE_RAW;
357*fb1b10abSAndroid Build Coastguard Worker   }
358*fb1b10abSAndroid Build Coastguard Worker }
359*fb1b10abSAndroid Build Coastguard Worker 
close_input_file(struct VpxInputContext * input)360*fb1b10abSAndroid Build Coastguard Worker void close_input_file(struct VpxInputContext *input) {
361*fb1b10abSAndroid Build Coastguard Worker   fclose(input->file);
362*fb1b10abSAndroid Build Coastguard Worker   if (input->file_type == FILE_TYPE_Y4M) y4m_input_close(&input->y4m);
363*fb1b10abSAndroid Build Coastguard Worker }
364*fb1b10abSAndroid Build Coastguard Worker #endif
365*fb1b10abSAndroid Build Coastguard Worker 
366*fb1b10abSAndroid Build Coastguard Worker // TODO(debargha): Consolidate the functions below into a separate file.
367*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
highbd_img_upshift(vpx_image_t * dst,vpx_image_t * src,int input_shift)368*fb1b10abSAndroid Build Coastguard Worker static void highbd_img_upshift(vpx_image_t *dst, vpx_image_t *src,
369*fb1b10abSAndroid Build Coastguard Worker                                int input_shift) {
370*fb1b10abSAndroid Build Coastguard Worker   // Note the offset is 1 less than half.
371*fb1b10abSAndroid Build Coastguard Worker   const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0;
372*fb1b10abSAndroid Build Coastguard Worker   int plane;
373*fb1b10abSAndroid Build Coastguard Worker   if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
374*fb1b10abSAndroid Build Coastguard Worker       dst->x_chroma_shift != src->x_chroma_shift ||
375*fb1b10abSAndroid Build Coastguard Worker       dst->y_chroma_shift != src->y_chroma_shift || dst->fmt != src->fmt ||
376*fb1b10abSAndroid Build Coastguard Worker       input_shift < 0) {
377*fb1b10abSAndroid Build Coastguard Worker     fatal("Unsupported image conversion");
378*fb1b10abSAndroid Build Coastguard Worker   }
379*fb1b10abSAndroid Build Coastguard Worker   switch (src->fmt) {
380*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I42016:
381*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I42216:
382*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I44416:
383*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I44016: break;
384*fb1b10abSAndroid Build Coastguard Worker     default: fatal("Unsupported image conversion");
385*fb1b10abSAndroid Build Coastguard Worker   }
386*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; plane++) {
387*fb1b10abSAndroid Build Coastguard Worker     int w = src->d_w;
388*fb1b10abSAndroid Build Coastguard Worker     int h = src->d_h;
389*fb1b10abSAndroid Build Coastguard Worker     int x, y;
390*fb1b10abSAndroid Build Coastguard Worker     if (plane) {
391*fb1b10abSAndroid Build Coastguard Worker       w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
392*fb1b10abSAndroid Build Coastguard Worker       h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
393*fb1b10abSAndroid Build Coastguard Worker     }
394*fb1b10abSAndroid Build Coastguard Worker     for (y = 0; y < h; y++) {
395*fb1b10abSAndroid Build Coastguard Worker       uint16_t *p_src =
396*fb1b10abSAndroid Build Coastguard Worker           (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
397*fb1b10abSAndroid Build Coastguard Worker       uint16_t *p_dst =
398*fb1b10abSAndroid Build Coastguard Worker           (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
399*fb1b10abSAndroid Build Coastguard Worker       for (x = 0; x < w; x++) *p_dst++ = (*p_src++ << input_shift) + offset;
400*fb1b10abSAndroid Build Coastguard Worker     }
401*fb1b10abSAndroid Build Coastguard Worker   }
402*fb1b10abSAndroid Build Coastguard Worker }
403*fb1b10abSAndroid Build Coastguard Worker 
lowbd_img_upshift(vpx_image_t * dst,vpx_image_t * src,int input_shift)404*fb1b10abSAndroid Build Coastguard Worker static void lowbd_img_upshift(vpx_image_t *dst, vpx_image_t *src,
405*fb1b10abSAndroid Build Coastguard Worker                               int input_shift) {
406*fb1b10abSAndroid Build Coastguard Worker   // Note the offset is 1 less than half.
407*fb1b10abSAndroid Build Coastguard Worker   const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0;
408*fb1b10abSAndroid Build Coastguard Worker   int plane;
409*fb1b10abSAndroid Build Coastguard Worker   if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
410*fb1b10abSAndroid Build Coastguard Worker       dst->x_chroma_shift != src->x_chroma_shift ||
411*fb1b10abSAndroid Build Coastguard Worker       dst->y_chroma_shift != src->y_chroma_shift ||
412*fb1b10abSAndroid Build Coastguard Worker       dst->fmt != src->fmt + VPX_IMG_FMT_HIGHBITDEPTH || input_shift < 0) {
413*fb1b10abSAndroid Build Coastguard Worker     fatal("Unsupported image conversion");
414*fb1b10abSAndroid Build Coastguard Worker   }
415*fb1b10abSAndroid Build Coastguard Worker   switch (src->fmt) {
416*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I420:
417*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I422:
418*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I444:
419*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I440: break;
420*fb1b10abSAndroid Build Coastguard Worker     default: fatal("Unsupported image conversion");
421*fb1b10abSAndroid Build Coastguard Worker   }
422*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; plane++) {
423*fb1b10abSAndroid Build Coastguard Worker     int w = src->d_w;
424*fb1b10abSAndroid Build Coastguard Worker     int h = src->d_h;
425*fb1b10abSAndroid Build Coastguard Worker     int x, y;
426*fb1b10abSAndroid Build Coastguard Worker     if (plane) {
427*fb1b10abSAndroid Build Coastguard Worker       w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
428*fb1b10abSAndroid Build Coastguard Worker       h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
429*fb1b10abSAndroid Build Coastguard Worker     }
430*fb1b10abSAndroid Build Coastguard Worker     for (y = 0; y < h; y++) {
431*fb1b10abSAndroid Build Coastguard Worker       uint8_t *p_src = src->planes[plane] + y * src->stride[plane];
432*fb1b10abSAndroid Build Coastguard Worker       uint16_t *p_dst =
433*fb1b10abSAndroid Build Coastguard Worker           (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
434*fb1b10abSAndroid Build Coastguard Worker       for (x = 0; x < w; x++) {
435*fb1b10abSAndroid Build Coastguard Worker         *p_dst++ = (*p_src++ << input_shift) + offset;
436*fb1b10abSAndroid Build Coastguard Worker       }
437*fb1b10abSAndroid Build Coastguard Worker     }
438*fb1b10abSAndroid Build Coastguard Worker   }
439*fb1b10abSAndroid Build Coastguard Worker }
440*fb1b10abSAndroid Build Coastguard Worker 
vpx_img_upshift(vpx_image_t * dst,vpx_image_t * src,int input_shift)441*fb1b10abSAndroid Build Coastguard Worker void vpx_img_upshift(vpx_image_t *dst, vpx_image_t *src, int input_shift) {
442*fb1b10abSAndroid Build Coastguard Worker   if (src->fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
443*fb1b10abSAndroid Build Coastguard Worker     highbd_img_upshift(dst, src, input_shift);
444*fb1b10abSAndroid Build Coastguard Worker   } else {
445*fb1b10abSAndroid Build Coastguard Worker     lowbd_img_upshift(dst, src, input_shift);
446*fb1b10abSAndroid Build Coastguard Worker   }
447*fb1b10abSAndroid Build Coastguard Worker }
448*fb1b10abSAndroid Build Coastguard Worker 
vpx_img_truncate_16_to_8(vpx_image_t * dst,vpx_image_t * src)449*fb1b10abSAndroid Build Coastguard Worker void vpx_img_truncate_16_to_8(vpx_image_t *dst, vpx_image_t *src) {
450*fb1b10abSAndroid Build Coastguard Worker   int plane;
451*fb1b10abSAndroid Build Coastguard Worker   if (dst->fmt + VPX_IMG_FMT_HIGHBITDEPTH != src->fmt || dst->d_w != src->d_w ||
452*fb1b10abSAndroid Build Coastguard Worker       dst->d_h != src->d_h || dst->x_chroma_shift != src->x_chroma_shift ||
453*fb1b10abSAndroid Build Coastguard Worker       dst->y_chroma_shift != src->y_chroma_shift) {
454*fb1b10abSAndroid Build Coastguard Worker     fatal("Unsupported image conversion");
455*fb1b10abSAndroid Build Coastguard Worker   }
456*fb1b10abSAndroid Build Coastguard Worker   switch (dst->fmt) {
457*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I420:
458*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I422:
459*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I444:
460*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I440: break;
461*fb1b10abSAndroid Build Coastguard Worker     default: fatal("Unsupported image conversion");
462*fb1b10abSAndroid Build Coastguard Worker   }
463*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; plane++) {
464*fb1b10abSAndroid Build Coastguard Worker     int w = src->d_w;
465*fb1b10abSAndroid Build Coastguard Worker     int h = src->d_h;
466*fb1b10abSAndroid Build Coastguard Worker     int x, y;
467*fb1b10abSAndroid Build Coastguard Worker     if (plane) {
468*fb1b10abSAndroid Build Coastguard Worker       w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
469*fb1b10abSAndroid Build Coastguard Worker       h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
470*fb1b10abSAndroid Build Coastguard Worker     }
471*fb1b10abSAndroid Build Coastguard Worker     for (y = 0; y < h; y++) {
472*fb1b10abSAndroid Build Coastguard Worker       uint16_t *p_src =
473*fb1b10abSAndroid Build Coastguard Worker           (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
474*fb1b10abSAndroid Build Coastguard Worker       uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane];
475*fb1b10abSAndroid Build Coastguard Worker       for (x = 0; x < w; x++) {
476*fb1b10abSAndroid Build Coastguard Worker         *p_dst++ = (uint8_t)(*p_src++);
477*fb1b10abSAndroid Build Coastguard Worker       }
478*fb1b10abSAndroid Build Coastguard Worker     }
479*fb1b10abSAndroid Build Coastguard Worker   }
480*fb1b10abSAndroid Build Coastguard Worker }
481*fb1b10abSAndroid Build Coastguard Worker 
highbd_img_downshift(vpx_image_t * dst,vpx_image_t * src,int down_shift)482*fb1b10abSAndroid Build Coastguard Worker static void highbd_img_downshift(vpx_image_t *dst, vpx_image_t *src,
483*fb1b10abSAndroid Build Coastguard Worker                                  int down_shift) {
484*fb1b10abSAndroid Build Coastguard Worker   int plane;
485*fb1b10abSAndroid Build Coastguard Worker   if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
486*fb1b10abSAndroid Build Coastguard Worker       dst->x_chroma_shift != src->x_chroma_shift ||
487*fb1b10abSAndroid Build Coastguard Worker       dst->y_chroma_shift != src->y_chroma_shift || dst->fmt != src->fmt ||
488*fb1b10abSAndroid Build Coastguard Worker       down_shift < 0) {
489*fb1b10abSAndroid Build Coastguard Worker     fatal("Unsupported image conversion");
490*fb1b10abSAndroid Build Coastguard Worker   }
491*fb1b10abSAndroid Build Coastguard Worker   switch (src->fmt) {
492*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I42016:
493*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I42216:
494*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I44416:
495*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I44016: break;
496*fb1b10abSAndroid Build Coastguard Worker     default: fatal("Unsupported image conversion");
497*fb1b10abSAndroid Build Coastguard Worker   }
498*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; plane++) {
499*fb1b10abSAndroid Build Coastguard Worker     int w = src->d_w;
500*fb1b10abSAndroid Build Coastguard Worker     int h = src->d_h;
501*fb1b10abSAndroid Build Coastguard Worker     int x, y;
502*fb1b10abSAndroid Build Coastguard Worker     if (plane) {
503*fb1b10abSAndroid Build Coastguard Worker       w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
504*fb1b10abSAndroid Build Coastguard Worker       h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
505*fb1b10abSAndroid Build Coastguard Worker     }
506*fb1b10abSAndroid Build Coastguard Worker     for (y = 0; y < h; y++) {
507*fb1b10abSAndroid Build Coastguard Worker       uint16_t *p_src =
508*fb1b10abSAndroid Build Coastguard Worker           (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
509*fb1b10abSAndroid Build Coastguard Worker       uint16_t *p_dst =
510*fb1b10abSAndroid Build Coastguard Worker           (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
511*fb1b10abSAndroid Build Coastguard Worker       for (x = 0; x < w; x++) *p_dst++ = *p_src++ >> down_shift;
512*fb1b10abSAndroid Build Coastguard Worker     }
513*fb1b10abSAndroid Build Coastguard Worker   }
514*fb1b10abSAndroid Build Coastguard Worker }
515*fb1b10abSAndroid Build Coastguard Worker 
lowbd_img_downshift(vpx_image_t * dst,vpx_image_t * src,int down_shift)516*fb1b10abSAndroid Build Coastguard Worker static void lowbd_img_downshift(vpx_image_t *dst, vpx_image_t *src,
517*fb1b10abSAndroid Build Coastguard Worker                                 int down_shift) {
518*fb1b10abSAndroid Build Coastguard Worker   int plane;
519*fb1b10abSAndroid Build Coastguard Worker   if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
520*fb1b10abSAndroid Build Coastguard Worker       dst->x_chroma_shift != src->x_chroma_shift ||
521*fb1b10abSAndroid Build Coastguard Worker       dst->y_chroma_shift != src->y_chroma_shift ||
522*fb1b10abSAndroid Build Coastguard Worker       src->fmt != dst->fmt + VPX_IMG_FMT_HIGHBITDEPTH || down_shift < 0) {
523*fb1b10abSAndroid Build Coastguard Worker     fatal("Unsupported image conversion");
524*fb1b10abSAndroid Build Coastguard Worker   }
525*fb1b10abSAndroid Build Coastguard Worker   switch (dst->fmt) {
526*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I420:
527*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I422:
528*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I444:
529*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I440: break;
530*fb1b10abSAndroid Build Coastguard Worker     default: fatal("Unsupported image conversion");
531*fb1b10abSAndroid Build Coastguard Worker   }
532*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; plane++) {
533*fb1b10abSAndroid Build Coastguard Worker     int w = src->d_w;
534*fb1b10abSAndroid Build Coastguard Worker     int h = src->d_h;
535*fb1b10abSAndroid Build Coastguard Worker     int x, y;
536*fb1b10abSAndroid Build Coastguard Worker     if (plane) {
537*fb1b10abSAndroid Build Coastguard Worker       w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
538*fb1b10abSAndroid Build Coastguard Worker       h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
539*fb1b10abSAndroid Build Coastguard Worker     }
540*fb1b10abSAndroid Build Coastguard Worker     for (y = 0; y < h; y++) {
541*fb1b10abSAndroid Build Coastguard Worker       uint16_t *p_src =
542*fb1b10abSAndroid Build Coastguard Worker           (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
543*fb1b10abSAndroid Build Coastguard Worker       uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane];
544*fb1b10abSAndroid Build Coastguard Worker       for (x = 0; x < w; x++) {
545*fb1b10abSAndroid Build Coastguard Worker         *p_dst++ = *p_src++ >> down_shift;
546*fb1b10abSAndroid Build Coastguard Worker       }
547*fb1b10abSAndroid Build Coastguard Worker     }
548*fb1b10abSAndroid Build Coastguard Worker   }
549*fb1b10abSAndroid Build Coastguard Worker }
550*fb1b10abSAndroid Build Coastguard Worker 
vpx_img_downshift(vpx_image_t * dst,vpx_image_t * src,int down_shift)551*fb1b10abSAndroid Build Coastguard Worker void vpx_img_downshift(vpx_image_t *dst, vpx_image_t *src, int down_shift) {
552*fb1b10abSAndroid Build Coastguard Worker   if (dst->fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
553*fb1b10abSAndroid Build Coastguard Worker     highbd_img_downshift(dst, src, down_shift);
554*fb1b10abSAndroid Build Coastguard Worker   } else {
555*fb1b10abSAndroid Build Coastguard Worker     lowbd_img_downshift(dst, src, down_shift);
556*fb1b10abSAndroid Build Coastguard Worker   }
557*fb1b10abSAndroid Build Coastguard Worker }
558*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
559*fb1b10abSAndroid Build Coastguard Worker 
compare_img(const vpx_image_t * const img1,const vpx_image_t * const img2)560*fb1b10abSAndroid Build Coastguard Worker int compare_img(const vpx_image_t *const img1, const vpx_image_t *const img2) {
561*fb1b10abSAndroid Build Coastguard Worker   uint32_t l_w = img1->d_w;
562*fb1b10abSAndroid Build Coastguard Worker   uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
563*fb1b10abSAndroid Build Coastguard Worker   const uint32_t c_h =
564*fb1b10abSAndroid Build Coastguard Worker       (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
565*fb1b10abSAndroid Build Coastguard Worker   uint32_t i;
566*fb1b10abSAndroid Build Coastguard Worker   int match = 1;
567*fb1b10abSAndroid Build Coastguard Worker 
568*fb1b10abSAndroid Build Coastguard Worker   match &= (img1->fmt == img2->fmt);
569*fb1b10abSAndroid Build Coastguard Worker   match &= (img1->d_w == img2->d_w);
570*fb1b10abSAndroid Build Coastguard Worker   match &= (img1->d_h == img2->d_h);
571*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
572*fb1b10abSAndroid Build Coastguard Worker   if (img1->fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
573*fb1b10abSAndroid Build Coastguard Worker     l_w *= 2;
574*fb1b10abSAndroid Build Coastguard Worker     c_w *= 2;
575*fb1b10abSAndroid Build Coastguard Worker   }
576*fb1b10abSAndroid Build Coastguard Worker #endif
577*fb1b10abSAndroid Build Coastguard Worker 
578*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < img1->d_h; ++i)
579*fb1b10abSAndroid Build Coastguard Worker     match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
580*fb1b10abSAndroid Build Coastguard Worker                      img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
581*fb1b10abSAndroid Build Coastguard Worker                      l_w) == 0);
582*fb1b10abSAndroid Build Coastguard Worker 
583*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < c_h; ++i)
584*fb1b10abSAndroid Build Coastguard Worker     match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
585*fb1b10abSAndroid Build Coastguard Worker                      img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
586*fb1b10abSAndroid Build Coastguard Worker                      c_w) == 0);
587*fb1b10abSAndroid Build Coastguard Worker 
588*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < c_h; ++i)
589*fb1b10abSAndroid Build Coastguard Worker     match &= (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
590*fb1b10abSAndroid Build Coastguard Worker                      img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
591*fb1b10abSAndroid Build Coastguard Worker                      c_w) == 0);
592*fb1b10abSAndroid Build Coastguard Worker 
593*fb1b10abSAndroid Build Coastguard Worker   return match;
594*fb1b10abSAndroid Build Coastguard Worker }
595*fb1b10abSAndroid Build Coastguard Worker 
596*fb1b10abSAndroid Build Coastguard Worker #define mmin(a, b) ((a) < (b) ? (a) : (b))
597*fb1b10abSAndroid Build Coastguard Worker 
598*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
find_mismatch_high(const vpx_image_t * const img1,const vpx_image_t * const img2,int yloc[4],int uloc[4],int vloc[4])599*fb1b10abSAndroid Build Coastguard Worker void find_mismatch_high(const vpx_image_t *const img1,
600*fb1b10abSAndroid Build Coastguard Worker                         const vpx_image_t *const img2, int yloc[4], int uloc[4],
601*fb1b10abSAndroid Build Coastguard Worker                         int vloc[4]) {
602*fb1b10abSAndroid Build Coastguard Worker   uint16_t *plane1, *plane2;
603*fb1b10abSAndroid Build Coastguard Worker   uint32_t stride1, stride2;
604*fb1b10abSAndroid Build Coastguard Worker   const uint32_t bsize = 64;
605*fb1b10abSAndroid Build Coastguard Worker   const uint32_t bsizey = bsize >> img1->y_chroma_shift;
606*fb1b10abSAndroid Build Coastguard Worker   const uint32_t bsizex = bsize >> img1->x_chroma_shift;
607*fb1b10abSAndroid Build Coastguard Worker   const uint32_t c_w =
608*fb1b10abSAndroid Build Coastguard Worker       (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
609*fb1b10abSAndroid Build Coastguard Worker   const uint32_t c_h =
610*fb1b10abSAndroid Build Coastguard Worker       (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
611*fb1b10abSAndroid Build Coastguard Worker   int match = 1;
612*fb1b10abSAndroid Build Coastguard Worker   uint32_t i, j;
613*fb1b10abSAndroid Build Coastguard Worker   yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
614*fb1b10abSAndroid Build Coastguard Worker   plane1 = (uint16_t *)img1->planes[VPX_PLANE_Y];
615*fb1b10abSAndroid Build Coastguard Worker   plane2 = (uint16_t *)img2->planes[VPX_PLANE_Y];
616*fb1b10abSAndroid Build Coastguard Worker   stride1 = img1->stride[VPX_PLANE_Y] / 2;
617*fb1b10abSAndroid Build Coastguard Worker   stride2 = img2->stride[VPX_PLANE_Y] / 2;
618*fb1b10abSAndroid Build Coastguard Worker   for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
619*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; match && j < img1->d_w; j += bsize) {
620*fb1b10abSAndroid Build Coastguard Worker       int k, l;
621*fb1b10abSAndroid Build Coastguard Worker       const int si = mmin(i + bsize, img1->d_h) - i;
622*fb1b10abSAndroid Build Coastguard Worker       const int sj = mmin(j + bsize, img1->d_w) - j;
623*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; match && k < si; ++k) {
624*fb1b10abSAndroid Build Coastguard Worker         for (l = 0; match && l < sj; ++l) {
625*fb1b10abSAndroid Build Coastguard Worker           if (*(plane1 + (i + k) * stride1 + j + l) !=
626*fb1b10abSAndroid Build Coastguard Worker               *(plane2 + (i + k) * stride2 + j + l)) {
627*fb1b10abSAndroid Build Coastguard Worker             yloc[0] = i + k;
628*fb1b10abSAndroid Build Coastguard Worker             yloc[1] = j + l;
629*fb1b10abSAndroid Build Coastguard Worker             yloc[2] = *(plane1 + (i + k) * stride1 + j + l);
630*fb1b10abSAndroid Build Coastguard Worker             yloc[3] = *(plane2 + (i + k) * stride2 + j + l);
631*fb1b10abSAndroid Build Coastguard Worker             match = 0;
632*fb1b10abSAndroid Build Coastguard Worker             break;
633*fb1b10abSAndroid Build Coastguard Worker           }
634*fb1b10abSAndroid Build Coastguard Worker         }
635*fb1b10abSAndroid Build Coastguard Worker       }
636*fb1b10abSAndroid Build Coastguard Worker     }
637*fb1b10abSAndroid Build Coastguard Worker   }
638*fb1b10abSAndroid Build Coastguard Worker 
639*fb1b10abSAndroid Build Coastguard Worker   uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
640*fb1b10abSAndroid Build Coastguard Worker   plane1 = (uint16_t *)img1->planes[VPX_PLANE_U];
641*fb1b10abSAndroid Build Coastguard Worker   plane2 = (uint16_t *)img2->planes[VPX_PLANE_U];
642*fb1b10abSAndroid Build Coastguard Worker   stride1 = img1->stride[VPX_PLANE_U] / 2;
643*fb1b10abSAndroid Build Coastguard Worker   stride2 = img2->stride[VPX_PLANE_U] / 2;
644*fb1b10abSAndroid Build Coastguard Worker   for (i = 0, match = 1; match && i < c_h; i += bsizey) {
645*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; match && j < c_w; j += bsizex) {
646*fb1b10abSAndroid Build Coastguard Worker       int k, l;
647*fb1b10abSAndroid Build Coastguard Worker       const int si = mmin(i + bsizey, c_h - i);
648*fb1b10abSAndroid Build Coastguard Worker       const int sj = mmin(j + bsizex, c_w - j);
649*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; match && k < si; ++k) {
650*fb1b10abSAndroid Build Coastguard Worker         for (l = 0; match && l < sj; ++l) {
651*fb1b10abSAndroid Build Coastguard Worker           if (*(plane1 + (i + k) * stride1 + j + l) !=
652*fb1b10abSAndroid Build Coastguard Worker               *(plane2 + (i + k) * stride2 + j + l)) {
653*fb1b10abSAndroid Build Coastguard Worker             uloc[0] = i + k;
654*fb1b10abSAndroid Build Coastguard Worker             uloc[1] = j + l;
655*fb1b10abSAndroid Build Coastguard Worker             uloc[2] = *(plane1 + (i + k) * stride1 + j + l);
656*fb1b10abSAndroid Build Coastguard Worker             uloc[3] = *(plane2 + (i + k) * stride2 + j + l);
657*fb1b10abSAndroid Build Coastguard Worker             match = 0;
658*fb1b10abSAndroid Build Coastguard Worker             break;
659*fb1b10abSAndroid Build Coastguard Worker           }
660*fb1b10abSAndroid Build Coastguard Worker         }
661*fb1b10abSAndroid Build Coastguard Worker       }
662*fb1b10abSAndroid Build Coastguard Worker     }
663*fb1b10abSAndroid Build Coastguard Worker   }
664*fb1b10abSAndroid Build Coastguard Worker 
665*fb1b10abSAndroid Build Coastguard Worker   vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
666*fb1b10abSAndroid Build Coastguard Worker   plane1 = (uint16_t *)img1->planes[VPX_PLANE_V];
667*fb1b10abSAndroid Build Coastguard Worker   plane2 = (uint16_t *)img2->planes[VPX_PLANE_V];
668*fb1b10abSAndroid Build Coastguard Worker   stride1 = img1->stride[VPX_PLANE_V] / 2;
669*fb1b10abSAndroid Build Coastguard Worker   stride2 = img2->stride[VPX_PLANE_V] / 2;
670*fb1b10abSAndroid Build Coastguard Worker   for (i = 0, match = 1; match && i < c_h; i += bsizey) {
671*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; match && j < c_w; j += bsizex) {
672*fb1b10abSAndroid Build Coastguard Worker       int k, l;
673*fb1b10abSAndroid Build Coastguard Worker       const int si = mmin(i + bsizey, c_h - i);
674*fb1b10abSAndroid Build Coastguard Worker       const int sj = mmin(j + bsizex, c_w - j);
675*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; match && k < si; ++k) {
676*fb1b10abSAndroid Build Coastguard Worker         for (l = 0; match && l < sj; ++l) {
677*fb1b10abSAndroid Build Coastguard Worker           if (*(plane1 + (i + k) * stride1 + j + l) !=
678*fb1b10abSAndroid Build Coastguard Worker               *(plane2 + (i + k) * stride2 + j + l)) {
679*fb1b10abSAndroid Build Coastguard Worker             vloc[0] = i + k;
680*fb1b10abSAndroid Build Coastguard Worker             vloc[1] = j + l;
681*fb1b10abSAndroid Build Coastguard Worker             vloc[2] = *(plane1 + (i + k) * stride1 + j + l);
682*fb1b10abSAndroid Build Coastguard Worker             vloc[3] = *(plane2 + (i + k) * stride2 + j + l);
683*fb1b10abSAndroid Build Coastguard Worker             match = 0;
684*fb1b10abSAndroid Build Coastguard Worker             break;
685*fb1b10abSAndroid Build Coastguard Worker           }
686*fb1b10abSAndroid Build Coastguard Worker         }
687*fb1b10abSAndroid Build Coastguard Worker       }
688*fb1b10abSAndroid Build Coastguard Worker     }
689*fb1b10abSAndroid Build Coastguard Worker   }
690*fb1b10abSAndroid Build Coastguard Worker }
691*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
692*fb1b10abSAndroid Build Coastguard Worker 
find_mismatch(const vpx_image_t * const img1,const vpx_image_t * const img2,int yloc[4],int uloc[4],int vloc[4])693*fb1b10abSAndroid Build Coastguard Worker void find_mismatch(const vpx_image_t *const img1, const vpx_image_t *const img2,
694*fb1b10abSAndroid Build Coastguard Worker                    int yloc[4], int uloc[4], int vloc[4]) {
695*fb1b10abSAndroid Build Coastguard Worker   const uint32_t bsize = 64;
696*fb1b10abSAndroid Build Coastguard Worker   const uint32_t bsizey = bsize >> img1->y_chroma_shift;
697*fb1b10abSAndroid Build Coastguard Worker   const uint32_t bsizex = bsize >> img1->x_chroma_shift;
698*fb1b10abSAndroid Build Coastguard Worker   const uint32_t c_w =
699*fb1b10abSAndroid Build Coastguard Worker       (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
700*fb1b10abSAndroid Build Coastguard Worker   const uint32_t c_h =
701*fb1b10abSAndroid Build Coastguard Worker       (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
702*fb1b10abSAndroid Build Coastguard Worker   int match = 1;
703*fb1b10abSAndroid Build Coastguard Worker   uint32_t i, j;
704*fb1b10abSAndroid Build Coastguard Worker   yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
705*fb1b10abSAndroid Build Coastguard Worker   for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
706*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; match && j < img1->d_w; j += bsize) {
707*fb1b10abSAndroid Build Coastguard Worker       int k, l;
708*fb1b10abSAndroid Build Coastguard Worker       const int si = mmin(i + bsize, img1->d_h) - i;
709*fb1b10abSAndroid Build Coastguard Worker       const int sj = mmin(j + bsize, img1->d_w) - j;
710*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; match && k < si; ++k) {
711*fb1b10abSAndroid Build Coastguard Worker         for (l = 0; match && l < sj; ++l) {
712*fb1b10abSAndroid Build Coastguard Worker           if (*(img1->planes[VPX_PLANE_Y] +
713*fb1b10abSAndroid Build Coastguard Worker                 (i + k) * img1->stride[VPX_PLANE_Y] + j + l) !=
714*fb1b10abSAndroid Build Coastguard Worker               *(img2->planes[VPX_PLANE_Y] +
715*fb1b10abSAndroid Build Coastguard Worker                 (i + k) * img2->stride[VPX_PLANE_Y] + j + l)) {
716*fb1b10abSAndroid Build Coastguard Worker             yloc[0] = i + k;
717*fb1b10abSAndroid Build Coastguard Worker             yloc[1] = j + l;
718*fb1b10abSAndroid Build Coastguard Worker             yloc[2] = *(img1->planes[VPX_PLANE_Y] +
719*fb1b10abSAndroid Build Coastguard Worker                         (i + k) * img1->stride[VPX_PLANE_Y] + j + l);
720*fb1b10abSAndroid Build Coastguard Worker             yloc[3] = *(img2->planes[VPX_PLANE_Y] +
721*fb1b10abSAndroid Build Coastguard Worker                         (i + k) * img2->stride[VPX_PLANE_Y] + j + l);
722*fb1b10abSAndroid Build Coastguard Worker             match = 0;
723*fb1b10abSAndroid Build Coastguard Worker             break;
724*fb1b10abSAndroid Build Coastguard Worker           }
725*fb1b10abSAndroid Build Coastguard Worker         }
726*fb1b10abSAndroid Build Coastguard Worker       }
727*fb1b10abSAndroid Build Coastguard Worker     }
728*fb1b10abSAndroid Build Coastguard Worker   }
729*fb1b10abSAndroid Build Coastguard Worker 
730*fb1b10abSAndroid Build Coastguard Worker   uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
731*fb1b10abSAndroid Build Coastguard Worker   for (i = 0, match = 1; match && i < c_h; i += bsizey) {
732*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; match && j < c_w; j += bsizex) {
733*fb1b10abSAndroid Build Coastguard Worker       int k, l;
734*fb1b10abSAndroid Build Coastguard Worker       const int si = mmin(i + bsizey, c_h - i);
735*fb1b10abSAndroid Build Coastguard Worker       const int sj = mmin(j + bsizex, c_w - j);
736*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; match && k < si; ++k) {
737*fb1b10abSAndroid Build Coastguard Worker         for (l = 0; match && l < sj; ++l) {
738*fb1b10abSAndroid Build Coastguard Worker           if (*(img1->planes[VPX_PLANE_U] +
739*fb1b10abSAndroid Build Coastguard Worker                 (i + k) * img1->stride[VPX_PLANE_U] + j + l) !=
740*fb1b10abSAndroid Build Coastguard Worker               *(img2->planes[VPX_PLANE_U] +
741*fb1b10abSAndroid Build Coastguard Worker                 (i + k) * img2->stride[VPX_PLANE_U] + j + l)) {
742*fb1b10abSAndroid Build Coastguard Worker             uloc[0] = i + k;
743*fb1b10abSAndroid Build Coastguard Worker             uloc[1] = j + l;
744*fb1b10abSAndroid Build Coastguard Worker             uloc[2] = *(img1->planes[VPX_PLANE_U] +
745*fb1b10abSAndroid Build Coastguard Worker                         (i + k) * img1->stride[VPX_PLANE_U] + j + l);
746*fb1b10abSAndroid Build Coastguard Worker             uloc[3] = *(img2->planes[VPX_PLANE_U] +
747*fb1b10abSAndroid Build Coastguard Worker                         (i + k) * img2->stride[VPX_PLANE_U] + j + l);
748*fb1b10abSAndroid Build Coastguard Worker             match = 0;
749*fb1b10abSAndroid Build Coastguard Worker             break;
750*fb1b10abSAndroid Build Coastguard Worker           }
751*fb1b10abSAndroid Build Coastguard Worker         }
752*fb1b10abSAndroid Build Coastguard Worker       }
753*fb1b10abSAndroid Build Coastguard Worker     }
754*fb1b10abSAndroid Build Coastguard Worker   }
755*fb1b10abSAndroid Build Coastguard Worker   vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
756*fb1b10abSAndroid Build Coastguard Worker   for (i = 0, match = 1; match && i < c_h; i += bsizey) {
757*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; match && j < c_w; j += bsizex) {
758*fb1b10abSAndroid Build Coastguard Worker       int k, l;
759*fb1b10abSAndroid Build Coastguard Worker       const int si = mmin(i + bsizey, c_h - i);
760*fb1b10abSAndroid Build Coastguard Worker       const int sj = mmin(j + bsizex, c_w - j);
761*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; match && k < si; ++k) {
762*fb1b10abSAndroid Build Coastguard Worker         for (l = 0; match && l < sj; ++l) {
763*fb1b10abSAndroid Build Coastguard Worker           if (*(img1->planes[VPX_PLANE_V] +
764*fb1b10abSAndroid Build Coastguard Worker                 (i + k) * img1->stride[VPX_PLANE_V] + j + l) !=
765*fb1b10abSAndroid Build Coastguard Worker               *(img2->planes[VPX_PLANE_V] +
766*fb1b10abSAndroid Build Coastguard Worker                 (i + k) * img2->stride[VPX_PLANE_V] + j + l)) {
767*fb1b10abSAndroid Build Coastguard Worker             vloc[0] = i + k;
768*fb1b10abSAndroid Build Coastguard Worker             vloc[1] = j + l;
769*fb1b10abSAndroid Build Coastguard Worker             vloc[2] = *(img1->planes[VPX_PLANE_V] +
770*fb1b10abSAndroid Build Coastguard Worker                         (i + k) * img1->stride[VPX_PLANE_V] + j + l);
771*fb1b10abSAndroid Build Coastguard Worker             vloc[3] = *(img2->planes[VPX_PLANE_V] +
772*fb1b10abSAndroid Build Coastguard Worker                         (i + k) * img2->stride[VPX_PLANE_V] + j + l);
773*fb1b10abSAndroid Build Coastguard Worker             match = 0;
774*fb1b10abSAndroid Build Coastguard Worker             break;
775*fb1b10abSAndroid Build Coastguard Worker           }
776*fb1b10abSAndroid Build Coastguard Worker         }
777*fb1b10abSAndroid Build Coastguard Worker       }
778*fb1b10abSAndroid Build Coastguard Worker     }
779*fb1b10abSAndroid Build Coastguard Worker   }
780*fb1b10abSAndroid Build Coastguard Worker }
781