1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/*
2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *
4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Use of this source code is governed by a BSD-style license
5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  that can be found in the LICENSE file in the root of the source
6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  tree. An additional intellectual property rights grant can be found
7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  in the file PATENTS.  All contributing project authors may
8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  be found in the AUTHORS file in the root of the source tree.
9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */
10d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
11411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include <math.h>
12d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <stdarg.h>
13d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <stdio.h>
14d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <stdlib.h>
15d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <string.h>
16d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
17411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "./tools_common.h"
18411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
1976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
2076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#include "vpx/vp8cx.h"
2176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#endif
2276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
23dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
24dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "vpx/vp8dx.h"
25dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
26dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
275c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#if defined(_WIN32) || defined(__OS2__)
28474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <io.h>
29474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <fcntl.h>
305c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org
315c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#ifdef __OS2__
325c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#define _setmode    setmode
335c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#define _fileno     fileno
345c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#define _O_BINARY   O_BINARY
355c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#endif
36474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
37474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
38d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define LOG_ERROR(label) do {\
39d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  const char *l = label;\
40d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  va_list ap;\
41d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  va_start(ap, fmt);\
42d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (l)\
43d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    fprintf(stderr, "%s: ", l);\
44d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  vfprintf(stderr, fmt, ap);\
45d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  fprintf(stderr, "\n");\
46d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  va_end(ap);\
47d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} while (0)
48d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
49d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgFILE *set_binary_mode(FILE *stream) {
516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  (void)stream;
525c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#if defined(_WIN32) || defined(__OS2__)
536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  _setmode(_fileno(stream), _O_BINARY);
54474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return stream;
56474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
57d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
58d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid die(const char *fmt, ...) {
59d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  LOG_ERROR(NULL);
60d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  usage_exit();
61d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
62d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
63d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid fatal(const char *fmt, ...) {
64d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  LOG_ERROR("Fatal");
65d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  exit(EXIT_FAILURE);
66d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
67d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
68d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid warn(const char *fmt, ...) {
69d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  LOG_ERROR("Warning");
70d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
71d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
72dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgvoid die_codec(vpx_codec_ctx_t *ctx, const char *s) {
73dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const char *detail = vpx_codec_error_detail(ctx);
74dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
75dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  printf("%s: %s\n", s, vpx_codec_error(ctx));
76dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (detail)
77dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    printf("    %s\n", detail);
78dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  exit(EXIT_FAILURE);
79dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
80dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
81d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgint read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) {
82d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  FILE *f = input_ctx->file;
83d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  struct FileTypeDetectionBuffer *detect = &input_ctx->detect;
84d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int plane = 0;
85d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int shortread = 0;
86d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org  const int bytespp = (yuv_frame->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
87d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
88d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  for (plane = 0; plane < 3; ++plane) {
89d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    uint8_t *ptr;
90ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org    const int w = vpx_img_plane_width(yuv_frame, plane);
91ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org    const int h = vpx_img_plane_height(yuv_frame, plane);
92d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    int r;
93d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
94d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    /* Determine the correct plane based on the image format. The for-loop
95d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org     * always counts in Y,U,V order, but this may not match the order of
96d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org     * the data on disk.
97d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org     */
98d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    switch (plane) {
99d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      case 1:
100d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        ptr = yuv_frame->planes[
101d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org            yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V : VPX_PLANE_U];
102d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        break;
103d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      case 2:
104d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        ptr = yuv_frame->planes[
105d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org            yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U : VPX_PLANE_V];
106d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        break;
107d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      default:
108d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        ptr = yuv_frame->planes[plane];
109d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
110d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
111d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    for (r = 0; r < h; ++r) {
112ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org      size_t needed = w * bytespp;
113d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      size_t buf_position = 0;
114d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const size_t left = detect->buf_read - detect->position;
115d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (left > 0) {
116d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        const size_t more = (left < needed) ? left : needed;
117d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        memcpy(ptr, detect->buf + detect->position, more);
118d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        buf_position = more;
119d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        needed -= more;
120d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        detect->position += more;
121d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
122d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (needed > 0) {
123d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        shortread |= (fread(ptr + buf_position, 1, needed, f) < needed);
124d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
125d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
126d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      ptr += yuv_frame->stride[plane];
127d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
128d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
129d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
130d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  return shortread;
131d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
132dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
13376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic const VpxInterface vpx_encoders[] = {
13476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#if CONFIG_VP8_ENCODER
13576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  {"vp8", VP8_FOURCC, &vpx_codec_vp8_cx},
13676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#endif
13776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
13876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#if CONFIG_VP9_ENCODER
13976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  {"vp9", VP9_FOURCC, &vpx_codec_vp9_cx},
14076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#endif
14176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org};
14276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
14376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint get_vpx_encoder_count() {
14476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return sizeof(vpx_encoders) / sizeof(vpx_encoders[0]);
14576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
14676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
14776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_encoder_by_index(int i) {
14876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return &vpx_encoders[i];
14976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
15076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
15176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_encoder_by_name(const char *name) {
15276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i;
15376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
15476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < get_vpx_encoder_count(); ++i) {
15576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const VpxInterface *encoder = get_vpx_encoder_by_index(i);
15676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (strcmp(encoder->name, name) == 0)
15776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      return encoder;
15876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
15976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
16076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return NULL;
16176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
16276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
16376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic const VpxInterface vpx_decoders[] = {
164dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#if CONFIG_VP8_DECODER
16576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  {"vp8", VP8_FOURCC, &vpx_codec_vp8_dx},
166dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
16776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
168dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#if CONFIG_VP9_DECODER
16976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  {"vp9", VP9_FOURCC, &vpx_codec_vp9_dx},
170dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
17176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org};
17276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
17376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint get_vpx_decoder_count() {
17476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return sizeof(vpx_decoders) / sizeof(vpx_decoders[0]);
17576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
17676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
17776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_decoder_by_index(int i) {
17876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return &vpx_decoders[i];
17976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
18076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
18176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_decoder_by_name(const char *name) {
18276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i;
18376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
18476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < get_vpx_decoder_count(); ++i) {
18576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org     const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
18676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org     if (strcmp(decoder->name, name) == 0)
18776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org       return decoder;
188dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
18976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
190dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  return NULL;
191dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
192dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
19376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_decoder_by_fourcc(uint32_t fourcc) {
19476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i;
19576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
19676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < get_vpx_decoder_count(); ++i) {
19776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
19876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (decoder->fourcc == fourcc)
19976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      return decoder;
20076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
20176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
20276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return NULL;
20376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
20476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
20576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// TODO(dkovalev): move this function to vpx_image.{c, h}, so it will be part
20676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// of vpx_image_t support
20776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vpx_img_plane_width(const vpx_image_t *img, int plane) {
20876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (plane > 0 && img->x_chroma_shift > 0)
20976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return (img->d_w + 1) >> img->x_chroma_shift;
21076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  else
21176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return img->d_w;
21276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
21376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
21476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vpx_img_plane_height(const vpx_image_t *img, int plane) {
21576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (plane > 0 &&  img->y_chroma_shift > 0)
21676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return (img->d_h + 1) >> img->y_chroma_shift;
21776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  else
21876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return img->d_h;
21976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
22076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
221dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgvoid vpx_img_write(const vpx_image_t *img, FILE *file) {
22276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int plane;
223dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
224dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  for (plane = 0; plane < 3; ++plane) {
225dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const unsigned char *buf = img->planes[plane];
226dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const int stride = img->stride[plane];
22776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int w = vpx_img_plane_width(img, plane);
22876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int h = vpx_img_plane_height(img, plane);
22976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    int y;
23076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
231dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    for (y = 0; y < h; ++y) {
232dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      fwrite(buf, 1, w, file);
233dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      buf += stride;
234dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
235dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
236dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
23776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
23876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vpx_img_read(vpx_image_t *img, FILE *file) {
23976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int plane;
24076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
24176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (plane = 0; plane < 3; ++plane) {
24276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    unsigned char *buf = img->planes[plane];
24376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int stride = img->stride[plane];
244d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org    const int w = vpx_img_plane_width(img, plane) *
245d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org        ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
24676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int h = vpx_img_plane_height(img, plane);
24776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    int y;
24876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
24976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    for (y = 0; y < h; ++y) {
25041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      if (fread(buf, 1, w, file) != (size_t)w)
25176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        return 0;
25276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      buf += stride;
25376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
25476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
25576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
25676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return 1;
25776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
25876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
259411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org// TODO(dkovalev) change sse_to_psnr signature: double -> int64_t
260411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgdouble sse_to_psnr(double samples, double peak, double sse) {
261411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  static const double kMaxPSNR = 100.0;
262411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
263411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  if (sse > 0.0) {
264411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    const double psnr = 10.0 * log10(samples * peak * peak / sse);
265411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    return psnr > kMaxPSNR ? kMaxPSNR : psnr;
266411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  } else {
267411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    return kMaxPSNR;
268411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  }
269411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org}
270