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