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;
86d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
87d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  for (plane = 0; plane < 3; ++plane) {
88d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    uint8_t *ptr;
89d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    const int w = (plane ? (1 + yuv_frame->d_w) / 2 : yuv_frame->d_w);
90d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    const int h = (plane ? (1 + yuv_frame->d_h) / 2 : yuv_frame->d_h);
91d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    int r;
92d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
93d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    /* Determine the correct plane based on the image format. The for-loop
94d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org     * always counts in Y,U,V order, but this may not match the order of
95d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org     * the data on disk.
96d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org     */
97d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    switch (plane) {
98d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      case 1:
99d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        ptr = yuv_frame->planes[
100d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org            yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V : VPX_PLANE_U];
101d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        break;
102d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      case 2:
103d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        ptr = yuv_frame->planes[
104d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org            yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U : VPX_PLANE_V];
105d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        break;
106d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      default:
107d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        ptr = yuv_frame->planes[plane];
108d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
109d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
110d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    for (r = 0; r < h; ++r) {
111d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      size_t needed = w;
112d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      size_t buf_position = 0;
113d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const size_t left = detect->buf_read - detect->position;
114d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (left > 0) {
115d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        const size_t more = (left < needed) ? left : needed;
116d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        memcpy(ptr, detect->buf + detect->position, more);
117d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        buf_position = more;
118d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        needed -= more;
119d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        detect->position += more;
120d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
121d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (needed > 0) {
122d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        shortread |= (fread(ptr + buf_position, 1, needed, f) < needed);
123d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
124d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
125d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      ptr += yuv_frame->stride[plane];
126d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
127d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
128d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
129d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  return shortread;
130d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
131dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
13276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic const VpxInterface vpx_encoders[] = {
13376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#if CONFIG_VP8_ENCODER
13476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  {"vp8", VP8_FOURCC, &vpx_codec_vp8_cx},
13576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#endif
13676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
13776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#if CONFIG_VP9_ENCODER
13876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  {"vp9", VP9_FOURCC, &vpx_codec_vp9_cx},
13976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#endif
14076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org};
14176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
14276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint get_vpx_encoder_count() {
14376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return sizeof(vpx_encoders) / sizeof(vpx_encoders[0]);
14476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
14576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
14676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_encoder_by_index(int i) {
14776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return &vpx_encoders[i];
14876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
14976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
15076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_encoder_by_name(const char *name) {
15176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i;
15276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
15376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < get_vpx_encoder_count(); ++i) {
15476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const VpxInterface *encoder = get_vpx_encoder_by_index(i);
15576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (strcmp(encoder->name, name) == 0)
15676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      return encoder;
15776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
15876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
15976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return NULL;
16076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
16176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
16276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic const VpxInterface vpx_decoders[] = {
163dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#if CONFIG_VP8_DECODER
16476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  {"vp8", VP8_FOURCC, &vpx_codec_vp8_dx},
165dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
16676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
167dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#if CONFIG_VP9_DECODER
16876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  {"vp9", VP9_FOURCC, &vpx_codec_vp9_dx},
169dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
17076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org};
17176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
17276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint get_vpx_decoder_count() {
17376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return sizeof(vpx_decoders) / sizeof(vpx_decoders[0]);
17476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
17576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
17676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_decoder_by_index(int i) {
17776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return &vpx_decoders[i];
17876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
17976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
18076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_decoder_by_name(const char *name) {
18176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i;
18276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
18376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < get_vpx_decoder_count(); ++i) {
18476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org     const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
18576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org     if (strcmp(decoder->name, name) == 0)
18676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org       return decoder;
187dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
18876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
189dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  return NULL;
190dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
191dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
19276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxInterface *get_vpx_decoder_by_fourcc(uint32_t fourcc) {
19376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i;
19476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
19576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < get_vpx_decoder_count(); ++i) {
19676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
19776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (decoder->fourcc == fourcc)
19876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      return decoder;
19976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
20076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
20176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return NULL;
20276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
20376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
20476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// TODO(dkovalev): move this function to vpx_image.{c, h}, so it will be part
20576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// of vpx_image_t support
20676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vpx_img_plane_width(const vpx_image_t *img, int plane) {
20776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (plane > 0 && img->x_chroma_shift > 0)
20876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return (img->d_w + 1) >> img->x_chroma_shift;
20976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  else
21076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return img->d_w;
21176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
21276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
21376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vpx_img_plane_height(const vpx_image_t *img, int plane) {
21476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (plane > 0 &&  img->y_chroma_shift > 0)
21576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return (img->d_h + 1) >> img->y_chroma_shift;
21676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  else
21776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return img->d_h;
21876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
21976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
220dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgvoid vpx_img_write(const vpx_image_t *img, FILE *file) {
22176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int plane;
222dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
223dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  for (plane = 0; plane < 3; ++plane) {
224dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const unsigned char *buf = img->planes[plane];
225dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const int stride = img->stride[plane];
22676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int w = vpx_img_plane_width(img, plane);
22776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int h = vpx_img_plane_height(img, plane);
22876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    int y;
22976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
230dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    for (y = 0; y < h; ++y) {
231dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      fwrite(buf, 1, w, file);
232dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      buf += stride;
233dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
234dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
235dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
23676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
23776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vpx_img_read(vpx_image_t *img, FILE *file) {
23876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int plane;
23976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
24076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (plane = 0; plane < 3; ++plane) {
24176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    unsigned char *buf = img->planes[plane];
24276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int stride = img->stride[plane];
24376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int w = vpx_img_plane_width(img, plane);
24476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int h = vpx_img_plane_height(img, plane);
24576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    int y;
24676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
24776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    for (y = 0; y < h; ++y) {
24876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (fread(buf, 1, w, file) != w)
24976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        return 0;
25076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      buf += stride;
25176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
25276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
25376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
25476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return 1;
25576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
25676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
257411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org// TODO(dkovalev) change sse_to_psnr signature: double -> int64_t
258411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgdouble sse_to_psnr(double samples, double peak, double sse) {
259411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  static const double kMaxPSNR = 100.0;
260411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
261411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  if (sse > 0.0) {
262411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    const double psnr = 10.0 * log10(samples * peak * peak / sse);
263411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    return psnr > kMaxPSNR ? kMaxPSNR : psnr;
264411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  } else {
265411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    return kMaxPSNR;
266411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  }
267411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org}
268