blob: 11695942d613d6ec2db2e3a2d00211bd78cf5d37 [file] [log] [blame]
John Koleszarc377bf02010-11-02 09:11:57 -04001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
John Koleszarc377bf02010-11-02 09:11:57 -04003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
John Koleszarc377bf02010-11-02 09:11:57 -040010 */
Tom Finegan00a35aa2013-11-14 12:37:42 -080011
Dmitry Kovalev2dad0e12014-02-27 14:00:41 -080012#include <math.h>
Tom Finegan03848f52013-11-05 10:02:18 -080013#include <stdarg.h>
Tom Finegan00a35aa2013-11-14 12:37:42 -080014#include <stdio.h>
Tom Finegan03848f52013-11-05 10:02:18 -080015#include <stdlib.h>
Tom Finegan00a35aa2013-11-14 12:37:42 -080016#include <string.h>
Tom Finegan03848f52013-11-05 10:02:18 -080017
Dmitry Kovalev2dad0e12014-02-27 14:00:41 -080018#include "./tools_common.h"
19
Yaowu Xuf883b422016-08-30 14:01:10 -070020#if CONFIG_AV1_ENCODER
21#include "aom/aomcx.h"
Dmitry Kovalev70d96642014-02-11 21:12:23 -080022#endif
23
Yaowu Xuf883b422016-08-30 14:01:10 -070024#if CONFIG_AV1_DECODER
25#include "aom/aomdx.h"
Dmitry Kovalev7ec27692014-01-27 13:40:29 -080026#endif
27
John Koleszar82b1a342012-11-06 12:08:05 -080028#if defined(_WIN32) || defined(__OS2__)
John Koleszarc377bf02010-11-02 09:11:57 -040029#include <io.h>
30#include <fcntl.h>
John Koleszar82b1a342012-11-06 12:08:05 -080031
32#ifdef __OS2__
clang-format6c4d83e2016-08-08 19:03:30 -070033#define _setmode setmode
34#define _fileno fileno
35#define _O_BINARY O_BINARY
John Koleszar82b1a342012-11-06 12:08:05 -080036#endif
John Koleszarc377bf02010-11-02 09:11:57 -040037#endif
38
clang-format6c4d83e2016-08-08 19:03:30 -070039#define LOG_ERROR(label) \
40 do { \
41 const char *l = label; \
42 va_list ap; \
43 va_start(ap, fmt); \
44 if (l) fprintf(stderr, "%s: ", l); \
45 vfprintf(stderr, fmt, ap); \
46 fprintf(stderr, "\n"); \
47 va_end(ap); \
48 } while (0)
Tom Finegan03848f52013-11-05 10:02:18 -080049
John Koleszarc6b90392012-07-13 15:21:29 -070050FILE *set_binary_mode(FILE *stream) {
51 (void)stream;
John Koleszar82b1a342012-11-06 12:08:05 -080052#if defined(_WIN32) || defined(__OS2__)
John Koleszarc6b90392012-07-13 15:21:29 -070053 _setmode(_fileno(stream), _O_BINARY);
John Koleszarc377bf02010-11-02 09:11:57 -040054#endif
John Koleszarc6b90392012-07-13 15:21:29 -070055 return stream;
John Koleszarc377bf02010-11-02 09:11:57 -040056}
Tom Finegan03848f52013-11-05 10:02:18 -080057
58void die(const char *fmt, ...) {
59 LOG_ERROR(NULL);
60 usage_exit();
61}
62
63void fatal(const char *fmt, ...) {
64 LOG_ERROR("Fatal");
65 exit(EXIT_FAILURE);
66}
67
clang-format6c4d83e2016-08-08 19:03:30 -070068void warn(const char *fmt, ...) { LOG_ERROR("Warning"); }
Tom Finegan00a35aa2013-11-14 12:37:42 -080069
Yaowu Xuf883b422016-08-30 14:01:10 -070070void die_codec(aom_codec_ctx_t *ctx, const char *s) {
71 const char *detail = aom_codec_error_detail(ctx);
Dmitry Kovalev7ec27692014-01-27 13:40:29 -080072
Yaowu Xuf883b422016-08-30 14:01:10 -070073 printf("%s: %s\n", s, aom_codec_error(ctx));
clang-format6c4d83e2016-08-08 19:03:30 -070074 if (detail) printf(" %s\n", detail);
Dmitry Kovalev7ec27692014-01-27 13:40:29 -080075 exit(EXIT_FAILURE);
76}
77
Yaowu Xuf883b422016-08-30 14:01:10 -070078int read_yuv_frame(struct AvxInputContext *input_ctx, aom_image_t *yuv_frame) {
Tom Finegan00a35aa2013-11-14 12:37:42 -080079 FILE *f = input_ctx->file;
80 struct FileTypeDetectionBuffer *detect = &input_ctx->detect;
81 int plane = 0;
82 int shortread = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070083 const int bytespp = (yuv_frame->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
Tom Finegan00a35aa2013-11-14 12:37:42 -080084
85 for (plane = 0; plane < 3; ++plane) {
86 uint8_t *ptr;
Yaowu Xuf883b422016-08-30 14:01:10 -070087 const int w = aom_img_plane_width(yuv_frame, plane);
88 const int h = aom_img_plane_height(yuv_frame, plane);
Tom Finegan00a35aa2013-11-14 12:37:42 -080089 int r;
90
91 /* Determine the correct plane based on the image format. The for-loop
92 * always counts in Y,U,V order, but this may not match the order of
93 * the data on disk.
94 */
95 switch (plane) {
96 case 1:
clang-format6c4d83e2016-08-08 19:03:30 -070097 ptr =
Yaowu Xuf883b422016-08-30 14:01:10 -070098 yuv_frame->planes[yuv_frame->fmt == AOM_IMG_FMT_YV12 ? AOM_PLANE_V
99 : AOM_PLANE_U];
Tom Finegan00a35aa2013-11-14 12:37:42 -0800100 break;
101 case 2:
clang-format6c4d83e2016-08-08 19:03:30 -0700102 ptr =
Yaowu Xuf883b422016-08-30 14:01:10 -0700103 yuv_frame->planes[yuv_frame->fmt == AOM_IMG_FMT_YV12 ? AOM_PLANE_U
104 : AOM_PLANE_V];
Tom Finegan00a35aa2013-11-14 12:37:42 -0800105 break;
clang-format6c4d83e2016-08-08 19:03:30 -0700106 default: ptr = yuv_frame->planes[plane];
Tom Finegan00a35aa2013-11-14 12:37:42 -0800107 }
108
109 for (r = 0; r < h; ++r) {
Deb Mukherjee449e5f22014-07-11 11:43:31 -0700110 size_t needed = w * bytespp;
Tom Finegan00a35aa2013-11-14 12:37:42 -0800111 size_t buf_position = 0;
112 const size_t left = detect->buf_read - detect->position;
113 if (left > 0) {
114 const size_t more = (left < needed) ? left : needed;
115 memcpy(ptr, detect->buf + detect->position, more);
116 buf_position = more;
117 needed -= more;
118 detect->position += more;
119 }
120 if (needed > 0) {
121 shortread |= (fread(ptr + buf_position, 1, needed, f) < needed);
122 }
123
124 ptr += yuv_frame->stride[plane];
125 }
126 }
127
128 return shortread;
129}
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800130
James Zern8465c932015-08-10 16:45:49 -0700131#if CONFIG_ENCODERS
132
Yaowu Xuf883b422016-08-30 14:01:10 -0700133static const AvxInterface aom_encoders[] = {
134#if CONFIG_AV1_ENCODER
135 { "av1", AV1_FOURCC, &aom_codec_av1_cx },
Jingning Han5dccce52015-08-15 15:57:54 -0700136#endif
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800137};
138
Yaowu Xuf883b422016-08-30 14:01:10 -0700139int get_aom_encoder_count(void) {
140 return sizeof(aom_encoders) / sizeof(aom_encoders[0]);
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800141}
142
Yaowu Xuf883b422016-08-30 14:01:10 -0700143const AvxInterface *get_aom_encoder_by_index(int i) { return &aom_encoders[i]; }
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800144
Yaowu Xuf883b422016-08-30 14:01:10 -0700145const AvxInterface *get_aom_encoder_by_name(const char *name) {
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800146 int i;
147
Yaowu Xuf883b422016-08-30 14:01:10 -0700148 for (i = 0; i < get_aom_encoder_count(); ++i) {
149 const AvxInterface *encoder = get_aom_encoder_by_index(i);
clang-format6c4d83e2016-08-08 19:03:30 -0700150 if (strcmp(encoder->name, name) == 0) return encoder;
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800151 }
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800152
153 return NULL;
154}
155
James Zern8465c932015-08-10 16:45:49 -0700156#endif // CONFIG_ENCODERS
157
158#if CONFIG_DECODERS
159
Yaowu Xuf883b422016-08-30 14:01:10 -0700160static const AvxInterface aom_decoders[] = {
Yaowu Xuf883b422016-08-30 14:01:10 -0700161#if CONFIG_AV1_DECODER
162 { "av1", AV1_FOURCC, &aom_codec_av1_dx },
Jingning Han3ee6db62015-08-05 19:00:31 -0700163#endif
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800164};
165
Yaowu Xuf883b422016-08-30 14:01:10 -0700166int get_aom_decoder_count(void) {
167 return sizeof(aom_decoders) / sizeof(aom_decoders[0]);
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800168}
169
Yaowu Xuf883b422016-08-30 14:01:10 -0700170const AvxInterface *get_aom_decoder_by_index(int i) { return &aom_decoders[i]; }
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800171
Yaowu Xuf883b422016-08-30 14:01:10 -0700172const AvxInterface *get_aom_decoder_by_name(const char *name) {
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800173 int i;
174
Yaowu Xuf883b422016-08-30 14:01:10 -0700175 for (i = 0; i < get_aom_decoder_count(); ++i) {
176 const AvxInterface *const decoder = get_aom_decoder_by_index(i);
clang-format6c4d83e2016-08-08 19:03:30 -0700177 if (strcmp(decoder->name, name) == 0) return decoder;
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800178 }
179
180 return NULL;
181}
182
Yaowu Xuf883b422016-08-30 14:01:10 -0700183const AvxInterface *get_aom_decoder_by_fourcc(uint32_t fourcc) {
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800184 int i;
185
Yaowu Xuf883b422016-08-30 14:01:10 -0700186 for (i = 0; i < get_aom_decoder_count(); ++i) {
187 const AvxInterface *const decoder = get_aom_decoder_by_index(i);
clang-format6c4d83e2016-08-08 19:03:30 -0700188 if (decoder->fourcc == fourcc) return decoder;
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800189 }
190
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800191 return NULL;
192}
193
James Zern8465c932015-08-10 16:45:49 -0700194#endif // CONFIG_DECODERS
195
Yaowu Xuf883b422016-08-30 14:01:10 -0700196// TODO(dkovalev): move this function to aom_image.{c, h}, so it will be part
197// of aom_image_t support
198int aom_img_plane_width(const aom_image_t *img, int plane) {
Dmitry Kovalev2bdd43d2014-02-12 18:36:36 -0800199 if (plane > 0 && img->x_chroma_shift > 0)
200 return (img->d_w + 1) >> img->x_chroma_shift;
201 else
202 return img->d_w;
203}
204
Yaowu Xuf883b422016-08-30 14:01:10 -0700205int aom_img_plane_height(const aom_image_t *img, int plane) {
clang-format6c4d83e2016-08-08 19:03:30 -0700206 if (plane > 0 && img->y_chroma_shift > 0)
Dmitry Kovalev2bdd43d2014-02-12 18:36:36 -0800207 return (img->d_h + 1) >> img->y_chroma_shift;
208 else
209 return img->d_h;
210}
211
Yaowu Xuf883b422016-08-30 14:01:10 -0700212void aom_img_write(const aom_image_t *img, FILE *file) {
Dmitry Kovalev2bdd43d2014-02-12 18:36:36 -0800213 int plane;
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800214
215 for (plane = 0; plane < 3; ++plane) {
216 const unsigned char *buf = img->planes[plane];
217 const int stride = img->stride[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -0700218 const int w = aom_img_plane_width(img, plane) *
219 ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
220 const int h = aom_img_plane_height(img, plane);
Dmitry Kovalev2bdd43d2014-02-12 18:36:36 -0800221 int y;
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800222
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800223 for (y = 0; y < h; ++y) {
224 fwrite(buf, 1, w, file);
225 buf += stride;
226 }
227 }
228}
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800229
Yaowu Xuf883b422016-08-30 14:01:10 -0700230int aom_img_read(aom_image_t *img, FILE *file) {
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800231 int plane;
232
233 for (plane = 0; plane < 3; ++plane) {
234 unsigned char *buf = img->planes[plane];
235 const int stride = img->stride[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -0700236 const int w = aom_img_plane_width(img, plane) *
237 ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
238 const int h = aom_img_plane_height(img, plane);
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800239 int y;
240
241 for (y = 0; y < h; ++y) {
clang-format6c4d83e2016-08-08 19:03:30 -0700242 if (fread(buf, 1, w, file) != (size_t)w) return 0;
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800243 buf += stride;
244 }
245 }
246
247 return 1;
248}
249
Dmitry Kovalev2dad0e12014-02-27 14:00:41 -0800250// TODO(dkovalev) change sse_to_psnr signature: double -> int64_t
251double sse_to_psnr(double samples, double peak, double sse) {
252 static const double kMaxPSNR = 100.0;
253
254 if (sse > 0.0) {
255 const double psnr = 10.0 * log10(samples * peak * peak / sse);
256 return psnr > kMaxPSNR ? kMaxPSNR : psnr;
257 } else {
258 return kMaxPSNR;
259 }
260}
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700261
262// TODO(debargha): Consolidate the functions below into a separate file.
Yaowu Xuf883b422016-08-30 14:01:10 -0700263#if CONFIG_AOM_HIGHBITDEPTH
264static void highbd_img_upshift(aom_image_t *dst, aom_image_t *src,
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700265 int input_shift) {
266 // Note the offset is 1 less than half.
267 const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0;
268 int plane;
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700269 if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700270 dst->x_chroma_shift != src->x_chroma_shift ||
clang-format6c4d83e2016-08-08 19:03:30 -0700271 dst->y_chroma_shift != src->y_chroma_shift || dst->fmt != src->fmt ||
272 input_shift < 0) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700273 fatal("Unsupported image conversion");
274 }
275 switch (src->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700276 case AOM_IMG_FMT_I42016:
277 case AOM_IMG_FMT_I42216:
278 case AOM_IMG_FMT_I44416:
279 case AOM_IMG_FMT_I44016: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700280 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700281 }
282 for (plane = 0; plane < 3; plane++) {
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700283 int w = src->d_w;
284 int h = src->d_h;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700285 int x, y;
286 if (plane) {
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700287 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
288 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700289 }
290 for (y = 0; y < h; y++) {
291 uint16_t *p_src =
292 (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
293 uint16_t *p_dst =
294 (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
clang-format6c4d83e2016-08-08 19:03:30 -0700295 for (x = 0; x < w; x++) *p_dst++ = (*p_src++ << input_shift) + offset;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700296 }
297 }
298}
299
Yaowu Xuf883b422016-08-30 14:01:10 -0700300static void lowbd_img_upshift(aom_image_t *dst, aom_image_t *src,
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700301 int input_shift) {
302 // Note the offset is 1 less than half.
303 const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0;
304 int plane;
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700305 if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700306 dst->x_chroma_shift != src->x_chroma_shift ||
307 dst->y_chroma_shift != src->y_chroma_shift ||
Yaowu Xuf883b422016-08-30 14:01:10 -0700308 dst->fmt != src->fmt + AOM_IMG_FMT_HIGHBITDEPTH || input_shift < 0) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700309 fatal("Unsupported image conversion");
310 }
311 switch (src->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700312 case AOM_IMG_FMT_I420:
313 case AOM_IMG_FMT_I422:
314 case AOM_IMG_FMT_I444:
315 case AOM_IMG_FMT_I440: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700316 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700317 }
318 for (plane = 0; plane < 3; plane++) {
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700319 int w = src->d_w;
320 int h = src->d_h;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700321 int x, y;
322 if (plane) {
323 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
324 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
325 }
326 for (y = 0; y < h; y++) {
327 uint8_t *p_src = src->planes[plane] + y * src->stride[plane];
328 uint16_t *p_dst =
329 (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
330 for (x = 0; x < w; x++) {
331 *p_dst++ = (*p_src++ << input_shift) + offset;
332 }
333 }
334 }
335}
336
Yaowu Xuf883b422016-08-30 14:01:10 -0700337void aom_img_upshift(aom_image_t *dst, aom_image_t *src, int input_shift) {
338 if (src->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700339 highbd_img_upshift(dst, src, input_shift);
340 } else {
341 lowbd_img_upshift(dst, src, input_shift);
342 }
343}
344
Yaowu Xuf883b422016-08-30 14:01:10 -0700345void aom_img_truncate_16_to_8(aom_image_t *dst, aom_image_t *src) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700346 int plane;
Yaowu Xuf883b422016-08-30 14:01:10 -0700347 if (dst->fmt + AOM_IMG_FMT_HIGHBITDEPTH != src->fmt || dst->d_w != src->d_w ||
clang-format6c4d83e2016-08-08 19:03:30 -0700348 dst->d_h != src->d_h || dst->x_chroma_shift != src->x_chroma_shift ||
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700349 dst->y_chroma_shift != src->y_chroma_shift) {
350 fatal("Unsupported image conversion");
351 }
352 switch (dst->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700353 case AOM_IMG_FMT_I420:
354 case AOM_IMG_FMT_I422:
355 case AOM_IMG_FMT_I444:
356 case AOM_IMG_FMT_I440: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700357 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700358 }
359 for (plane = 0; plane < 3; plane++) {
360 int w = src->d_w;
361 int h = src->d_h;
362 int x, y;
363 if (plane) {
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700364 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
365 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700366 }
367 for (y = 0; y < h; y++) {
368 uint16_t *p_src =
369 (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
370 uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane];
371 for (x = 0; x < w; x++) {
Yaowu Xuc369daf2015-07-07 14:22:07 -0700372 *p_dst++ = (uint8_t)(*p_src++);
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700373 }
374 }
375 }
376}
377
Yaowu Xuf883b422016-08-30 14:01:10 -0700378static void highbd_img_downshift(aom_image_t *dst, aom_image_t *src,
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700379 int down_shift) {
380 int plane;
381 if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
382 dst->x_chroma_shift != src->x_chroma_shift ||
clang-format6c4d83e2016-08-08 19:03:30 -0700383 dst->y_chroma_shift != src->y_chroma_shift || dst->fmt != src->fmt ||
384 down_shift < 0) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700385 fatal("Unsupported image conversion");
386 }
387 switch (src->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700388 case AOM_IMG_FMT_I42016:
389 case AOM_IMG_FMT_I42216:
390 case AOM_IMG_FMT_I44416:
391 case AOM_IMG_FMT_I44016: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700392 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700393 }
394 for (plane = 0; plane < 3; plane++) {
395 int w = src->d_w;
396 int h = src->d_h;
397 int x, y;
398 if (plane) {
399 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
400 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
401 }
402 for (y = 0; y < h; y++) {
403 uint16_t *p_src =
404 (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
405 uint16_t *p_dst =
406 (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
clang-format6c4d83e2016-08-08 19:03:30 -0700407 for (x = 0; x < w; x++) *p_dst++ = *p_src++ >> down_shift;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700408 }
409 }
410}
411
Yaowu Xuf883b422016-08-30 14:01:10 -0700412static void lowbd_img_downshift(aom_image_t *dst, aom_image_t *src,
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700413 int down_shift) {
414 int plane;
415 if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
416 dst->x_chroma_shift != src->x_chroma_shift ||
417 dst->y_chroma_shift != src->y_chroma_shift ||
Yaowu Xuf883b422016-08-30 14:01:10 -0700418 src->fmt != dst->fmt + AOM_IMG_FMT_HIGHBITDEPTH || down_shift < 0) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700419 fatal("Unsupported image conversion");
420 }
421 switch (dst->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700422 case AOM_IMG_FMT_I420:
423 case AOM_IMG_FMT_I422:
424 case AOM_IMG_FMT_I444:
425 case AOM_IMG_FMT_I440: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700426 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700427 }
428 for (plane = 0; plane < 3; plane++) {
429 int w = src->d_w;
430 int h = src->d_h;
431 int x, y;
432 if (plane) {
433 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
434 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
435 }
436 for (y = 0; y < h; y++) {
437 uint16_t *p_src =
438 (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
439 uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane];
440 for (x = 0; x < w; x++) {
441 *p_dst++ = *p_src++ >> down_shift;
442 }
443 }
444 }
445}
446
Yaowu Xuf883b422016-08-30 14:01:10 -0700447void aom_img_downshift(aom_image_t *dst, aom_image_t *src, int down_shift) {
448 if (dst->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700449 highbd_img_downshift(dst, src, down_shift);
450 } else {
451 lowbd_img_downshift(dst, src, down_shift);
452 }
453}
Yaowu Xuf883b422016-08-30 14:01:10 -0700454#endif // CONFIG_AOM_HIGHBITDEPTH