blob: d1115ac27bed2065c9044d81749f957675b66471 [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
Yaowu Xuf883b422016-08-30 14:01:10 -0700131#if CONFIG_AV1_ENCODER
Tom Fineganba02c242017-05-16 15:01:54 -0700132static const AvxInterface aom_encoders[] = {
Yaowu Xuf883b422016-08-30 14:01:10 -0700133 { "av1", AV1_FOURCC, &aom_codec_av1_cx },
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800134};
135
Yaowu Xuf883b422016-08-30 14:01:10 -0700136int get_aom_encoder_count(void) {
137 return sizeof(aom_encoders) / sizeof(aom_encoders[0]);
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800138}
139
Yaowu Xuf883b422016-08-30 14:01:10 -0700140const AvxInterface *get_aom_encoder_by_index(int i) { return &aom_encoders[i]; }
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800141
Yaowu Xuf883b422016-08-30 14:01:10 -0700142const AvxInterface *get_aom_encoder_by_name(const char *name) {
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800143 int i;
144
Yaowu Xuf883b422016-08-30 14:01:10 -0700145 for (i = 0; i < get_aom_encoder_count(); ++i) {
146 const AvxInterface *encoder = get_aom_encoder_by_index(i);
clang-format6c4d83e2016-08-08 19:03:30 -0700147 if (strcmp(encoder->name, name) == 0) return encoder;
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800148 }
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800149
150 return NULL;
151}
Tom Fineganba02c242017-05-16 15:01:54 -0700152#endif // CONFIG_AV1_ENCODER
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800153
Yaowu Xuf883b422016-08-30 14:01:10 -0700154#if CONFIG_AV1_DECODER
Tom Fineganba02c242017-05-16 15:01:54 -0700155static const AvxInterface aom_decoders[] = {
Yaowu Xuf883b422016-08-30 14:01:10 -0700156 { "av1", AV1_FOURCC, &aom_codec_av1_dx },
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800157};
158
Yaowu Xuf883b422016-08-30 14:01:10 -0700159int get_aom_decoder_count(void) {
160 return sizeof(aom_decoders) / sizeof(aom_decoders[0]);
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800161}
162
Yaowu Xuf883b422016-08-30 14:01:10 -0700163const AvxInterface *get_aom_decoder_by_index(int i) { return &aom_decoders[i]; }
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800164
Yaowu Xuf883b422016-08-30 14:01:10 -0700165const AvxInterface *get_aom_decoder_by_name(const char *name) {
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800166 int i;
167
Yaowu Xuf883b422016-08-30 14:01:10 -0700168 for (i = 0; i < get_aom_decoder_count(); ++i) {
169 const AvxInterface *const decoder = get_aom_decoder_by_index(i);
clang-format6c4d83e2016-08-08 19:03:30 -0700170 if (strcmp(decoder->name, name) == 0) return decoder;
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800171 }
172
173 return NULL;
174}
175
Yaowu Xuf883b422016-08-30 14:01:10 -0700176const AvxInterface *get_aom_decoder_by_fourcc(uint32_t fourcc) {
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800177 int i;
178
Yaowu Xuf883b422016-08-30 14:01:10 -0700179 for (i = 0; i < get_aom_decoder_count(); ++i) {
180 const AvxInterface *const decoder = get_aom_decoder_by_index(i);
clang-format6c4d83e2016-08-08 19:03:30 -0700181 if (decoder->fourcc == fourcc) return decoder;
Dmitry Kovalev70d96642014-02-11 21:12:23 -0800182 }
183
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800184 return NULL;
185}
Tom Fineganba02c242017-05-16 15:01:54 -0700186#endif // CONFIG_AV1_DECODER
James Zern8465c932015-08-10 16:45:49 -0700187
Yaowu Xuf883b422016-08-30 14:01:10 -0700188// TODO(dkovalev): move this function to aom_image.{c, h}, so it will be part
189// of aom_image_t support
190int aom_img_plane_width(const aom_image_t *img, int plane) {
Dmitry Kovalev2bdd43d2014-02-12 18:36:36 -0800191 if (plane > 0 && img->x_chroma_shift > 0)
192 return (img->d_w + 1) >> img->x_chroma_shift;
193 else
194 return img->d_w;
195}
196
Yaowu Xuf883b422016-08-30 14:01:10 -0700197int aom_img_plane_height(const aom_image_t *img, int plane) {
clang-format6c4d83e2016-08-08 19:03:30 -0700198 if (plane > 0 && img->y_chroma_shift > 0)
Dmitry Kovalev2bdd43d2014-02-12 18:36:36 -0800199 return (img->d_h + 1) >> img->y_chroma_shift;
200 else
201 return img->d_h;
202}
203
Yaowu Xuf883b422016-08-30 14:01:10 -0700204void aom_img_write(const aom_image_t *img, FILE *file) {
Dmitry Kovalev2bdd43d2014-02-12 18:36:36 -0800205 int plane;
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800206
207 for (plane = 0; plane < 3; ++plane) {
208 const unsigned char *buf = img->planes[plane];
209 const int stride = img->stride[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -0700210 const int w = aom_img_plane_width(img, plane) *
211 ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
212 const int h = aom_img_plane_height(img, plane);
Dmitry Kovalev2bdd43d2014-02-12 18:36:36 -0800213 int y;
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800214
Dmitry Kovalev7ec27692014-01-27 13:40:29 -0800215 for (y = 0; y < h; ++y) {
216 fwrite(buf, 1, w, file);
217 buf += stride;
218 }
219 }
220}
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800221
Yaowu Xuf883b422016-08-30 14:01:10 -0700222int aom_img_read(aom_image_t *img, FILE *file) {
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800223 int plane;
224
225 for (plane = 0; plane < 3; ++plane) {
226 unsigned char *buf = img->planes[plane];
227 const int stride = img->stride[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -0700228 const int w = aom_img_plane_width(img, plane) *
229 ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
230 const int h = aom_img_plane_height(img, plane);
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800231 int y;
232
233 for (y = 0; y < h; ++y) {
clang-format6c4d83e2016-08-08 19:03:30 -0700234 if (fread(buf, 1, w, file) != (size_t)w) return 0;
Dmitry Kovalev592936b2014-02-07 11:37:39 -0800235 buf += stride;
236 }
237 }
238
239 return 1;
240}
241
Dmitry Kovalev2dad0e12014-02-27 14:00:41 -0800242// TODO(dkovalev) change sse_to_psnr signature: double -> int64_t
243double sse_to_psnr(double samples, double peak, double sse) {
244 static const double kMaxPSNR = 100.0;
245
246 if (sse > 0.0) {
247 const double psnr = 10.0 * log10(samples * peak * peak / sse);
248 return psnr > kMaxPSNR ? kMaxPSNR : psnr;
249 } else {
250 return kMaxPSNR;
251 }
252}
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700253
254// TODO(debargha): Consolidate the functions below into a separate file.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200255#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -0700256static void highbd_img_upshift(aom_image_t *dst, aom_image_t *src,
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700257 int input_shift) {
258 // Note the offset is 1 less than half.
259 const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0;
260 int plane;
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700261 if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700262 dst->x_chroma_shift != src->x_chroma_shift ||
clang-format6c4d83e2016-08-08 19:03:30 -0700263 dst->y_chroma_shift != src->y_chroma_shift || dst->fmt != src->fmt ||
264 input_shift < 0) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700265 fatal("Unsupported image conversion");
266 }
267 switch (src->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700268 case AOM_IMG_FMT_I42016:
269 case AOM_IMG_FMT_I42216:
270 case AOM_IMG_FMT_I44416:
271 case AOM_IMG_FMT_I44016: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700272 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700273 }
274 for (plane = 0; plane < 3; plane++) {
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700275 int w = src->d_w;
276 int h = src->d_h;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700277 int x, y;
278 if (plane) {
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700279 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
280 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700281 }
282 for (y = 0; y < h; y++) {
283 uint16_t *p_src =
284 (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
285 uint16_t *p_dst =
286 (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
clang-format6c4d83e2016-08-08 19:03:30 -0700287 for (x = 0; x < w; x++) *p_dst++ = (*p_src++ << input_shift) + offset;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700288 }
289 }
290}
291
Yaowu Xuf883b422016-08-30 14:01:10 -0700292static void lowbd_img_upshift(aom_image_t *dst, aom_image_t *src,
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700293 int input_shift) {
294 // Note the offset is 1 less than half.
295 const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0;
296 int plane;
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700297 if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700298 dst->x_chroma_shift != src->x_chroma_shift ||
299 dst->y_chroma_shift != src->y_chroma_shift ||
Yaowu Xuf883b422016-08-30 14:01:10 -0700300 dst->fmt != src->fmt + AOM_IMG_FMT_HIGHBITDEPTH || input_shift < 0) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700301 fatal("Unsupported image conversion");
302 }
303 switch (src->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700304 case AOM_IMG_FMT_I420:
305 case AOM_IMG_FMT_I422:
306 case AOM_IMG_FMT_I444:
307 case AOM_IMG_FMT_I440: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700308 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700309 }
310 for (plane = 0; plane < 3; plane++) {
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700311 int w = src->d_w;
312 int h = src->d_h;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700313 int x, y;
314 if (plane) {
315 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
316 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
317 }
318 for (y = 0; y < h; y++) {
319 uint8_t *p_src = src->planes[plane] + y * src->stride[plane];
320 uint16_t *p_dst =
321 (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
322 for (x = 0; x < w; x++) {
323 *p_dst++ = (*p_src++ << input_shift) + offset;
324 }
325 }
326 }
327}
328
Yaowu Xuf883b422016-08-30 14:01:10 -0700329void aom_img_upshift(aom_image_t *dst, aom_image_t *src, int input_shift) {
330 if (src->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700331 highbd_img_upshift(dst, src, input_shift);
332 } else {
333 lowbd_img_upshift(dst, src, input_shift);
334 }
335}
336
Yaowu Xuf883b422016-08-30 14:01:10 -0700337void aom_img_truncate_16_to_8(aom_image_t *dst, aom_image_t *src) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700338 int plane;
Yaowu Xuf883b422016-08-30 14:01:10 -0700339 if (dst->fmt + AOM_IMG_FMT_HIGHBITDEPTH != src->fmt || dst->d_w != src->d_w ||
clang-format6c4d83e2016-08-08 19:03:30 -0700340 dst->d_h != src->d_h || dst->x_chroma_shift != src->x_chroma_shift ||
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700341 dst->y_chroma_shift != src->y_chroma_shift) {
342 fatal("Unsupported image conversion");
343 }
344 switch (dst->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700345 case AOM_IMG_FMT_I420:
346 case AOM_IMG_FMT_I422:
347 case AOM_IMG_FMT_I444:
348 case AOM_IMG_FMT_I440: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700349 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700350 }
351 for (plane = 0; plane < 3; plane++) {
352 int w = src->d_w;
353 int h = src->d_h;
354 int x, y;
355 if (plane) {
Deb Mukherjee23fc1f72014-10-15 10:01:34 -0700356 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
357 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700358 }
359 for (y = 0; y < h; y++) {
360 uint16_t *p_src =
361 (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
362 uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane];
363 for (x = 0; x < w; x++) {
Yaowu Xuc369daf2015-07-07 14:22:07 -0700364 *p_dst++ = (uint8_t)(*p_src++);
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700365 }
366 }
367 }
368}
369
Yaowu Xuf883b422016-08-30 14:01:10 -0700370static void highbd_img_downshift(aom_image_t *dst, aom_image_t *src,
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700371 int down_shift) {
372 int plane;
373 if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
374 dst->x_chroma_shift != src->x_chroma_shift ||
clang-format6c4d83e2016-08-08 19:03:30 -0700375 dst->y_chroma_shift != src->y_chroma_shift || dst->fmt != src->fmt ||
376 down_shift < 0) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700377 fatal("Unsupported image conversion");
378 }
379 switch (src->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700380 case AOM_IMG_FMT_I42016:
381 case AOM_IMG_FMT_I42216:
382 case AOM_IMG_FMT_I44416:
383 case AOM_IMG_FMT_I44016: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700384 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700385 }
386 for (plane = 0; plane < 3; plane++) {
387 int w = src->d_w;
388 int h = src->d_h;
389 int x, y;
390 if (plane) {
391 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
392 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
393 }
394 for (y = 0; y < h; y++) {
395 uint16_t *p_src =
396 (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
397 uint16_t *p_dst =
398 (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]);
clang-format6c4d83e2016-08-08 19:03:30 -0700399 for (x = 0; x < w; x++) *p_dst++ = *p_src++ >> down_shift;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700400 }
401 }
402}
403
Yaowu Xuf883b422016-08-30 14:01:10 -0700404static void lowbd_img_downshift(aom_image_t *dst, aom_image_t *src,
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700405 int down_shift) {
406 int plane;
407 if (dst->d_w != src->d_w || dst->d_h != src->d_h ||
408 dst->x_chroma_shift != src->x_chroma_shift ||
409 dst->y_chroma_shift != src->y_chroma_shift ||
Yaowu Xuf883b422016-08-30 14:01:10 -0700410 src->fmt != dst->fmt + AOM_IMG_FMT_HIGHBITDEPTH || down_shift < 0) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700411 fatal("Unsupported image conversion");
412 }
413 switch (dst->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700414 case AOM_IMG_FMT_I420:
415 case AOM_IMG_FMT_I422:
416 case AOM_IMG_FMT_I444:
417 case AOM_IMG_FMT_I440: break;
clang-format6c4d83e2016-08-08 19:03:30 -0700418 default: fatal("Unsupported image conversion"); break;
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700419 }
420 for (plane = 0; plane < 3; plane++) {
421 int w = src->d_w;
422 int h = src->d_h;
423 int x, y;
424 if (plane) {
425 w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
426 h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
427 }
428 for (y = 0; y < h; y++) {
429 uint16_t *p_src =
430 (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
431 uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane];
432 for (x = 0; x < w; x++) {
433 *p_dst++ = *p_src++ >> down_shift;
434 }
435 }
436 }
437}
438
Yaowu Xuf883b422016-08-30 14:01:10 -0700439void aom_img_downshift(aom_image_t *dst, aom_image_t *src, int down_shift) {
440 if (dst->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
Deb Mukherjee7a2a6112014-10-06 20:46:11 -0700441 highbd_img_downshift(dst, src, down_shift);
442 } else {
443 lowbd_img_downshift(dst, src, down_shift);
444 }
445}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200446#endif // CONFIG_HIGHBITDEPTH