tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

y4minput.c (43158B)


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