176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Small jpeg decoder library 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 2006, Luc Saillard <luc@saillard.org> 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * All rights reserved. 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Redistribution and use in source and binary forms, with or without 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * modification, are permitted provided that the following conditions are met: 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * - Redistributions of source code must retain the above copyright notice, 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * this list of conditions and the following disclaimer. 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * - Redistributions in binary form must reproduce the above copyright notice, 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * this list of conditions and the following disclaimer in the documentation 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and/or other materials provided with the distribution. 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * - Neither the name of the author nor the names of its contributors may be 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * used to endorse or promote products derived from this software without 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * specific prior written permission. 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * POSSIBILITY OF SUCH DAMAGE. 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * yuv420p.c 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h> 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h> 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdint.h> 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "tinyjpeg.h" 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "tinyjpeg-internal.h" 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/******************************************************************************* 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Colorspace conversion routine 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Note: 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * YCbCr is defined per CCIR 601-1, except that Cb and Cr are 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The conversion equations to be implemented are therefore 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * R = Y + 1.40200 * Cr 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * G = Y - 0.34414 * Cb - 0.71414 * Cr 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * B = Y + 1.77200 * Cb 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ******************************************************************************/ 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * YCrCb -> YUV420P (1x1) 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * .---. 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * | 1 | 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * `---' 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void YCrCB_to_YUV420P_1x1(struct jdec_private *priv, int sx, int sy) 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const unsigned char *s, *y; 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned char *p; 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i,j; 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[0]; 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman y = priv->Y; 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i--) 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(p, y, sx); 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[0]; 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman y += 8; 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[1]; 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s = priv->Cb; 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i--) 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (j = sx; j >= 0; j -= 2) { 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *p++ = *s; 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 2; 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 8; /* Skip one line */ 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[1] - 4; 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[2]; 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s = priv->Cr; 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i=0; i<8; i+=2) 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (j = sx; j >= 0; j -= 2) { 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *p++ = *s; 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 2; 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 8; /* Skip one line */ 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[2] - 4; 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * YCrCb -> YUV420P (2x1) 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * .-------. 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * | 1 | 2 | 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * `-------' 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void YCrCB_to_YUV420P_2x1(struct jdec_private *priv, int sx, int sy) 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned char *p; 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const unsigned char *s, *y1; 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[0]; 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman y1 = priv->Y; 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i--) 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(p, y1, sx); 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[0]; 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman y1 += 16; 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sx = (sx+1) >> 1; 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[1]; 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s = priv->Cb; 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i -= 2) 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(p, s, sx); 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 16; /* Skip one line */ 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[1]; 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[2]; 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s = priv->Cr; 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i -= 2) 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(p, s, sx); 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 16; /* Skip one line */ 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[2]; 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * YCrCb -> YUV420P (1x2) 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * .---. 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * | 1 | 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * |---| 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * | 2 | 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * `---' 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void YCrCB_to_YUV420P_1x2(struct jdec_private *priv, int sx, int sy) 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const unsigned char *s, *y; 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned char *p, *pr; 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i,j; 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[0]; 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman y = priv->Y; 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i++) 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(p, y, sx); 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p+=priv->bytes_per_row[0]; 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman y+=8; 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pr = priv->plane[1]; 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s = priv->Cb; 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i -= 2) 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = pr; 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (j = sx; j > 0; j -= 2) { 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *p++ = *s; 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 2; 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pr += priv->bytes_per_row[1]; 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pr = priv->plane[2]; 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s = priv->Cr; 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i=0; i<8; i++) 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = pr; 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (j = sx; j > 0; j -= 2) { 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *p++ = *s; 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 2; 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pr += priv->bytes_per_row[2] - 4; 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * YCrCb -> YUV420P (2x2) 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * .-------. 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * | 1 | 2 | 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * |---+---| 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * | 3 | 4 | 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * `-------' 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void YCrCB_to_YUV420P_2x2(struct jdec_private *priv, int sx, int sy) 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned char *p; 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const unsigned char *s, *y1; 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[0]; 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman y1 = priv->Y; 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i--) 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(p, y1, sx); 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[0]; 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman y1 += 16; 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sx = (sx+1) >> 1; 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[1]; 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s = priv->Cb; 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i -= 2) 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(p, s, sx); 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 8; 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[1]; 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = priv->plane[2]; 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s = priv->Cr; 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = sy; i > 0; i -= 2) 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(p, s, sx); 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s += 8; 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p += priv->bytes_per_row[2]; 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int initialize_yuv420p(struct jdec_private *priv, 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int *bytes_per_blocklines, 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int *bytes_per_mcu) 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int half_height = (priv->height + 1) >> 2; 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int half_width = (priv->width + 1) >> 2; 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!priv->bytes_per_row[0]) 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman priv->bytes_per_row[0] = priv->width; 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!priv->components[0]) 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]); 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!priv->bytes_per_row[1]) 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman priv->bytes_per_row[1] = half_width; 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!priv->components[1]) 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman priv->components[1] = malloc(half_height * priv->bytes_per_row[1]); 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!priv->bytes_per_row[2]) 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman priv->bytes_per_row[2] = half_width; 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!priv->components[2]) 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman priv->components[2] = malloc(half_height * priv->bytes_per_row[2]); 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bytes_per_mcu[0] = 8; 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bytes_per_mcu[1] = 4; 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bytes_per_mcu[2] = 4; 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bytes_per_blocklines[0] = priv->width << 3; 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bytes_per_blocklines[1] = half_width << 2; 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bytes_per_blocklines[2] = half_width << 2; 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Return nonzero on failure */ 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return !priv->components[0] || !priv->components[1] || !priv->components[2]; 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const struct tinyjpeg_colorspace format_yuv420p = 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman YCrCB_to_YUV420P_1x1, 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman YCrCB_to_YUV420P_1x2, 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman YCrCB_to_YUV420P_2x1, 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman YCrCB_to_YUV420P_2x2, 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }, 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tinyjpeg_decode_mcu_3comp_table, 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman initialize_yuv420p 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanconst tinyjpeg_colorspace_t TINYJPEG_FMT_YUV420P = &format_yuv420p; 289