Merge "ppc: Add vpx_iwht4x4_16_add_vsx"
[platform/upstream/libvpx.git] / y4minput.c
1 /*
2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  *
10  *  Based on code from the OggTheora software codec source code,
11  *  Copyright (C) 2002-2010 The Xiph.Org Foundation and contributors.
12  */
13 #include <errno.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include "vpx/vpx_integer.h"
18 #include "y4minput.h"
19
20 // Reads 'size' bytes from 'file' into 'buf' with some fault tolerance.
21 // Returns true on success.
22 static int file_read(void *buf, size_t size, FILE *file) {
23   const int kMaxRetries = 5;
24   int retry_count = 0;
25   int file_error;
26   size_t len = 0;
27   do {
28     const size_t n = fread((uint8_t *)buf + len, 1, size - len, file);
29     len += n;
30     file_error = ferror(file);
31     if (file_error) {
32       if (errno == EINTR || errno == EAGAIN) {
33         clearerr(file);
34         continue;
35       } else {
36         fprintf(stderr, "Error reading file: %u of %u bytes read, %d: %s\n",
37                 (uint32_t)len, (uint32_t)size, errno, strerror(errno));
38         return 0;
39       }
40     }
41   } while (!feof(file) && len < size && ++retry_count < kMaxRetries);
42
43   if (!feof(file) && len != size) {
44     fprintf(stderr,
45             "Error reading file: %u of %u bytes read,"
46             " error: %d, retries: %d, %d: %s\n",
47             (uint32_t)len, (uint32_t)size, file_error, retry_count, errno,
48             strerror(errno));
49   }
50   return len == size;
51 }
52
53 static int y4m_parse_tags(y4m_input *_y4m, char *_tags) {
54   int got_w;
55   int got_h;
56   int got_fps;
57   int got_interlace;
58   int got_par;
59   int got_chroma;
60   char *p;
61   char *q;
62   got_w = got_h = got_fps = got_interlace = got_par = got_chroma = 0;
63   for (p = _tags;; p = q) {
64     /*Skip any leading spaces.*/
65     while (*p == ' ') p++;
66     /*If that's all we have, stop.*/
67     if (p[0] == '\0') break;
68     /*Find the end of this tag.*/
69     for (q = p + 1; *q != '\0' && *q != ' '; q++) {
70     }
71     /*Process the tag.*/
72     switch (p[0]) {
73       case 'W': {
74         if (sscanf(p + 1, "%d", &_y4m->pic_w) != 1) return -1;
75         got_w = 1;
76         break;
77       }
78       case 'H': {
79         if (sscanf(p + 1, "%d", &_y4m->pic_h) != 1) return -1;
80         got_h = 1;
81         break;
82       }
83       case 'F': {
84         if (sscanf(p + 1, "%d:%d", &_y4m->fps_n, &_y4m->fps_d) != 2) {
85           return -1;
86         }
87         got_fps = 1;
88         break;
89       }
90       case 'I': {
91         _y4m->interlace = p[1];
92         got_interlace = 1;
93         break;
94       }
95       case 'A': {
96         if (sscanf(p + 1, "%d:%d", &_y4m->par_n, &_y4m->par_d) != 2) {
97           return -1;
98         }
99         got_par = 1;
100         break;
101       }
102       case 'C': {
103         if (q - p > 16) return -1;
104         memcpy(_y4m->chroma_type, p + 1, q - p - 1);
105         _y4m->chroma_type[q - p - 1] = '\0';
106         got_chroma = 1;
107         break;
108       }
109         /*Ignore unknown tags.*/
110     }
111   }
112   if (!got_w || !got_h || !got_fps) return -1;
113   if (!got_interlace) _y4m->interlace = '?';
114   if (!got_par) _y4m->par_n = _y4m->par_d = 0;
115   /*Chroma-type is not specified in older files, e.g., those generated by
116      mplayer.*/
117   if (!got_chroma) strcpy(_y4m->chroma_type, "420");
118   return 0;
119 }
120
121 /*All anti-aliasing filters in the following conversion functions are based on
122    one of two window functions:
123   The 6-tap Lanczos window (for down-sampling and shifts):
124    sinc(\pi*t)*sinc(\pi*t/3), |t|<3  (sinc(t)==sin(t)/t)
125    0,                         |t|>=3
126   The 4-tap Mitchell window (for up-sampling):
127    7|t|^3-12|t|^2+16/3,             |t|<1
128    -(7/3)|x|^3+12|x|^2-20|x|+32/3,  |t|<2
129    0,                               |t|>=2
130   The number of taps is intentionally kept small to reduce computational
131    overhead and limit ringing.
132
133   The taps from these filters are scaled so that their sum is 1, and the
134   result is scaled by 128 and rounded to integers to create a filter whose
135    intermediate values fit inside 16 bits.
136   Coefficients are rounded in such a way as to ensure their sum is still 128,
137    which is usually equivalent to normal rounding.
138
139   Conversions which require both horizontal and vertical filtering could
140    have these steps pipelined, for less memory consumption and better cache
141    performance, but we do them separately for simplicity.*/
142 #define OC_MINI(_a, _b) ((_a) > (_b) ? (_b) : (_a))
143 #define OC_MAXI(_a, _b) ((_a) < (_b) ? (_b) : (_a))
144 #define OC_CLAMPI(_a, _b, _c) (OC_MAXI(_a, OC_MINI(_b, _c)))
145
146 /*420jpeg chroma samples are sited like:
147   Y-------Y-------Y-------Y-------
148   |       |       |       |
149   |   BR  |       |   BR  |
150   |       |       |       |
151   Y-------Y-------Y-------Y-------
152   |       |       |       |
153   |       |       |       |
154   |       |       |       |
155   Y-------Y-------Y-------Y-------
156   |       |       |       |
157   |   BR  |       |   BR  |
158   |       |       |       |
159   Y-------Y-------Y-------Y-------
160   |       |       |       |
161   |       |       |       |
162   |       |       |       |
163
164   420mpeg2 chroma samples are sited like:
165   Y-------Y-------Y-------Y-------
166   |       |       |       |
167   BR      |       BR      |
168   |       |       |       |
169   Y-------Y-------Y-------Y-------
170   |       |       |       |
171   |       |       |       |
172   |       |       |       |
173   Y-------Y-------Y-------Y-------
174   |       |       |       |
175   BR      |       BR      |
176   |       |       |       |
177   Y-------Y-------Y-------Y-------
178   |       |       |       |
179   |       |       |       |
180   |       |       |       |
181
182   We use a resampling filter to shift the site locations one quarter pixel (at
183    the chroma plane's resolution) to the right.
184   The 4:2:2 modes look exactly the same, except there are twice as many chroma
185    lines, and they are vertically co-sited with the luma samples in both the
186    mpeg2 and jpeg cases (thus requiring no vertical resampling).*/
187 static void y4m_42xmpeg2_42xjpeg_helper(unsigned char *_dst,
188                                         const unsigned char *_src, int _c_w,
189                                         int _c_h) {
190   int y;
191   int x;
192   for (y = 0; y < _c_h; y++) {
193     /*Filter: [4 -17 114 35 -9 1]/128, derived from a 6-tap Lanczos
194        window.*/
195     for (x = 0; x < OC_MINI(_c_w, 2); x++) {
196       _dst[x] = (unsigned char)OC_CLAMPI(
197           0,
198           (4 * _src[0] - 17 * _src[OC_MAXI(x - 1, 0)] + 114 * _src[x] +
199            35 * _src[OC_MINI(x + 1, _c_w - 1)] -
200            9 * _src[OC_MINI(x + 2, _c_w - 1)] + _src[OC_MINI(x + 3, _c_w - 1)] +
201            64) >>
202               7,
203           255);
204     }
205     for (; x < _c_w - 3; x++) {
206       _dst[x] = (unsigned char)OC_CLAMPI(
207           0,
208           (4 * _src[x - 2] - 17 * _src[x - 1] + 114 * _src[x] +
209            35 * _src[x + 1] - 9 * _src[x + 2] + _src[x + 3] + 64) >>
210               7,
211           255);
212     }
213     for (; x < _c_w; x++) {
214       _dst[x] = (unsigned char)OC_CLAMPI(
215           0,
216           (4 * _src[x - 2] - 17 * _src[x - 1] + 114 * _src[x] +
217            35 * _src[OC_MINI(x + 1, _c_w - 1)] -
218            9 * _src[OC_MINI(x + 2, _c_w - 1)] + _src[_c_w - 1] + 64) >>
219               7,
220           255);
221     }
222     _dst += _c_w;
223     _src += _c_w;
224   }
225 }
226
227 /*Handles both 422 and 420mpeg2 to 422jpeg and 420jpeg, respectively.*/
228 static void y4m_convert_42xmpeg2_42xjpeg(y4m_input *_y4m, unsigned char *_dst,
229                                          unsigned char *_aux) {
230   int c_w;
231   int c_h;
232   int c_sz;
233   int pli;
234   /*Skip past the luma data.*/
235   _dst += _y4m->pic_w * _y4m->pic_h;
236   /*Compute the size of each chroma plane.*/
237   c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h;
238   c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v;
239   c_sz = c_w * c_h;
240   for (pli = 1; pli < 3; pli++) {
241     y4m_42xmpeg2_42xjpeg_helper(_dst, _aux, c_w, c_h);
242     _dst += c_sz;
243     _aux += c_sz;
244   }
245 }
246
247 /*This format is only used for interlaced content, but is included for
248    completeness.
249
250   420jpeg chroma samples are sited like:
251   Y-------Y-------Y-------Y-------
252   |       |       |       |
253   |   BR  |       |   BR  |
254   |       |       |       |
255   Y-------Y-------Y-------Y-------
256   |       |       |       |
257   |       |       |       |
258   |       |       |       |
259   Y-------Y-------Y-------Y-------
260   |       |       |       |
261   |   BR  |       |   BR  |
262   |       |       |       |
263   Y-------Y-------Y-------Y-------
264   |       |       |       |
265   |       |       |       |
266   |       |       |       |
267
268   420paldv chroma samples are sited like:
269   YR------Y-------YR------Y-------
270   |       |       |       |
271   |       |       |       |
272   |       |       |       |
273   YB------Y-------YB------Y-------
274   |       |       |       |
275   |       |       |       |
276   |       |       |       |
277   YR------Y-------YR------Y-------
278   |       |       |       |
279   |       |       |       |
280   |       |       |       |
281   YB------Y-------YB------Y-------
282   |       |       |       |
283   |       |       |       |
284   |       |       |       |
285
286   We use a resampling filter to shift the site locations one quarter pixel (at
287    the chroma plane's resolution) to the right.
288   Then we use another filter to move the C_r location down one quarter pixel,
289    and the C_b location up one quarter pixel.*/
290 static void y4m_convert_42xpaldv_42xjpeg(y4m_input *_y4m, unsigned char *_dst,
291                                          unsigned char *_aux) {
292   unsigned char *tmp;
293   int c_w;
294   int c_h;
295   int c_sz;
296   int pli;
297   int y;
298   int x;
299   /*Skip past the luma data.*/
300   _dst += _y4m->pic_w * _y4m->pic_h;
301   /*Compute the size of each chroma plane.*/
302   c_w = (_y4m->pic_w + 1) / 2;
303   c_h = (_y4m->pic_h + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h;
304   c_sz = c_w * c_h;
305   tmp = _aux + 2 * c_sz;
306   for (pli = 1; pli < 3; pli++) {
307     /*First do the horizontal re-sampling.
308       This is the same as the mpeg2 case, except that after the horizontal
309        case, we need to apply a second vertical filter.*/
310     y4m_42xmpeg2_42xjpeg_helper(tmp, _aux, c_w, c_h);
311     _aux += c_sz;
312     switch (pli) {
313       case 1: {
314         /*Slide C_b up a quarter-pel.
315           This is the same filter used above, but in the other order.*/
316         for (x = 0; x < c_w; x++) {
317           for (y = 0; y < OC_MINI(c_h, 3); y++) {
318             _dst[y * c_w] = (unsigned char)OC_CLAMPI(
319                 0,
320                 (tmp[0] - 9 * tmp[OC_MAXI(y - 2, 0) * c_w] +
321                  35 * tmp[OC_MAXI(y - 1, 0) * c_w] + 114 * tmp[y * c_w] -
322                  17 * tmp[OC_MINI(y + 1, c_h - 1) * c_w] +
323                  4 * tmp[OC_MINI(y + 2, c_h - 1) * c_w] + 64) >>
324                     7,
325                 255);
326           }
327           for (; y < c_h - 2; y++) {
328             _dst[y * c_w] = (unsigned char)OC_CLAMPI(
329                 0,
330                 (tmp[(y - 3) * c_w] - 9 * tmp[(y - 2) * c_w] +
331                  35 * tmp[(y - 1) * c_w] + 114 * tmp[y * c_w] -
332                  17 * tmp[(y + 1) * c_w] + 4 * tmp[(y + 2) * c_w] + 64) >>
333                     7,
334                 255);
335           }
336           for (; y < c_h; y++) {
337             _dst[y * c_w] = (unsigned char)OC_CLAMPI(
338                 0,
339                 (tmp[(y - 3) * c_w] - 9 * tmp[(y - 2) * c_w] +
340                  35 * tmp[(y - 1) * c_w] + 114 * tmp[y * c_w] -
341                  17 * tmp[OC_MINI(y + 1, c_h - 1) * c_w] +
342                  4 * tmp[(c_h - 1) * c_w] + 64) >>
343                     7,
344                 255);
345           }
346           _dst++;
347           tmp++;
348         }
349         _dst += c_sz - c_w;
350         tmp -= c_w;
351         break;
352       }
353       case 2: {
354         /*Slide C_r down a quarter-pel.
355           This is the same as the horizontal filter.*/
356         for (x = 0; x < c_w; x++) {
357           for (y = 0; y < OC_MINI(c_h, 2); y++) {
358             _dst[y * c_w] = (unsigned char)OC_CLAMPI(
359                 0,
360                 (4 * tmp[0] - 17 * tmp[OC_MAXI(y - 1, 0) * c_w] +
361                  114 * tmp[y * c_w] + 35 * tmp[OC_MINI(y + 1, c_h - 1) * c_w] -
362                  9 * tmp[OC_MINI(y + 2, c_h - 1) * c_w] +
363                  tmp[OC_MINI(y + 3, c_h - 1) * c_w] + 64) >>
364                     7,
365                 255);
366           }
367           for (; y < c_h - 3; y++) {
368             _dst[y * c_w] = (unsigned char)OC_CLAMPI(
369                 0,
370                 (4 * tmp[(y - 2) * c_w] - 17 * tmp[(y - 1) * c_w] +
371                  114 * tmp[y * c_w] + 35 * tmp[(y + 1) * c_w] -
372                  9 * tmp[(y + 2) * c_w] + tmp[(y + 3) * c_w] + 64) >>
373                     7,
374                 255);
375           }
376           for (; y < c_h; y++) {
377             _dst[y * c_w] = (unsigned char)OC_CLAMPI(
378                 0,
379                 (4 * tmp[(y - 2) * c_w] - 17 * tmp[(y - 1) * c_w] +
380                  114 * tmp[y * c_w] + 35 * tmp[OC_MINI(y + 1, c_h - 1) * c_w] -
381                  9 * tmp[OC_MINI(y + 2, c_h - 1) * c_w] + tmp[(c_h - 1) * c_w] +
382                  64) >>
383                     7,
384                 255);
385           }
386           _dst++;
387           tmp++;
388         }
389         break;
390       }
391     }
392     /*For actual interlaced material, this would have to be done separately on
393        each field, and the shift amounts would be different.
394       C_r moves down 1/8, C_b up 3/8 in the top field, and C_r moves down 3/8,
395        C_b up 1/8 in the bottom field.
396       The corresponding filters would be:
397        Down 1/8 (reverse order for up): [3 -11 125 15 -4 0]/128
398        Down 3/8 (reverse order for up): [4 -19 98 56 -13 2]/128*/
399   }
400 }
401
402 /*Perform vertical filtering to reduce a single plane from 4:2:2 to 4:2:0.
403   This is used as a helper by several converation routines.*/
404 static void y4m_422jpeg_420jpeg_helper(unsigned char *_dst,
405                                        const unsigned char *_src, int _c_w,
406                                        int _c_h) {
407   int y;
408   int x;
409   /*Filter: [3 -17 78 78 -17 3]/128, derived from a 6-tap Lanczos window.*/
410   for (x = 0; x < _c_w; x++) {
411     for (y = 0; y < OC_MINI(_c_h, 2); y += 2) {
412       _dst[(y >> 1) * _c_w] =
413           OC_CLAMPI(0,
414                     (64 * _src[0] + 78 * _src[OC_MINI(1, _c_h - 1) * _c_w] -
415                      17 * _src[OC_MINI(2, _c_h - 1) * _c_w] +
416                      3 * _src[OC_MINI(3, _c_h - 1) * _c_w] + 64) >>
417                         7,
418                     255);
419     }
420     for (; y < _c_h - 3; y += 2) {
421       _dst[(y >> 1) * _c_w] =
422           OC_CLAMPI(0,
423                     (3 * (_src[(y - 2) * _c_w] + _src[(y + 3) * _c_w]) -
424                      17 * (_src[(y - 1) * _c_w] + _src[(y + 2) * _c_w]) +
425                      78 * (_src[y * _c_w] + _src[(y + 1) * _c_w]) + 64) >>
426                         7,
427                     255);
428     }
429     for (; y < _c_h; y += 2) {
430       _dst[(y >> 1) * _c_w] = OC_CLAMPI(
431           0,
432           (3 * (_src[(y - 2) * _c_w] + _src[(_c_h - 1) * _c_w]) -
433            17 * (_src[(y - 1) * _c_w] + _src[OC_MINI(y + 2, _c_h - 1) * _c_w]) +
434            78 * (_src[y * _c_w] + _src[OC_MINI(y + 1, _c_h - 1) * _c_w]) +
435            64) >>
436               7,
437           255);
438     }
439     _src++;
440     _dst++;
441   }
442 }
443
444 /*420jpeg chroma samples are sited like:
445   Y-------Y-------Y-------Y-------
446   |       |       |       |
447   |   BR  |       |   BR  |
448   |       |       |       |
449   Y-------Y-------Y-------Y-------
450   |       |       |       |
451   |       |       |       |
452   |       |       |       |
453   Y-------Y-------Y-------Y-------
454   |       |       |       |
455   |   BR  |       |   BR  |
456   |       |       |       |
457   Y-------Y-------Y-------Y-------
458   |       |       |       |
459   |       |       |       |
460   |       |       |       |
461
462   422jpeg chroma samples are sited like:
463   Y---BR--Y-------Y---BR--Y-------
464   |       |       |       |
465   |       |       |       |
466   |       |       |       |
467   Y---BR--Y-------Y---BR--Y-------
468   |       |       |       |
469   |       |       |       |
470   |       |       |       |
471   Y---BR--Y-------Y---BR--Y-------
472   |       |       |       |
473   |       |       |       |
474   |       |       |       |
475   Y---BR--Y-------Y---BR--Y-------
476   |       |       |       |
477   |       |       |       |
478   |       |       |       |
479
480   We use a resampling filter to decimate the chroma planes by two in the
481    vertical direction.*/
482 static void y4m_convert_422jpeg_420jpeg(y4m_input *_y4m, unsigned char *_dst,
483                                         unsigned char *_aux) {
484   int c_w;
485   int c_h;
486   int c_sz;
487   int dst_c_w;
488   int dst_c_h;
489   int dst_c_sz;
490   int pli;
491   /*Skip past the luma data.*/
492   _dst += _y4m->pic_w * _y4m->pic_h;
493   /*Compute the size of each chroma plane.*/
494   c_w = (_y4m->pic_w + _y4m->src_c_dec_h - 1) / _y4m->src_c_dec_h;
495   c_h = _y4m->pic_h;
496   dst_c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h;
497   dst_c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v;
498   c_sz = c_w * c_h;
499   dst_c_sz = dst_c_w * dst_c_h;
500   for (pli = 1; pli < 3; pli++) {
501     y4m_422jpeg_420jpeg_helper(_dst, _aux, c_w, c_h);
502     _aux += c_sz;
503     _dst += dst_c_sz;
504   }
505 }
506
507 /*420jpeg chroma samples are sited like:
508   Y-------Y-------Y-------Y-------
509   |       |       |       |
510   |   BR  |       |   BR  |
511   |       |       |       |
512   Y-------Y-------Y-------Y-------
513   |       |       |       |
514   |       |       |       |
515   |       |       |       |
516   Y-------Y-------Y-------Y-------
517   |       |       |       |
518   |   BR  |       |   BR  |
519   |       |       |       |
520   Y-------Y-------Y-------Y-------
521   |       |       |       |
522   |       |       |       |
523   |       |       |       |
524
525   422 chroma samples are sited like:
526   YBR-----Y-------YBR-----Y-------
527   |       |       |       |
528   |       |       |       |
529   |       |       |       |
530   YBR-----Y-------YBR-----Y-------
531   |       |       |       |
532   |       |       |       |
533   |       |       |       |
534   YBR-----Y-------YBR-----Y-------
535   |       |       |       |
536   |       |       |       |
537   |       |       |       |
538   YBR-----Y-------YBR-----Y-------
539   |       |       |       |
540   |       |       |       |
541   |       |       |       |
542
543   We use a resampling filter to shift the original site locations one quarter
544    pixel (at the original chroma resolution) to the right.
545   Then we use a second resampling filter to decimate the chroma planes by two
546    in the vertical direction.*/
547 static void y4m_convert_422_420jpeg(y4m_input *_y4m, unsigned char *_dst,
548                                     unsigned char *_aux) {
549   unsigned char *tmp;
550   int c_w;
551   int c_h;
552   int c_sz;
553   int dst_c_h;
554   int dst_c_sz;
555   int pli;
556   /*Skip past the luma data.*/
557   _dst += _y4m->pic_w * _y4m->pic_h;
558   /*Compute the size of each chroma plane.*/
559   c_w = (_y4m->pic_w + _y4m->src_c_dec_h - 1) / _y4m->src_c_dec_h;
560   c_h = _y4m->pic_h;
561   dst_c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v;
562   c_sz = c_w * c_h;
563   dst_c_sz = c_w * dst_c_h;
564   tmp = _aux + 2 * c_sz;
565   for (pli = 1; pli < 3; pli++) {
566     /*In reality, the horizontal and vertical steps could be pipelined, for
567        less memory consumption and better cache performance, but we do them
568        separately for simplicity.*/
569     /*First do horizontal filtering (convert to 422jpeg)*/
570     y4m_42xmpeg2_42xjpeg_helper(tmp, _aux, c_w, c_h);
571     /*Now do the vertical filtering.*/
572     y4m_422jpeg_420jpeg_helper(_dst, tmp, c_w, c_h);
573     _aux += c_sz;
574     _dst += dst_c_sz;
575   }
576 }
577
578 /*420jpeg chroma samples are sited like:
579   Y-------Y-------Y-------Y-------
580   |       |       |       |
581   |   BR  |       |   BR  |
582   |       |       |       |
583   Y-------Y-------Y-------Y-------
584   |       |       |       |
585   |       |       |       |
586   |       |       |       |
587   Y-------Y-------Y-------Y-------
588   |       |       |       |
589   |   BR  |       |   BR  |
590   |       |       |       |
591   Y-------Y-------Y-------Y-------
592   |       |       |       |
593   |       |       |       |
594   |       |       |       |
595
596   411 chroma samples are sited like:
597   YBR-----Y-------Y-------Y-------
598   |       |       |       |
599   |       |       |       |
600   |       |       |       |
601   YBR-----Y-------Y-------Y-------
602   |       |       |       |
603   |       |       |       |
604   |       |       |       |
605   YBR-----Y-------Y-------Y-------
606   |       |       |       |
607   |       |       |       |
608   |       |       |       |
609   YBR-----Y-------Y-------Y-------
610   |       |       |       |
611   |       |       |       |
612   |       |       |       |
613
614   We use a filter to resample at site locations one eighth pixel (at the source
615    chroma plane's horizontal resolution) and five eighths of a pixel to the
616    right.
617   Then we use another filter to decimate the planes by 2 in the vertical
618    direction.*/
619 static void y4m_convert_411_420jpeg(y4m_input *_y4m, unsigned char *_dst,
620                                     unsigned char *_aux) {
621   unsigned char *tmp;
622   int c_w;
623   int c_h;
624   int c_sz;
625   int dst_c_w;
626   int dst_c_h;
627   int dst_c_sz;
628   int tmp_sz;
629   int pli;
630   int y;
631   int x;
632   /*Skip past the luma data.*/
633   _dst += _y4m->pic_w * _y4m->pic_h;
634   /*Compute the size of each chroma plane.*/
635   c_w = (_y4m->pic_w + _y4m->src_c_dec_h - 1) / _y4m->src_c_dec_h;
636   c_h = _y4m->pic_h;
637   dst_c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h;
638   dst_c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v;
639   c_sz = c_w * c_h;
640   dst_c_sz = dst_c_w * dst_c_h;
641   tmp_sz = dst_c_w * c_h;
642   tmp = _aux + 2 * c_sz;
643   for (pli = 1; pli < 3; pli++) {
644     /*In reality, the horizontal and vertical steps could be pipelined, for
645        less memory consumption and better cache performance, but we do them
646        separately for simplicity.*/
647     /*First do horizontal filtering (convert to 422jpeg)*/
648     for (y = 0; y < c_h; y++) {
649       /*Filters: [1 110 18 -1]/128 and [-3 50 86 -5]/128, both derived from a
650          4-tap Mitchell window.*/
651       for (x = 0; x < OC_MINI(c_w, 1); x++) {
652         tmp[x << 1] = (unsigned char)OC_CLAMPI(
653             0,
654             (111 * _aux[0] + 18 * _aux[OC_MINI(1, c_w - 1)] -
655              _aux[OC_MINI(2, c_w - 1)] + 64) >>
656                 7,
657             255);
658         tmp[x << 1 | 1] = (unsigned char)OC_CLAMPI(
659             0,
660             (47 * _aux[0] + 86 * _aux[OC_MINI(1, c_w - 1)] -
661              5 * _aux[OC_MINI(2, c_w - 1)] + 64) >>
662                 7,
663             255);
664       }
665       for (; x < c_w - 2; x++) {
666         tmp[x << 1] =
667             (unsigned char)OC_CLAMPI(0,
668                                      (_aux[x - 1] + 110 * _aux[x] +
669                                       18 * _aux[x + 1] - _aux[x + 2] + 64) >>
670                                          7,
671                                      255);
672         tmp[x << 1 | 1] = (unsigned char)OC_CLAMPI(
673             0,
674             (-3 * _aux[x - 1] + 50 * _aux[x] + 86 * _aux[x + 1] -
675              5 * _aux[x + 2] + 64) >>
676                 7,
677             255);
678       }
679       for (; x < c_w; x++) {
680         tmp[x << 1] = (unsigned char)OC_CLAMPI(
681             0,
682             (_aux[x - 1] + 110 * _aux[x] + 18 * _aux[OC_MINI(x + 1, c_w - 1)] -
683              _aux[c_w - 1] + 64) >>
684                 7,
685             255);
686         if ((x << 1 | 1) < dst_c_w) {
687           tmp[x << 1 | 1] = (unsigned char)OC_CLAMPI(
688               0,
689               (-3 * _aux[x - 1] + 50 * _aux[x] +
690                86 * _aux[OC_MINI(x + 1, c_w - 1)] - 5 * _aux[c_w - 1] + 64) >>
691                   7,
692               255);
693         }
694       }
695       tmp += dst_c_w;
696       _aux += c_w;
697     }
698     tmp -= tmp_sz;
699     /*Now do the vertical filtering.*/
700     y4m_422jpeg_420jpeg_helper(_dst, tmp, dst_c_w, c_h);
701     _dst += dst_c_sz;
702   }
703 }
704
705 /*Convert 444 to 420jpeg.*/
706 static void y4m_convert_444_420jpeg(y4m_input *_y4m, unsigned char *_dst,
707                                     unsigned char *_aux) {
708   unsigned char *tmp;
709   int c_w;
710   int c_h;
711   int c_sz;
712   int dst_c_w;
713   int dst_c_h;
714   int dst_c_sz;
715   int tmp_sz;
716   int pli;
717   int y;
718   int x;
719   /*Skip past the luma data.*/
720   _dst += _y4m->pic_w * _y4m->pic_h;
721   /*Compute the size of each chroma plane.*/
722   c_w = (_y4m->pic_w + _y4m->src_c_dec_h - 1) / _y4m->src_c_dec_h;
723   c_h = _y4m->pic_h;
724   dst_c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h;
725   dst_c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v;
726   c_sz = c_w * c_h;
727   dst_c_sz = dst_c_w * dst_c_h;
728   tmp_sz = dst_c_w * c_h;
729   tmp = _aux + 2 * c_sz;
730   for (pli = 1; pli < 3; pli++) {
731     /*Filter: [3 -17 78 78 -17 3]/128, derived from a 6-tap Lanczos window.*/
732     for (y = 0; y < c_h; y++) {
733       for (x = 0; x < OC_MINI(c_w, 2); x += 2) {
734         tmp[x >> 1] = OC_CLAMPI(0,
735                                 (64 * _aux[0] + 78 * _aux[OC_MINI(1, c_w - 1)] -
736                                  17 * _aux[OC_MINI(2, c_w - 1)] +
737                                  3 * _aux[OC_MINI(3, c_w - 1)] + 64) >>
738                                     7,
739                                 255);
740       }
741       for (; x < c_w - 3; x += 2) {
742         tmp[x >> 1] = OC_CLAMPI(0,
743                                 (3 * (_aux[x - 2] + _aux[x + 3]) -
744                                  17 * (_aux[x - 1] + _aux[x + 2]) +
745                                  78 * (_aux[x] + _aux[x + 1]) + 64) >>
746                                     7,
747                                 255);
748       }
749       for (; x < c_w; x += 2) {
750         tmp[x >> 1] =
751             OC_CLAMPI(0,
752                       (3 * (_aux[x - 2] + _aux[c_w - 1]) -
753                        17 * (_aux[x - 1] + _aux[OC_MINI(x + 2, c_w - 1)]) +
754                        78 * (_aux[x] + _aux[OC_MINI(x + 1, c_w - 1)]) + 64) >>
755                           7,
756                       255);
757       }
758       tmp += dst_c_w;
759       _aux += c_w;
760     }
761     tmp -= tmp_sz;
762     /*Now do the vertical filtering.*/
763     y4m_422jpeg_420jpeg_helper(_dst, tmp, dst_c_w, c_h);
764     _dst += dst_c_sz;
765   }
766 }
767
768 /*The image is padded with empty chroma components at 4:2:0.*/
769 static void y4m_convert_mono_420jpeg(y4m_input *_y4m, unsigned char *_dst,
770                                      unsigned char *_aux) {
771   int c_sz;
772   (void)_aux;
773   _dst += _y4m->pic_w * _y4m->pic_h;
774   c_sz = ((_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h) *
775          ((_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v);
776   memset(_dst, 128, c_sz * 2);
777 }
778
779 /*No conversion function needed.*/
780 static void y4m_convert_null(y4m_input *_y4m, unsigned char *_dst,
781                              unsigned char *_aux) {
782   (void)_y4m;
783   (void)_dst;
784   (void)_aux;
785 }
786
787 int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip,
788                    int only_420) {
789   char buffer[80] = { 0 };
790   int ret;
791   int i;
792   /*Read until newline, or 80 cols, whichever happens first.*/
793   for (i = 0; i < 79; i++) {
794     if (_nskip > 0) {
795       buffer[i] = *_skip++;
796       _nskip--;
797     } else {
798       if (!file_read(buffer + i, 1, _fin)) return -1;
799     }
800     if (buffer[i] == '\n') break;
801   }
802   /*We skipped too much header data.*/
803   if (_nskip > 0) return -1;
804   if (i == 79) {
805     fprintf(stderr, "Error parsing header; not a YUV2MPEG2 file?\n");
806     return -1;
807   }
808   buffer[i] = '\0';
809   if (memcmp(buffer, "YUV4MPEG", 8)) {
810     fprintf(stderr, "Incomplete magic for YUV4MPEG file.\n");
811     return -1;
812   }
813   if (buffer[8] != '2') {
814     fprintf(stderr, "Incorrect YUV input file version; YUV4MPEG2 required.\n");
815   }
816   ret = y4m_parse_tags(_y4m, buffer + 5);
817   if (ret < 0) {
818     fprintf(stderr, "Error parsing YUV4MPEG2 header.\n");
819     return ret;
820   }
821   if (_y4m->interlace == '?') {
822     fprintf(stderr,
823             "Warning: Input video interlacing format unknown; "
824             "assuming progressive scan.\n");
825   } else if (_y4m->interlace != 'p') {
826     fprintf(stderr,
827             "Input video is interlaced; "
828             "Only progressive scan handled.\n");
829     return -1;
830   }
831   _y4m->vpx_fmt = VPX_IMG_FMT_I420;
832   _y4m->bps = 12;
833   _y4m->bit_depth = 8;
834   if (strcmp(_y4m->chroma_type, "420") == 0 ||
835       strcmp(_y4m->chroma_type, "420jpeg") == 0) {
836     _y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v =
837         _y4m->dst_c_dec_v = 2;
838     _y4m->dst_buf_read_sz =
839         _y4m->pic_w * _y4m->pic_h +
840         2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2);
841     /* Natively supported: no conversion required. */
842     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
843     _y4m->convert = y4m_convert_null;
844   } else if (strcmp(_y4m->chroma_type, "420p10") == 0) {
845     _y4m->src_c_dec_h = 2;
846     _y4m->dst_c_dec_h = 2;
847     _y4m->src_c_dec_v = 2;
848     _y4m->dst_c_dec_v = 2;
849     _y4m->dst_buf_read_sz =
850         2 * (_y4m->pic_w * _y4m->pic_h +
851              2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2));
852     /* Natively supported: no conversion required. */
853     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
854     _y4m->convert = y4m_convert_null;
855     _y4m->bit_depth = 10;
856     _y4m->bps = 15;
857     _y4m->vpx_fmt = VPX_IMG_FMT_I42016;
858     if (only_420) {
859       fprintf(stderr, "Unsupported conversion from 420p10 to 420jpeg\n");
860       return -1;
861     }
862   } else if (strcmp(_y4m->chroma_type, "420p12") == 0) {
863     _y4m->src_c_dec_h = 2;
864     _y4m->dst_c_dec_h = 2;
865     _y4m->src_c_dec_v = 2;
866     _y4m->dst_c_dec_v = 2;
867     _y4m->dst_buf_read_sz =
868         2 * (_y4m->pic_w * _y4m->pic_h +
869              2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2));
870     /* Natively supported: no conversion required. */
871     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
872     _y4m->convert = y4m_convert_null;
873     _y4m->bit_depth = 12;
874     _y4m->bps = 18;
875     _y4m->vpx_fmt = VPX_IMG_FMT_I42016;
876     if (only_420) {
877       fprintf(stderr, "Unsupported conversion from 420p12 to 420jpeg\n");
878       return -1;
879     }
880   } else if (strcmp(_y4m->chroma_type, "420mpeg2") == 0) {
881     _y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v =
882         _y4m->dst_c_dec_v = 2;
883     _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
884     /*Chroma filter required: read into the aux buf first.*/
885     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz =
886         2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2);
887     _y4m->convert = y4m_convert_42xmpeg2_42xjpeg;
888   } else if (strcmp(_y4m->chroma_type, "420paldv") == 0) {
889     _y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v =
890         _y4m->dst_c_dec_v = 2;
891     _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
892     /*Chroma filter required: read into the aux buf first.
893       We need to make two filter passes, so we need some extra space in the
894        aux buffer.*/
895     _y4m->aux_buf_sz = 3 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2);
896     _y4m->aux_buf_read_sz =
897         2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2);
898     _y4m->convert = y4m_convert_42xpaldv_42xjpeg;
899   } else if (strcmp(_y4m->chroma_type, "422jpeg") == 0) {
900     _y4m->src_c_dec_h = _y4m->dst_c_dec_h = 2;
901     _y4m->src_c_dec_v = 1;
902     _y4m->dst_c_dec_v = 2;
903     _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
904     /*Chroma filter required: read into the aux buf first.*/
905     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz =
906         2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
907     _y4m->convert = y4m_convert_422jpeg_420jpeg;
908   } else if (strcmp(_y4m->chroma_type, "422") == 0) {
909     _y4m->src_c_dec_h = 2;
910     _y4m->src_c_dec_v = 1;
911     if (only_420) {
912       _y4m->dst_c_dec_h = 2;
913       _y4m->dst_c_dec_v = 2;
914       _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
915       /*Chroma filter required: read into the aux buf first.
916         We need to make two filter passes, so we need some extra space in the
917          aux buffer.*/
918       _y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
919       _y4m->aux_buf_sz =
920           _y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
921       _y4m->convert = y4m_convert_422_420jpeg;
922     } else {
923       _y4m->vpx_fmt = VPX_IMG_FMT_I422;
924       _y4m->bps = 16;
925       _y4m->dst_c_dec_h = _y4m->src_c_dec_h;
926       _y4m->dst_c_dec_v = _y4m->src_c_dec_v;
927       _y4m->dst_buf_read_sz =
928           _y4m->pic_w * _y4m->pic_h + 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
929       /*Natively supported: no conversion required.*/
930       _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
931       _y4m->convert = y4m_convert_null;
932     }
933   } else if (strcmp(_y4m->chroma_type, "422p10") == 0) {
934     _y4m->src_c_dec_h = 2;
935     _y4m->src_c_dec_v = 1;
936     _y4m->vpx_fmt = VPX_IMG_FMT_I42216;
937     _y4m->bps = 20;
938     _y4m->bit_depth = 10;
939     _y4m->dst_c_dec_h = _y4m->src_c_dec_h;
940     _y4m->dst_c_dec_v = _y4m->src_c_dec_v;
941     _y4m->dst_buf_read_sz = 2 * (_y4m->pic_w * _y4m->pic_h +
942                                  2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h);
943     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
944     _y4m->convert = y4m_convert_null;
945     if (only_420) {
946       fprintf(stderr, "Unsupported conversion from 422p10 to 420jpeg\n");
947       return -1;
948     }
949   } else if (strcmp(_y4m->chroma_type, "422p12") == 0) {
950     _y4m->src_c_dec_h = 2;
951     _y4m->src_c_dec_v = 1;
952     _y4m->vpx_fmt = VPX_IMG_FMT_I42216;
953     _y4m->bps = 24;
954     _y4m->bit_depth = 12;
955     _y4m->dst_c_dec_h = _y4m->src_c_dec_h;
956     _y4m->dst_c_dec_v = _y4m->src_c_dec_v;
957     _y4m->dst_buf_read_sz = 2 * (_y4m->pic_w * _y4m->pic_h +
958                                  2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h);
959     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
960     _y4m->convert = y4m_convert_null;
961     if (only_420) {
962       fprintf(stderr, "Unsupported conversion from 422p12 to 420jpeg\n");
963       return -1;
964     }
965   } else if (strcmp(_y4m->chroma_type, "411") == 0) {
966     _y4m->src_c_dec_h = 4;
967     _y4m->dst_c_dec_h = 2;
968     _y4m->src_c_dec_v = 1;
969     _y4m->dst_c_dec_v = 2;
970     _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
971     /*Chroma filter required: read into the aux buf first.
972       We need to make two filter passes, so we need some extra space in the
973        aux buffer.*/
974     _y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 3) / 4) * _y4m->pic_h;
975     _y4m->aux_buf_sz =
976         _y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
977     _y4m->convert = y4m_convert_411_420jpeg;
978     fprintf(stderr, "Unsupported conversion from yuv 411\n");
979     return -1;
980   } else if (strcmp(_y4m->chroma_type, "444") == 0) {
981     _y4m->src_c_dec_h = 1;
982     _y4m->src_c_dec_v = 1;
983     if (only_420) {
984       _y4m->dst_c_dec_h = 2;
985       _y4m->dst_c_dec_v = 2;
986       _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
987       /*Chroma filter required: read into the aux buf first.
988         We need to make two filter passes, so we need some extra space in the
989          aux buffer.*/
990       _y4m->aux_buf_read_sz = 2 * _y4m->pic_w * _y4m->pic_h;
991       _y4m->aux_buf_sz =
992           _y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
993       _y4m->convert = y4m_convert_444_420jpeg;
994     } else {
995       _y4m->vpx_fmt = VPX_IMG_FMT_I444;
996       _y4m->bps = 24;
997       _y4m->dst_c_dec_h = _y4m->src_c_dec_h;
998       _y4m->dst_c_dec_v = _y4m->src_c_dec_v;
999       _y4m->dst_buf_read_sz = 3 * _y4m->pic_w * _y4m->pic_h;
1000       /*Natively supported: no conversion required.*/
1001       _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
1002       _y4m->convert = y4m_convert_null;
1003     }
1004   } else if (strcmp(_y4m->chroma_type, "444p10") == 0) {
1005     _y4m->src_c_dec_h = 1;
1006     _y4m->src_c_dec_v = 1;
1007     _y4m->vpx_fmt = VPX_IMG_FMT_I44416;
1008     _y4m->bps = 30;
1009     _y4m->bit_depth = 10;
1010     _y4m->dst_c_dec_h = _y4m->src_c_dec_h;
1011     _y4m->dst_c_dec_v = _y4m->src_c_dec_v;
1012     _y4m->dst_buf_read_sz = 2 * 3 * _y4m->pic_w * _y4m->pic_h;
1013     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
1014     _y4m->convert = y4m_convert_null;
1015     if (only_420) {
1016       fprintf(stderr, "Unsupported conversion from 444p10 to 420jpeg\n");
1017       return -1;
1018     }
1019   } else if (strcmp(_y4m->chroma_type, "444p12") == 0) {
1020     _y4m->src_c_dec_h = 1;
1021     _y4m->src_c_dec_v = 1;
1022     _y4m->vpx_fmt = VPX_IMG_FMT_I44416;
1023     _y4m->bps = 36;
1024     _y4m->bit_depth = 12;
1025     _y4m->dst_c_dec_h = _y4m->src_c_dec_h;
1026     _y4m->dst_c_dec_v = _y4m->src_c_dec_v;
1027     _y4m->dst_buf_read_sz = 2 * 3 * _y4m->pic_w * _y4m->pic_h;
1028     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
1029     _y4m->convert = y4m_convert_null;
1030     if (only_420) {
1031       fprintf(stderr, "Unsupported conversion from 444p12 to 420jpeg\n");
1032       return -1;
1033     }
1034   } else if (strcmp(_y4m->chroma_type, "mono") == 0) {
1035     _y4m->src_c_dec_h = _y4m->src_c_dec_v = 0;
1036     _y4m->dst_c_dec_h = _y4m->dst_c_dec_v = 2;
1037     _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
1038     /*No extra space required, but we need to clear the chroma planes.*/
1039     _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
1040     _y4m->convert = y4m_convert_mono_420jpeg;
1041   } else {
1042     fprintf(stderr, "Unknown chroma sampling type: %s\n", _y4m->chroma_type);
1043     return -1;
1044   }
1045   /*The size of the final frame buffers is always computed from the
1046      destination chroma decimation type.*/
1047   _y4m->dst_buf_sz =
1048       _y4m->pic_w * _y4m->pic_h +
1049       2 * ((_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h) *
1050           ((_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v);
1051   if (_y4m->bit_depth == 8)
1052     _y4m->dst_buf = (unsigned char *)malloc(_y4m->dst_buf_sz);
1053   else
1054     _y4m->dst_buf = (unsigned char *)malloc(2 * _y4m->dst_buf_sz);
1055
1056   if (_y4m->aux_buf_sz > 0)
1057     _y4m->aux_buf = (unsigned char *)malloc(_y4m->aux_buf_sz);
1058   return 0;
1059 }
1060
1061 void y4m_input_close(y4m_input *_y4m) {
1062   free(_y4m->dst_buf);
1063   free(_y4m->aux_buf);
1064 }
1065
1066 int y4m_input_fetch_frame(y4m_input *_y4m, FILE *_fin, vpx_image_t *_img) {
1067   char frame[6];
1068   int pic_sz;
1069   int c_w;
1070   int c_h;
1071   int c_sz;
1072   int bytes_per_sample = _y4m->bit_depth > 8 ? 2 : 1;
1073   /*Read and skip the frame header.*/
1074   if (!file_read(frame, 6, _fin)) return 0;
1075   if (memcmp(frame, "FRAME", 5)) {
1076     fprintf(stderr, "Loss of framing in Y4M input data\n");
1077     return -1;
1078   }
1079   if (frame[5] != '\n') {
1080     char c;
1081     int j;
1082     for (j = 0; j < 79 && file_read(&c, 1, _fin) && c != '\n'; j++) {
1083     }
1084     if (j == 79) {
1085       fprintf(stderr, "Error parsing Y4M frame header\n");
1086       return -1;
1087     }
1088   }
1089   /*Read the frame data that needs no conversion.*/
1090   if (!file_read(_y4m->dst_buf, _y4m->dst_buf_read_sz, _fin)) {
1091     fprintf(stderr, "Error reading Y4M frame data.\n");
1092     return -1;
1093   }
1094   /*Read the frame data that does need conversion.*/
1095   if (!file_read(_y4m->aux_buf, _y4m->aux_buf_read_sz, _fin)) {
1096     fprintf(stderr, "Error reading Y4M frame data.\n");
1097     return -1;
1098   }
1099   /*Now convert the just read frame.*/
1100   (*_y4m->convert)(_y4m, _y4m->dst_buf, _y4m->aux_buf);
1101   /*Fill in the frame buffer pointers.
1102     We don't use vpx_img_wrap() because it forces padding for odd picture
1103      sizes, which would require a separate fread call for every row.*/
1104   memset(_img, 0, sizeof(*_img));
1105   /*Y4M has the planes in Y'CbCr order, which libvpx calls Y, U, and V.*/
1106   _img->fmt = _y4m->vpx_fmt;
1107   _img->w = _img->d_w = _y4m->pic_w;
1108   _img->h = _img->d_h = _y4m->pic_h;
1109   _img->x_chroma_shift = _y4m->dst_c_dec_h >> 1;
1110   _img->y_chroma_shift = _y4m->dst_c_dec_v >> 1;
1111   _img->bps = _y4m->bps;
1112
1113   /*Set up the buffer pointers.*/
1114   pic_sz = _y4m->pic_w * _y4m->pic_h * bytes_per_sample;
1115   c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h;
1116   c_w *= bytes_per_sample;
1117   c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v;
1118   c_sz = c_w * c_h;
1119   _img->stride[VPX_PLANE_Y] = _img->stride[VPX_PLANE_ALPHA] =
1120       _y4m->pic_w * bytes_per_sample;
1121   _img->stride[VPX_PLANE_U] = _img->stride[VPX_PLANE_V] = c_w;
1122   _img->planes[VPX_PLANE_Y] = _y4m->dst_buf;
1123   _img->planes[VPX_PLANE_U] = _y4m->dst_buf + pic_sz;
1124   _img->planes[VPX_PLANE_V] = _y4m->dst_buf + pic_sz + c_sz;
1125   _img->planes[VPX_PLANE_ALPHA] = _y4m->dst_buf + pic_sz + 2 * c_sz;
1126   return 1;
1127 }