turbojpeg.c revision bdfcb74d509b2c151cdc4c8b388c8a5975a7da65
19b28defe6ac85dd8a52479cf276606beae24920eDRC/* 22eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC * Copyright (C)2009-2012 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> 34296c71ba0ffb034390a3d0b00a0cc6d6fa014b6eDRC#include <jinclude.h> 35fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define JPEG_INTERNALS 362e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jpeglib.h> 372e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jerror.h> 382e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <setjmp.h> 392e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include "./turbojpeg.h" 40a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#include "./tjutil.h" 41890f1e0413b54c40b663208779d4ea9dae20eaefDRC#include "transupp.h" 422a2e451ddc9e3c093a903ccb5a06962d05c21b67DRC 439b28defe6ac85dd8a52479cf276606beae24920eDRCextern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, 449b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *, boolean); 459b28defe6ac85dd8a52479cf276606beae24920eDRCextern void jpeg_mem_src_tj(j_decompress_ptr, unsigned char *, unsigned long); 469b28defe6ac85dd8a52479cf276606beae24920eDRC 47fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define PAD(v, p) ((v+(p)-1)&(~((p)-1))) 482e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 492e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 509b28defe6ac85dd8a52479cf276606beae24920eDRC/* Error handling (based on example in example.c) */ 512e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 529b28defe6ac85dd8a52479cf276606beae24920eDRCstatic char errStr[JMSG_LENGTH_MAX]="No error"; 532e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 549b28defe6ac85dd8a52479cf276606beae24920eDRCstruct my_error_mgr 552e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 562e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_error_mgr pub; 579b28defe6ac85dd8a52479cf276606beae24920eDRC jmp_buf setjmp_buffer; 589b28defe6ac85dd8a52479cf276606beae24920eDRC}; 599b28defe6ac85dd8a52479cf276606beae24920eDRCtypedef struct my_error_mgr *my_error_ptr; 602e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 612e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCstatic void my_error_exit(j_common_ptr cinfo) 622e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 639b28defe6ac85dd8a52479cf276606beae24920eDRC my_error_ptr myerr=(my_error_ptr)cinfo->err; 642e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC (*cinfo->err->output_message)(cinfo); 659b28defe6ac85dd8a52479cf276606beae24920eDRC longjmp(myerr->setjmp_buffer, 1); 662e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 672e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 689b28defe6ac85dd8a52479cf276606beae24920eDRC/* Based on output_message() in jerror.c */ 699b28defe6ac85dd8a52479cf276606beae24920eDRC 702e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCstatic void my_output_message(j_common_ptr cinfo) 712e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 729b28defe6ac85dd8a52479cf276606beae24920eDRC (*cinfo->err->format_message)(cinfo, errStr); 732e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 742e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 752e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 769b28defe6ac85dd8a52479cf276606beae24920eDRC/* Global structures, macros, etc. */ 772e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 789b28defe6ac85dd8a52479cf276606beae24920eDRCenum {COMPRESS=1, DECOMPRESS=2}; 799b28defe6ac85dd8a52479cf276606beae24920eDRC 809b28defe6ac85dd8a52479cf276606beae24920eDRCtypedef struct _tjinstance 812e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 822e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_compress_struct cinfo; 832e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_decompress_struct dinfo; 849b28defe6ac85dd8a52479cf276606beae24920eDRC struct my_error_mgr jerr; 859b28defe6ac85dd8a52479cf276606beae24920eDRC int init; 869b28defe6ac85dd8a52479cf276606beae24920eDRC} tjinstance; 872e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 88007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRCstatic const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3}; 899b28defe6ac85dd8a52479cf276606beae24920eDRC 90007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRCstatic const JXFORM_CODE xformtypes[TJ_NUMXOP]= 91007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC{ 92890f1e0413b54c40b663208779d4ea9dae20eaefDRC JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE, 93890f1e0413b54c40b663208779d4ea9dae20eaefDRC JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270 94890f1e0413b54c40b663208779d4ea9dae20eaefDRC}; 959b28defe6ac85dd8a52479cf276606beae24920eDRC 96ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC#define NUMSF 16 97109a578e89ea8cd2c39d50b012698148dd11dedbDRCstatic const tjscalingfactor sf[NUMSF]={ 98ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {2, 1}, 99ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {15, 8}, 100ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {7, 4}, 101ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {13, 8}, 102ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 2}, 103ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {11, 8}, 104ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {5, 4}, 105ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {9, 8}, 106109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 1}, 107ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {7, 8}, 108ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 4}, 109ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {5, 8}, 110109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 2}, 111ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 8}, 112109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 4}, 113109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 8} 114109a578e89ea8cd2c39d50b012698148dd11dedbDRC}; 1152e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 116a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ 117da5220acdd525242bff4e40b1d90324ebb889825DRC retval=-1; goto bailout;} 1189b28defe6ac85dd8a52479cf276606beae24920eDRC#define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ 1199b28defe6ac85dd8a52479cf276606beae24920eDRC j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ 1209b28defe6ac85dd8a52479cf276606beae24920eDRC if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ 1219b28defe6ac85dd8a52479cf276606beae24920eDRC return -1;} \ 1229b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo=&this->cinfo; dinfo=&this->dinfo; 1239b28defe6ac85dd8a52479cf276606beae24920eDRC 1249b28defe6ac85dd8a52479cf276606beae24920eDRCstatic int getPixelFormat(int pixelSize, int flags) 1259b28defe6ac85dd8a52479cf276606beae24920eDRC{ 12625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(pixelSize==1) return TJPF_GRAY; 1279b28defe6ac85dd8a52479cf276606beae24920eDRC if(pixelSize==3) 1289b28defe6ac85dd8a52479cf276606beae24920eDRC { 12925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_BGR; 13025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_RGB; 1319b28defe6ac85dd8a52479cf276606beae24920eDRC } 1329b28defe6ac85dd8a52479cf276606beae24920eDRC if(pixelSize==4) 1339b28defe6ac85dd8a52479cf276606beae24920eDRC { 1349b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_ALPHAFIRST) 1359b28defe6ac85dd8a52479cf276606beae24920eDRC { 13625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_XBGR; 13725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_XRGB; 1389b28defe6ac85dd8a52479cf276606beae24920eDRC } 1399b28defe6ac85dd8a52479cf276606beae24920eDRC else 1409b28defe6ac85dd8a52479cf276606beae24920eDRC { 14125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_BGRX; 14225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_RGBX; 1439b28defe6ac85dd8a52479cf276606beae24920eDRC } 1449b28defe6ac85dd8a52479cf276606beae24920eDRC } 1459b28defe6ac85dd8a52479cf276606beae24920eDRC return -1; 1469b28defe6ac85dd8a52479cf276606beae24920eDRC} 1479b28defe6ac85dd8a52479cf276606beae24920eDRC 148f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setCompDefaults(struct jpeg_compress_struct *cinfo, 14973d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC int pixelFormat, int subsamp, int jpegQual, int flags) 1509b28defe6ac85dd8a52479cf276606beae24920eDRC{ 151f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC int retval=0; 152f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 1539b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 1549b28defe6ac85dd8a52479cf276606beae24920eDRC { 15525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 1569b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_GRAYSCALE; break; 1579b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 15825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 1599b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGB; break; 16025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 1619b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGR; break; 16225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 16367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_RGBA: 1649b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGBX; break; 16525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 16667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_BGRA: 1679b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGRX; break; 16825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 16967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ARGB: 1709b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XRGB; break; 17125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 17267ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ABGR: 1739b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XBGR; break; 1749b28defe6ac85dd8a52479cf276606beae24920eDRC #else 17525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 176afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 177afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 178afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 179afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 180afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 181afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 182afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 183afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 184afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 185afc06929e0a9cf64bdf50da30326076235df7b4fDRC cinfo->in_color_space=JCS_RGB; pixelFormat=TJPF_RGB; 186afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 1879b28defe6ac85dd8a52479cf276606beae24920eDRC #endif 1889b28defe6ac85dd8a52479cf276606beae24920eDRC } 1899b28defe6ac85dd8a52479cf276606beae24920eDRC 1909b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->input_components=tjPixelSize[pixelFormat]; 1919b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_defaults(cinfo); 1929b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegQual>=0) 1939b28defe6ac85dd8a52479cf276606beae24920eDRC { 1949b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_quality(cinfo, jpegQual, TRUE); 19573d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(jpegQual>=96 || flags&TJFLAG_ACCURATEDCT) cinfo->dct_method=JDCT_ISLOW; 1969b28defe6ac85dd8a52479cf276606beae24920eDRC else cinfo->dct_method=JDCT_FASTEST; 1979b28defe6ac85dd8a52479cf276606beae24920eDRC } 19825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(subsamp==TJSAMP_GRAY) 1999b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); 2009b28defe6ac85dd8a52479cf276606beae24920eDRC else 2019b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_YCbCr); 2029b28defe6ac85dd8a52479cf276606beae24920eDRC 2039b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; 2049b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].h_samp_factor=1; 2059b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].h_samp_factor=1; 2069b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; 2079b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].v_samp_factor=1; 2089b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].v_samp_factor=1; 209f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 210f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return retval; 2119b28defe6ac85dd8a52479cf276606beae24920eDRC} 2129b28defe6ac85dd8a52479cf276606beae24920eDRC 213f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setDecompDefaults(struct jpeg_decompress_struct *dinfo, 21473d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC int pixelFormat, int flags) 2159b28defe6ac85dd8a52479cf276606beae24920eDRC{ 216f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC int retval=0; 217f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 2189b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 2199b28defe6ac85dd8a52479cf276606beae24920eDRC { 22025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 2219b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_GRAYSCALE; break; 2229b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 22325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 2249b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGB; break; 22525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 2269b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGR; break; 22725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 2289b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGBX; break; 22925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 2309b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGRX; break; 23125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 2329b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XRGB; break; 23325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 2349b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XBGR; break; 23567ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #if JCS_ALPHA_EXTENSIONS==1 23667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_RGBA: 23767ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_RGBA; break; 23867ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_BGRA: 23967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_BGRA; break; 24067ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ARGB: 24167ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_ARGB; break; 24267ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ABGR: 24367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_ABGR; break; 24467ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #endif 2459b28defe6ac85dd8a52479cf276606beae24920eDRC #else 24625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 247afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 248afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 249afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 250afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 251afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 252afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 253afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 254afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 255afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 256afc06929e0a9cf64bdf50da30326076235df7b4fDRC dinfo->out_color_space=JCS_RGB; break; 25767ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #endif 2589b28defe6ac85dd8a52479cf276606beae24920eDRC default: 2599b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("Unsupported pixel format"); 2609b28defe6ac85dd8a52479cf276606beae24920eDRC } 261f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 26273d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; 26373d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC 264f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC bailout: 265f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return retval; 2669b28defe6ac85dd8a52479cf276606beae24920eDRC} 2672e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2682e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2699b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCstatic int getSubsamp(j_decompress_ptr dinfo) 2709b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 2719b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=-1, i, k; 2729b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC for(i=0; i<NUMSUBOPT; i++) 2739b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2749b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->num_components==pixelsize[i]) 2759b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2769b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8 2779b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC && dinfo->comp_info[0].v_samp_factor==tjMCUHeight[i]/8) 2789b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2799b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int match=0; 2809b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC for(k=1; k<dinfo->num_components; k++) 2819b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2829b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->comp_info[k].h_samp_factor==1 2839b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC && dinfo->comp_info[k].v_samp_factor==1) 2849b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC match++; 2859b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2869b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(match==dinfo->num_components-1) 2879b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2889b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC retval=i; break; 2899b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2909b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2919b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2929b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2939b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return retval; 2949b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 2959b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 2969b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 297afc06929e0a9cf64bdf50da30326076235df7b4fDRC#ifndef JCS_EXTENSIONS 298afc06929e0a9cf64bdf50da30326076235df7b4fDRC 299afc06929e0a9cf64bdf50da30326076235df7b4fDRC/* Conversion functions to emulate the colorspace extensions. This allows the 300afc06929e0a9cf64bdf50da30326076235df7b4fDRC TurboJPEG wrapper to be used with libjpeg */ 301afc06929e0a9cf64bdf50da30326076235df7b4fDRC 302afc06929e0a9cf64bdf50da30326076235df7b4fDRC#define TORGB(PS, ROFFSET, GOFFSET, BOFFSET) { \ 303afc06929e0a9cf64bdf50da30326076235df7b4fDRC int rowPad=pitch-width*PS; \ 304afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(height--) \ 305afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 306afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *endOfRow=src+width*PS; \ 307afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(src<endOfRow) \ 308afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 309afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_RED]=src[ROFFSET]; \ 310afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_GREEN]=src[GOFFSET]; \ 311afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_BLUE]=src[BOFFSET]; \ 312afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=RGB_PIXELSIZE; src+=PS; \ 313afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 314afc06929e0a9cf64bdf50da30326076235df7b4fDRC src+=rowPad; \ 315afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 316afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 317afc06929e0a9cf64bdf50da30326076235df7b4fDRC 318afc06929e0a9cf64bdf50da30326076235df7b4fDRCstatic unsigned char *toRGB(unsigned char *src, int width, int pitch, 319afc06929e0a9cf64bdf50da30326076235df7b4fDRC int height, int pixelFormat, unsigned char *dst) 320afc06929e0a9cf64bdf50da30326076235df7b4fDRC{ 321afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *retval=src; 322afc06929e0a9cf64bdf50da30326076235df7b4fDRC switch(pixelFormat) 323afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 324afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGB: 325afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3 326afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(3, 0, 1, 2); 327afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 328afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 329afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 330afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3 331afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(3, 2, 1, 0); 332afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 333afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 334afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 335afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 336afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 337afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 0, 1, 2); 338afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 339afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 340afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 341afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 342afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 343afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 2, 1, 0); 344afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 345afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 346afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 347afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 348afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 349afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 1, 2, 3); 350afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 351afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 352afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 353afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 354afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 355afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 3, 2, 1); 356afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 357afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 358afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 359afc06929e0a9cf64bdf50da30326076235df7b4fDRC return retval; 360afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 361afc06929e0a9cf64bdf50da30326076235df7b4fDRC 362afc06929e0a9cf64bdf50da30326076235df7b4fDRC#define FROMRGB(PS, ROFFSET, GOFFSET, BOFFSET, SETALPHA) { \ 363afc06929e0a9cf64bdf50da30326076235df7b4fDRC int rowPad=pitch-width*PS; \ 364afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(height--) \ 365afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 366afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *endOfRow=dst+width*PS; \ 367afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(dst<endOfRow) \ 368afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 369afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[ROFFSET]=src[RGB_RED]; \ 370afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[GOFFSET]=src[RGB_GREEN]; \ 371afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[BOFFSET]=src[RGB_BLUE]; \ 372afc06929e0a9cf64bdf50da30326076235df7b4fDRC SETALPHA \ 373afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=PS; src+=RGB_PIXELSIZE; \ 374afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 375afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=rowPad; \ 376afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 377afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 378afc06929e0a9cf64bdf50da30326076235df7b4fDRC 379afc06929e0a9cf64bdf50da30326076235df7b4fDRCstatic void fromRGB(unsigned char *src, unsigned char *dst, int width, 380afc06929e0a9cf64bdf50da30326076235df7b4fDRC int pitch, int height, int pixelFormat) 381afc06929e0a9cf64bdf50da30326076235df7b4fDRC{ 382afc06929e0a9cf64bdf50da30326076235df7b4fDRC switch(pixelFormat) 383afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 384afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGB: 385afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3 386afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(3, 0, 1, 2,); 387afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 388afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 389afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 390afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3 391afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(3, 2, 1, 0,); 392afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 393afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 394afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 395afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 396afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 0, 1, 2,); 397afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 398afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 399afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 400afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 401afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 0, 1, 2, dst[3]=0xFF;); 402afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 403afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 404afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 405afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 406afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 2, 1, 0,); 407afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 408afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 409afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 410afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 411afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 2, 1, 0, dst[3]=0xFF;); return; 412afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 413afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 414afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 415afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 416afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 1, 2, 3,); return; 417afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 418afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 419afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 420afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 421afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 1, 2, 3, dst[0]=0xFF;); return; 422afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 423afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 424afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 425afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 426afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 3, 2, 1,); return; 427afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 428afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 429afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 430afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 431afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 3, 2, 1, dst[0]=0xFF;); return; 432afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 433afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 434afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 435afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 436afc06929e0a9cf64bdf50da30326076235df7b4fDRC 437afc06929e0a9cf64bdf50da30326076235df7b4fDRC#endif 438afc06929e0a9cf64bdf50da30326076235df7b4fDRC 439afc06929e0a9cf64bdf50da30326076235df7b4fDRC 4409b28defe6ac85dd8a52479cf276606beae24920eDRC/* General API functions */ 4412e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4429b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT char* DLLCALL tjGetErrorStr(void) 4432e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 4449b28defe6ac85dd8a52479cf276606beae24920eDRC return errStr; 4452e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 4462e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4479b28defe6ac85dd8a52479cf276606beae24920eDRC 4489b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDestroy(tjhandle handle) 4492e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 4509b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 4519b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) return -1; 4529b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&COMPRESS) jpeg_destroy_compress(cinfo); 4539b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&DECOMPRESS) jpeg_destroy_decompress(dinfo); 4549b28defe6ac85dd8a52479cf276606beae24920eDRC free(this); 4559b28defe6ac85dd8a52479cf276606beae24920eDRC return 0; 4562e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 4572e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4589b28defe6ac85dd8a52479cf276606beae24920eDRC 4596b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC/* These are exposed mainly because Windows can't malloc() and free() across 4606b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC DLL boundaries except when the CRT DLL is used, and we don't use the CRT DLL 4616b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC with turbojpeg.dll for compatibility reasons. However, these functions 4626b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC can potentially be used for other purposes by different implementations. */ 4636b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4646b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT void DLLCALL tjFree(unsigned char *buf) 4656b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 4666b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC if(buf) free(buf); 4676b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 4686b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4696b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4706b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes) 4716b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 4726b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC return (unsigned char *)malloc(bytes); 4736b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 4746b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4756b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4769b28defe6ac85dd8a52479cf276606beae24920eDRC/* Compressor */ 4779b28defe6ac85dd8a52479cf276606beae24920eDRC 4789b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitCompress(tjinstance *this) 4792e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 4809b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char buffer[1], *buf=buffer; unsigned long size=1; 4819b28defe6ac85dd8a52479cf276606beae24920eDRC 4829b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 4839b28defe6ac85dd8a52479cf276606beae24920eDRC this->cinfo.err=jpeg_std_error(&this->jerr.pub); 4849b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 4859b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 4862e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4879b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 4889b28defe6ac85dd8a52479cf276606beae24920eDRC { 4899b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 4909b28defe6ac85dd8a52479cf276606beae24920eDRC if(this) free(this); return NULL; 491efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 4922e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4939b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_compress(&this->cinfo); 4949b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the destination manager */ 4959b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); 4962e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 497007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=COMPRESS; 4989b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 4992e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 5002e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 501890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitCompress(void) 502890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 5039b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; 5049b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 505da5220acdd525242bff4e40b1d90324ebb889825DRC { 506007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 507007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitCompress(): Memory allocation failure"); 508da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 509da5220acdd525242bff4e40b1d90324ebb889825DRC } 510007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 5119b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitCompress(this); 512890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 513890f1e0413b54c40b663208779d4ea9dae20eaefDRC 514842416034561f6d5320165a4fe98825e999a4a37DRC 5159b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, 5169b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int jpegSubsamp) 5179b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 5189b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC unsigned long retval=0; int mcuw, mcuh, chromasf; 5199b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT) 5209b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjBufSize(): Invalid argument"); 5219b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5229b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // This allows for rare corner cases in which a JPEG image can actually be 5239b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // larger than the uncompressed input (we wouldn't mention it if it hadn't 5249b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // happened before.) 5259b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC mcuw=tjMCUWidth[jpegSubsamp]; 5269b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC mcuh=tjMCUHeight[jpegSubsamp]; 5279b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh); 5289b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048; 5299b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5309b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC bailout: 5319b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return retval; 5329b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 5339b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5349b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5352e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) 5362e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 537f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 538f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1) 539007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("TJBUFSIZE(): Invalid argument"); 540f3cf973e8e51e0078f402ca5547c026967c27321DRC 541f3cf973e8e51e0078f402ca5547c026967c27321DRC // This allows for rare corner cases in which a JPEG image can actually be 542f3cf973e8e51e0078f402ca5547c026967c27321DRC // larger than the uncompressed input (we wouldn't mention it if it hadn't 543b28fc5710a510410d2b498255a423dd62b353b3aDRC // happened before.) 544007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; 545f3cf973e8e51e0078f402ca5547c026967c27321DRC 546f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 547f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 548f3cf973e8e51e0078f402ca5547c026967c27321DRC} 549f3cf973e8e51e0078f402ca5547c026967c27321DRC 550842416034561f6d5320165a4fe98825e999a4a37DRC 5519b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, 552f3cf973e8e51e0078f402ca5547c026967c27321DRC int subsamp) 553f3cf973e8e51e0078f402ca5547c026967c27321DRC{ 554f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 555f3cf973e8e51e0078f402ca5547c026967c27321DRC int pw, ph, cw, ch; 556f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) 5579b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjBufSizeYUV(): Invalid argument"); 5589b28defe6ac85dd8a52479cf276606beae24920eDRC pw=PAD(width, tjMCUWidth[subsamp]/8); 5599b28defe6ac85dd8a52479cf276606beae24920eDRC ph=PAD(height, tjMCUHeight[subsamp]/8); 5609b28defe6ac85dd8a52479cf276606beae24920eDRC cw=pw*8/tjMCUWidth[subsamp]; ch=ph*8/tjMCUHeight[subsamp]; 56125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC retval=PAD(pw, 4)*ph + (subsamp==TJSAMP_GRAY? 0:PAD(cw, 4)*ch*2); 562f3cf973e8e51e0078f402ca5547c026967c27321DRC 563f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 564f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 5652e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 5662e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 567842416034561f6d5320165a4fe98825e999a4a37DRC 5689b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height, 5699b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int subsamp) 5709b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 5719b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return tjBufSizeYUV(width, height, subsamp); 5729b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 5739b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5749b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5759b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, 5769b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, 5779b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 5789b28defe6ac85dd8a52479cf276606beae24920eDRC{ 579ff78e37595c8462f64fd100f928aa1d08539527eDRC int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; 580afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 581afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 582afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 5839b28defe6ac85dd8a52479cf276606beae24920eDRC 5849b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle) 5859b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 586007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Instance has not been initialized for compression"); 5879b28defe6ac85dd8a52479cf276606beae24920eDRC 5889b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 5899b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL 5909b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100) 591007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Invalid argument"); 5929b28defe6ac85dd8a52479cf276606beae24920eDRC 5939b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 5949b28defe6ac85dd8a52479cf276606beae24920eDRC { 5959b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 5969b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 5979b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 5989b28defe6ac85dd8a52479cf276606beae24920eDRC } 5999b28defe6ac85dd8a52479cf276606beae24920eDRC 6009b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 6019b28defe6ac85dd8a52479cf276606beae24920eDRC 602afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 603afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(pixelFormat!=TJPF_GRAY) 604afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 605afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); 606afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure"); 607afc06929e0a9cf64bdf50da30326076235df7b4fDRC srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); 608afc06929e0a9cf64bdf50da30326076235df7b4fDRC pitch=width*RGB_PIXELSIZE; 609afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 610afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 611afc06929e0a9cf64bdf50da30326076235df7b4fDRC 6129b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 6139b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 6149b28defe6ac85dd8a52479cf276606beae24920eDRC 61525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 61625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 61725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 6189b28defe6ac85dd8a52479cf276606beae24920eDRC 619ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 620ff78e37595c8462f64fd100f928aa1d08539527eDRC { 6219b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp); 622ff78e37595c8462f64fd100f928aa1d08539527eDRC } 623ff78e37595c8462f64fd100f928aa1d08539527eDRC jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); 62473d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual, flags)==-1) 625f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return -1; 6269b28defe6ac85dd8a52479cf276606beae24920eDRC 6279b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 6289b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) 629007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Memory allocation failure"); 6309b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 6319b28defe6ac85dd8a52479cf276606beae24920eDRC { 63225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch]; 6339b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&srcBuf[i*pitch]; 6349b28defe6ac85dd8a52479cf276606beae24920eDRC } 6359b28defe6ac85dd8a52479cf276606beae24920eDRC while(cinfo->next_scanline<cinfo->image_height) 6369b28defe6ac85dd8a52479cf276606beae24920eDRC { 6379b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], 6389b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height-cinfo->next_scanline); 6399b28defe6ac85dd8a52479cf276606beae24920eDRC } 6409b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_compress(cinfo); 6419b28defe6ac85dd8a52479cf276606beae24920eDRC 6429b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 6439b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 644afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 645ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 646afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 6479b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 6489b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 6499b28defe6ac85dd8a52479cf276606beae24920eDRC} 6509b28defe6ac85dd8a52479cf276606beae24920eDRC 6519b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, 6529b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, 6539b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 6549b28defe6ac85dd8a52479cf276606beae24920eDRC{ 6559b28defe6ac85dd8a52479cf276606beae24920eDRC int retval=0; unsigned long size; 6569b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 6579b28defe6ac85dd8a52479cf276606beae24920eDRC { 6589b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC size=tjBufSizeYUV(width, height, jpegSubsamp); 6599b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height, 6609b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp, flags); 6619b28defe6ac85dd8a52479cf276606beae24920eDRC } 6629b28defe6ac85dd8a52479cf276606beae24920eDRC else 6639b28defe6ac85dd8a52479cf276606beae24920eDRC { 6649b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjCompress2(handle, srcBuf, width, pitch, height, 6659b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegSubsamp, jpegQual, 66625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC flags|TJFLAG_NOREALLOC); 6679b28defe6ac85dd8a52479cf276606beae24920eDRC } 6689b28defe6ac85dd8a52479cf276606beae24920eDRC *jpegSize=size; 6699b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 6709b28defe6ac85dd8a52479cf276606beae24920eDRC} 6719b28defe6ac85dd8a52479cf276606beae24920eDRC 6729b28defe6ac85dd8a52479cf276606beae24920eDRC 6739b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, 6749b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, 6759b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 6762e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 67791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC int i, retval=0; JSAMPROW *row_pointer=NULL; 678fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; 679fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; 680fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *outbuf[MAX_COMPONENTS]; 6819b28defe6ac85dd8a52479cf276606beae24920eDRC int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS]; 6829b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPLE *ptr=dstBuf; 683afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned long yuvsize=0; 6849b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr; 685afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 686afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 687afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 6882e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6899b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 6909b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 691007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjEncodeYUV2(): Instance has not been initialized for compression"); 6922e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 693fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 694fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 695fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf[i]=NULL; _tmpbuf[i]=NULL; 696fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; 697fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 698fbb674707e01a61e8b7083faa632dfd46c568b13DRC 6999b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 7009b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0 7019b28defe6ac85dd8a52479cf276606beae24920eDRC || subsamp>=NUMSUBOPT) 7029b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjEncodeYUV2(): Invalid argument"); 7032e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7049b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 7059b28defe6ac85dd8a52479cf276606beae24920eDRC { 7069b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 70791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 70891e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 709efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 7102e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7119b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 7122e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 713afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 714afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(pixelFormat!=TJPF_GRAY) 715afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 716afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); 717afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(!rgbBuf) _throw("tjEncodeYUV2(): Memory allocation failure"); 718afc06929e0a9cf64bdf50da30326076235df7b4fDRC srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); 719afc06929e0a9cf64bdf50da30326076235df7b4fDRC pitch=width*RGB_PIXELSIZE; 720afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 721afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 722afc06929e0a9cf64bdf50da30326076235df7b4fDRC 7239b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 7249b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 7252e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 72625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 72725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 72825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 7292e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7309b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC yuvsize=tjBufSizeYUV(width, height, subsamp); 7319b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0); 73273d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags)==-1) return -1; 7332e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7349b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 7359b28defe6ac85dd8a52479cf276606beae24920eDRC pw=PAD(width, cinfo->max_h_samp_factor); 7369b28defe6ac85dd8a52479cf276606beae24920eDRC ph=PAD(height, cinfo->max_v_samp_factor); 7379b28defe6ac85dd8a52479cf276606beae24920eDRC 7389b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL) 739007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjEncodeYUV2(): Memory allocation failure"); 7409b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 7412e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC { 74225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch]; 7439b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&srcBuf[i*pitch]; 7449b28defe6ac85dd8a52479cf276606beae24920eDRC } 7459b28defe6ac85dd8a52479cf276606beae24920eDRC if(height<ph) 7469b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=height; i<ph; i++) row_pointer[i]=row_pointer[height-1]; 747fbb674707e01a61e8b7083faa632dfd46c568b13DRC 7489b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<cinfo->num_components; i++) 7499b28defe6ac85dd8a52479cf276606beae24920eDRC { 7509b28defe6ac85dd8a52479cf276606beae24920eDRC compptr=&cinfo->comp_info[i]; 7519b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf[i]=(JSAMPLE *)malloc( 7529b28defe6ac85dd8a52479cf276606beae24920eDRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 7539b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16); 754007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!_tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7559b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor); 756007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7579b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<cinfo->max_v_samp_factor; row++) 758fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 7599b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf_aligned= 7609b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf[i], 16); 7619b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=&_tmpbuf_aligned[ 762fbb674707e01a61e8b7083faa632dfd46c568b13DRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 7639b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * row]; 764fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 7659b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16) 7669b28defe6ac85dd8a52479cf276606beae24920eDRC * compptr->v_samp_factor + 16); 767007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!_tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7689b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor); 769007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7709b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<compptr->v_samp_factor; row++) 771fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 7729b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf2_aligned= 7739b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf2[i], 16); 7749b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i][row]=&_tmpbuf2_aligned[ 7759b28defe6ac85dd8a52479cf276606beae24920eDRC PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]; 776fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 7779b28defe6ac85dd8a52479cf276606beae24920eDRC cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor; 7789b28defe6ac85dd8a52479cf276606beae24920eDRC ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor; 7799b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]); 780007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!outbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7819b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ch[i]; row++) 782fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 7839b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 7849b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=PAD(cw[i], 4); 785fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 7866ee54594591d0ae958b81adc8ba3cacde522e5e3DRC } 7879b28defe6ac85dd8a52479cf276606beae24920eDRC if(yuvsize!=(unsigned long)(ptr-dstBuf)) 7889b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjEncodeYUV2(): Generated image is not the correct size"); 7899b28defe6ac85dd8a52479cf276606beae24920eDRC 7909b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ph; row+=cinfo->max_v_samp_factor) 7919b28defe6ac85dd8a52479cf276606beae24920eDRC { 7929b28defe6ac85dd8a52479cf276606beae24920eDRC (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, 0, 7939b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->max_v_samp_factor); 7949b28defe6ac85dd8a52479cf276606beae24920eDRC (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0); 7959b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++, compptr++) 7969b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], 7979b28defe6ac85dd8a52479cf276606beae24920eDRC row*compptr->v_samp_factor/cinfo->max_v_samp_factor, 7989b28defe6ac85dd8a52479cf276606beae24920eDRC compptr->v_samp_factor, cw[i]); 7999b28defe6ac85dd8a52479cf276606beae24920eDRC } 8009b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->next_scanline+=height; 8019b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_compress(cinfo); 8022e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 80391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 8049b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 805afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 806ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 807afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 8082e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC if(row_pointer) free(row_pointer); 809fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 810fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 811fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf[i]!=NULL) free(tmpbuf[i]); 81257423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); 813fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); 81457423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); 815fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(outbuf[i]!=NULL) free(outbuf[i]); 816fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 81791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 8182e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 8192e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8209b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, 8219b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, 8229b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 823842416034561f6d5320165a4fe98825e999a4a37DRC{ 8249b28defe6ac85dd8a52479cf276606beae24920eDRC return tjEncodeYUV2(handle, srcBuf, width, pitch, height, 8259b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags); 826842416034561f6d5320165a4fe98825e999a4a37DRC} 827842416034561f6d5320165a4fe98825e999a4a37DRC 828842416034561f6d5320165a4fe98825e999a4a37DRC 8299b28defe6ac85dd8a52479cf276606beae24920eDRC/* Decompressor */ 8302e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8319b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitDecompress(tjinstance *this) 8322e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 8339b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char buffer[1]; 8342e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8359b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 8369b28defe6ac85dd8a52479cf276606beae24920eDRC this->dinfo.err=jpeg_std_error(&this->jerr.pub); 8379b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 8389b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 8392e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8409b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 8419b28defe6ac85dd8a52479cf276606beae24920eDRC { 8429b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 8439b28defe6ac85dd8a52479cf276606beae24920eDRC if(this) free(this); return NULL; 8449e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8452e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8469b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_decompress(&this->dinfo); 8479b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the source manager */ 8489b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(&this->dinfo, buffer, 1); 8492e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 850007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=DECOMPRESS; 8519b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 8522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 8532e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 854890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitDecompress(void) 855890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 8569b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this; 8579b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 858da5220acdd525242bff4e40b1d90324ebb889825DRC { 859007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 860007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitDecompress(): Memory allocation failure"); 861da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 862da5220acdd525242bff4e40b1d90324ebb889825DRC } 863007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 8649b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitDecompress(this); 865890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 866890f1e0413b54c40b663208779d4ea9dae20eaefDRC 8672e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8689b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, 8699b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, 8709b28defe6ac85dd8a52479cf276606beae24920eDRC int *jpegSubsamp) 8711fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC{ 8729b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=0; 8731fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8749b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 8759b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 876007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Instance has not been initialized for decompression"); 8771fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8789b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL 8799b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp==NULL) 8809b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompressHeader2(): Invalid argument"); 8811fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8829b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 8839b28defe6ac85dd8a52479cf276606beae24920eDRC { 8849b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 8851fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC return -1; 8861fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 8871fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8889b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 8899b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 8901fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8919b28defe6ac85dd8a52479cf276606beae24920eDRC *width=dinfo->image_width; 8929b28defe6ac85dd8a52479cf276606beae24920eDRC *height=dinfo->image_height; 8939b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC *jpegSubsamp=getSubsamp(dinfo); 8941fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8959b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_decompress(dinfo); 8961fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8979b28defe6ac85dd8a52479cf276606beae24920eDRC if(*jpegSubsamp<0) 898007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Could not determine subsampling type for JPEG image"); 899007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(*width<1 || *height<1) 900007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Invalid data returned in header"); 90191e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 90291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 90391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 90491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC} 90591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 9069b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, 9079b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height) 90891e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC{ 9099b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegSubsamp; 9109b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, 9119b28defe6ac85dd8a52479cf276606beae24920eDRC &jpegSubsamp); 9121fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC} 9131fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 9141fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 915109a578e89ea8cd2c39d50b012698148dd11dedbDRCDLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors) 916b28fc5710a510410d2b498255a423dd62b353b3aDRC{ 917109a578e89ea8cd2c39d50b012698148dd11dedbDRC if(numscalingfactors==NULL) 918b28fc5710a510410d2b498255a423dd62b353b3aDRC { 9199b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 920007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjGetScalingFactors(): Invalid argument"); 921109a578e89ea8cd2c39d50b012698148dd11dedbDRC return NULL; 922b28fc5710a510410d2b498255a423dd62b353b3aDRC } 923b28fc5710a510410d2b498255a423dd62b353b3aDRC 924109a578e89ea8cd2c39d50b012698148dd11dedbDRC *numscalingfactors=NUMSF; 925109a578e89ea8cd2c39d50b012698148dd11dedbDRC return (tjscalingfactor *)sf; 926b28fc5710a510410d2b498255a423dd62b353b3aDRC} 927b28fc5710a510410d2b498255a423dd62b353b3aDRC 928b28fc5710a510410d2b498255a423dd62b353b3aDRC 9299b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, 9309b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 9319b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelFormat, int flags) 9329b28defe6ac85dd8a52479cf276606beae24920eDRC{ 9339b28defe6ac85dd8a52479cf276606beae24920eDRC int i, retval=0; JSAMPROW *row_pointer=NULL; 9349b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegwidth, jpegheight, scaledw, scaledh; 935afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 936afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 937afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *_dstBuf=NULL; int _pitch=0; 938afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 9399b28defe6ac85dd8a52479cf276606beae24920eDRC 9409b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 9419b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 942007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Instance has not been initialized for decompression"); 9439b28defe6ac85dd8a52479cf276606beae24920eDRC 9449b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 9459b28defe6ac85dd8a52479cf276606beae24920eDRC || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) 9469b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompress2(): Invalid argument"); 9479b28defe6ac85dd8a52479cf276606beae24920eDRC 94825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 94925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 95025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 9519b28defe6ac85dd8a52479cf276606beae24920eDRC 9529b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 9539b28defe6ac85dd8a52479cf276606beae24920eDRC { 9549b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 9559b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 9569b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 9579b28defe6ac85dd8a52479cf276606beae24920eDRC } 9589b28defe6ac85dd8a52479cf276606beae24920eDRC 9599b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 9609b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 96173d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC if(setDecompDefaults(dinfo, pixelFormat, flags)==-1) 9622eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC { 9632eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC retval=-1; goto bailout; 9642eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC } 9659b28defe6ac85dd8a52479cf276606beae24920eDRC 96625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 9679b28defe6ac85dd8a52479cf276606beae24920eDRC 9689b28defe6ac85dd8a52479cf276606beae24920eDRC jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; 9699b28defe6ac85dd8a52479cf276606beae24920eDRC if(width==0) width=jpegwidth; 9709b28defe6ac85dd8a52479cf276606beae24920eDRC if(height==0) height=jpegheight; 9719b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<NUMSF; i++) 9729b28defe6ac85dd8a52479cf276606beae24920eDRC { 9739b28defe6ac85dd8a52479cf276606beae24920eDRC scaledw=TJSCALED(jpegwidth, sf[i]); 9749b28defe6ac85dd8a52479cf276606beae24920eDRC scaledh=TJSCALED(jpegheight, sf[i]); 9759b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw<=width && scaledh<=height) 9769b28defe6ac85dd8a52479cf276606beae24920eDRC break; 9779b28defe6ac85dd8a52479cf276606beae24920eDRC } 9789b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw>width || scaledh>height) 979007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Could not scale down to desired image dimensions"); 9809b28defe6ac85dd8a52479cf276606beae24920eDRC width=scaledw; height=scaledh; 9819b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_num=sf[i].num; 9829b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_denom=sf[i].denom; 9839b28defe6ac85dd8a52479cf276606beae24920eDRC 9849b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 9859b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; 986afc06929e0a9cf64bdf50da30326076235df7b4fDRC 987afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 988afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(pixelFormat!=TJPF_GRAY && 989afc06929e0a9cf64bdf50da30326076235df7b4fDRC (RGB_RED!=tjRedOffset[pixelFormat] || 990afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_GREEN!=tjGreenOffset[pixelFormat] || 991afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_BLUE!=tjBlueOffset[pixelFormat] || 992afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) 993afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 994afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*3); 995afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure"); 996afc06929e0a9cf64bdf50da30326076235df7b4fDRC _pitch=pitch; pitch=width*3; 997afc06929e0a9cf64bdf50da30326076235df7b4fDRC _dstBuf=dstBuf; dstBuf=rgbBuf; 998afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 999afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 1000afc06929e0a9cf64bdf50da30326076235df7b4fDRC 10019b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) 10029b28defe6ac85dd8a52479cf276606beae24920eDRC *dinfo->output_height))==NULL) 1003007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Memory allocation failure"); 10049b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<(int)dinfo->output_height; i++) 10059b28defe6ac85dd8a52479cf276606beae24920eDRC { 100625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) 10079b28defe6ac85dd8a52479cf276606beae24920eDRC row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]; 10089b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&dstBuf[i*pitch]; 10099b28defe6ac85dd8a52479cf276606beae24920eDRC } 10109b28defe6ac85dd8a52479cf276606beae24920eDRC while(dinfo->output_scanline<dinfo->output_height) 10119b28defe6ac85dd8a52479cf276606beae24920eDRC { 10129b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], 10139b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->output_height-dinfo->output_scanline); 10149b28defe6ac85dd8a52479cf276606beae24920eDRC } 10159b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 10169b28defe6ac85dd8a52479cf276606beae24920eDRC 1017afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1018afc06929e0a9cf64bdf50da30326076235df7b4fDRC fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); 1019afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 1020afc06929e0a9cf64bdf50da30326076235df7b4fDRC 10219b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 10229b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 1023afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1024ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 1025afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 10269b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 10279b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 10289b28defe6ac85dd8a52479cf276606beae24920eDRC} 10299b28defe6ac85dd8a52479cf276606beae24920eDRC 10309b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, 10319b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 10329b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelSize, int flags) 10339b28defe6ac85dd8a52479cf276606beae24920eDRC{ 10349b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 10359b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags); 10369b28defe6ac85dd8a52479cf276606beae24920eDRC else 10379b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch, 10389b28defe6ac85dd8a52479cf276606beae24920eDRC height, getPixelFormat(pixelSize, flags), flags); 10399b28defe6ac85dd8a52479cf276606beae24920eDRC} 10409b28defe6ac85dd8a52479cf276606beae24920eDRC 10419b28defe6ac85dd8a52479cf276606beae24920eDRC 10429b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, 10439b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, 1044b28fc5710a510410d2b498255a423dd62b353b3aDRC int flags) 10452e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 10469b28defe6ac85dd8a52479cf276606beae24920eDRC int i, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS]; 1047f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS], 1048f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; 10499b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPLE *_tmpbuf=NULL, *ptr=dstBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS]; 10502e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 10519b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 10529b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 1053007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Instance has not been initialized for decompression"); 10542e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1055f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<MAX_COMPONENTS; i++) 1056f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 1057f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbuf[i]=NULL; outbuf[i]=NULL; 1058f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 10599e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC 10609b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL) 10619b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompressToYUV(): Invalid argument"); 10622e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 106325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 106425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 106525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 10660c6a271f974529e4795332c9ad428500ef17fb42DRC 10679b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 10689b28defe6ac85dd8a52479cf276606beae24920eDRC { 10699b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 107091e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 107191e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 10729e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 10732e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 10749b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 10759b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 10762e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 10779b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 10789e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 10799b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 10809b28defe6ac85dd8a52479cf276606beae24920eDRC int ih; 10819b28defe6ac85dd8a52479cf276606beae24920eDRC iw[i]=compptr->width_in_blocks*DCTSIZE; 10829b28defe6ac85dd8a52479cf276606beae24920eDRC ih=compptr->height_in_blocks*DCTSIZE; 10839b28defe6ac85dd8a52479cf276606beae24920eDRC cw[i]=PAD(dinfo->image_width, dinfo->max_h_samp_factor) 10849b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->h_samp_factor/dinfo->max_h_samp_factor; 10859b28defe6ac85dd8a52479cf276606beae24920eDRC ch[i]=PAD(dinfo->image_height, dinfo->max_v_samp_factor) 10869b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->v_samp_factor/dinfo->max_v_samp_factor; 10879b28defe6ac85dd8a52479cf276606beae24920eDRC if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1; 10889b28defe6ac85dd8a52479cf276606beae24920eDRC th[i]=compptr->v_samp_factor*DCTSIZE; 10899b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbufsize+=iw[i]*th[i]; 10909b28defe6ac85dd8a52479cf276606beae24920eDRC if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]))==NULL) 1091007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 10929b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ch[i]; row++) 10939e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 10949b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 10959b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=PAD(cw[i], 4); 1096f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 10979b28defe6ac85dd8a52479cf276606beae24920eDRC } 10989b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 10999b28defe6ac85dd8a52479cf276606beae24920eDRC { 11009b28defe6ac85dd8a52479cf276606beae24920eDRC if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL) 1101007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 11029b28defe6ac85dd8a52479cf276606beae24920eDRC ptr=_tmpbuf; 11039b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 1104f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 11059b28defe6ac85dd8a52479cf276606beae24920eDRC if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL) 1106007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 11079b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<th[i]; row++) 1108f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 11099b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=ptr; 11109b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=iw[i]; 11119e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11129e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11139e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11142e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 111525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 1116e0419b530b3cecb9d7546893d893489a24d21032DRC if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; 11179b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->raw_data_out=TRUE; 11189b28defe6ac85dd8a52479cf276606beae24920eDRC 11199b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 11209b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<(int)dinfo->output_height; 11219b28defe6ac85dd8a52479cf276606beae24920eDRC row+=dinfo->max_v_samp_factor*DCTSIZE) 11228ed7b814039172fe3cbfadfee3922801a3888b73DRC { 11239b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPARRAY yuvptr[MAX_COMPONENTS]; 11249b28defe6ac85dd8a52479cf276606beae24920eDRC int crow[MAX_COMPONENTS]; 11259b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 1126842416034561f6d5320165a4fe98825e999a4a37DRC { 11279b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 11289b28defe6ac85dd8a52479cf276606beae24920eDRC crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_factor; 11299b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) yuvptr[i]=tmpbuf[i]; 11309b28defe6ac85dd8a52479cf276606beae24920eDRC else yuvptr[i]=&outbuf[i][crow[i]]; 1131842416034561f6d5320165a4fe98825e999a4a37DRC } 11329b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_raw_data(dinfo, yuvptr, dinfo->max_v_samp_factor*DCTSIZE); 11339b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 11349e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 11359b28defe6ac85dd8a52479cf276606beae24920eDRC int j; 1136f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<dinfo->num_components; i++) 11379e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 11389b28defe6ac85dd8a52479cf276606beae24920eDRC for(j=0; j<min(th[i], ch[i]-crow[i]); j++) 1139f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 11409b28defe6ac85dd8a52479cf276606beae24920eDRC memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j], cw[i]); 1141f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 11429e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11439e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11449e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11459b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 11462e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 114791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 11489b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 11499e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC for(i=0; i<MAX_COMPONENTS; i++) 1150f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 1151f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(tmpbuf[i]) free(tmpbuf[i]); 11529e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC if(outbuf[i]) free(outbuf[i]); 1153f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 1154f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(_tmpbuf) free(_tmpbuf); 115591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 11562e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 11572e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 11582e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 11599b28defe6ac85dd8a52479cf276606beae24920eDRC/* Transformer */ 1160890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1161890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitTransform(void) 1162890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 11639b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; tjhandle handle=NULL; 11649b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 1165da5220acdd525242bff4e40b1d90324ebb889825DRC { 1166007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 1167007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitTransform(): Memory allocation failure"); 1168da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 1169da5220acdd525242bff4e40b1d90324ebb889825DRC } 1170007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 11719b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitCompress(this); 11729b28defe6ac85dd8a52479cf276606beae24920eDRC if(!handle) return NULL; 11739b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitDecompress(this); 11749b28defe6ac85dd8a52479cf276606beae24920eDRC return handle; 1175890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 1176890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1177890f1e0413b54c40b663208779d4ea9dae20eaefDRC 11789b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf, 11799b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, int n, unsigned char **dstBufs, 11809b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *dstSizes, tjtransform *t, int flags) 1181890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 11820a325197dedd2eede99731c68ae0e0a145473f64DRC jpeg_transform_info *xinfo=NULL; 1183890f1e0413b54c40b663208779d4ea9dae20eaefDRC jvirt_barray_ptr *srccoefs, *dstcoefs; 11849b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=0, i, jpegSubsamp; 1185890f1e0413b54c40b663208779d4ea9dae20eaefDRC 11869b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 11879b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0) 1188007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Instance has not been initialized for transformation"); 1189890f1e0413b54c40b663208779d4ea9dae20eaefDRC 11909b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NULL 11910a325197dedd2eede99731c68ae0e0a145473f64DRC || t==NULL || flags<0) 11929b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjTransform(): Invalid argument"); 1193890f1e0413b54c40b663208779d4ea9dae20eaefDRC 119425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 119525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 119625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 1197890f1e0413b54c40b663208779d4ea9dae20eaefDRC 11989b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 11999b28defe6ac85dd8a52479cf276606beae24920eDRC { 12009b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 1201890f1e0413b54c40b663208779d4ea9dae20eaefDRC retval=-1; 1202890f1e0413b54c40b663208779d4ea9dae20eaefDRC goto bailout; 1203890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1204890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12059b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 1206890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12070a325197dedd2eede99731c68ae0e0a145473f64DRC if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n)) 12080a325197dedd2eede99731c68ae0e0a145473f64DRC ==NULL) 1209007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Memory allocation failure"); 1210007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(xinfo, sizeof(jpeg_transform_info)*n); 1211890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12120a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 1213890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 12140a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].transform=xformtypes[t[i].op]; 121525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].perfect=(t[i].options&TJXOPT_PERFECT)? 1:0; 121625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].trim=(t[i].options&TJXOPT_TRIM)? 1:0; 121725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].force_grayscale=(t[i].options&TJXOPT_GRAY)? 1:0; 121825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].crop=(t[i].options&TJXOPT_CROP)? 1:0; 121925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(n!=1 && t[i].op==TJXOP_HFLIP) xinfo[i].slow_hflip=1; 1220ba5ea5143e48b71234414139e3b4cb244599e875DRC else xinfo[i].slow_hflip=0; 12210a325197dedd2eede99731c68ae0e0a145473f64DRC 12220a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 1223890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 12240a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_xoffset=t[i].r.x; xinfo[i].crop_xoffset_set=JCROP_POS; 12250a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_yoffset=t[i].r.y; xinfo[i].crop_yoffset_set=JCROP_POS; 12260a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.w!=0) 12270a325197dedd2eede99731c68ae0e0a145473f64DRC { 12280a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_width=t[i].r.w; xinfo[i].crop_width_set=JCROP_POS; 12290a325197dedd2eede99731c68ae0e0a145473f64DRC } 1230d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_width=JCROP_UNSET; 12310a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.h!=0) 12320a325197dedd2eede99731c68ae0e0a145473f64DRC { 12330a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_height=t[i].r.h; xinfo[i].crop_height_set=JCROP_POS; 12340a325197dedd2eede99731c68ae0e0a145473f64DRC } 1235d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_height=JCROP_UNSET; 1236890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1237890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1238890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12399b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_markers_setup(dinfo, JCOPYOPT_ALL); 12409b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 12419b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC jpegSubsamp=getSubsamp(dinfo); 12429b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(jpegSubsamp<0) 12439b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjTransform(): Could not determine subsampling type for JPEG image"); 1244890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12450a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 1246890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 12479b28defe6ac85dd8a52479cf276606beae24920eDRC if(!jtransform_request_workspace(dinfo, &xinfo[i])) 1248007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Transform is not perfect"); 12490a325197dedd2eede99731c68ae0e0a145473f64DRC 12500a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 12510a325197dedd2eede99731c68ae0e0a145473f64DRC { 12520a325197dedd2eede99731c68ae0e0a145473f64DRC if((t[i].r.x%xinfo[i].iMCU_sample_width)!=0 12530a325197dedd2eede99731c68ae0e0a145473f64DRC || (t[i].r.y%xinfo[i].iMCU_sample_height)!=0) 12540a325197dedd2eede99731c68ae0e0a145473f64DRC { 12559b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 12560a325197dedd2eede99731c68ae0e0a145473f64DRC "To crop this JPEG image, x must be a multiple of %d\n" 12570a325197dedd2eede99731c68ae0e0a145473f64DRC "and y must be a multiple of %d.\n", 12580a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].iMCU_sample_width, xinfo[i].iMCU_sample_height); 12590a325197dedd2eede99731c68ae0e0a145473f64DRC retval=-1; goto bailout; 12600a325197dedd2eede99731c68ae0e0a145473f64DRC } 12610a325197dedd2eede99731c68ae0e0a145473f64DRC } 1262890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1263890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12649b28defe6ac85dd8a52479cf276606beae24920eDRC srccoefs=jpeg_read_coefficients(dinfo); 1265890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12660a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 1267890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 1268ff78e37595c8462f64fd100f928aa1d08539527eDRC int w, h, alloc=1; 12690a325197dedd2eede99731c68ae0e0a145473f64DRC if(!xinfo[i].crop) 1270890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 12719b28defe6ac85dd8a52479cf276606beae24920eDRC w=dinfo->image_width; h=dinfo->image_height; 1272890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 12730a325197dedd2eede99731c68ae0e0a145473f64DRC else 12740a325197dedd2eede99731c68ae0e0a145473f64DRC { 12750a325197dedd2eede99731c68ae0e0a145473f64DRC w=xinfo[i].crop_width; h=xinfo[i].crop_height; 12760a325197dedd2eede99731c68ae0e0a145473f64DRC } 1277ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 1278ff78e37595c8462f64fd100f928aa1d08539527eDRC { 12799b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC alloc=0; dstSizes[i]=tjBufSize(w, h, jpegSubsamp); 1280ff78e37595c8462f64fd100f928aa1d08539527eDRC } 12817bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) 12827bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_mem_dest_tj(cinfo, &dstBufs[i], &dstSizes[i], alloc); 12839b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_copy_critical_parameters(dinfo, cinfo); 12849b28defe6ac85dd8a52479cf276606beae24920eDRC dstcoefs=jtransform_adjust_parameters(dinfo, cinfo, srccoefs, 12850a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 12867bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) 12877bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 12887bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_write_coefficients(cinfo, dstcoefs); 12897bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL); 12907bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 12917bf04d399ebf9a3b39a6d5b5639d895df618353dDRC else jinit_c_master_control(cinfo, TRUE); 12929b28defe6ac85dd8a52479cf276606beae24920eDRC jtransform_execute_transformation(dinfo, cinfo, srccoefs, 12930a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 12947bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(t[i].customFilter) 12957bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 1296efe28cec4b29b5a7357d9cd1c30a066486d19b12DRC int ci, y; JDIMENSION by; 12977bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(ci=0; ci<cinfo->num_components; ci++) 12987bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 12997bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_component_info *compptr=&cinfo->comp_info[ci]; 13007bf04d399ebf9a3b39a6d5b5639d895df618353dDRC tjregion arrayRegion={0, 0, compptr->width_in_blocks*DCTSIZE, 13017bf04d399ebf9a3b39a6d5b5639d895df618353dDRC DCTSIZE}; 13027bf04d399ebf9a3b39a6d5b5639d895df618353dDRC tjregion planeRegion={0, 0, compptr->width_in_blocks*DCTSIZE, 13037bf04d399ebf9a3b39a6d5b5639d895df618353dDRC compptr->height_in_blocks*DCTSIZE}; 13047bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(by=0; by<compptr->height_in_blocks; by+=compptr->v_samp_factor) 13057bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 13067bf04d399ebf9a3b39a6d5b5639d895df618353dDRC JBLOCKARRAY barray=(dinfo->mem->access_virt_barray) 13077bf04d399ebf9a3b39a6d5b5639d895df618353dDRC ((j_common_ptr)dinfo, dstcoefs[ci], by, compptr->v_samp_factor, 13087bf04d399ebf9a3b39a6d5b5639d895df618353dDRC TRUE); 13097bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(y=0; y<compptr->v_samp_factor; y++) 13107bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 13117bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(t[i].customFilter(barray[y][0], arrayRegion, planeRegion, 1312f5467110763f7a44ca8baf1c035eb39a68c913c6DRC ci, i, &t[i])==-1) 13137bf04d399ebf9a3b39a6d5b5639d895df618353dDRC _throw("tjTransform(): Error in custom filter"); 13147bf04d399ebf9a3b39a6d5b5639d895df618353dDRC arrayRegion.y+=DCTSIZE; 13157bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 13167bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 13177bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 13187bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 13197bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) jpeg_finish_compress(cinfo); 1320890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1321890f1e0413b54c40b663208779d4ea9dae20eaefDRC 13229b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 1323890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1324890f1e0413b54c40b663208779d4ea9dae20eaefDRC bailout: 13259b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 13269b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 13270a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo) free(xinfo); 1328890f1e0413b54c40b663208779d4ea9dae20eaefDRC return retval; 1329890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 1330