tools_common.c 4.12 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
2
3
4
5
6
7
8
9
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
10

John Koleszar's avatar
John Koleszar committed
11
#include "tools_common.h"
12
13

#include <stdarg.h>
14
#include <stdio.h>
15
#include <stdlib.h>
16
#include <string.h>
17

18
19
20
21
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
#include "vpx/vp8dx.h"
#endif

John Koleszar's avatar
John Koleszar committed
22
#if defined(_WIN32) || defined(__OS2__)
John Koleszar's avatar
John Koleszar committed
23
24
#include <io.h>
#include <fcntl.h>
John Koleszar's avatar
John Koleszar committed
25
26
27
28
29
30

#ifdef __OS2__
#define _setmode    setmode
#define _fileno     fileno
#define _O_BINARY   O_BINARY
#endif
John Koleszar's avatar
John Koleszar committed
31
32
#endif

33
34
35
36
37
38
39
40
41
42
43
44
#define LOG_ERROR(label) do {\
  const char *l = label;\
  va_list ap;\
  va_start(ap, fmt);\
  if (l)\
    fprintf(stderr, "%s: ", l);\
  vfprintf(stderr, fmt, ap);\
  fprintf(stderr, "\n");\
  va_end(ap);\
} while (0)


John Koleszar's avatar
John Koleszar committed
45
46
FILE *set_binary_mode(FILE *stream) {
  (void)stream;
John Koleszar's avatar
John Koleszar committed
47
#if defined(_WIN32) || defined(__OS2__)
John Koleszar's avatar
John Koleszar committed
48
  _setmode(_fileno(stream), _O_BINARY);
John Koleszar's avatar
John Koleszar committed
49
#endif
John Koleszar's avatar
John Koleszar committed
50
  return stream;
John Koleszar's avatar
John Koleszar committed
51
}
52
53
54
55
56
57
58
59
60
61
62
63
64
65

void die(const char *fmt, ...) {
  LOG_ERROR(NULL);
  usage_exit();
}

void fatal(const char *fmt, ...) {
  LOG_ERROR("Fatal");
  exit(EXIT_FAILURE);
}

void warn(const char *fmt, ...) {
  LOG_ERROR("Warning");
}
66

67
68
69
70
71
72
73
74
75
void die_codec(vpx_codec_ctx_t *ctx, const char *s) {
  const char *detail = vpx_codec_error_detail(ctx);

  printf("%s: %s\n", s, vpx_codec_error(ctx));
  if (detail)
    printf("    %s\n", detail);
  exit(EXIT_FAILURE);
}

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
uint16_t mem_get_le16(const void *data) {
  uint16_t val;
  const uint8_t *mem = (const uint8_t*)data;

  val = mem[1] << 8;
  val |= mem[0];
  return val;
}

uint32_t mem_get_le32(const void *data) {
  uint32_t val;
  const uint8_t *mem = (const uint8_t*)data;

  val = mem[3] << 24;
  val |= mem[2] << 16;
  val |= mem[1] << 8;
  val |= mem[0];
  return val;
}

int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) {
  FILE *f = input_ctx->file;
  struct FileTypeDetectionBuffer *detect = &input_ctx->detect;
  int plane = 0;
  int shortread = 0;

  for (plane = 0; plane < 3; ++plane) {
    uint8_t *ptr;
    const int w = (plane ? (1 + yuv_frame->d_w) / 2 : yuv_frame->d_w);
    const int h = (plane ? (1 + yuv_frame->d_h) / 2 : yuv_frame->d_h);
    int r;

    /* Determine the correct plane based on the image format. The for-loop
     * always counts in Y,U,V order, but this may not match the order of
     * the data on disk.
     */
    switch (plane) {
      case 1:
        ptr = yuv_frame->planes[
            yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V : VPX_PLANE_U];
        break;
      case 2:
        ptr = yuv_frame->planes[
            yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U : VPX_PLANE_V];
        break;
      default:
        ptr = yuv_frame->planes[plane];
    }

    for (r = 0; r < h; ++r) {
      size_t needed = w;
      size_t buf_position = 0;
      const size_t left = detect->buf_read - detect->position;
      if (left > 0) {
        const size_t more = (left < needed) ? left : needed;
        memcpy(ptr, detect->buf + detect->position, more);
        buf_position = more;
        needed -= more;
        detect->position += more;
      }
      if (needed > 0) {
        shortread |= (fread(ptr + buf_position, 1, needed, f) < needed);
      }

      ptr += yuv_frame->stride[plane];
    }
  }

  return shortread;
}
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

vpx_codec_iface_t *get_codec_interface(unsigned int fourcc) {
  switch (fourcc) {
#if CONFIG_VP8_DECODER
    case VP8_FOURCC:
      return vpx_codec_vp8_dx();
#endif
#if CONFIG_VP9_DECODER
    case VP9_FOURCC:
      return vpx_codec_vp9_dx();
#endif
    default:
      return NULL;
  }
  return NULL;
}

void vpx_img_write(const vpx_image_t *img, FILE *file) {
  int plane, y;

  for (plane = 0; plane < 3; ++plane) {
    const unsigned char *buf = img->planes[plane];
    const int stride = img->stride[plane];
    const int w = plane ? (img->d_w + 1) >> 1 : img->d_w;
    const int h = plane ? (img->d_h + 1) >> 1 : img->d_h;
    for (y = 0; y < h; ++y) {
      fwrite(buf, 1, w, file);
      buf += stride;
    }
  }
}