19b28defe6ac85dd8a52479cf276606beae24920eDRC/* 26eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis * Copyright (C)2009-2016 D. R. Commander. All Rights Reserved. 32e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC * 49b28defe6ac85dd8a52479cf276606beae24920eDRC * Redistribution and use in source and binary forms, with or without 59b28defe6ac85dd8a52479cf276606beae24920eDRC * modification, are permitted provided that the following conditions are met: 62e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC * 79b28defe6ac85dd8a52479cf276606beae24920eDRC * - Redistributions of source code must retain the above copyright notice, 89b28defe6ac85dd8a52479cf276606beae24920eDRC * this list of conditions and the following disclaimer. 99b28defe6ac85dd8a52479cf276606beae24920eDRC * - Redistributions in binary form must reproduce the above copyright notice, 109b28defe6ac85dd8a52479cf276606beae24920eDRC * this list of conditions and the following disclaimer in the documentation 119b28defe6ac85dd8a52479cf276606beae24920eDRC * and/or other materials provided with the distribution. 129b28defe6ac85dd8a52479cf276606beae24920eDRC * - Neither the name of the libjpeg-turbo Project nor the names of its 139b28defe6ac85dd8a52479cf276606beae24920eDRC * contributors may be used to endorse or promote products derived from this 149b28defe6ac85dd8a52479cf276606beae24920eDRC * software without specific prior written permission. 159b28defe6ac85dd8a52479cf276606beae24920eDRC * 169b28defe6ac85dd8a52479cf276606beae24920eDRC * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", 179b28defe6ac85dd8a52479cf276606beae24920eDRC * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 189b28defe6ac85dd8a52479cf276606beae24920eDRC * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 199b28defe6ac85dd8a52479cf276606beae24920eDRC * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 209b28defe6ac85dd8a52479cf276606beae24920eDRC * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 219b28defe6ac85dd8a52479cf276606beae24920eDRC * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 229b28defe6ac85dd8a52479cf276606beae24920eDRC * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 239b28defe6ac85dd8a52479cf276606beae24920eDRC * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 249b28defe6ac85dd8a52479cf276606beae24920eDRC * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 259b28defe6ac85dd8a52479cf276606beae24920eDRC * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 269b28defe6ac85dd8a52479cf276606beae24920eDRC * POSSIBILITY OF SUCH DAMAGE. 272e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC */ 282e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 29bdfcb74d509b2c151cdc4c8b388c8a5975a7da65DRC/* TurboJPEG/LJT: this implements the TurboJPEG API using libjpeg or 30bdfcb74d509b2c151cdc4c8b388c8a5975a7da65DRC libjpeg-turbo */ 312e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 322e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <stdio.h> 332e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <stdlib.h> 340713c1bb542672257c08782a5a930a577eb20167DRC#include <ctype.h> 35296c71ba0ffb034390a3d0b00a0cc6d6fa014b6eDRC#include <jinclude.h> 36fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define JPEG_INTERNALS 372e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jpeglib.h> 382e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jerror.h> 392e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <setjmp.h> 402e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include "./turbojpeg.h" 41a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#include "./tjutil.h" 42890f1e0413b54c40b663208779d4ea9dae20eaefDRC#include "transupp.h" 43418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC#include "./jpegcomp.h" 442a2e451ddc9e3c093a903ccb5a06962d05c21b67DRC 459b28defe6ac85dd8a52479cf276606beae24920eDRCextern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, 469b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *, boolean); 476eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidisextern void jpeg_mem_src_tj(j_decompress_ptr, const unsigned char *, 486eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis unsigned long); 499b28defe6ac85dd8a52479cf276606beae24920eDRC 50fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define PAD(v, p) ((v+(p)-1)&(~((p)-1))) 51f610d61fcc38b36a8a29879e5c053015164242f8DRC#define isPow2(x) (((x)&(x-1))==0) 522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 532e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 549b28defe6ac85dd8a52479cf276606beae24920eDRC/* Error handling (based on example in example.c) */ 552e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 569b28defe6ac85dd8a52479cf276606beae24920eDRCstatic char errStr[JMSG_LENGTH_MAX]="No error"; 572e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 589b28defe6ac85dd8a52479cf276606beae24920eDRCstruct my_error_mgr 592e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 602e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_error_mgr pub; 619b28defe6ac85dd8a52479cf276606beae24920eDRC jmp_buf setjmp_buffer; 621f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC void (*emit_message)(j_common_ptr, int); 631f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC boolean warning; 649b28defe6ac85dd8a52479cf276606beae24920eDRC}; 659b28defe6ac85dd8a52479cf276606beae24920eDRCtypedef struct my_error_mgr *my_error_ptr; 662e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 672e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCstatic void my_error_exit(j_common_ptr cinfo) 682e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 699b28defe6ac85dd8a52479cf276606beae24920eDRC my_error_ptr myerr=(my_error_ptr)cinfo->err; 702e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC (*cinfo->err->output_message)(cinfo); 719b28defe6ac85dd8a52479cf276606beae24920eDRC longjmp(myerr->setjmp_buffer, 1); 722e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 732e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 749b28defe6ac85dd8a52479cf276606beae24920eDRC/* Based on output_message() in jerror.c */ 759b28defe6ac85dd8a52479cf276606beae24920eDRC 762e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCstatic void my_output_message(j_common_ptr cinfo) 772e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 789b28defe6ac85dd8a52479cf276606beae24920eDRC (*cinfo->err->format_message)(cinfo, errStr); 792e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 811f79c7c8c8c5e993042ea816e1dd161fb69061a3DRCstatic void my_emit_message(j_common_ptr cinfo, int msg_level) 821f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC{ 831f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC my_error_ptr myerr=(my_error_ptr)cinfo->err; 841f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC myerr->emit_message(cinfo, msg_level); 851f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(msg_level<0) myerr->warning=TRUE; 861f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC} 871f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC 882e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 899b28defe6ac85dd8a52479cf276606beae24920eDRC/* Global structures, macros, etc. */ 902e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 919b28defe6ac85dd8a52479cf276606beae24920eDRCenum {COMPRESS=1, DECOMPRESS=2}; 929b28defe6ac85dd8a52479cf276606beae24920eDRC 939b28defe6ac85dd8a52479cf276606beae24920eDRCtypedef struct _tjinstance 942e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 952e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_compress_struct cinfo; 962e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_decompress_struct dinfo; 979b28defe6ac85dd8a52479cf276606beae24920eDRC struct my_error_mgr jerr; 98aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC int init, headerRead; 999b28defe6ac85dd8a52479cf276606beae24920eDRC} tjinstance; 1002e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1011f3635c4969f2319a01c9fe561958815b733227fDRCstatic const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3, 3}; 1029b28defe6ac85dd8a52479cf276606beae24920eDRC 103007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRCstatic const JXFORM_CODE xformtypes[TJ_NUMXOP]= 104007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC{ 105890f1e0413b54c40b663208779d4ea9dae20eaefDRC JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE, 106890f1e0413b54c40b663208779d4ea9dae20eaefDRC JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270 107890f1e0413b54c40b663208779d4ea9dae20eaefDRC}; 1089b28defe6ac85dd8a52479cf276606beae24920eDRC 109ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC#define NUMSF 16 110109a578e89ea8cd2c39d50b012698148dd11dedbDRCstatic const tjscalingfactor sf[NUMSF]={ 111ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {2, 1}, 112ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {15, 8}, 113ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {7, 4}, 114ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {13, 8}, 115ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 2}, 116ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {11, 8}, 117ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {5, 4}, 118ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {9, 8}, 119109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 1}, 120ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {7, 8}, 121ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 4}, 122ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {5, 8}, 123109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 2}, 124ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 8}, 125109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 4}, 126109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 8} 127109a578e89ea8cd2c39d50b012698148dd11dedbDRC}; 1282e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 129a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ 130da5220acdd525242bff4e40b1d90324ebb889825DRC retval=-1; goto bailout;} 1319b28defe6ac85dd8a52479cf276606beae24920eDRC#define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ 1329b28defe6ac85dd8a52479cf276606beae24920eDRC j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ 1339b28defe6ac85dd8a52479cf276606beae24920eDRC if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ 1349b28defe6ac85dd8a52479cf276606beae24920eDRC return -1;} \ 1351f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC cinfo=&this->cinfo; dinfo=&this->dinfo; \ 1361f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC this->jerr.warning=FALSE; 137418616266582fa978d4d1950cf739bbdac7ebee5DRC#define getcinstance(handle) tjinstance *this=(tjinstance *)handle; \ 138418616266582fa978d4d1950cf739bbdac7ebee5DRC j_compress_ptr cinfo=NULL; \ 139418616266582fa978d4d1950cf739bbdac7ebee5DRC if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ 140418616266582fa978d4d1950cf739bbdac7ebee5DRC return -1;} \ 1411f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC cinfo=&this->cinfo; \ 1421f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC this->jerr.warning=FALSE; 143418616266582fa978d4d1950cf739bbdac7ebee5DRC#define getdinstance(handle) tjinstance *this=(tjinstance *)handle; \ 144418616266582fa978d4d1950cf739bbdac7ebee5DRC j_decompress_ptr dinfo=NULL; \ 145418616266582fa978d4d1950cf739bbdac7ebee5DRC if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ 146418616266582fa978d4d1950cf739bbdac7ebee5DRC return -1;} \ 1471f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC dinfo=&this->dinfo; \ 1481f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC this->jerr.warning=FALSE; 1499b28defe6ac85dd8a52479cf276606beae24920eDRC 1509b28defe6ac85dd8a52479cf276606beae24920eDRCstatic int getPixelFormat(int pixelSize, int flags) 1519b28defe6ac85dd8a52479cf276606beae24920eDRC{ 15225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(pixelSize==1) return TJPF_GRAY; 1539b28defe6ac85dd8a52479cf276606beae24920eDRC if(pixelSize==3) 1549b28defe6ac85dd8a52479cf276606beae24920eDRC { 15525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_BGR; 15625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_RGB; 1579b28defe6ac85dd8a52479cf276606beae24920eDRC } 1589b28defe6ac85dd8a52479cf276606beae24920eDRC if(pixelSize==4) 1599b28defe6ac85dd8a52479cf276606beae24920eDRC { 1609b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_ALPHAFIRST) 1619b28defe6ac85dd8a52479cf276606beae24920eDRC { 16225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_XBGR; 16325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_XRGB; 1649b28defe6ac85dd8a52479cf276606beae24920eDRC } 1659b28defe6ac85dd8a52479cf276606beae24920eDRC else 1669b28defe6ac85dd8a52479cf276606beae24920eDRC { 16725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_BGRX; 16825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_RGBX; 1699b28defe6ac85dd8a52479cf276606beae24920eDRC } 1709b28defe6ac85dd8a52479cf276606beae24920eDRC } 1719b28defe6ac85dd8a52479cf276606beae24920eDRC return -1; 1729b28defe6ac85dd8a52479cf276606beae24920eDRC} 1739b28defe6ac85dd8a52479cf276606beae24920eDRC 174f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setCompDefaults(struct jpeg_compress_struct *cinfo, 17573d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC int pixelFormat, int subsamp, int jpegQual, int flags) 1769b28defe6ac85dd8a52479cf276606beae24920eDRC{ 177f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC int retval=0; 1780713c1bb542672257c08782a5a930a577eb20167DRC char *env=NULL; 179f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 1809b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 1819b28defe6ac85dd8a52479cf276606beae24920eDRC { 18225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 1839b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_GRAYSCALE; break; 1849b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 18525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 1869b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGB; break; 18725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 1889b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGR; break; 18925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 19067ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_RGBA: 1919b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGBX; break; 19225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 19367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_BGRA: 1949b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGRX; break; 19525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 19667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ARGB: 1979b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XRGB; break; 19825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 19967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ABGR: 2009b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XBGR; break; 2019b28defe6ac85dd8a52479cf276606beae24920eDRC #else 20225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 203afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 204afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 205afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 206afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 207afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 208afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 209afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 210afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 211afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 212afc06929e0a9cf64bdf50da30326076235df7b4fDRC cinfo->in_color_space=JCS_RGB; pixelFormat=TJPF_RGB; 213afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 2149b28defe6ac85dd8a52479cf276606beae24920eDRC #endif 215cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC case TJPF_CMYK: 216cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC cinfo->in_color_space=JCS_CMYK; break; 2179b28defe6ac85dd8a52479cf276606beae24920eDRC } 2189b28defe6ac85dd8a52479cf276606beae24920eDRC 2199b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->input_components=tjPixelSize[pixelFormat]; 2209b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_defaults(cinfo); 2210713c1bb542672257c08782a5a930a577eb20167DRC 222feccdcf8c89f44bd6a139200b6748daac0d39b1eDRC#ifndef NO_GETENV 2230713c1bb542672257c08782a5a930a577eb20167DRC if((env=getenv("TJ_OPTIMIZE"))!=NULL && strlen(env)>0 && !strcmp(env, "1")) 2240713c1bb542672257c08782a5a930a577eb20167DRC cinfo->optimize_coding=TRUE; 2250713c1bb542672257c08782a5a930a577eb20167DRC if((env=getenv("TJ_ARITHMETIC"))!=NULL && strlen(env)>0 && !strcmp(env, "1")) 2260713c1bb542672257c08782a5a930a577eb20167DRC cinfo->arith_code=TRUE; 2270713c1bb542672257c08782a5a930a577eb20167DRC if((env=getenv("TJ_RESTART"))!=NULL && strlen(env)>0) 2280713c1bb542672257c08782a5a930a577eb20167DRC { 2290713c1bb542672257c08782a5a930a577eb20167DRC int temp=-1; char tempc=0; 2300713c1bb542672257c08782a5a930a577eb20167DRC if(sscanf(env, "%d%c", &temp, &tempc)>=1 && temp>=0 && temp<=65535) 2310713c1bb542672257c08782a5a930a577eb20167DRC { 2320713c1bb542672257c08782a5a930a577eb20167DRC if(toupper(tempc)=='B') 2330713c1bb542672257c08782a5a930a577eb20167DRC { 2340713c1bb542672257c08782a5a930a577eb20167DRC cinfo->restart_interval=temp; 2350713c1bb542672257c08782a5a930a577eb20167DRC cinfo->restart_in_rows=0; 2360713c1bb542672257c08782a5a930a577eb20167DRC } 2370713c1bb542672257c08782a5a930a577eb20167DRC else 2380713c1bb542672257c08782a5a930a577eb20167DRC cinfo->restart_in_rows=temp; 2390713c1bb542672257c08782a5a930a577eb20167DRC } 2400713c1bb542672257c08782a5a930a577eb20167DRC } 241feccdcf8c89f44bd6a139200b6748daac0d39b1eDRC#endif 2420713c1bb542672257c08782a5a930a577eb20167DRC 2439b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegQual>=0) 2449b28defe6ac85dd8a52479cf276606beae24920eDRC { 2459b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_quality(cinfo, jpegQual, TRUE); 24673d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(jpegQual>=96 || flags&TJFLAG_ACCURATEDCT) cinfo->dct_method=JDCT_ISLOW; 2479b28defe6ac85dd8a52479cf276606beae24920eDRC else cinfo->dct_method=JDCT_FASTEST; 2489b28defe6ac85dd8a52479cf276606beae24920eDRC } 24925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(subsamp==TJSAMP_GRAY) 2509b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); 251cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC else if(pixelFormat==TJPF_CMYK) 252cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC jpeg_set_colorspace(cinfo, JCS_YCCK); 253cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC else jpeg_set_colorspace(cinfo, JCS_YCbCr); 2549b28defe6ac85dd8a52479cf276606beae24920eDRC 255feccdcf8c89f44bd6a139200b6748daac0d39b1eDRC#ifndef NO_GETENV 2560713c1bb542672257c08782a5a930a577eb20167DRC if((env=getenv("TJ_PROGRESSIVE"))!=NULL && strlen(env)>0 2570713c1bb542672257c08782a5a930a577eb20167DRC && !strcmp(env, "1")) 2580713c1bb542672257c08782a5a930a577eb20167DRC jpeg_simple_progression(cinfo); 259feccdcf8c89f44bd6a139200b6748daac0d39b1eDRC#endif 2600713c1bb542672257c08782a5a930a577eb20167DRC 2619b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; 2629b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].h_samp_factor=1; 2639b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].h_samp_factor=1; 264cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC if(cinfo->num_components>3) 265cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC cinfo->comp_info[3].h_samp_factor=tjMCUWidth[subsamp]/8; 2669b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; 2679b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].v_samp_factor=1; 2689b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].v_samp_factor=1; 269cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC if(cinfo->num_components>3) 270cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC cinfo->comp_info[3].v_samp_factor=tjMCUHeight[subsamp]/8; 271f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 272f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return retval; 2739b28defe6ac85dd8a52479cf276606beae24920eDRC} 2749b28defe6ac85dd8a52479cf276606beae24920eDRC 275f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setDecompDefaults(struct jpeg_decompress_struct *dinfo, 27673d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC int pixelFormat, int flags) 2779b28defe6ac85dd8a52479cf276606beae24920eDRC{ 278f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC int retval=0; 279f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 2809b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 2819b28defe6ac85dd8a52479cf276606beae24920eDRC { 28225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 2839b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_GRAYSCALE; break; 2849b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 28525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 2869b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGB; break; 28725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 2889b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGR; break; 28925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 2909b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGBX; break; 29125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 2929b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGRX; break; 29325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 2949b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XRGB; break; 29525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 2969b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XBGR; break; 29767ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #if JCS_ALPHA_EXTENSIONS==1 29867ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_RGBA: 29967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_RGBA; break; 30067ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_BGRA: 30167ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_BGRA; break; 30267ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ARGB: 30367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_ARGB; break; 30467ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ABGR: 30567ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_ABGR; break; 30667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #endif 3079b28defe6ac85dd8a52479cf276606beae24920eDRC #else 30825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 309afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 310afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 311afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 312afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 313afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 314afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 315afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 316afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 317afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 318afc06929e0a9cf64bdf50da30326076235df7b4fDRC dinfo->out_color_space=JCS_RGB; break; 31967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #endif 320cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC case TJPF_CMYK: 321cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC dinfo->out_color_space=JCS_CMYK; break; 3229b28defe6ac85dd8a52479cf276606beae24920eDRC default: 3239b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("Unsupported pixel format"); 3249b28defe6ac85dd8a52479cf276606beae24920eDRC } 325f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 32673d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; 32773d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC 328f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC bailout: 329f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return retval; 3309b28defe6ac85dd8a52479cf276606beae24920eDRC} 3312e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 3322e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 3339b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCstatic int getSubsamp(j_decompress_ptr dinfo) 3349b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 3359b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=-1, i, k; 336ea1eea47423df40809f165519094761045e832aeDRC 337ea1eea47423df40809f165519094761045e832aeDRC /* The sampling factors actually have no meaning with grayscale JPEG files, 338ea1eea47423df40809f165519094761045e832aeDRC and in fact it's possible to generate grayscale JPEGs with sampling 339ea1eea47423df40809f165519094761045e832aeDRC factors > 1 (even though those sampling factors are ignored by the 340ea1eea47423df40809f165519094761045e832aeDRC decompressor.) Thus, we need to treat grayscale as a special case. */ 341ea1eea47423df40809f165519094761045e832aeDRC if(dinfo->num_components==1 && dinfo->jpeg_color_space==JCS_GRAYSCALE) 342ea1eea47423df40809f165519094761045e832aeDRC return TJSAMP_GRAY; 343ea1eea47423df40809f165519094761045e832aeDRC 3449b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC for(i=0; i<NUMSUBOPT; i++) 3459b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 346cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC if(dinfo->num_components==pixelsize[i] 347cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC || ((dinfo->jpeg_color_space==JCS_YCCK 348cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC || dinfo->jpeg_color_space==JCS_CMYK) 349cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC && pixelsize[i]==3 && dinfo->num_components==4)) 3509b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 3519b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8 3529b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC && dinfo->comp_info[0].v_samp_factor==tjMCUHeight[i]/8) 3539b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 3549b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int match=0; 3559b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC for(k=1; k<dinfo->num_components; k++) 3569b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 357cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC int href=1, vref=1; 358cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC if(dinfo->jpeg_color_space==JCS_YCCK && k==3) 359cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC { 360cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC href=tjMCUWidth[i]/8; vref=tjMCUHeight[i]/8; 361cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC } 362cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC if(dinfo->comp_info[k].h_samp_factor==href 363cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC && dinfo->comp_info[k].v_samp_factor==vref) 3649b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC match++; 3659b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 3669b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(match==dinfo->num_components-1) 3679b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 3689b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC retval=i; break; 3699b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 3709b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 3716eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis /* Handle 4:2:2 and 4:4:0 images whose sampling factors are specified 3726eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis in non-standard ways. */ 3736eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(dinfo->comp_info[0].h_samp_factor==2 && 3746eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis dinfo->comp_info[0].v_samp_factor==2 && 3756eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis (i==TJSAMP_422 || i==TJSAMP_440)) 3766eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis { 3776eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int match=0; 3786eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis for(k=1; k<dinfo->num_components; k++) 3796eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis { 3806eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int href=tjMCUHeight[i]/8, vref=tjMCUWidth[i]/8; 3816eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(dinfo->jpeg_color_space==JCS_YCCK && k==3) 3826eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis { 3836eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis href=vref=2; 3846eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis } 3856eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(dinfo->comp_info[k].h_samp_factor==href 3866eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis && dinfo->comp_info[k].v_samp_factor==vref) 3876eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis match++; 3886eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis } 3896eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(match==dinfo->num_components-1) 3906eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis { 3916eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis retval=i; break; 3926eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis } 3936eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis } 3949b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 3959b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 3969b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return retval; 3979b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 3989b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 3999b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 400afc06929e0a9cf64bdf50da30326076235df7b4fDRC#ifndef JCS_EXTENSIONS 401afc06929e0a9cf64bdf50da30326076235df7b4fDRC 402afc06929e0a9cf64bdf50da30326076235df7b4fDRC/* Conversion functions to emulate the colorspace extensions. This allows the 403afc06929e0a9cf64bdf50da30326076235df7b4fDRC TurboJPEG wrapper to be used with libjpeg */ 404afc06929e0a9cf64bdf50da30326076235df7b4fDRC 405afc06929e0a9cf64bdf50da30326076235df7b4fDRC#define TORGB(PS, ROFFSET, GOFFSET, BOFFSET) { \ 406afc06929e0a9cf64bdf50da30326076235df7b4fDRC int rowPad=pitch-width*PS; \ 407afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(height--) \ 408afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 409afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *endOfRow=src+width*PS; \ 410afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(src<endOfRow) \ 411afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 412afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_RED]=src[ROFFSET]; \ 413afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_GREEN]=src[GOFFSET]; \ 414afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_BLUE]=src[BOFFSET]; \ 415afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=RGB_PIXELSIZE; src+=PS; \ 416afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 417afc06929e0a9cf64bdf50da30326076235df7b4fDRC src+=rowPad; \ 418afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 419afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 420afc06929e0a9cf64bdf50da30326076235df7b4fDRC 421afc06929e0a9cf64bdf50da30326076235df7b4fDRCstatic unsigned char *toRGB(unsigned char *src, int width, int pitch, 422afc06929e0a9cf64bdf50da30326076235df7b4fDRC int height, int pixelFormat, unsigned char *dst) 423afc06929e0a9cf64bdf50da30326076235df7b4fDRC{ 424afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *retval=src; 425afc06929e0a9cf64bdf50da30326076235df7b4fDRC switch(pixelFormat) 426afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 427afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGB: 428afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3 429afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(3, 0, 1, 2); 430afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 431afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 432afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 433afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3 434afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(3, 2, 1, 0); 435afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 436afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 437afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 438afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 439afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 440afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 0, 1, 2); 441afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 442afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 443afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 444afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 445afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 446afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 2, 1, 0); 447afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 448afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 449afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 450afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 451afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 452afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 1, 2, 3); 453afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 454afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 455afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 456afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 457afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 458afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 3, 2, 1); 459afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 460afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 461afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 462afc06929e0a9cf64bdf50da30326076235df7b4fDRC return retval; 463afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 464afc06929e0a9cf64bdf50da30326076235df7b4fDRC 465afc06929e0a9cf64bdf50da30326076235df7b4fDRC#define FROMRGB(PS, ROFFSET, GOFFSET, BOFFSET, SETALPHA) { \ 466afc06929e0a9cf64bdf50da30326076235df7b4fDRC int rowPad=pitch-width*PS; \ 467afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(height--) \ 468afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 469afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *endOfRow=dst+width*PS; \ 470afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(dst<endOfRow) \ 471afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 472afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[ROFFSET]=src[RGB_RED]; \ 473afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[GOFFSET]=src[RGB_GREEN]; \ 474afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[BOFFSET]=src[RGB_BLUE]; \ 475afc06929e0a9cf64bdf50da30326076235df7b4fDRC SETALPHA \ 476afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=PS; src+=RGB_PIXELSIZE; \ 477afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 478afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=rowPad; \ 479afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 480afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 481afc06929e0a9cf64bdf50da30326076235df7b4fDRC 482afc06929e0a9cf64bdf50da30326076235df7b4fDRCstatic void fromRGB(unsigned char *src, unsigned char *dst, int width, 483afc06929e0a9cf64bdf50da30326076235df7b4fDRC int pitch, int height, int pixelFormat) 484afc06929e0a9cf64bdf50da30326076235df7b4fDRC{ 485afc06929e0a9cf64bdf50da30326076235df7b4fDRC switch(pixelFormat) 486afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 487afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGB: 488afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3 489afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(3, 0, 1, 2,); 490afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 491afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 492afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 493afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3 494afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(3, 2, 1, 0,); 495afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 496afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 497afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 498afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 499afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 0, 1, 2,); 500afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 501afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 502afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 503afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 504afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 0, 1, 2, dst[3]=0xFF;); 505afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 506afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 507afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 508afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 509afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 2, 1, 0,); 510afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 511afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 512afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 513afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 514afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 2, 1, 0, dst[3]=0xFF;); return; 515afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 516afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 517afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 518afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 519afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 1, 2, 3,); return; 520afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 521afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 522afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 523afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 524afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 1, 2, 3, dst[0]=0xFF;); return; 525afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 526afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 527afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 528afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 529afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 3, 2, 1,); return; 530afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 531afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 532afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 533afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 534afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 3, 2, 1, dst[0]=0xFF;); return; 535afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 536afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 537afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 538afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 539afc06929e0a9cf64bdf50da30326076235df7b4fDRC 540afc06929e0a9cf64bdf50da30326076235df7b4fDRC#endif 541afc06929e0a9cf64bdf50da30326076235df7b4fDRC 542afc06929e0a9cf64bdf50da30326076235df7b4fDRC 5439b28defe6ac85dd8a52479cf276606beae24920eDRC/* General API functions */ 5442e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5459b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT char* DLLCALL tjGetErrorStr(void) 5462e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 5479b28defe6ac85dd8a52479cf276606beae24920eDRC return errStr; 5482e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 5492e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5509b28defe6ac85dd8a52479cf276606beae24920eDRC 5519b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDestroy(tjhandle handle) 5522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 5539b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 5549b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) return -1; 5559b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&COMPRESS) jpeg_destroy_compress(cinfo); 5569b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&DECOMPRESS) jpeg_destroy_decompress(dinfo); 5579b28defe6ac85dd8a52479cf276606beae24920eDRC free(this); 5589b28defe6ac85dd8a52479cf276606beae24920eDRC return 0; 5592e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 5602e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5619b28defe6ac85dd8a52479cf276606beae24920eDRC 5626b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC/* These are exposed mainly because Windows can't malloc() and free() across 5636b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC DLL boundaries except when the CRT DLL is used, and we don't use the CRT DLL 5646b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC with turbojpeg.dll for compatibility reasons. However, these functions 5656b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC can potentially be used for other purposes by different implementations. */ 5666b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 5676b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT void DLLCALL tjFree(unsigned char *buf) 5686b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 5696b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC if(buf) free(buf); 5706b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 5716b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 5726b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 5736b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes) 5746b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 5756b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC return (unsigned char *)malloc(bytes); 5766b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 5776b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 5786b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 5799b28defe6ac85dd8a52479cf276606beae24920eDRC/* Compressor */ 5809b28defe6ac85dd8a52479cf276606beae24920eDRC 5819b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitCompress(tjinstance *this) 5822e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 5836eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis static unsigned char buffer[1]; 5846eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis unsigned char *buf=buffer; unsigned long size=1; 5859b28defe6ac85dd8a52479cf276606beae24920eDRC 5869b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 5879b28defe6ac85dd8a52479cf276606beae24920eDRC this->cinfo.err=jpeg_std_error(&this->jerr.pub); 5889b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 5899b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 5901f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC this->jerr.emit_message=this->jerr.pub.emit_message; 5911f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC this->jerr.pub.emit_message=my_emit_message; 5922e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5939b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 5949b28defe6ac85dd8a52479cf276606beae24920eDRC { 5959b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 5966eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(this) free(this); 5976eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis return NULL; 598efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 5992e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6009b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_compress(&this->cinfo); 6019b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the destination manager */ 6029b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); 6032e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 604007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=COMPRESS; 6059b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 6062e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 6072e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 608890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitCompress(void) 609890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 6109b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; 6119b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 612da5220acdd525242bff4e40b1d90324ebb889825DRC { 613007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 614007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitCompress(): Memory allocation failure"); 615da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 616da5220acdd525242bff4e40b1d90324ebb889825DRC } 617007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 6189b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitCompress(this); 619890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 620890f1e0413b54c40b663208779d4ea9dae20eaefDRC 621842416034561f6d5320165a4fe98825e999a4a37DRC 6229b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, 6239b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int jpegSubsamp) 6249b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 6259b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC unsigned long retval=0; int mcuw, mcuh, chromasf; 6269b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT) 6279b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjBufSize(): Invalid argument"); 6289b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 629006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC /* This allows for rare corner cases in which a JPEG image can actually be 630006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC larger than the uncompressed input (we wouldn't mention it if it hadn't 631006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC happened before.) */ 6329b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC mcuw=tjMCUWidth[jpegSubsamp]; 6339b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC mcuh=tjMCUHeight[jpegSubsamp]; 6349b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh); 6359b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048; 6369b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 6379b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC bailout: 6389b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return retval; 6399b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 6409b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 6412e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) 6422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 643f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 644f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1) 645007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("TJBUFSIZE(): Invalid argument"); 646f3cf973e8e51e0078f402ca5547c026967c27321DRC 647006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC /* This allows for rare corner cases in which a JPEG image can actually be 648006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC larger than the uncompressed input (we wouldn't mention it if it hadn't 649006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC happened before.) */ 650007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; 651f3cf973e8e51e0078f402ca5547c026967c27321DRC 652f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 653f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 654f3cf973e8e51e0078f402ca5547c026967c27321DRC} 655f3cf973e8e51e0078f402ca5547c026967c27321DRC 656842416034561f6d5320165a4fe98825e999a4a37DRC 657f610d61fcc38b36a8a29879e5c053015164242f8DRCDLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height, 658f3cf973e8e51e0078f402ca5547c026967c27321DRC int subsamp) 659f3cf973e8e51e0078f402ca5547c026967c27321DRC{ 66040dd3146cde2ba5036fe76a4f09e1125b4592347DRC int retval=0, nc, i; 66140dd3146cde2ba5036fe76a4f09e1125b4592347DRC 66240dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(subsamp<0 || subsamp>=NUMSUBOPT) 663f610d61fcc38b36a8a29879e5c053015164242f8DRC _throw("tjBufSizeYUV2(): Invalid argument"); 66440dd3146cde2ba5036fe76a4f09e1125b4592347DRC 66540dd3146cde2ba5036fe76a4f09e1125b4592347DRC nc=(subsamp==TJSAMP_GRAY? 1:3); 66640dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(i=0; i<nc; i++) 66740dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 66855620c6ef28b02524dc763ba5ffc438c4a08419bDRC int pw=tjPlaneWidth(i, width, subsamp); 66955620c6ef28b02524dc763ba5ffc438c4a08419bDRC int stride=PAD(pw, pad); 67040dd3146cde2ba5036fe76a4f09e1125b4592347DRC int ph=tjPlaneHeight(i, height, subsamp); 67155620c6ef28b02524dc763ba5ffc438c4a08419bDRC if(pw<0 || ph<0) return -1; 67240dd3146cde2ba5036fe76a4f09e1125b4592347DRC else retval+=stride*ph; 67340dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 674f3cf973e8e51e0078f402ca5547c026967c27321DRC 675f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 676f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 6772e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 6782e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 679f610d61fcc38b36a8a29879e5c053015164242f8DRCDLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, 680f610d61fcc38b36a8a29879e5c053015164242f8DRC int subsamp) 681f610d61fcc38b36a8a29879e5c053015164242f8DRC{ 682f610d61fcc38b36a8a29879e5c053015164242f8DRC return tjBufSizeYUV2(width, 4, height, subsamp); 683f610d61fcc38b36a8a29879e5c053015164242f8DRC} 684842416034561f6d5320165a4fe98825e999a4a37DRC 6859b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height, 6869b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int subsamp) 6879b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 6889b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return tjBufSizeYUV(width, height, subsamp); 6899b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 6909b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 6919b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 69240dd3146cde2ba5036fe76a4f09e1125b4592347DRCDLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp) 69340dd3146cde2ba5036fe76a4f09e1125b4592347DRC{ 69440dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw, nc, retval=0; 69540dd3146cde2ba5036fe76a4f09e1125b4592347DRC 69640dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(width<1 || subsamp<0 || subsamp>=TJ_NUMSAMP) 69740dd3146cde2ba5036fe76a4f09e1125b4592347DRC _throw("tjPlaneWidth(): Invalid argument"); 69840dd3146cde2ba5036fe76a4f09e1125b4592347DRC nc=(subsamp==TJSAMP_GRAY? 1:3); 69940dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(componentID<0 || componentID>=nc) 70040dd3146cde2ba5036fe76a4f09e1125b4592347DRC _throw("tjPlaneWidth(): Invalid argument"); 70140dd3146cde2ba5036fe76a4f09e1125b4592347DRC 70240dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw=PAD(width, tjMCUWidth[subsamp]/8); 70340dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(componentID==0) 70440dd3146cde2ba5036fe76a4f09e1125b4592347DRC retval=pw; 70540dd3146cde2ba5036fe76a4f09e1125b4592347DRC else 70640dd3146cde2ba5036fe76a4f09e1125b4592347DRC retval=pw*8/tjMCUWidth[subsamp]; 70740dd3146cde2ba5036fe76a4f09e1125b4592347DRC 70840dd3146cde2ba5036fe76a4f09e1125b4592347DRC bailout: 70940dd3146cde2ba5036fe76a4f09e1125b4592347DRC return retval; 71040dd3146cde2ba5036fe76a4f09e1125b4592347DRC} 71140dd3146cde2ba5036fe76a4f09e1125b4592347DRC 71240dd3146cde2ba5036fe76a4f09e1125b4592347DRC 71340dd3146cde2ba5036fe76a4f09e1125b4592347DRCDLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp) 71440dd3146cde2ba5036fe76a4f09e1125b4592347DRC{ 71540dd3146cde2ba5036fe76a4f09e1125b4592347DRC int ph, nc, retval=0; 71640dd3146cde2ba5036fe76a4f09e1125b4592347DRC 71740dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(height<1 || subsamp<0 || subsamp>=TJ_NUMSAMP) 71840dd3146cde2ba5036fe76a4f09e1125b4592347DRC _throw("tjPlaneHeight(): Invalid argument"); 71940dd3146cde2ba5036fe76a4f09e1125b4592347DRC nc=(subsamp==TJSAMP_GRAY? 1:3); 72040dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(componentID<0 || componentID>=nc) 72140dd3146cde2ba5036fe76a4f09e1125b4592347DRC _throw("tjPlaneHeight(): Invalid argument"); 72240dd3146cde2ba5036fe76a4f09e1125b4592347DRC 72340dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph=PAD(height, tjMCUHeight[subsamp]/8); 72440dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(componentID==0) 72540dd3146cde2ba5036fe76a4f09e1125b4592347DRC retval=ph; 72640dd3146cde2ba5036fe76a4f09e1125b4592347DRC else 72740dd3146cde2ba5036fe76a4f09e1125b4592347DRC retval=ph*8/tjMCUHeight[subsamp]; 72840dd3146cde2ba5036fe76a4f09e1125b4592347DRC 72940dd3146cde2ba5036fe76a4f09e1125b4592347DRC bailout: 73040dd3146cde2ba5036fe76a4f09e1125b4592347DRC return retval; 73140dd3146cde2ba5036fe76a4f09e1125b4592347DRC} 73240dd3146cde2ba5036fe76a4f09e1125b4592347DRC 73340dd3146cde2ba5036fe76a4f09e1125b4592347DRC 73440dd3146cde2ba5036fe76a4f09e1125b4592347DRCDLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width, 73540dd3146cde2ba5036fe76a4f09e1125b4592347DRC int stride, int height, int subsamp) 73640dd3146cde2ba5036fe76a4f09e1125b4592347DRC{ 73740dd3146cde2ba5036fe76a4f09e1125b4592347DRC unsigned long retval=0; 73840dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw, ph; 73940dd3146cde2ba5036fe76a4f09e1125b4592347DRC 74040dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) 74140dd3146cde2ba5036fe76a4f09e1125b4592347DRC _throw("tjPlaneSizeYUV(): Invalid argument"); 74240dd3146cde2ba5036fe76a4f09e1125b4592347DRC 74340dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw=tjPlaneWidth(componentID, width, subsamp); 74440dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph=tjPlaneHeight(componentID, height, subsamp); 7452240974d5dc23a27ceb513af3cfc18f7298af0dcDRC if(pw<0 || ph<0) return -1; 74640dd3146cde2ba5036fe76a4f09e1125b4592347DRC 74740dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(stride==0) stride=pw; 74840dd3146cde2ba5036fe76a4f09e1125b4592347DRC else stride=abs(stride); 74940dd3146cde2ba5036fe76a4f09e1125b4592347DRC 75040dd3146cde2ba5036fe76a4f09e1125b4592347DRC retval=stride*(ph-1)+pw; 75140dd3146cde2ba5036fe76a4f09e1125b4592347DRC 75240dd3146cde2ba5036fe76a4f09e1125b4592347DRC bailout: 75340dd3146cde2ba5036fe76a4f09e1125b4592347DRC return retval; 75440dd3146cde2ba5036fe76a4f09e1125b4592347DRC} 75540dd3146cde2ba5036fe76a4f09e1125b4592347DRC 75640dd3146cde2ba5036fe76a4f09e1125b4592347DRC 7576eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf, 7589b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, 7599b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 7609b28defe6ac85dd8a52479cf276606beae24920eDRC{ 761ff78e37595c8462f64fd100f928aa1d08539527eDRC int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; 762afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 763afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 764afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 7659b28defe6ac85dd8a52479cf276606beae24920eDRC 766418616266582fa978d4d1950cf739bbdac7ebee5DRC getcinstance(handle) 7679b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 768007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Instance has not been initialized for compression"); 7699b28defe6ac85dd8a52479cf276606beae24920eDRC 7709b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 7719b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL 7729b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100) 773007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Invalid argument"); 7749b28defe6ac85dd8a52479cf276606beae24920eDRC 7759b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 7769b28defe6ac85dd8a52479cf276606beae24920eDRC { 7779b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 7789b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 7799b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 7809b28defe6ac85dd8a52479cf276606beae24920eDRC } 7819b28defe6ac85dd8a52479cf276606beae24920eDRC 7829b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 7839b28defe6ac85dd8a52479cf276606beae24920eDRC 784afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 785230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK) 786afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 787afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); 788afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure"); 789afc06929e0a9cf64bdf50da30326076235df7b4fDRC srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); 790afc06929e0a9cf64bdf50da30326076235df7b4fDRC pitch=width*RGB_PIXELSIZE; 791afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 792afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 793afc06929e0a9cf64bdf50da30326076235df7b4fDRC 7949b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 7959b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 7969b28defe6ac85dd8a52479cf276606beae24920eDRC 797bec45b162bb77a57c147a9c44113af1968a79be4DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 798bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 799bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 8009b28defe6ac85dd8a52479cf276606beae24920eDRC 801ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 802ff78e37595c8462f64fd100f928aa1d08539527eDRC { 8039b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp); 804ff78e37595c8462f64fd100f928aa1d08539527eDRC } 805ff78e37595c8462f64fd100f928aa1d08539527eDRC jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); 80673d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual, flags)==-1) 807f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return -1; 8089b28defe6ac85dd8a52479cf276606beae24920eDRC 8099b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 8109b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) 811007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Memory allocation failure"); 8129b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 8139b28defe6ac85dd8a52479cf276606beae24920eDRC { 8146eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(flags&TJFLAG_BOTTOMUP) 8156eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch]; 8166eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch]; 8179b28defe6ac85dd8a52479cf276606beae24920eDRC } 8189b28defe6ac85dd8a52479cf276606beae24920eDRC while(cinfo->next_scanline<cinfo->image_height) 8199b28defe6ac85dd8a52479cf276606beae24920eDRC { 8209b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], 8219b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height-cinfo->next_scanline); 8229b28defe6ac85dd8a52479cf276606beae24920eDRC } 8239b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_compress(cinfo); 8249b28defe6ac85dd8a52479cf276606beae24920eDRC 8259b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 8269b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 827afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 828ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 829afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 8309b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 8311f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(this->jerr.warning) retval=-1; 8329b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 8339b28defe6ac85dd8a52479cf276606beae24920eDRC} 8349b28defe6ac85dd8a52479cf276606beae24920eDRC 8359b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, 8369b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, 8379b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 8389b28defe6ac85dd8a52479cf276606beae24920eDRC{ 8399b28defe6ac85dd8a52479cf276606beae24920eDRC int retval=0; unsigned long size; 8409b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 8419b28defe6ac85dd8a52479cf276606beae24920eDRC { 8429b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC size=tjBufSizeYUV(width, height, jpegSubsamp); 8439b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height, 8449b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp, flags); 8459b28defe6ac85dd8a52479cf276606beae24920eDRC } 8469b28defe6ac85dd8a52479cf276606beae24920eDRC else 8479b28defe6ac85dd8a52479cf276606beae24920eDRC { 8489b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjCompress2(handle, srcBuf, width, pitch, height, 8499b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegSubsamp, jpegQual, 85025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC flags|TJFLAG_NOREALLOC); 8519b28defe6ac85dd8a52479cf276606beae24920eDRC } 8529b28defe6ac85dd8a52479cf276606beae24920eDRC *jpegSize=size; 8539b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 8549b28defe6ac85dd8a52479cf276606beae24920eDRC} 8559b28defe6ac85dd8a52479cf276606beae24920eDRC 8569b28defe6ac85dd8a52479cf276606beae24920eDRC 8576eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, 8586eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *srcBuf, int width, int pitch, int height, 8596eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int pixelFormat, unsigned char **dstPlanes, int *strides, int subsamp, 8606eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int flags) 8612e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 86291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC int i, retval=0; JSAMPROW *row_pointer=NULL; 863fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; 864fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; 865fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *outbuf[MAX_COMPONENTS]; 86640dd3146cde2ba5036fe76a4f09e1125b4592347DRC int row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS]; 867aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC JSAMPLE *ptr; 8689b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr; 869afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 870afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 871afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 8722e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 873418616266582fa978d4d1950cf739bbdac7ebee5DRC getcinstance(handle); 874b51ee895d8266529af7f96cb24fba53df273d32eDRC 875fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 876fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 877fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf[i]=NULL; _tmpbuf[i]=NULL; 878fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; 879fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 880fbb674707e01a61e8b7083faa632dfd46c568b13DRC 881e2f8e694d0d1ec333c18d803cf0ba083e9feb1c0DRC if((this->init&COMPRESS)==0) 882aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjEncodeYUVPlanes(): Instance has not been initialized for compression"); 883e2f8e694d0d1ec333c18d803cf0ba083e9feb1c0DRC 8849b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 885aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC || pixelFormat>=TJ_NUMPF || !dstPlanes || !dstPlanes[0] || subsamp<0 886aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC || subsamp>=NUMSUBOPT) 887aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjEncodeYUVPlanes(): Invalid argument"); 888aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(subsamp!=TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) 889aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjEncodeYUVPlanes(): Invalid argument"); 8902e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8919b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 8929b28defe6ac85dd8a52479cf276606beae24920eDRC { 8939b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 89491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 89591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 896efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 8972e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 898cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC if(pixelFormat==TJPF_CMYK) 899aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels"); 900cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC 9019b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 9022e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 903afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 904230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK) 905afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 906afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); 907aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!rgbBuf) _throw("tjEncodeYUVPlanes(): Memory allocation failure"); 908afc06929e0a9cf64bdf50da30326076235df7b4fDRC srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); 909afc06929e0a9cf64bdf50da30326076235df7b4fDRC pitch=width*RGB_PIXELSIZE; 910afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 911afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 912afc06929e0a9cf64bdf50da30326076235df7b4fDRC 9139b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 9149b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 9152e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 916bec45b162bb77a57c147a9c44113af1968a79be4DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 917bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 918bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 9192e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 92073d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags)==-1) return -1; 9212e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 92238c9970b95f8f83769b5476a9d7e6062714c19f6DRC /* Execute only the parts of jpeg_start_compress() that we need. If we 92338c9970b95f8f83769b5476a9d7e6062714c19f6DRC were to call the whole jpeg_start_compress() function, then it would try 92438c9970b95f8f83769b5476a9d7e6062714c19f6DRC to write the file headers, which could overflow the output buffer if the 92538c9970b95f8f83769b5476a9d7e6062714c19f6DRC YUV image were very small. */ 92638c9970b95f8f83769b5476a9d7e6062714c19f6DRC if(cinfo->global_state!=CSTATE_START) 927aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjEncodeYUVPlanes(): libjpeg API is in the wrong state"); 92838c9970b95f8f83769b5476a9d7e6062714c19f6DRC (*cinfo->err->reset_error_mgr)((j_common_ptr)cinfo); 92938c9970b95f8f83769b5476a9d7e6062714c19f6DRC jinit_c_master_control(cinfo, FALSE); 93038c9970b95f8f83769b5476a9d7e6062714c19f6DRC jinit_color_converter(cinfo); 93138c9970b95f8f83769b5476a9d7e6062714c19f6DRC jinit_downsampler(cinfo); 93250cfc464b8fdee7f7388ef14284c632b553c2f4aDRC (*cinfo->cconvert->start_pass)(cinfo); 93338c9970b95f8f83769b5476a9d7e6062714c19f6DRC 93440dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw0=PAD(width, cinfo->max_h_samp_factor); 93540dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph0=PAD(height, cinfo->max_v_samp_factor); 9369b28defe6ac85dd8a52479cf276606beae24920eDRC 93740dd3146cde2ba5036fe76a4f09e1125b4592347DRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph0))==NULL) 938aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjEncodeYUVPlanes(): Memory allocation failure"); 9399b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 9402e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC { 9416eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(flags&TJFLAG_BOTTOMUP) 9426eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch]; 9436eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch]; 9449b28defe6ac85dd8a52479cf276606beae24920eDRC } 94540dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(height<ph0) 94640dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1]; 947fbb674707e01a61e8b7083faa632dfd46c568b13DRC 9489b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<cinfo->num_components; i++) 9499b28defe6ac85dd8a52479cf276606beae24920eDRC { 9509b28defe6ac85dd8a52479cf276606beae24920eDRC compptr=&cinfo->comp_info[i]; 9519b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf[i]=(JSAMPLE *)malloc( 9529b28defe6ac85dd8a52479cf276606beae24920eDRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 9539b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16); 954aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!_tmpbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure"); 9559b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor); 956aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!tmpbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure"); 9579b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<cinfo->max_v_samp_factor; row++) 958fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 9599b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf_aligned= 9609b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf[i], 16); 9619b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=&_tmpbuf_aligned[ 962fbb674707e01a61e8b7083faa632dfd46c568b13DRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 9639b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * row]; 964fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 9659b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16) 9669b28defe6ac85dd8a52479cf276606beae24920eDRC * compptr->v_samp_factor + 16); 967aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!_tmpbuf2[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure"); 9689b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor); 969aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!tmpbuf2[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure"); 9709b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<compptr->v_samp_factor; row++) 971fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 9729b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf2_aligned= 9739b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf2[i], 16); 9749b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i][row]=&_tmpbuf2_aligned[ 9759b28defe6ac85dd8a52479cf276606beae24920eDRC PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]; 976fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 97740dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw[i]=pw0*compptr->h_samp_factor/cinfo->max_h_samp_factor; 97840dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph[i]=ph0*compptr->v_samp_factor/cinfo->max_v_samp_factor; 97940dd3146cde2ba5036fe76a4f09e1125b4592347DRC outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]); 980aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!outbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure"); 981aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC ptr=dstPlanes[i]; 98240dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(row=0; row<ph[i]; row++) 983fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 9849b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 98540dd3146cde2ba5036fe76a4f09e1125b4592347DRC ptr+=(strides && strides[i]!=0)? strides[i]:pw[i]; 986fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 9876ee54594591d0ae958b81adc8ba3cacde522e5e3DRC } 9889b28defe6ac85dd8a52479cf276606beae24920eDRC 98940dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(row=0; row<ph0; row+=cinfo->max_v_samp_factor) 9909b28defe6ac85dd8a52479cf276606beae24920eDRC { 9919b28defe6ac85dd8a52479cf276606beae24920eDRC (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, 0, 9929b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->max_v_samp_factor); 9939b28defe6ac85dd8a52479cf276606beae24920eDRC (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0); 9949b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++, compptr++) 9959b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], 9969b28defe6ac85dd8a52479cf276606beae24920eDRC row*compptr->v_samp_factor/cinfo->max_v_samp_factor, 99740dd3146cde2ba5036fe76a4f09e1125b4592347DRC compptr->v_samp_factor, pw[i]); 9989b28defe6ac85dd8a52479cf276606beae24920eDRC } 9999b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->next_scanline+=height; 10009b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_compress(cinfo); 10012e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 100291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 10039b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 1004afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1005ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 1006afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 10072e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC if(row_pointer) free(row_pointer); 1008fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 1009fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 1010fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf[i]!=NULL) free(tmpbuf[i]); 101157423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); 1012fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); 101357423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); 1014fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(outbuf[i]!=NULL) free(outbuf[i]); 1015fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 10161f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(this->jerr.warning) retval=-1; 101791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 10182e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 10192e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 10206eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, 10216eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *srcBuf, int width, int pitch, int height, 10226eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int pixelFormat, unsigned char *dstBuf, int pad, int subsamp, int flags) 1023aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC{ 1024aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC unsigned char *dstPlanes[3]; 102540dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw0, ph0, strides[3], retval=-1; 1026aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1027aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(width<=0 || height<=0 || dstBuf==NULL || pad<0 || !isPow2(pad) 1028aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC || subsamp<0 || subsamp>=NUMSUBOPT) 1029aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjEncodeYUV3(): Invalid argument"); 1030aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 103140dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw0=tjPlaneWidth(0, width, subsamp); 103240dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph0=tjPlaneHeight(0, height, subsamp); 1033aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC dstPlanes[0]=dstBuf; 103440dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[0]=PAD(pw0, pad); 103540dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(subsamp==TJSAMP_GRAY) 103640dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 103740dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[1]=strides[2]=0; 103840dd3146cde2ba5036fe76a4f09e1125b4592347DRC dstPlanes[1]=dstPlanes[2]=NULL; 103940dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 104040dd3146cde2ba5036fe76a4f09e1125b4592347DRC else 104140dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 104240dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw1=tjPlaneWidth(1, width, subsamp); 104340dd3146cde2ba5036fe76a4f09e1125b4592347DRC int ph1=tjPlaneHeight(1, height, subsamp); 104440dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[1]=strides[2]=PAD(pw1, pad); 104540dd3146cde2ba5036fe76a4f09e1125b4592347DRC dstPlanes[1]=dstPlanes[0]+strides[0]*ph0; 104640dd3146cde2ba5036fe76a4f09e1125b4592347DRC dstPlanes[2]=dstPlanes[1]+strides[1]*ph1; 104740dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 1048aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1049aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC return tjEncodeYUVPlanes(handle, srcBuf, width, pitch, height, pixelFormat, 1050aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC dstPlanes, strides, subsamp, flags); 1051aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1052aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC bailout: 1053aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC return retval; 1054aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC} 1055aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1056f610d61fcc38b36a8a29879e5c053015164242f8DRCDLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, 1057f610d61fcc38b36a8a29879e5c053015164242f8DRC int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, 1058f610d61fcc38b36a8a29879e5c053015164242f8DRC int subsamp, int flags) 1059f610d61fcc38b36a8a29879e5c053015164242f8DRC{ 1060f610d61fcc38b36a8a29879e5c053015164242f8DRC return tjEncodeYUV3(handle, srcBuf, width, pitch, height, pixelFormat, 1061f610d61fcc38b36a8a29879e5c053015164242f8DRC dstBuf, 4, subsamp, flags); 1062f610d61fcc38b36a8a29879e5c053015164242f8DRC} 1063f610d61fcc38b36a8a29879e5c053015164242f8DRC 10649b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, 10659b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, 10669b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 1067842416034561f6d5320165a4fe98825e999a4a37DRC{ 10689b28defe6ac85dd8a52479cf276606beae24920eDRC return tjEncodeYUV2(handle, srcBuf, width, pitch, height, 10699b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags); 1070842416034561f6d5320165a4fe98825e999a4a37DRC} 1071842416034561f6d5320165a4fe98825e999a4a37DRC 1072842416034561f6d5320165a4fe98825e999a4a37DRC 1073aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRCDLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle, 10746eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char **srcPlanes, int width, const int *strides, int height, 10756eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int subsamp, unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQual, 10766eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int flags) 1077910a35725cb52913c248f39e3f273a4baadbd7ddDRC{ 1078910a35725cb52913c248f39e3f273a4baadbd7ddDRC int i, row, retval=0, alloc=1; JSAMPROW *inbuf[MAX_COMPONENTS]; 107940dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS], 1080910a35725cb52913c248f39e3f273a4baadbd7ddDRC tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; 1081aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC JSAMPLE *_tmpbuf=NULL, *ptr; JSAMPROW *tmpbuf[MAX_COMPONENTS]; 1082910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1083418616266582fa978d4d1950cf739bbdac7ebee5DRC getcinstance(handle) 1084b51ee895d8266529af7f96cb24fba53df273d32eDRC 1085910a35725cb52913c248f39e3f273a4baadbd7ddDRC for(i=0; i<MAX_COMPONENTS; i++) 1086910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1087910a35725cb52913c248f39e3f273a4baadbd7ddDRC tmpbuf[i]=NULL; inbuf[i]=NULL; 1088910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1089910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1090910a35725cb52913c248f39e3f273a4baadbd7ddDRC if((this->init&COMPRESS)==0) 1091aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjCompressFromYUVPlanes(): Instance has not been initialized for compression"); 1092910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1093aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!srcPlanes || !srcPlanes[0] || width<=0 || height<=0 || subsamp<0 1094910a35725cb52913c248f39e3f273a4baadbd7ddDRC || subsamp>=NUMSUBOPT || jpegBuf==NULL || jpegSize==NULL || jpegQual<0 1095910a35725cb52913c248f39e3f273a4baadbd7ddDRC || jpegQual>100) 1096aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjCompressFromYUVPlanes(): Invalid argument"); 1097aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(subsamp!=TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2])) 1098aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjCompressFromYUVPlanes(): Invalid argument"); 1099910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1100910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(setjmp(this->jerr.setjmp_buffer)) 1101910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1102910a35725cb52913c248f39e3f273a4baadbd7ddDRC /* If we get here, the JPEG code has signaled an error. */ 1103910a35725cb52913c248f39e3f273a4baadbd7ddDRC retval=-1; 1104910a35725cb52913c248f39e3f273a4baadbd7ddDRC goto bailout; 1105910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1106910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1107910a35725cb52913c248f39e3f273a4baadbd7ddDRC cinfo->image_width=width; 1108910a35725cb52913c248f39e3f273a4baadbd7ddDRC cinfo->image_height=height; 1109910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1110bec45b162bb77a57c147a9c44113af1968a79be4DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 1111bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 1112bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 1113910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1114910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(flags&TJFLAG_NOREALLOC) 1115910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1116910a35725cb52913c248f39e3f273a4baadbd7ddDRC alloc=0; *jpegSize=tjBufSize(width, height, subsamp); 1117910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1118910a35725cb52913c248f39e3f273a4baadbd7ddDRC jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); 1119910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(setCompDefaults(cinfo, TJPF_RGB, subsamp, jpegQual, flags)==-1) 1120910a35725cb52913c248f39e3f273a4baadbd7ddDRC return -1; 1121910a35725cb52913c248f39e3f273a4baadbd7ddDRC cinfo->raw_data_in=TRUE; 1122910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1123910a35725cb52913c248f39e3f273a4baadbd7ddDRC jpeg_start_compress(cinfo, TRUE); 1124910a35725cb52913c248f39e3f273a4baadbd7ddDRC for(i=0; i<cinfo->num_components; i++) 1125910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1126910a35725cb52913c248f39e3f273a4baadbd7ddDRC jpeg_component_info *compptr=&cinfo->comp_info[i]; 1127910a35725cb52913c248f39e3f273a4baadbd7ddDRC int ih; 1128910a35725cb52913c248f39e3f273a4baadbd7ddDRC iw[i]=compptr->width_in_blocks*DCTSIZE; 1129910a35725cb52913c248f39e3f273a4baadbd7ddDRC ih=compptr->height_in_blocks*DCTSIZE; 113040dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw[i]=PAD(cinfo->image_width, cinfo->max_h_samp_factor) 1131910a35725cb52913c248f39e3f273a4baadbd7ddDRC *compptr->h_samp_factor/cinfo->max_h_samp_factor; 113240dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph[i]=PAD(cinfo->image_height, cinfo->max_v_samp_factor) 1133910a35725cb52913c248f39e3f273a4baadbd7ddDRC *compptr->v_samp_factor/cinfo->max_v_samp_factor; 113440dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(iw[i]!=pw[i] || ih!=ph[i]) usetmpbuf=1; 1135910a35725cb52913c248f39e3f273a4baadbd7ddDRC th[i]=compptr->v_samp_factor*DCTSIZE; 1136910a35725cb52913c248f39e3f273a4baadbd7ddDRC tmpbufsize+=iw[i]*th[i]; 113740dd3146cde2ba5036fe76a4f09e1125b4592347DRC if((inbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]))==NULL) 1138aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjCompressFromYUVPlanes(): Memory allocation failure"); 11396eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis ptr=(JSAMPLE *)srcPlanes[i]; 114040dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(row=0; row<ph[i]; row++) 1141910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1142910a35725cb52913c248f39e3f273a4baadbd7ddDRC inbuf[i][row]=ptr; 114340dd3146cde2ba5036fe76a4f09e1125b4592347DRC ptr+=(strides && strides[i]!=0)? strides[i]:pw[i]; 1144910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1145910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1146910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(usetmpbuf) 1147910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1148910a35725cb52913c248f39e3f273a4baadbd7ddDRC if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL) 1149aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjCompressFromYUVPlanes(): Memory allocation failure"); 1150910a35725cb52913c248f39e3f273a4baadbd7ddDRC ptr=_tmpbuf; 1151910a35725cb52913c248f39e3f273a4baadbd7ddDRC for(i=0; i<cinfo->num_components; i++) 1152910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1153910a35725cb52913c248f39e3f273a4baadbd7ddDRC if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL) 1154aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjCompressFromYUVPlanes(): Memory allocation failure"); 1155910a35725cb52913c248f39e3f273a4baadbd7ddDRC for(row=0; row<th[i]; row++) 1156910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1157910a35725cb52913c248f39e3f273a4baadbd7ddDRC tmpbuf[i][row]=ptr; 1158910a35725cb52913c248f39e3f273a4baadbd7ddDRC ptr+=iw[i]; 1159910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1160910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1161910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1162910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1163910a35725cb52913c248f39e3f273a4baadbd7ddDRC for(row=0; row<(int)cinfo->image_height; 1164910a35725cb52913c248f39e3f273a4baadbd7ddDRC row+=cinfo->max_v_samp_factor*DCTSIZE) 1165910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1166910a35725cb52913c248f39e3f273a4baadbd7ddDRC JSAMPARRAY yuvptr[MAX_COMPONENTS]; 1167910a35725cb52913c248f39e3f273a4baadbd7ddDRC int crow[MAX_COMPONENTS]; 1168910a35725cb52913c248f39e3f273a4baadbd7ddDRC for(i=0; i<cinfo->num_components; i++) 1169910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1170910a35725cb52913c248f39e3f273a4baadbd7ddDRC jpeg_component_info *compptr=&cinfo->comp_info[i]; 1171910a35725cb52913c248f39e3f273a4baadbd7ddDRC crow[i]=row*compptr->v_samp_factor/cinfo->max_v_samp_factor; 1172910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(usetmpbuf) 1173910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1174910a35725cb52913c248f39e3f273a4baadbd7ddDRC int j, k; 117540dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(j=0; j<min(th[i], ph[i]-crow[i]); j++) 1176910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 117740dd3146cde2ba5036fe76a4f09e1125b4592347DRC memcpy(tmpbuf[i][j], inbuf[i][crow[i]+j], pw[i]); 1178006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC /* Duplicate last sample in row to fill out MCU */ 117940dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(k=pw[i]; k<iw[i]; k++) tmpbuf[i][j][k]=tmpbuf[i][j][pw[i]-1]; 1180910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1181006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC /* Duplicate last row to fill out MCU */ 118240dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(j=ph[i]-crow[i]; j<th[i]; j++) 118340dd3146cde2ba5036fe76a4f09e1125b4592347DRC memcpy(tmpbuf[i][j], tmpbuf[i][ph[i]-crow[i]-1], iw[i]); 1184910a35725cb52913c248f39e3f273a4baadbd7ddDRC yuvptr[i]=tmpbuf[i]; 1185910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1186910a35725cb52913c248f39e3f273a4baadbd7ddDRC else 1187910a35725cb52913c248f39e3f273a4baadbd7ddDRC yuvptr[i]=&inbuf[i][crow[i]]; 1188910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1189910a35725cb52913c248f39e3f273a4baadbd7ddDRC jpeg_write_raw_data(cinfo, yuvptr, cinfo->max_v_samp_factor*DCTSIZE); 1190910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1191910a35725cb52913c248f39e3f273a4baadbd7ddDRC jpeg_finish_compress(cinfo); 1192910a35725cb52913c248f39e3f273a4baadbd7ddDRC 1193910a35725cb52913c248f39e3f273a4baadbd7ddDRC bailout: 1194910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 1195910a35725cb52913c248f39e3f273a4baadbd7ddDRC for(i=0; i<MAX_COMPONENTS; i++) 1196910a35725cb52913c248f39e3f273a4baadbd7ddDRC { 1197910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(tmpbuf[i]) free(tmpbuf[i]); 1198910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(inbuf[i]) free(inbuf[i]); 1199910a35725cb52913c248f39e3f273a4baadbd7ddDRC } 1200910a35725cb52913c248f39e3f273a4baadbd7ddDRC if(_tmpbuf) free(_tmpbuf); 12011f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(this->jerr.warning) retval=-1; 1202910a35725cb52913c248f39e3f273a4baadbd7ddDRC return retval; 1203910a35725cb52913c248f39e3f273a4baadbd7ddDRC} 1204910a35725cb52913c248f39e3f273a4baadbd7ddDRC 12056eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, 12066eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *srcBuf, int width, int pad, int height, int subsamp, 12076eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQual, int flags) 1208aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC{ 12096eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *srcPlanes[3]; 121040dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw0, ph0, strides[3], retval=-1; 1211aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1212aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(srcBuf==NULL || width<=0 || pad<1 || height<=0 || subsamp<0 1213aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC || subsamp>=NUMSUBOPT) 1214aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjCompressFromYUV(): Invalid argument"); 1215aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 121640dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw0=tjPlaneWidth(0, width, subsamp); 121740dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph0=tjPlaneHeight(0, height, subsamp); 1218aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC srcPlanes[0]=srcBuf; 121940dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[0]=PAD(pw0, pad); 122040dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(subsamp==TJSAMP_GRAY) 122140dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 122240dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[1]=strides[2]=0; 122340dd3146cde2ba5036fe76a4f09e1125b4592347DRC srcPlanes[1]=srcPlanes[2]=NULL; 122440dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 122540dd3146cde2ba5036fe76a4f09e1125b4592347DRC else 122640dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 122740dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw1=tjPlaneWidth(1, width, subsamp); 122840dd3146cde2ba5036fe76a4f09e1125b4592347DRC int ph1=tjPlaneHeight(1, height, subsamp); 122940dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[1]=strides[2]=PAD(pw1, pad); 123040dd3146cde2ba5036fe76a4f09e1125b4592347DRC srcPlanes[1]=srcPlanes[0]+strides[0]*ph0; 123140dd3146cde2ba5036fe76a4f09e1125b4592347DRC srcPlanes[2]=srcPlanes[1]+strides[1]*ph1; 123240dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 1233aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1234aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC return tjCompressFromYUVPlanes(handle, srcPlanes, width, strides, height, 1235aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC subsamp, jpegBuf, jpegSize, jpegQual, flags); 1236aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1237aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC bailout: 1238aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC return retval; 1239aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC} 1240aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1241910a35725cb52913c248f39e3f273a4baadbd7ddDRC 12429b28defe6ac85dd8a52479cf276606beae24920eDRC/* Decompressor */ 12432e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 12449b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitDecompress(tjinstance *this) 12452e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 12466eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis static unsigned char buffer[1]; 12472e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 12489b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 12499b28defe6ac85dd8a52479cf276606beae24920eDRC this->dinfo.err=jpeg_std_error(&this->jerr.pub); 12509b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 12519b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 12521f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC this->jerr.emit_message=this->jerr.pub.emit_message; 12531f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC this->jerr.pub.emit_message=my_emit_message; 12542e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 12559b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 12569b28defe6ac85dd8a52479cf276606beae24920eDRC { 12579b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 12586eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(this) free(this); 12596eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis return NULL; 12609e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 12612e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 12629b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_decompress(&this->dinfo); 12639b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the source manager */ 12649b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(&this->dinfo, buffer, 1); 12652e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1266007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=DECOMPRESS; 12679b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 12682e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 12692e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1270890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitDecompress(void) 1271890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 12729b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this; 12739b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 1274da5220acdd525242bff4e40b1d90324ebb889825DRC { 1275007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 1276007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitDecompress(): Memory allocation failure"); 1277da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 1278da5220acdd525242bff4e40b1d90324ebb889825DRC } 1279007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 12809b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitDecompress(this); 1281890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 1282890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12832e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1284cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRCDLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle, 12856eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *jpegBuf, unsigned long jpegSize, int *width, 12866eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int *height, int *jpegSubsamp, int *jpegColorspace) 12871fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC{ 12889b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=0; 12891fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 1290418616266582fa978d4d1950cf739bbdac7ebee5DRC getdinstance(handle); 12919b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 1292cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC _throw("tjDecompressHeader3(): Instance has not been initialized for decompression"); 12931fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 12949b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL 1295cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC || jpegSubsamp==NULL || jpegColorspace==NULL) 1296cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC _throw("tjDecompressHeader3(): Invalid argument"); 12971fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 12989b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 12999b28defe6ac85dd8a52479cf276606beae24920eDRC { 13009b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 13011fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC return -1; 13021fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 13031fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 13049b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 13059b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 13061fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 13079b28defe6ac85dd8a52479cf276606beae24920eDRC *width=dinfo->image_width; 13089b28defe6ac85dd8a52479cf276606beae24920eDRC *height=dinfo->image_height; 13099b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC *jpegSubsamp=getSubsamp(dinfo); 1310cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC switch(dinfo->jpeg_color_space) 1311cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC { 1312cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC case JCS_GRAYSCALE: *jpegColorspace=TJCS_GRAY; break; 1313cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC case JCS_RGB: *jpegColorspace=TJCS_RGB; break; 1314cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC case JCS_YCbCr: *jpegColorspace=TJCS_YCbCr; break; 1315cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC case JCS_CMYK: *jpegColorspace=TJCS_CMYK; break; 1316cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC case JCS_YCCK: *jpegColorspace=TJCS_YCCK; break; 1317cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC default: *jpegColorspace=-1; break; 1318cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC } 13191fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 13209b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_decompress(dinfo); 13211fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 13229b28defe6ac85dd8a52479cf276606beae24920eDRC if(*jpegSubsamp<0) 1323cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC _throw("tjDecompressHeader3(): Could not determine subsampling type for JPEG image"); 1324cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC if(*jpegColorspace<0) 1325cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC _throw("tjDecompressHeader3(): Could not determine colorspace of JPEG image"); 1326007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(*width<1 || *height<1) 1327cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC _throw("tjDecompressHeader3(): Invalid data returned in header"); 132891e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 132991e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 13301f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(this->jerr.warning) retval=-1; 133191e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 133291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC} 133391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 1334cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRCDLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, 1335cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, 1336cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC int *jpegSubsamp) 1337cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC{ 1338cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC int jpegColorspace; 1339cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC return tjDecompressHeader3(handle, jpegBuf, jpegSize, width, height, 1340cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC jpegSubsamp, &jpegColorspace); 1341cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC} 1342cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC 13439b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, 13449b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height) 134591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC{ 13469b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegSubsamp; 13479b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, 13489b28defe6ac85dd8a52479cf276606beae24920eDRC &jpegSubsamp); 13491fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC} 13501fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 13511fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 1352109a578e89ea8cd2c39d50b012698148dd11dedbDRCDLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors) 1353b28fc5710a510410d2b498255a423dd62b353b3aDRC{ 1354109a578e89ea8cd2c39d50b012698148dd11dedbDRC if(numscalingfactors==NULL) 1355b28fc5710a510410d2b498255a423dd62b353b3aDRC { 13569b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 1357007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjGetScalingFactors(): Invalid argument"); 1358109a578e89ea8cd2c39d50b012698148dd11dedbDRC return NULL; 1359b28fc5710a510410d2b498255a423dd62b353b3aDRC } 1360b28fc5710a510410d2b498255a423dd62b353b3aDRC 1361109a578e89ea8cd2c39d50b012698148dd11dedbDRC *numscalingfactors=NUMSF; 1362109a578e89ea8cd2c39d50b012698148dd11dedbDRC return (tjscalingfactor *)sf; 1363b28fc5710a510410d2b498255a423dd62b353b3aDRC} 1364b28fc5710a510410d2b498255a423dd62b353b3aDRC 1365b28fc5710a510410d2b498255a423dd62b353b3aDRC 13666eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, 13676eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, 13686eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int width, int pitch, int height, int pixelFormat, int flags) 13699b28defe6ac85dd8a52479cf276606beae24920eDRC{ 13709b28defe6ac85dd8a52479cf276606beae24920eDRC int i, retval=0; JSAMPROW *row_pointer=NULL; 13719b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegwidth, jpegheight, scaledw, scaledh; 1372afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1373afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 1374afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *_dstBuf=NULL; int _pitch=0; 1375afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 13769b28defe6ac85dd8a52479cf276606beae24920eDRC 1377418616266582fa978d4d1950cf739bbdac7ebee5DRC getdinstance(handle); 13789b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 1379007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Instance has not been initialized for decompression"); 13809b28defe6ac85dd8a52479cf276606beae24920eDRC 13819b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 13829b28defe6ac85dd8a52479cf276606beae24920eDRC || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) 13839b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompress2(): Invalid argument"); 13849b28defe6ac85dd8a52479cf276606beae24920eDRC 1385bec45b162bb77a57c147a9c44113af1968a79be4DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 1386bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 1387bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 13889b28defe6ac85dd8a52479cf276606beae24920eDRC 13899b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 13909b28defe6ac85dd8a52479cf276606beae24920eDRC { 13919b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 13929b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 13939b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 13949b28defe6ac85dd8a52479cf276606beae24920eDRC } 13959b28defe6ac85dd8a52479cf276606beae24920eDRC 13969b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 13979b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 139873d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(setDecompDefaults(dinfo, pixelFormat, flags)==-1) 13992eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC { 14002eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC retval=-1; goto bailout; 14012eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC } 14029b28defe6ac85dd8a52479cf276606beae24920eDRC 140325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 14049b28defe6ac85dd8a52479cf276606beae24920eDRC 14059b28defe6ac85dd8a52479cf276606beae24920eDRC jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; 14069b28defe6ac85dd8a52479cf276606beae24920eDRC if(width==0) width=jpegwidth; 14079b28defe6ac85dd8a52479cf276606beae24920eDRC if(height==0) height=jpegheight; 14089b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<NUMSF; i++) 14099b28defe6ac85dd8a52479cf276606beae24920eDRC { 14109b28defe6ac85dd8a52479cf276606beae24920eDRC scaledw=TJSCALED(jpegwidth, sf[i]); 14119b28defe6ac85dd8a52479cf276606beae24920eDRC scaledh=TJSCALED(jpegheight, sf[i]); 14129b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw<=width && scaledh<=height) 1413f610d61fcc38b36a8a29879e5c053015164242f8DRC break; 14149b28defe6ac85dd8a52479cf276606beae24920eDRC } 141558ae401e503ac61babb9d66be8fc06bfb0445dbfDRC if(i>=NUMSF) 1416007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Could not scale down to desired image dimensions"); 14179b28defe6ac85dd8a52479cf276606beae24920eDRC width=scaledw; height=scaledh; 14189b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_num=sf[i].num; 14199b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_denom=sf[i].denom; 14209b28defe6ac85dd8a52479cf276606beae24920eDRC 14219b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 14229b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; 1423afc06929e0a9cf64bdf50da30326076235df7b4fDRC 1424afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1425230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK && 1426afc06929e0a9cf64bdf50da30326076235df7b4fDRC (RGB_RED!=tjRedOffset[pixelFormat] || 1427afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_GREEN!=tjGreenOffset[pixelFormat] || 1428afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_BLUE!=tjBlueOffset[pixelFormat] || 1429afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) 1430afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 1431afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*3); 1432afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure"); 1433afc06929e0a9cf64bdf50da30326076235df7b4fDRC _pitch=pitch; pitch=width*3; 1434afc06929e0a9cf64bdf50da30326076235df7b4fDRC _dstBuf=dstBuf; dstBuf=rgbBuf; 1435afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 1436afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 1437afc06929e0a9cf64bdf50da30326076235df7b4fDRC 14389b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) 14399b28defe6ac85dd8a52479cf276606beae24920eDRC *dinfo->output_height))==NULL) 1440007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Memory allocation failure"); 14419b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<(int)dinfo->output_height; i++) 14429b28defe6ac85dd8a52479cf276606beae24920eDRC { 144325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) 14449b28defe6ac85dd8a52479cf276606beae24920eDRC row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]; 14459b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&dstBuf[i*pitch]; 14469b28defe6ac85dd8a52479cf276606beae24920eDRC } 14479b28defe6ac85dd8a52479cf276606beae24920eDRC while(dinfo->output_scanline<dinfo->output_height) 14489b28defe6ac85dd8a52479cf276606beae24920eDRC { 14499b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], 14509b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->output_height-dinfo->output_scanline); 14519b28defe6ac85dd8a52479cf276606beae24920eDRC } 14529b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 14539b28defe6ac85dd8a52479cf276606beae24920eDRC 1454afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1455afc06929e0a9cf64bdf50da30326076235df7b4fDRC fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); 1456afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 1457afc06929e0a9cf64bdf50da30326076235df7b4fDRC 14589b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 14599b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 1460afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1461ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 1462afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 14639b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 14641f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(this->jerr.warning) retval=-1; 14659b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 14669b28defe6ac85dd8a52479cf276606beae24920eDRC} 14679b28defe6ac85dd8a52479cf276606beae24920eDRC 14689b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, 14699b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 14709b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelSize, int flags) 14719b28defe6ac85dd8a52479cf276606beae24920eDRC{ 14729b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 14739b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags); 14749b28defe6ac85dd8a52479cf276606beae24920eDRC else 14759b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch, 14769b28defe6ac85dd8a52479cf276606beae24920eDRC height, getPixelFormat(pixelSize, flags), flags); 14779b28defe6ac85dd8a52479cf276606beae24920eDRC} 14789b28defe6ac85dd8a52479cf276606beae24920eDRC 14799b28defe6ac85dd8a52479cf276606beae24920eDRC 148034dca052271f4a75b3c0f7b11a2c5024159628d4DRCstatic int setDecodeDefaults(struct jpeg_decompress_struct *dinfo, 148134dca052271f4a75b3c0f7b11a2c5024159628d4DRC int pixelFormat, int subsamp, int flags) 148234dca052271f4a75b3c0f7b11a2c5024159628d4DRC{ 1483895fd6d0d370d64df9dbb1bc53342c734a6933fcDRC int i; 1484895fd6d0d370d64df9dbb1bc53342c734a6933fcDRC 148534dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->scale_num=dinfo->scale_denom=1; 148634dca052271f4a75b3c0f7b11a2c5024159628d4DRC 148734dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(subsamp==TJSAMP_GRAY) 148834dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 1489c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC dinfo->num_components=dinfo->comps_in_scan=1; 149034dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->jpeg_color_space=JCS_GRAYSCALE; 149134dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 149234dca052271f4a75b3c0f7b11a2c5024159628d4DRC else 149334dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 1494c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC dinfo->num_components=dinfo->comps_in_scan=3; 149534dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->jpeg_color_space=JCS_YCbCr; 149634dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 149734dca052271f4a75b3c0f7b11a2c5024159628d4DRC 149834dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->comp_info=(jpeg_component_info *) 149934dca052271f4a75b3c0f7b11a2c5024159628d4DRC (*dinfo->mem->alloc_small)((j_common_ptr)dinfo, JPOOL_IMAGE, 15005de454b291f48382648a5d1dc2aa0fca8b5786d4DRC dinfo->num_components*sizeof(jpeg_component_info)); 150134dca052271f4a75b3c0f7b11a2c5024159628d4DRC 15022bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC for(i=0; i<dinfo->num_components; i++) 150334dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 15042bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 15052bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC compptr->h_samp_factor=(i==0)? tjMCUWidth[subsamp]/8:1; 15062bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC compptr->v_samp_factor=(i==0)? tjMCUHeight[subsamp]/8:1; 15072bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC compptr->component_index=i; 150815c0876191b927cbe4d797b9ef89b51b08a12cc2DRC compptr->component_id=i+1; 15092bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC compptr->quant_tbl_no=compptr->dc_tbl_no=compptr->ac_tbl_no= 15102bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC (i==0)? 0:1; 15112bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC dinfo->cur_comp_info[i]=compptr; 151234dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 1513c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC dinfo->data_precision=8; 1514c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC for(i=0; i<2; i++) 1515c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC { 1516c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC if(dinfo->quant_tbl_ptrs[i]==NULL) 1517c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC dinfo->quant_tbl_ptrs[i]=jpeg_alloc_quant_table((j_common_ptr)dinfo); 1518c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC } 151934dca052271f4a75b3c0f7b11a2c5024159628d4DRC 152034dca052271f4a75b3c0f7b11a2c5024159628d4DRC return 0; 152134dca052271f4a75b3c0f7b11a2c5024159628d4DRC} 152234dca052271f4a75b3c0f7b11a2c5024159628d4DRC 152334dca052271f4a75b3c0f7b11a2c5024159628d4DRC 152434dca052271f4a75b3c0f7b11a2c5024159628d4DRCint my_read_markers(j_decompress_ptr dinfo) 152534dca052271f4a75b3c0f7b11a2c5024159628d4DRC{ 152634dca052271f4a75b3c0f7b11a2c5024159628d4DRC return JPEG_REACHED_SOS; 152734dca052271f4a75b3c0f7b11a2c5024159628d4DRC} 152834dca052271f4a75b3c0f7b11a2c5024159628d4DRC 152934dca052271f4a75b3c0f7b11a2c5024159628d4DRCvoid my_reset_marker_reader(j_decompress_ptr dinfo) 153034dca052271f4a75b3c0f7b11a2c5024159628d4DRC{ 153134dca052271f4a75b3c0f7b11a2c5024159628d4DRC} 153234dca052271f4a75b3c0f7b11a2c5024159628d4DRC 1533aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRCDLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, 15346eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char **srcPlanes, const int *strides, int subsamp, 15356eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat, 15366eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis int flags) 153734dca052271f4a75b3c0f7b11a2c5024159628d4DRC{ 153834dca052271f4a75b3c0f7b11a2c5024159628d4DRC int i, retval=0; JSAMPROW *row_pointer=NULL; 153934dca052271f4a75b3c0f7b11a2c5024159628d4DRC JSAMPLE *_tmpbuf[MAX_COMPONENTS]; 154034dca052271f4a75b3c0f7b11a2c5024159628d4DRC JSAMPROW *tmpbuf[MAX_COMPONENTS], *inbuf[MAX_COMPONENTS]; 154140dd3146cde2ba5036fe76a4f09e1125b4592347DRC int row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS]; 1542aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC JSAMPLE *ptr; 154334dca052271f4a75b3c0f7b11a2c5024159628d4DRC jpeg_component_info *compptr; 154434dca052271f4a75b3c0f7b11a2c5024159628d4DRC #ifndef JCS_EXTENSIONS 154534dca052271f4a75b3c0f7b11a2c5024159628d4DRC unsigned char *rgbBuf=NULL; 1546230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC unsigned char *_dstBuf=NULL; int _pitch=0; 154734dca052271f4a75b3c0f7b11a2c5024159628d4DRC #endif 1548bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC int (*old_read_markers)(j_decompress_ptr); 1549bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC void (*old_reset_marker_reader)(j_decompress_ptr); 155034dca052271f4a75b3c0f7b11a2c5024159628d4DRC 1551418616266582fa978d4d1950cf739bbdac7ebee5DRC getdinstance(handle); 155234dca052271f4a75b3c0f7b11a2c5024159628d4DRC 155334dca052271f4a75b3c0f7b11a2c5024159628d4DRC for(i=0; i<MAX_COMPONENTS; i++) 155434dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 155534dca052271f4a75b3c0f7b11a2c5024159628d4DRC tmpbuf[i]=NULL; _tmpbuf[i]=NULL; inbuf[i]=NULL; 155634dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 155734dca052271f4a75b3c0f7b11a2c5024159628d4DRC 155834dca052271f4a75b3c0f7b11a2c5024159628d4DRC if((this->init&DECOMPRESS)==0) 1559aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecodeYUVPlanes(): Instance has not been initialized for decompression"); 156034dca052271f4a75b3c0f7b11a2c5024159628d4DRC 1561aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!srcPlanes || !srcPlanes[0] || subsamp<0 || subsamp>=NUMSUBOPT 156234dca052271f4a75b3c0f7b11a2c5024159628d4DRC || dstBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 156334dca052271f4a75b3c0f7b11a2c5024159628d4DRC || pixelFormat>=TJ_NUMPF) 1564aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecodeYUVPlanes(): Invalid argument"); 1565aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(subsamp!=TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2])) 1566aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecodeYUVPlanes(): Invalid argument"); 156734dca052271f4a75b3c0f7b11a2c5024159628d4DRC 156834dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(setjmp(this->jerr.setjmp_buffer)) 156934dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 157034dca052271f4a75b3c0f7b11a2c5024159628d4DRC /* If we get here, the JPEG code has signaled an error. */ 157134dca052271f4a75b3c0f7b11a2c5024159628d4DRC retval=-1; 157234dca052271f4a75b3c0f7b11a2c5024159628d4DRC goto bailout; 157334dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 157434dca052271f4a75b3c0f7b11a2c5024159628d4DRC 157534dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(pixelFormat==TJPF_CMYK) 1576aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK pixels."); 157734dca052271f4a75b3c0f7b11a2c5024159628d4DRC 157834dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 157934dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->image_width=width; 158034dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->image_height=height; 158134dca052271f4a75b3c0f7b11a2c5024159628d4DRC 1582bec45b162bb77a57c147a9c44113af1968a79be4DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 1583bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 1584bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 158534dca052271f4a75b3c0f7b11a2c5024159628d4DRC 158634dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(setDecodeDefaults(dinfo, pixelFormat, subsamp, flags)==-1) 158734dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 158834dca052271f4a75b3c0f7b11a2c5024159628d4DRC retval=-1; goto bailout; 158934dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 159034dca052271f4a75b3c0f7b11a2c5024159628d4DRC old_read_markers=dinfo->marker->read_markers; 159134dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->marker->read_markers=my_read_markers; 159234dca052271f4a75b3c0f7b11a2c5024159628d4DRC old_reset_marker_reader=dinfo->marker->reset_marker_reader; 159334dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->marker->reset_marker_reader=my_reset_marker_reader; 159434dca052271f4a75b3c0f7b11a2c5024159628d4DRC jpeg_read_header(dinfo, TRUE); 159534dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->marker->read_markers=old_read_markers; 159634dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->marker->reset_marker_reader=old_reset_marker_reader; 159734dca052271f4a75b3c0f7b11a2c5024159628d4DRC 159834dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(setDecompDefaults(dinfo, pixelFormat, flags)==-1) 159934dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 160034dca052271f4a75b3c0f7b11a2c5024159628d4DRC retval=-1; goto bailout; 160134dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 16027d9f758e5251e129431b03cdab1160710d4b3fb8DRC dinfo->do_fancy_upsampling=FALSE; 1603db6d8fca591c924ba3da8ef525925b92e261e66aDRC dinfo->Se=DCTSIZE2-1; 16042bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC jinit_master_decompress(dinfo); 160534dca052271f4a75b3c0f7b11a2c5024159628d4DRC (*dinfo->upsample->start_pass)(dinfo); 160634dca052271f4a75b3c0f7b11a2c5024159628d4DRC 160740dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw0=PAD(width, dinfo->max_h_samp_factor); 160840dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph0=PAD(height, dinfo->max_v_samp_factor); 160934dca052271f4a75b3c0f7b11a2c5024159628d4DRC 161034dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; 161134dca052271f4a75b3c0f7b11a2c5024159628d4DRC 1612230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC #ifndef JCS_EXTENSIONS 1613230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK && 1614230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC (RGB_RED!=tjRedOffset[pixelFormat] || 1615230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC RGB_GREEN!=tjGreenOffset[pixelFormat] || 1616230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC RGB_BLUE!=tjBlueOffset[pixelFormat] || 1617230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) 1618230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC { 1619230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC rgbBuf=(unsigned char *)malloc(width*height*3); 1620aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!rgbBuf) _throw("tjDecodeYUVPlanes(): Memory allocation failure"); 1621230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC _pitch=pitch; pitch=width*3; 1622230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC _dstBuf=dstBuf; dstBuf=rgbBuf; 1623230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC } 1624230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC #endif 1625230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC 162640dd3146cde2ba5036fe76a4f09e1125b4592347DRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph0))==NULL) 1627aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecodeYUVPlanes(): Memory allocation failure"); 162834dca052271f4a75b3c0f7b11a2c5024159628d4DRC for(i=0; i<height; i++) 162934dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 163034dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&dstBuf[(height-i-1)*pitch]; 163134dca052271f4a75b3c0f7b11a2c5024159628d4DRC else row_pointer[i]=&dstBuf[i*pitch]; 163234dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 163340dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(height<ph0) 163440dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1]; 163534dca052271f4a75b3c0f7b11a2c5024159628d4DRC 163634dca052271f4a75b3c0f7b11a2c5024159628d4DRC for(i=0; i<dinfo->num_components; i++) 163734dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 163834dca052271f4a75b3c0f7b11a2c5024159628d4DRC compptr=&dinfo->comp_info[i]; 163934dca052271f4a75b3c0f7b11a2c5024159628d4DRC _tmpbuf[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16) 164034dca052271f4a75b3c0f7b11a2c5024159628d4DRC * compptr->v_samp_factor + 16); 1641aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!_tmpbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation failure"); 164234dca052271f4a75b3c0f7b11a2c5024159628d4DRC tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor); 1643aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!tmpbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation failure"); 164434dca052271f4a75b3c0f7b11a2c5024159628d4DRC for(row=0; row<compptr->v_samp_factor; row++) 164534dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 164634dca052271f4a75b3c0f7b11a2c5024159628d4DRC unsigned char *_tmpbuf_aligned= 164734dca052271f4a75b3c0f7b11a2c5024159628d4DRC (unsigned char *)PAD((size_t)_tmpbuf[i], 16); 164834dca052271f4a75b3c0f7b11a2c5024159628d4DRC tmpbuf[i][row]=&_tmpbuf_aligned[ 164934dca052271f4a75b3c0f7b11a2c5024159628d4DRC PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]; 165034dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 165140dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw[i]=pw0*compptr->h_samp_factor/dinfo->max_h_samp_factor; 165240dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph[i]=ph0*compptr->v_samp_factor/dinfo->max_v_samp_factor; 165340dd3146cde2ba5036fe76a4f09e1125b4592347DRC inbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]); 1654aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!inbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation failure"); 16556eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis ptr=(JSAMPLE *)srcPlanes[i]; 165640dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(row=0; row<ph[i]; row++) 165734dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 165834dca052271f4a75b3c0f7b11a2c5024159628d4DRC inbuf[i][row]=ptr; 165940dd3146cde2ba5036fe76a4f09e1125b4592347DRC ptr+=(strides && strides[i]!=0)? strides[i]:pw[i]; 166034dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 166134dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 166234dca052271f4a75b3c0f7b11a2c5024159628d4DRC 166340dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(row=0; row<ph0; row+=dinfo->max_v_samp_factor) 166434dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 166534dca052271f4a75b3c0f7b11a2c5024159628d4DRC JDIMENSION inrow=0, outrow=0; 166634dca052271f4a75b3c0f7b11a2c5024159628d4DRC for(i=0, compptr=dinfo->comp_info; i<dinfo->num_components; i++, compptr++) 166734dca052271f4a75b3c0f7b11a2c5024159628d4DRC jcopy_sample_rows(inbuf[i], 166834dca052271f4a75b3c0f7b11a2c5024159628d4DRC row*compptr->v_samp_factor/dinfo->max_v_samp_factor, tmpbuf[i], 0, 166940dd3146cde2ba5036fe76a4f09e1125b4592347DRC compptr->v_samp_factor, pw[i]); 167034dca052271f4a75b3c0f7b11a2c5024159628d4DRC (dinfo->upsample->upsample)(dinfo, tmpbuf, &inrow, 167134dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->max_v_samp_factor, &row_pointer[row], &outrow, 167234dca052271f4a75b3c0f7b11a2c5024159628d4DRC dinfo->max_v_samp_factor); 167334dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 167434dca052271f4a75b3c0f7b11a2c5024159628d4DRC jpeg_abort_decompress(dinfo); 167534dca052271f4a75b3c0f7b11a2c5024159628d4DRC 1676230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC #ifndef JCS_EXTENSIONS 1677230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); 1678230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC #endif 1679230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC 168034dca052271f4a75b3c0f7b11a2c5024159628d4DRC bailout: 168134dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 168234dca052271f4a75b3c0f7b11a2c5024159628d4DRC #ifndef JCS_EXTENSIONS 168334dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(rgbBuf) free(rgbBuf); 168434dca052271f4a75b3c0f7b11a2c5024159628d4DRC #endif 168534dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(row_pointer) free(row_pointer); 168634dca052271f4a75b3c0f7b11a2c5024159628d4DRC for(i=0; i<MAX_COMPONENTS; i++) 168734dca052271f4a75b3c0f7b11a2c5024159628d4DRC { 168834dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(tmpbuf[i]!=NULL) free(tmpbuf[i]); 168934dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); 169034dca052271f4a75b3c0f7b11a2c5024159628d4DRC if(inbuf[i]!=NULL) free(inbuf[i]); 169134dca052271f4a75b3c0f7b11a2c5024159628d4DRC } 16921f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(this->jerr.warning) retval=-1; 169334dca052271f4a75b3c0f7b11a2c5024159628d4DRC return retval; 169434dca052271f4a75b3c0f7b11a2c5024159628d4DRC} 169534dca052271f4a75b3c0f7b11a2c5024159628d4DRC 16966eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, 1697aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC int pad, int subsamp, unsigned char *dstBuf, int width, int pitch, 1698aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC int height, int pixelFormat, int flags) 1699aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC{ 17006eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *srcPlanes[3]; 170140dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw0, ph0, strides[3], retval=-1; 170234dca052271f4a75b3c0f7b11a2c5024159628d4DRC 1703aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(srcBuf==NULL || pad<0 || !isPow2(pad) || subsamp<0 || subsamp>=NUMSUBOPT 1704aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC || width<=0 || height<=0) 1705aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecodeYUV(): Invalid argument"); 1706aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 170740dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw0=tjPlaneWidth(0, width, subsamp); 170840dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph0=tjPlaneHeight(0, height, subsamp); 1709aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC srcPlanes[0]=srcBuf; 171040dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[0]=PAD(pw0, pad); 171140dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(subsamp==TJSAMP_GRAY) 171240dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 171340dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[1]=strides[2]=0; 171440dd3146cde2ba5036fe76a4f09e1125b4592347DRC srcPlanes[1]=srcPlanes[2]=NULL; 171540dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 171640dd3146cde2ba5036fe76a4f09e1125b4592347DRC else 171740dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 171840dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw1=tjPlaneWidth(1, width, subsamp); 171940dd3146cde2ba5036fe76a4f09e1125b4592347DRC int ph1=tjPlaneHeight(1, height, subsamp); 172040dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[1]=strides[2]=PAD(pw1, pad); 172140dd3146cde2ba5036fe76a4f09e1125b4592347DRC srcPlanes[1]=srcPlanes[0]+strides[0]*ph0; 172240dd3146cde2ba5036fe76a4f09e1125b4592347DRC srcPlanes[2]=srcPlanes[1]+strides[1]*ph1; 172340dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 1724aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1725aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC return tjDecodeYUVPlanes(handle, srcPlanes, strides, subsamp, dstBuf, width, 1726aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC pitch, height, pixelFormat, flags); 1727aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1728aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC bailout: 1729aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC return retval; 1730aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC} 1731aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1732aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRCDLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle, 17336eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *jpegBuf, unsigned long jpegSize, 17346eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis unsigned char **dstPlanes, int width, int *strides, int height, int flags) 17352e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 1736f610d61fcc38b36a8a29879e5c053015164242f8DRC int i, sfi, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS]; 1737418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC int jpegwidth, jpegheight, jpegSubsamp, scaledw, scaledh; 173840dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS], 1739f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; 1740aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC JSAMPLE *_tmpbuf=NULL, *ptr; JSAMPROW *tmpbuf[MAX_COMPONENTS]; 1741418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC int dctsize; 17422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1743418616266582fa978d4d1950cf739bbdac7ebee5DRC getdinstance(handle); 1744b51ee895d8266529af7f96cb24fba53df273d32eDRC 1745f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<MAX_COMPONENTS; i++) 1746f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 1747f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbuf[i]=NULL; outbuf[i]=NULL; 1748f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 17499e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC 1750e2f8e694d0d1ec333c18d803cf0ba083e9feb1c0DRC if((this->init&DECOMPRESS)==0) 1751aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): Instance has not been initialized for decompression"); 1752e2f8e694d0d1ec333c18d803cf0ba083e9feb1c0DRC 1753aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(jpegBuf==NULL || jpegSize<=0 || !dstPlanes || !dstPlanes[0] || width<0 1754aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC || height<0) 1755aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): Invalid argument"); 17562e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1757bec45b162bb77a57c147a9c44113af1968a79be4DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 1758bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 1759bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 17600c6a271f974529e4795332c9ad428500ef17fb42DRC 17619b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 17629b28defe6ac85dd8a52479cf276606beae24920eDRC { 17639b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 176491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 176591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 17669e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 17672e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1768aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(!this->headerRead) 1769aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC { 1770aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 1771aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC jpeg_read_header(dinfo, TRUE); 1772aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC } 1773aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC this->headerRead=0; 1774418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC jpegSubsamp=getSubsamp(dinfo); 1775418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC if(jpegSubsamp<0) 1776aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): Could not determine subsampling type for JPEG image"); 1777aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1778aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(jpegSubsamp!=TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) 1779aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): Invalid argument"); 17802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1781f610d61fcc38b36a8a29879e5c053015164242f8DRC jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; 1782f610d61fcc38b36a8a29879e5c053015164242f8DRC if(width==0) width=jpegwidth; 1783f610d61fcc38b36a8a29879e5c053015164242f8DRC if(height==0) height=jpegheight; 1784f610d61fcc38b36a8a29879e5c053015164242f8DRC for(i=0; i<NUMSF; i++) 1785f610d61fcc38b36a8a29879e5c053015164242f8DRC { 1786f610d61fcc38b36a8a29879e5c053015164242f8DRC scaledw=TJSCALED(jpegwidth, sf[i]); 1787f610d61fcc38b36a8a29879e5c053015164242f8DRC scaledh=TJSCALED(jpegheight, sf[i]); 1788f610d61fcc38b36a8a29879e5c053015164242f8DRC if(scaledw<=width && scaledh<=height) 1789f610d61fcc38b36a8a29879e5c053015164242f8DRC break; 1790f610d61fcc38b36a8a29879e5c053015164242f8DRC } 179158ae401e503ac61babb9d66be8fc06bfb0445dbfDRC if(i>=NUMSF) 1792aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): Could not scale down to desired image dimensions"); 1793cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC if(dinfo->num_components>3) 1794aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): JPEG image must have 3 or fewer components"); 1795cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC 1796f610d61fcc38b36a8a29879e5c053015164242f8DRC width=scaledw; height=scaledh; 1797f610d61fcc38b36a8a29879e5c053015164242f8DRC dinfo->scale_num=sf[i].num; 1798f610d61fcc38b36a8a29879e5c053015164242f8DRC dinfo->scale_denom=sf[i].denom; 1799f610d61fcc38b36a8a29879e5c053015164242f8DRC sfi=i; 1800f610d61fcc38b36a8a29879e5c053015164242f8DRC jpeg_calc_output_dimensions(dinfo); 1801f610d61fcc38b36a8a29879e5c053015164242f8DRC 1802418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC dctsize=DCTSIZE*sf[sfi].num/sf[sfi].denom; 1803418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC 18049b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 18059e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 18069b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 18079b28defe6ac85dd8a52479cf276606beae24920eDRC int ih; 1808418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC iw[i]=compptr->width_in_blocks*dctsize; 1809418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC ih=compptr->height_in_blocks*dctsize; 181040dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw[i]=PAD(dinfo->output_width, dinfo->max_h_samp_factor) 18119b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->h_samp_factor/dinfo->max_h_samp_factor; 181240dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph[i]=PAD(dinfo->output_height, dinfo->max_v_samp_factor) 18139b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->v_samp_factor/dinfo->max_v_samp_factor; 181440dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(iw[i]!=pw[i] || ih!=ph[i]) usetmpbuf=1; 1815418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC th[i]=compptr->v_samp_factor*dctsize; 18169b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbufsize+=iw[i]*th[i]; 181740dd3146cde2ba5036fe76a4f09e1125b4592347DRC if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]))==NULL) 1818aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): Memory allocation failure"); 1819aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC ptr=dstPlanes[i]; 182040dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(row=0; row<ph[i]; row++) 18219e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 18229b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 182340dd3146cde2ba5036fe76a4f09e1125b4592347DRC ptr+=(strides && strides[i]!=0)? strides[i]:pw[i]; 1824f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 18259b28defe6ac85dd8a52479cf276606beae24920eDRC } 18269b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 18279b28defe6ac85dd8a52479cf276606beae24920eDRC { 18289b28defe6ac85dd8a52479cf276606beae24920eDRC if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL) 1829aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): Memory allocation failure"); 18309b28defe6ac85dd8a52479cf276606beae24920eDRC ptr=_tmpbuf; 18319b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 1832f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 18339b28defe6ac85dd8a52479cf276606beae24920eDRC if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL) 1834aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUVPlanes(): Memory allocation failure"); 18359b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<th[i]; row++) 1836f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 18379b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=ptr; 18389b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=iw[i]; 18399e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 18409e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 18419e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 18422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 184325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 1844e0419b530b3cecb9d7546893d893489a24d21032DRC if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; 18459b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->raw_data_out=TRUE; 18469b28defe6ac85dd8a52479cf276606beae24920eDRC 18479b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 18489b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<(int)dinfo->output_height; 1849418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC row+=dinfo->max_v_samp_factor*dinfo->_min_DCT_scaled_size) 18508ed7b814039172fe3cbfadfee3922801a3888b73DRC { 18519b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPARRAY yuvptr[MAX_COMPONENTS]; 18529b28defe6ac85dd8a52479cf276606beae24920eDRC int crow[MAX_COMPONENTS]; 18539b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 1854842416034561f6d5320165a4fe98825e999a4a37DRC { 18559b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 1856418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC if(jpegSubsamp==TJ_420) 1857418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC { 1858418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC /* When 4:2:0 subsampling is used with IDCT scaling, libjpeg will try 1859418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC to be clever and use the IDCT to perform upsampling on the U and V 1860418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC planes. For instance, if the output image is to be scaled by 1/2 1861418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC relative to the JPEG image, then the scaling factor and upsampling 1862418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC effectively cancel each other, so a normal 8x8 IDCT can be used. 1863418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC However, this is not desirable when using the decompress-to-YUV 1864418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC functionality in TurboJPEG, since we want to output the U and V 1865418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC planes in their subsampled form. Thus, we have to override some 1866418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC internal libjpeg parameters to force it to use the "scaled" IDCT 1867418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC functions on the U and V planes. */ 1868418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC compptr->_DCT_scaled_size=dctsize; 1869418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC compptr->MCU_sample_width=tjMCUWidth[jpegSubsamp]* 1870418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC sf[sfi].num/sf[sfi].denom* 1871418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC compptr->v_samp_factor/dinfo->max_v_samp_factor; 1872418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC dinfo->idct->inverse_DCT[i] = dinfo->idct->inverse_DCT[0]; 1873418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC } 18749b28defe6ac85dd8a52479cf276606beae24920eDRC crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_factor; 18759b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) yuvptr[i]=tmpbuf[i]; 18769b28defe6ac85dd8a52479cf276606beae24920eDRC else yuvptr[i]=&outbuf[i][crow[i]]; 1877842416034561f6d5320165a4fe98825e999a4a37DRC } 1878f610d61fcc38b36a8a29879e5c053015164242f8DRC jpeg_read_raw_data(dinfo, yuvptr, 1879418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC dinfo->max_v_samp_factor*dinfo->_min_DCT_scaled_size); 18809b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 18819e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 18829b28defe6ac85dd8a52479cf276606beae24920eDRC int j; 1883f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<dinfo->num_components; i++) 18849e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 188540dd3146cde2ba5036fe76a4f09e1125b4592347DRC for(j=0; j<min(th[i], ph[i]-crow[i]); j++) 1886f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 188740dd3146cde2ba5036fe76a4f09e1125b4592347DRC memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j], pw[i]); 1888f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 18899e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 18909e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 18919e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 18929b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 18932e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 189491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 18959b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 18969e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC for(i=0; i<MAX_COMPONENTS; i++) 1897f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 1898f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(tmpbuf[i]) free(tmpbuf[i]); 18999e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC if(outbuf[i]) free(outbuf[i]); 1900f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 1901f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(_tmpbuf) free(_tmpbuf); 19021f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(this->jerr.warning) retval=-1; 190391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 19042e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 19052e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1906aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRCDLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle, 19076eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, 1908aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC int width, int pad, int height, int flags) 1909aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC{ 1910aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC unsigned char *dstPlanes[3]; 191140dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw0, ph0, strides[3], retval=-1, jpegSubsamp=-1; 1912aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC int i, jpegwidth, jpegheight, scaledw, scaledh; 1913aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1914aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC getdinstance(handle); 1915aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1916aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pad<1 1917aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC || !isPow2(pad) || height<0) 1918aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUV2(): Invalid argument"); 1919aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 19206eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis if(setjmp(this->jerr.setjmp_buffer)) 19216eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis { 19226eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis /* If we get here, the JPEG code has signaled an error. */ 19236eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis return -1; 19246eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis } 19256eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis 1926aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 1927aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC jpeg_read_header(dinfo, TRUE); 1928aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC jpegSubsamp=getSubsamp(dinfo); 1929aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(jpegSubsamp<0) 1930aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUV2(): Could not determine subsampling type for JPEG image"); 1931aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1932aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; 1933aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(width==0) width=jpegwidth; 1934aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(height==0) height=jpegheight; 1935aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1936aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC for(i=0; i<NUMSF; i++) 1937aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC { 1938aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC scaledw=TJSCALED(jpegwidth, sf[i]); 1939aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC scaledh=TJSCALED(jpegheight, sf[i]); 1940aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC if(scaledw<=width && scaledh<=height) 1941aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC break; 1942aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC } 194358ae401e503ac61babb9d66be8fc06bfb0445dbfDRC if(i>=NUMSF) 1944aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC _throw("tjDecompressToYUV2(): Could not scale down to desired image dimensions"); 1945aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 194640dd3146cde2ba5036fe76a4f09e1125b4592347DRC pw0=tjPlaneWidth(0, width, jpegSubsamp); 194740dd3146cde2ba5036fe76a4f09e1125b4592347DRC ph0=tjPlaneHeight(0, height, jpegSubsamp); 1948aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC dstPlanes[0]=dstBuf; 194940dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[0]=PAD(pw0, pad); 195040dd3146cde2ba5036fe76a4f09e1125b4592347DRC if(jpegSubsamp==TJSAMP_GRAY) 195140dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 195240dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[1]=strides[2]=0; 195340dd3146cde2ba5036fe76a4f09e1125b4592347DRC dstPlanes[1]=dstPlanes[2]=NULL; 195440dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 195540dd3146cde2ba5036fe76a4f09e1125b4592347DRC else 195640dd3146cde2ba5036fe76a4f09e1125b4592347DRC { 195740dd3146cde2ba5036fe76a4f09e1125b4592347DRC int pw1=tjPlaneWidth(1, width, jpegSubsamp); 195840dd3146cde2ba5036fe76a4f09e1125b4592347DRC int ph1=tjPlaneHeight(1, height, jpegSubsamp); 195940dd3146cde2ba5036fe76a4f09e1125b4592347DRC strides[1]=strides[2]=PAD(pw1, pad); 196040dd3146cde2ba5036fe76a4f09e1125b4592347DRC dstPlanes[1]=dstPlanes[0]+strides[0]*ph0; 196140dd3146cde2ba5036fe76a4f09e1125b4592347DRC dstPlanes[2]=dstPlanes[1]+strides[1]*ph1; 196240dd3146cde2ba5036fe76a4f09e1125b4592347DRC } 1963aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1964aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC this->headerRead=1; 1965aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC return tjDecompressToYUVPlanes(handle, jpegBuf, jpegSize, dstPlanes, width, 1966aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC strides, height, flags); 1967aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1968aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC bailout: 1969aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC return retval; 1970aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1971aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC} 1972aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC 1973f610d61fcc38b36a8a29879e5c053015164242f8DRCDLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, 1974f610d61fcc38b36a8a29879e5c053015164242f8DRC unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, 1975f610d61fcc38b36a8a29879e5c053015164242f8DRC int flags) 1976f610d61fcc38b36a8a29879e5c053015164242f8DRC{ 1977f610d61fcc38b36a8a29879e5c053015164242f8DRC return tjDecompressToYUV2(handle, jpegBuf, jpegSize, dstBuf, 0, 4, 0, flags); 1978f610d61fcc38b36a8a29879e5c053015164242f8DRC} 1979f610d61fcc38b36a8a29879e5c053015164242f8DRC 19802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 19819b28defe6ac85dd8a52479cf276606beae24920eDRC/* Transformer */ 1982890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1983890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitTransform(void) 1984890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 19859b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; tjhandle handle=NULL; 19869b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 1987da5220acdd525242bff4e40b1d90324ebb889825DRC { 1988007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 1989007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitTransform(): Memory allocation failure"); 1990da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 1991da5220acdd525242bff4e40b1d90324ebb889825DRC } 1992007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 19939b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitCompress(this); 19949b28defe6ac85dd8a52479cf276606beae24920eDRC if(!handle) return NULL; 19959b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitDecompress(this); 19969b28defe6ac85dd8a52479cf276606beae24920eDRC return handle; 1997890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 1998890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1999890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20006eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjTransform(tjhandle handle, 20016eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis const unsigned char *jpegBuf, unsigned long jpegSize, int n, 20026eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis unsigned char **dstBufs, unsigned long *dstSizes, tjtransform *t, int flags) 2003890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 20040a325197dedd2eede99731c68ae0e0a145473f64DRC jpeg_transform_info *xinfo=NULL; 2005890f1e0413b54c40b663208779d4ea9dae20eaefDRC jvirt_barray_ptr *srccoefs, *dstcoefs; 20069b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=0, i, jpegSubsamp; 2007890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20089b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 20099b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0) 2010007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Instance has not been initialized for transformation"); 2011890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20129b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NULL 20130a325197dedd2eede99731c68ae0e0a145473f64DRC || t==NULL || flags<0) 20149b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjTransform(): Invalid argument"); 2015890f1e0413b54c40b663208779d4ea9dae20eaefDRC 2016bec45b162bb77a57c147a9c44113af1968a79be4DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 2017bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 2018bec45b162bb77a57c147a9c44113af1968a79be4DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 2019890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20209b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 20219b28defe6ac85dd8a52479cf276606beae24920eDRC { 20229b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 2023890f1e0413b54c40b663208779d4ea9dae20eaefDRC retval=-1; 2024890f1e0413b54c40b663208779d4ea9dae20eaefDRC goto bailout; 2025890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 2026890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20279b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 2028890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20290a325197dedd2eede99731c68ae0e0a145473f64DRC if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n)) 20300a325197dedd2eede99731c68ae0e0a145473f64DRC ==NULL) 2031007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Memory allocation failure"); 2032007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(xinfo, sizeof(jpeg_transform_info)*n); 2033890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20340a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 2035890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 20360a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].transform=xformtypes[t[i].op]; 203725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].perfect=(t[i].options&TJXOPT_PERFECT)? 1:0; 203825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].trim=(t[i].options&TJXOPT_TRIM)? 1:0; 203925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].force_grayscale=(t[i].options&TJXOPT_GRAY)? 1:0; 204025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].crop=(t[i].options&TJXOPT_CROP)? 1:0; 204125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(n!=1 && t[i].op==TJXOP_HFLIP) xinfo[i].slow_hflip=1; 2042ba5ea5143e48b71234414139e3b4cb244599e875DRC else xinfo[i].slow_hflip=0; 20430a325197dedd2eede99731c68ae0e0a145473f64DRC 20440a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 2045890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 20460a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_xoffset=t[i].r.x; xinfo[i].crop_xoffset_set=JCROP_POS; 20470a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_yoffset=t[i].r.y; xinfo[i].crop_yoffset_set=JCROP_POS; 20480a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.w!=0) 20490a325197dedd2eede99731c68ae0e0a145473f64DRC { 20500a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_width=t[i].r.w; xinfo[i].crop_width_set=JCROP_POS; 20510a325197dedd2eede99731c68ae0e0a145473f64DRC } 2052d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_width=JCROP_UNSET; 20530a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.h!=0) 20540a325197dedd2eede99731c68ae0e0a145473f64DRC { 20550a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_height=t[i].r.h; xinfo[i].crop_height_set=JCROP_POS; 20560a325197dedd2eede99731c68ae0e0a145473f64DRC } 2057d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_height=JCROP_UNSET; 2058890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 2059890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 2060890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20619b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_markers_setup(dinfo, JCOPYOPT_ALL); 20629b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 20639b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC jpegSubsamp=getSubsamp(dinfo); 20649b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(jpegSubsamp<0) 20659b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjTransform(): Could not determine subsampling type for JPEG image"); 2066890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20670a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 2068890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 20699b28defe6ac85dd8a52479cf276606beae24920eDRC if(!jtransform_request_workspace(dinfo, &xinfo[i])) 2070007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Transform is not perfect"); 20710a325197dedd2eede99731c68ae0e0a145473f64DRC 20720a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 20730a325197dedd2eede99731c68ae0e0a145473f64DRC { 20740a325197dedd2eede99731c68ae0e0a145473f64DRC if((t[i].r.x%xinfo[i].iMCU_sample_width)!=0 20750a325197dedd2eede99731c68ae0e0a145473f64DRC || (t[i].r.y%xinfo[i].iMCU_sample_height)!=0) 20760a325197dedd2eede99731c68ae0e0a145473f64DRC { 20779b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 20780a325197dedd2eede99731c68ae0e0a145473f64DRC "To crop this JPEG image, x must be a multiple of %d\n" 20790a325197dedd2eede99731c68ae0e0a145473f64DRC "and y must be a multiple of %d.\n", 20800a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].iMCU_sample_width, xinfo[i].iMCU_sample_height); 20810a325197dedd2eede99731c68ae0e0a145473f64DRC retval=-1; goto bailout; 20820a325197dedd2eede99731c68ae0e0a145473f64DRC } 20830a325197dedd2eede99731c68ae0e0a145473f64DRC } 2084890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 2085890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20869b28defe6ac85dd8a52479cf276606beae24920eDRC srccoefs=jpeg_read_coefficients(dinfo); 2087890f1e0413b54c40b663208779d4ea9dae20eaefDRC 20880a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 2089890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 2090ff78e37595c8462f64fd100f928aa1d08539527eDRC int w, h, alloc=1; 20910a325197dedd2eede99731c68ae0e0a145473f64DRC if(!xinfo[i].crop) 2092890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 20939b28defe6ac85dd8a52479cf276606beae24920eDRC w=dinfo->image_width; h=dinfo->image_height; 2094890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 20950a325197dedd2eede99731c68ae0e0a145473f64DRC else 20960a325197dedd2eede99731c68ae0e0a145473f64DRC { 20970a325197dedd2eede99731c68ae0e0a145473f64DRC w=xinfo[i].crop_width; h=xinfo[i].crop_height; 20980a325197dedd2eede99731c68ae0e0a145473f64DRC } 2099ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 2100ff78e37595c8462f64fd100f928aa1d08539527eDRC { 21019b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC alloc=0; dstSizes[i]=tjBufSize(w, h, jpegSubsamp); 2102ff78e37595c8462f64fd100f928aa1d08539527eDRC } 21037bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) 21047bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_mem_dest_tj(cinfo, &dstBufs[i], &dstSizes[i], alloc); 21059b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_copy_critical_parameters(dinfo, cinfo); 21069b28defe6ac85dd8a52479cf276606beae24920eDRC dstcoefs=jtransform_adjust_parameters(dinfo, cinfo, srccoefs, 21070a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 21087bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) 21097bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 21107bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_write_coefficients(cinfo, dstcoefs); 21117bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL); 21127bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 21137bf04d399ebf9a3b39a6d5b5639d895df618353dDRC else jinit_c_master_control(cinfo, TRUE); 21149b28defe6ac85dd8a52479cf276606beae24920eDRC jtransform_execute_transformation(dinfo, cinfo, srccoefs, 21150a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 21167bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(t[i].customFilter) 21177bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 2118efe28cec4b29b5a7357d9cd1c30a066486d19b12DRC int ci, y; JDIMENSION by; 21197bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(ci=0; ci<cinfo->num_components; ci++) 21207bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 21217bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_component_info *compptr=&cinfo->comp_info[ci]; 21227bf04d399ebf9a3b39a6d5b5639d895df618353dDRC tjregion arrayRegion={0, 0, compptr->width_in_blocks*DCTSIZE, 21237bf04d399ebf9a3b39a6d5b5639d895df618353dDRC DCTSIZE}; 21247bf04d399ebf9a3b39a6d5b5639d895df618353dDRC tjregion planeRegion={0, 0, compptr->width_in_blocks*DCTSIZE, 21257bf04d399ebf9a3b39a6d5b5639d895df618353dDRC compptr->height_in_blocks*DCTSIZE}; 21267bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(by=0; by<compptr->height_in_blocks; by+=compptr->v_samp_factor) 21277bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 21287bf04d399ebf9a3b39a6d5b5639d895df618353dDRC JBLOCKARRAY barray=(dinfo->mem->access_virt_barray) 21297bf04d399ebf9a3b39a6d5b5639d895df618353dDRC ((j_common_ptr)dinfo, dstcoefs[ci], by, compptr->v_samp_factor, 21307bf04d399ebf9a3b39a6d5b5639d895df618353dDRC TRUE); 21317bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(y=0; y<compptr->v_samp_factor; y++) 21327bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 21337bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(t[i].customFilter(barray[y][0], arrayRegion, planeRegion, 2134f5467110763f7a44ca8baf1c035eb39a68c913c6DRC ci, i, &t[i])==-1) 21357bf04d399ebf9a3b39a6d5b5639d895df618353dDRC _throw("tjTransform(): Error in custom filter"); 21367bf04d399ebf9a3b39a6d5b5639d895df618353dDRC arrayRegion.y+=DCTSIZE; 21377bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 21387bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 21397bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 21407bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 21417bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) jpeg_finish_compress(cinfo); 2142890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 2143890f1e0413b54c40b663208779d4ea9dae20eaefDRC 21449b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 2145890f1e0413b54c40b663208779d4ea9dae20eaefDRC 2146890f1e0413b54c40b663208779d4ea9dae20eaefDRC bailout: 21479b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 21489b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 21490a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo) free(xinfo); 21501f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC if(this->jerr.warning) retval=-1; 2151890f1e0413b54c40b663208779d4ea9dae20eaefDRC return retval; 2152890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 2153