1538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/*
2538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *
4538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  Use of this source code is governed by a BSD-style license
5538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  that can be found in the LICENSE file in the root of the source
6538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  tree. An additional intellectual property rights grant can be found
7538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  in the file PATENTS.  All contributing project authors may
8538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
9538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber */
105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
11b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <math.h>
125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include <stdarg.h>
13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdio.h>
145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include <stdlib.h>
15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <string.h>
16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./tools_common.h"
18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vp8cx.h"
21b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif
22b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
23b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
24b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vp8dx.h"
25b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif
265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
271b362b15af34006e6a11974088a46d42b903418eJohann#if defined(_WIN32) || defined(__OS2__)
28538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <io.h>
29538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <fcntl.h>
301b362b15af34006e6a11974088a46d42b903418eJohann
311b362b15af34006e6a11974088a46d42b903418eJohann#ifdef __OS2__
321b362b15af34006e6a11974088a46d42b903418eJohann#define _setmode    setmode
331b362b15af34006e6a11974088a46d42b903418eJohann#define _fileno     fileno
341b362b15af34006e6a11974088a46d42b903418eJohann#define _O_BINARY   O_BINARY
351b362b15af34006e6a11974088a46d42b903418eJohann#endif
36538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
37538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define LOG_ERROR(label) do {\
395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const char *l = label;\
405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  va_list ap;\
415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  va_start(ap, fmt);\
425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (l)\
435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    fprintf(stderr, "%s: ", l);\
445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vfprintf(stderr, fmt, ap);\
455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  fprintf(stderr, "\n");\
465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  va_end(ap);\
475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang} while (0)
485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangFILE *set_binary_mode(FILE *stream) {
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  (void)stream;
521b362b15af34006e6a11974088a46d42b903418eJohann#if defined(_WIN32) || defined(__OS2__)
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  _setmode(_fileno(stream), _O_BINARY);
54538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return stream;
56538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangvoid die(const char *fmt, ...) {
595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  LOG_ERROR(NULL);
605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  usage_exit();
615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangvoid fatal(const char *fmt, ...) {
645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  LOG_ERROR("Fatal");
655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  exit(EXIT_FAILURE);
665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangvoid warn(const char *fmt, ...) {
695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  LOG_ERROR("Warning");
705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
71b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
72b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid die_codec(vpx_codec_ctx_t *ctx, const char *s) {
73b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const char *detail = vpx_codec_error_detail(ctx);
74b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
75b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  printf("%s: %s\n", s, vpx_codec_error(ctx));
76b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (detail)
77b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    printf("    %s\n", detail);
78b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  exit(EXIT_FAILURE);
79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
80b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
81b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) {
82b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  FILE *f = input_ctx->file;
83b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct FileTypeDetectionBuffer *detect = &input_ctx->detect;
84b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int plane = 0;
85b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int shortread = 0;
86b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
87b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (plane = 0; plane < 3; ++plane) {
88b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    uint8_t *ptr;
89b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int w = (plane ? (1 + yuv_frame->d_w) / 2 : yuv_frame->d_w);
90b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int h = (plane ? (1 + yuv_frame->d_h) / 2 : yuv_frame->d_h);
91b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int r;
92b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
93b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    /* Determine the correct plane based on the image format. The for-loop
94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     * always counts in Y,U,V order, but this may not match the order of
95b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     * the data on disk.
96b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     */
97b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    switch (plane) {
98b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      case 1:
99b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        ptr = yuv_frame->planes[
100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V : VPX_PLANE_U];
101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        break;
102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      case 2:
103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        ptr = yuv_frame->planes[
104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U : VPX_PLANE_V];
105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        break;
106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      default:
107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        ptr = yuv_frame->planes[plane];
108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (r = 0; r < h; ++r) {
111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      size_t needed = w;
112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      size_t buf_position = 0;
113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const size_t left = detect->buf_read - detect->position;
114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (left > 0) {
115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        const size_t more = (left < needed) ? left : needed;
116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        memcpy(ptr, detect->buf + detect->position, more);
117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        buf_position = more;
118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        needed -= more;
119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        detect->position += more;
120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (needed > 0) {
122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        shortread |= (fread(ptr + buf_position, 1, needed, f) < needed);
123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      ptr += yuv_frame->stride[plane];
126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return shortread;
130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic const VpxInterface vpx_encoders[] = {
133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if CONFIG_VP8_ENCODER
134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {"vp8", VP8_FOURCC, &vpx_codec_vp8_cx},
135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif
136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if CONFIG_VP9_ENCODER
138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {"vp9", VP9_FOURCC, &vpx_codec_vp9_cx},
139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif
140b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian};
141b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint get_vpx_encoder_count() {
143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return sizeof(vpx_encoders) / sizeof(vpx_encoders[0]);
144b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianconst VpxInterface *get_vpx_encoder_by_index(int i) {
147b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return &vpx_encoders[i];
148b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianconst VpxInterface *get_vpx_encoder_by_name(const char *name) {
151b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i;
152b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
153b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < get_vpx_encoder_count(); ++i) {
154b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const VpxInterface *encoder = get_vpx_encoder_by_index(i);
155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (strcmp(encoder->name, name) == 0)
156b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      return encoder;
157b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
158b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
159b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return NULL;
160b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
161b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
162b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic const VpxInterface vpx_decoders[] = {
163b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if CONFIG_VP8_DECODER
164b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {"vp8", VP8_FOURCC, &vpx_codec_vp8_dx},
165b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif
166b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
167b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#if CONFIG_VP9_DECODER
168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {"vp9", VP9_FOURCC, &vpx_codec_vp9_dx},
169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif
170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian};
171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint get_vpx_decoder_count() {
173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return sizeof(vpx_decoders) / sizeof(vpx_decoders[0]);
174b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
175b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianconst VpxInterface *get_vpx_decoder_by_index(int i) {
177b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return &vpx_decoders[i];
178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianconst VpxInterface *get_vpx_decoder_by_name(const char *name) {
181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i;
182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < get_vpx_decoder_count(); ++i) {
184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
185b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     if (strcmp(decoder->name, name) == 0)
186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       return decoder;
187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return NULL;
190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianconst VpxInterface *get_vpx_decoder_by_fourcc(uint32_t fourcc) {
193b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i;
194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < get_vpx_decoder_count(); ++i) {
196b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
197b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (decoder->fourcc == fourcc)
198b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      return decoder;
199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return NULL;
202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// TODO(dkovalev): move this function to vpx_image.{c, h}, so it will be part
205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// of vpx_image_t support
206b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint vpx_img_plane_width(const vpx_image_t *img, int plane) {
207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (plane > 0 && img->x_chroma_shift > 0)
208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return (img->d_w + 1) >> img->x_chroma_shift;
209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  else
210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return img->d_w;
211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint vpx_img_plane_height(const vpx_image_t *img, int plane) {
214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (plane > 0 &&  img->y_chroma_shift > 0)
215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return (img->d_h + 1) >> img->y_chroma_shift;
216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  else
217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return img->d_h;
218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vpx_img_write(const vpx_image_t *img, FILE *file) {
221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int plane;
222b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (plane = 0; plane < 3; ++plane) {
224b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const unsigned char *buf = img->planes[plane];
225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int stride = img->stride[plane];
226b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int w = vpx_img_plane_width(img, plane);
227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int h = vpx_img_plane_height(img, plane);
228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int y;
229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (y = 0; y < h; ++y) {
231b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      fwrite(buf, 1, w, file);
232b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      buf += stride;
233b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
234b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
235b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
236b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
237b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint vpx_img_read(vpx_image_t *img, FILE *file) {
238b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int plane;
239b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
240b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (plane = 0; plane < 3; ++plane) {
241b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    unsigned char *buf = img->planes[plane];
242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int stride = img->stride[plane];
243b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int w = vpx_img_plane_width(img, plane);
244b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int h = vpx_img_plane_height(img, plane);
245b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int y;
246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
247b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (y = 0; y < h; ++y) {
248b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (fread(buf, 1, w, file) != w)
249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        return 0;
250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      buf += stride;
251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
254b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return 1;
255b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// TODO(dkovalev) change sse_to_psnr signature: double -> int64_t
258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandouble sse_to_psnr(double samples, double peak, double sse) {
259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  static const double kMaxPSNR = 100.0;
260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (sse > 0.0) {
262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const double psnr = 10.0 * log10(samples * peak * peak / sse);
263b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return psnr > kMaxPSNR ? kMaxPSNR : psnr;
264b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else {
265b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return kMaxPSNR;
266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
267b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
268