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