turbojpeg.c revision ea3396a9456fbe403e0defd2991a308d7c400abc
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 299b28defe6ac85dd8a52479cf276606beae24920eDRC/* TurboJPEG/OSS: this implements the TurboJPEG API using libjpeg-turbo */ 302e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 312e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <stdio.h> 322e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <stdlib.h> 33296c71ba0ffb034390a3d0b00a0cc6d6fa014b6eDRC#include <jinclude.h> 34fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define JPEG_INTERNALS 352e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jpeglib.h> 362e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jerror.h> 372e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <setjmp.h> 382e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include "./turbojpeg.h" 39a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#include "./tjutil.h" 40890f1e0413b54c40b663208779d4ea9dae20eaefDRC#include "transupp.h" 412a2e451ddc9e3c093a903ccb5a06962d05c21b67DRC 429b28defe6ac85dd8a52479cf276606beae24920eDRCextern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, 439b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *, boolean); 449b28defe6ac85dd8a52479cf276606beae24920eDRCextern void jpeg_mem_src_tj(j_decompress_ptr, unsigned char *, unsigned long); 459b28defe6ac85dd8a52479cf276606beae24920eDRC 46fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define PAD(v, p) ((v+(p)-1)&(~((p)-1))) 472e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 482e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 499b28defe6ac85dd8a52479cf276606beae24920eDRC/* Error handling (based on example in example.c) */ 502e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 519b28defe6ac85dd8a52479cf276606beae24920eDRCstatic char errStr[JMSG_LENGTH_MAX]="No error"; 522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 539b28defe6ac85dd8a52479cf276606beae24920eDRCstruct my_error_mgr 542e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 552e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_error_mgr pub; 569b28defe6ac85dd8a52479cf276606beae24920eDRC jmp_buf setjmp_buffer; 579b28defe6ac85dd8a52479cf276606beae24920eDRC}; 589b28defe6ac85dd8a52479cf276606beae24920eDRCtypedef struct my_error_mgr *my_error_ptr; 592e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 602e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCstatic void my_error_exit(j_common_ptr cinfo) 612e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 629b28defe6ac85dd8a52479cf276606beae24920eDRC my_error_ptr myerr=(my_error_ptr)cinfo->err; 632e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC (*cinfo->err->output_message)(cinfo); 649b28defe6ac85dd8a52479cf276606beae24920eDRC longjmp(myerr->setjmp_buffer, 1); 652e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 662e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 679b28defe6ac85dd8a52479cf276606beae24920eDRC/* Based on output_message() in jerror.c */ 689b28defe6ac85dd8a52479cf276606beae24920eDRC 692e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCstatic void my_output_message(j_common_ptr cinfo) 702e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 719b28defe6ac85dd8a52479cf276606beae24920eDRC (*cinfo->err->format_message)(cinfo, errStr); 722e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 732e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 742e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 759b28defe6ac85dd8a52479cf276606beae24920eDRC/* Global structures, macros, etc. */ 762e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 779b28defe6ac85dd8a52479cf276606beae24920eDRCenum {COMPRESS=1, DECOMPRESS=2}; 789b28defe6ac85dd8a52479cf276606beae24920eDRC 799b28defe6ac85dd8a52479cf276606beae24920eDRCtypedef struct _tjinstance 802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 812e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_compress_struct cinfo; 822e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC struct jpeg_decompress_struct dinfo; 839b28defe6ac85dd8a52479cf276606beae24920eDRC struct my_error_mgr jerr; 849b28defe6ac85dd8a52479cf276606beae24920eDRC int init; 859b28defe6ac85dd8a52479cf276606beae24920eDRC} tjinstance; 862e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 87007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRCstatic const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3}; 889b28defe6ac85dd8a52479cf276606beae24920eDRC 89007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRCstatic const JXFORM_CODE xformtypes[TJ_NUMXOP]= 90007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC{ 91890f1e0413b54c40b663208779d4ea9dae20eaefDRC JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE, 92890f1e0413b54c40b663208779d4ea9dae20eaefDRC JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270 93890f1e0413b54c40b663208779d4ea9dae20eaefDRC}; 949b28defe6ac85dd8a52479cf276606beae24920eDRC 95ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC#define NUMSF 16 96109a578e89ea8cd2c39d50b012698148dd11dedbDRCstatic const tjscalingfactor sf[NUMSF]={ 97ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {2, 1}, 98ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {15, 8}, 99ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {7, 4}, 100ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {13, 8}, 101ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 2}, 102ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {11, 8}, 103ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {5, 4}, 104ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {9, 8}, 105109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 1}, 106ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {7, 8}, 107ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 4}, 108ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {5, 8}, 109109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 2}, 110ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC {3, 8}, 111109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 4}, 112109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 8} 113109a578e89ea8cd2c39d50b012698148dd11dedbDRC}; 1142e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 115a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ 116da5220acdd525242bff4e40b1d90324ebb889825DRC retval=-1; goto bailout;} 1179b28defe6ac85dd8a52479cf276606beae24920eDRC#define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ 1189b28defe6ac85dd8a52479cf276606beae24920eDRC j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ 1199b28defe6ac85dd8a52479cf276606beae24920eDRC if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ 1209b28defe6ac85dd8a52479cf276606beae24920eDRC return -1;} \ 1219b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo=&this->cinfo; dinfo=&this->dinfo; 1229b28defe6ac85dd8a52479cf276606beae24920eDRC 1239b28defe6ac85dd8a52479cf276606beae24920eDRCstatic int getPixelFormat(int pixelSize, int flags) 1249b28defe6ac85dd8a52479cf276606beae24920eDRC{ 12525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(pixelSize==1) return TJPF_GRAY; 1269b28defe6ac85dd8a52479cf276606beae24920eDRC if(pixelSize==3) 1279b28defe6ac85dd8a52479cf276606beae24920eDRC { 12825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_BGR; 12925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_RGB; 1309b28defe6ac85dd8a52479cf276606beae24920eDRC } 1319b28defe6ac85dd8a52479cf276606beae24920eDRC if(pixelSize==4) 1329b28defe6ac85dd8a52479cf276606beae24920eDRC { 1339b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_ALPHAFIRST) 1349b28defe6ac85dd8a52479cf276606beae24920eDRC { 13525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_XBGR; 13625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_XRGB; 1379b28defe6ac85dd8a52479cf276606beae24920eDRC } 1389b28defe6ac85dd8a52479cf276606beae24920eDRC else 1399b28defe6ac85dd8a52479cf276606beae24920eDRC { 14025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_BGRX; 14125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_RGBX; 1429b28defe6ac85dd8a52479cf276606beae24920eDRC } 1439b28defe6ac85dd8a52479cf276606beae24920eDRC } 1449b28defe6ac85dd8a52479cf276606beae24920eDRC return -1; 1459b28defe6ac85dd8a52479cf276606beae24920eDRC} 1469b28defe6ac85dd8a52479cf276606beae24920eDRC 147f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setCompDefaults(struct jpeg_compress_struct *cinfo, 1489b28defe6ac85dd8a52479cf276606beae24920eDRC int pixelFormat, int subsamp, int jpegQual) 1499b28defe6ac85dd8a52479cf276606beae24920eDRC{ 150f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC int retval=0; 151f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 1529b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 1539b28defe6ac85dd8a52479cf276606beae24920eDRC { 15425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 1559b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_GRAYSCALE; break; 1569b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 15725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 1589b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGB; break; 15925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 1609b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGR; break; 16125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 16267ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_RGBA: 1639b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGBX; break; 16425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 16567ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_BGRA: 1669b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGRX; break; 16725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 16867ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ARGB: 1699b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XRGB; break; 17025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 17167ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ABGR: 1729b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XBGR; break; 1739b28defe6ac85dd8a52479cf276606beae24920eDRC #else 17425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 175afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 176afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 177afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 178afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 179afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 180afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 181afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 182afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 183afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 184afc06929e0a9cf64bdf50da30326076235df7b4fDRC cinfo->in_color_space=JCS_RGB; pixelFormat=TJPF_RGB; 185afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 1869b28defe6ac85dd8a52479cf276606beae24920eDRC #endif 1879b28defe6ac85dd8a52479cf276606beae24920eDRC } 1889b28defe6ac85dd8a52479cf276606beae24920eDRC 1899b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->input_components=tjPixelSize[pixelFormat]; 1909b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_defaults(cinfo); 1919b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegQual>=0) 1929b28defe6ac85dd8a52479cf276606beae24920eDRC { 1939b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_quality(cinfo, jpegQual, TRUE); 1949b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegQual>=96) cinfo->dct_method=JDCT_ISLOW; 1959b28defe6ac85dd8a52479cf276606beae24920eDRC else cinfo->dct_method=JDCT_FASTEST; 1969b28defe6ac85dd8a52479cf276606beae24920eDRC } 19725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(subsamp==TJSAMP_GRAY) 1989b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); 1999b28defe6ac85dd8a52479cf276606beae24920eDRC else 2009b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_YCbCr); 2019b28defe6ac85dd8a52479cf276606beae24920eDRC 2029b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; 2039b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].h_samp_factor=1; 2049b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].h_samp_factor=1; 2059b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; 2069b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].v_samp_factor=1; 2079b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].v_samp_factor=1; 208f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 209f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return retval; 2109b28defe6ac85dd8a52479cf276606beae24920eDRC} 2119b28defe6ac85dd8a52479cf276606beae24920eDRC 212f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setDecompDefaults(struct jpeg_decompress_struct *dinfo, 2139b28defe6ac85dd8a52479cf276606beae24920eDRC int pixelFormat) 2149b28defe6ac85dd8a52479cf276606beae24920eDRC{ 215f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC int retval=0; 216f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 2179b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 2189b28defe6ac85dd8a52479cf276606beae24920eDRC { 21925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 2209b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_GRAYSCALE; break; 2219b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 22225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 2239b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGB; break; 22425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 2259b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGR; break; 22625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 2279b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGBX; break; 22825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 2299b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGRX; break; 23025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 2319b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XRGB; break; 23225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 2339b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XBGR; break; 23467ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #if JCS_ALPHA_EXTENSIONS==1 23567ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_RGBA: 23667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_RGBA; break; 23767ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_BGRA: 23867ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_BGRA; break; 23967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ARGB: 24067ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_ARGB; break; 24167ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ABGR: 24267ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_ABGR; break; 24367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #endif 2449b28defe6ac85dd8a52479cf276606beae24920eDRC #else 24525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 246afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 247afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 248afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 249afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 250afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 251afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 252afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 253afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 254afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 255afc06929e0a9cf64bdf50da30326076235df7b4fDRC dinfo->out_color_space=JCS_RGB; break; 25667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #endif 2579b28defe6ac85dd8a52479cf276606beae24920eDRC default: 2589b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("Unsupported pixel format"); 2599b28defe6ac85dd8a52479cf276606beae24920eDRC } 260f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 261f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC bailout: 262f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return retval; 2639b28defe6ac85dd8a52479cf276606beae24920eDRC} 2642e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2652e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2669b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCstatic int getSubsamp(j_decompress_ptr dinfo) 2679b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 2689b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=-1, i, k; 2699b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC for(i=0; i<NUMSUBOPT; i++) 2709b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2719b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->num_components==pixelsize[i]) 2729b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2739b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8 2749b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC && dinfo->comp_info[0].v_samp_factor==tjMCUHeight[i]/8) 2759b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2769b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int match=0; 2779b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC for(k=1; k<dinfo->num_components; k++) 2789b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2799b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->comp_info[k].h_samp_factor==1 2809b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC && dinfo->comp_info[k].v_samp_factor==1) 2819b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC match++; 2829b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2839b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(match==dinfo->num_components-1) 2849b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2859b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC retval=i; break; 2869b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2879b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2889b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2899b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2909b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return retval; 2919b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 2929b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 2939b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 294afc06929e0a9cf64bdf50da30326076235df7b4fDRC#ifndef JCS_EXTENSIONS 295afc06929e0a9cf64bdf50da30326076235df7b4fDRC 296afc06929e0a9cf64bdf50da30326076235df7b4fDRC/* Conversion functions to emulate the colorspace extensions. This allows the 297afc06929e0a9cf64bdf50da30326076235df7b4fDRC TurboJPEG wrapper to be used with libjpeg */ 298afc06929e0a9cf64bdf50da30326076235df7b4fDRC 299afc06929e0a9cf64bdf50da30326076235df7b4fDRC#define TORGB(PS, ROFFSET, GOFFSET, BOFFSET) { \ 300afc06929e0a9cf64bdf50da30326076235df7b4fDRC int rowPad=pitch-width*PS; \ 301afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(height--) \ 302afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 303afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *endOfRow=src+width*PS; \ 304afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(src<endOfRow) \ 305afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 306afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_RED]=src[ROFFSET]; \ 307afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_GREEN]=src[GOFFSET]; \ 308afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[RGB_BLUE]=src[BOFFSET]; \ 309afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=RGB_PIXELSIZE; src+=PS; \ 310afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 311afc06929e0a9cf64bdf50da30326076235df7b4fDRC src+=rowPad; \ 312afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 313afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 314afc06929e0a9cf64bdf50da30326076235df7b4fDRC 315afc06929e0a9cf64bdf50da30326076235df7b4fDRCstatic unsigned char *toRGB(unsigned char *src, int width, int pitch, 316afc06929e0a9cf64bdf50da30326076235df7b4fDRC int height, int pixelFormat, unsigned char *dst) 317afc06929e0a9cf64bdf50da30326076235df7b4fDRC{ 318afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *retval=src; 319afc06929e0a9cf64bdf50da30326076235df7b4fDRC switch(pixelFormat) 320afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 321afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGB: 322afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3 323afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(3, 0, 1, 2); 324afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 325afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 326afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 327afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3 328afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(3, 2, 1, 0); 329afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 330afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 331afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 332afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 333afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 334afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 0, 1, 2); 335afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 336afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 337afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 338afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 339afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 340afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 2, 1, 0); 341afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 342afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 343afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 344afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 345afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 346afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 1, 2, 3); 347afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 348afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 349afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 350afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 351afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 352afc06929e0a9cf64bdf50da30326076235df7b4fDRC retval=dst; TORGB(4, 3, 2, 1); 353afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 354afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 355afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 356afc06929e0a9cf64bdf50da30326076235df7b4fDRC return retval; 357afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 358afc06929e0a9cf64bdf50da30326076235df7b4fDRC 359afc06929e0a9cf64bdf50da30326076235df7b4fDRC#define FROMRGB(PS, ROFFSET, GOFFSET, BOFFSET, SETALPHA) { \ 360afc06929e0a9cf64bdf50da30326076235df7b4fDRC int rowPad=pitch-width*PS; \ 361afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(height--) \ 362afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 363afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *endOfRow=dst+width*PS; \ 364afc06929e0a9cf64bdf50da30326076235df7b4fDRC while(dst<endOfRow) \ 365afc06929e0a9cf64bdf50da30326076235df7b4fDRC { \ 366afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[ROFFSET]=src[RGB_RED]; \ 367afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[GOFFSET]=src[RGB_GREEN]; \ 368afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst[BOFFSET]=src[RGB_BLUE]; \ 369afc06929e0a9cf64bdf50da30326076235df7b4fDRC SETALPHA \ 370afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=PS; src+=RGB_PIXELSIZE; \ 371afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 372afc06929e0a9cf64bdf50da30326076235df7b4fDRC dst+=rowPad; \ 373afc06929e0a9cf64bdf50da30326076235df7b4fDRC } \ 374afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 375afc06929e0a9cf64bdf50da30326076235df7b4fDRC 376afc06929e0a9cf64bdf50da30326076235df7b4fDRCstatic void fromRGB(unsigned char *src, unsigned char *dst, int width, 377afc06929e0a9cf64bdf50da30326076235df7b4fDRC int pitch, int height, int pixelFormat) 378afc06929e0a9cf64bdf50da30326076235df7b4fDRC{ 379afc06929e0a9cf64bdf50da30326076235df7b4fDRC switch(pixelFormat) 380afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 381afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGB: 382afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3 383afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(3, 0, 1, 2,); 384afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 385afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 386afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGR: 387afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3 388afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(3, 2, 1, 0,); 389afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 390afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 391afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBX: 392afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 393afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 0, 1, 2,); 394afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 395afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 396afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_RGBA: 397afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4 398afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 0, 1, 2, dst[3]=0xFF;); 399afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 400afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 401afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRX: 402afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 403afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 2, 1, 0,); 404afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 405afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 406afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_BGRA: 407afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4 408afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 2, 1, 0, dst[3]=0xFF;); return; 409afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 410afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 411afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XRGB: 412afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 413afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 1, 2, 3,); return; 414afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 415afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 416afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ARGB: 417afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4 418afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 1, 2, 3, dst[0]=0xFF;); return; 419afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 420afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 421afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_XBGR: 422afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 423afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 3, 2, 1,); return; 424afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 425afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 426afc06929e0a9cf64bdf50da30326076235df7b4fDRC case TJPF_ABGR: 427afc06929e0a9cf64bdf50da30326076235df7b4fDRC #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4 428afc06929e0a9cf64bdf50da30326076235df7b4fDRC FROMRGB(4, 3, 2, 1, dst[0]=0xFF;); return; 429afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 430afc06929e0a9cf64bdf50da30326076235df7b4fDRC break; 431afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 432afc06929e0a9cf64bdf50da30326076235df7b4fDRC} 433afc06929e0a9cf64bdf50da30326076235df7b4fDRC 434afc06929e0a9cf64bdf50da30326076235df7b4fDRC#endif 435afc06929e0a9cf64bdf50da30326076235df7b4fDRC 436afc06929e0a9cf64bdf50da30326076235df7b4fDRC 4379b28defe6ac85dd8a52479cf276606beae24920eDRC/* General API functions */ 4382e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4399b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT char* DLLCALL tjGetErrorStr(void) 4402e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 4419b28defe6ac85dd8a52479cf276606beae24920eDRC return errStr; 4422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 4432e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4449b28defe6ac85dd8a52479cf276606beae24920eDRC 4459b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDestroy(tjhandle handle) 4462e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 4479b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 4489b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) return -1; 4499b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&COMPRESS) jpeg_destroy_compress(cinfo); 4509b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&DECOMPRESS) jpeg_destroy_decompress(dinfo); 4519b28defe6ac85dd8a52479cf276606beae24920eDRC free(this); 4529b28defe6ac85dd8a52479cf276606beae24920eDRC return 0; 4532e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 4542e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4559b28defe6ac85dd8a52479cf276606beae24920eDRC 4566b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC/* These are exposed mainly because Windows can't malloc() and free() across 4576b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC DLL boundaries except when the CRT DLL is used, and we don't use the CRT DLL 4586b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC with turbojpeg.dll for compatibility reasons. However, these functions 4596b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC can potentially be used for other purposes by different implementations. */ 4606b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4616b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT void DLLCALL tjFree(unsigned char *buf) 4626b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 4636b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC if(buf) free(buf); 4646b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 4656b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4666b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4676b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes) 4686b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 4696b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC return (unsigned char *)malloc(bytes); 4706b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 4716b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4726b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 4739b28defe6ac85dd8a52479cf276606beae24920eDRC/* Compressor */ 4749b28defe6ac85dd8a52479cf276606beae24920eDRC 4759b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitCompress(tjinstance *this) 4762e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 4779b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char buffer[1], *buf=buffer; unsigned long size=1; 4789b28defe6ac85dd8a52479cf276606beae24920eDRC 4799b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 4809b28defe6ac85dd8a52479cf276606beae24920eDRC this->cinfo.err=jpeg_std_error(&this->jerr.pub); 4819b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 4829b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 4832e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4849b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 4859b28defe6ac85dd8a52479cf276606beae24920eDRC { 4869b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 4879b28defe6ac85dd8a52479cf276606beae24920eDRC if(this) free(this); return NULL; 488efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 4892e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4909b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_compress(&this->cinfo); 4919b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the destination manager */ 4929b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); 4932e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 494007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=COMPRESS; 4959b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 4962e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 4972e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 498890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitCompress(void) 499890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 5009b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; 5019b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 502da5220acdd525242bff4e40b1d90324ebb889825DRC { 503007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 504007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitCompress(): Memory allocation failure"); 505da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 506da5220acdd525242bff4e40b1d90324ebb889825DRC } 507007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 5089b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitCompress(this); 509890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 510890f1e0413b54c40b663208779d4ea9dae20eaefDRC 511842416034561f6d5320165a4fe98825e999a4a37DRC 5129b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, 5139b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int jpegSubsamp) 5149b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 5159b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC unsigned long retval=0; int mcuw, mcuh, chromasf; 5169b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT) 5179b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjBufSize(): Invalid argument"); 5189b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5199b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // This allows for rare corner cases in which a JPEG image can actually be 5209b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // larger than the uncompressed input (we wouldn't mention it if it hadn't 5219b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // happened before.) 5229b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC mcuw=tjMCUWidth[jpegSubsamp]; 5239b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC mcuh=tjMCUHeight[jpegSubsamp]; 5249b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh); 5259b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048; 5269b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5279b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC bailout: 5289b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return retval; 5299b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 5309b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5319b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5322e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) 5332e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 534f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 535f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1) 536007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("TJBUFSIZE(): Invalid argument"); 537f3cf973e8e51e0078f402ca5547c026967c27321DRC 538f3cf973e8e51e0078f402ca5547c026967c27321DRC // This allows for rare corner cases in which a JPEG image can actually be 539f3cf973e8e51e0078f402ca5547c026967c27321DRC // larger than the uncompressed input (we wouldn't mention it if it hadn't 540b28fc5710a510410d2b498255a423dd62b353b3aDRC // happened before.) 541007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; 542f3cf973e8e51e0078f402ca5547c026967c27321DRC 543f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 544f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 545f3cf973e8e51e0078f402ca5547c026967c27321DRC} 546f3cf973e8e51e0078f402ca5547c026967c27321DRC 547842416034561f6d5320165a4fe98825e999a4a37DRC 5489b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, 549f3cf973e8e51e0078f402ca5547c026967c27321DRC int subsamp) 550f3cf973e8e51e0078f402ca5547c026967c27321DRC{ 551f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 552f3cf973e8e51e0078f402ca5547c026967c27321DRC int pw, ph, cw, ch; 553f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) 5549b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjBufSizeYUV(): Invalid argument"); 5559b28defe6ac85dd8a52479cf276606beae24920eDRC pw=PAD(width, tjMCUWidth[subsamp]/8); 5569b28defe6ac85dd8a52479cf276606beae24920eDRC ph=PAD(height, tjMCUHeight[subsamp]/8); 5579b28defe6ac85dd8a52479cf276606beae24920eDRC cw=pw*8/tjMCUWidth[subsamp]; ch=ph*8/tjMCUHeight[subsamp]; 55825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC retval=PAD(pw, 4)*ph + (subsamp==TJSAMP_GRAY? 0:PAD(cw, 4)*ch*2); 559f3cf973e8e51e0078f402ca5547c026967c27321DRC 560f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 561f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 5622e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 5632e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 564842416034561f6d5320165a4fe98825e999a4a37DRC 5659b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height, 5669b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int subsamp) 5679b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 5689b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return tjBufSizeYUV(width, height, subsamp); 5699b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 5709b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5719b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 5729b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, 5739b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, 5749b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 5759b28defe6ac85dd8a52479cf276606beae24920eDRC{ 576ff78e37595c8462f64fd100f928aa1d08539527eDRC int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; 577afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 578afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 579afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 5809b28defe6ac85dd8a52479cf276606beae24920eDRC 5819b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle) 5829b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 583007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Instance has not been initialized for compression"); 5849b28defe6ac85dd8a52479cf276606beae24920eDRC 5859b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 5869b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL 5879b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100) 588007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Invalid argument"); 5899b28defe6ac85dd8a52479cf276606beae24920eDRC 5909b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 5919b28defe6ac85dd8a52479cf276606beae24920eDRC { 5929b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 5939b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 5949b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 5959b28defe6ac85dd8a52479cf276606beae24920eDRC } 5969b28defe6ac85dd8a52479cf276606beae24920eDRC 5979b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 5989b28defe6ac85dd8a52479cf276606beae24920eDRC 599afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 600afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(pixelFormat!=TJPF_GRAY) 601afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 602afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); 603afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure"); 604afc06929e0a9cf64bdf50da30326076235df7b4fDRC srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); 605afc06929e0a9cf64bdf50da30326076235df7b4fDRC pitch=width*RGB_PIXELSIZE; 606afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 607afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 608afc06929e0a9cf64bdf50da30326076235df7b4fDRC 6099b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 6109b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 6119b28defe6ac85dd8a52479cf276606beae24920eDRC 61225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 61325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 61425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 6159b28defe6ac85dd8a52479cf276606beae24920eDRC 616ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 617ff78e37595c8462f64fd100f928aa1d08539527eDRC { 6189b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp); 619ff78e37595c8462f64fd100f928aa1d08539527eDRC } 620ff78e37595c8462f64fd100f928aa1d08539527eDRC jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); 621f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC if(setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual)==-1) 622f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return -1; 6239b28defe6ac85dd8a52479cf276606beae24920eDRC 6249b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 6259b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) 626007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Memory allocation failure"); 6279b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 6289b28defe6ac85dd8a52479cf276606beae24920eDRC { 62925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch]; 6309b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&srcBuf[i*pitch]; 6319b28defe6ac85dd8a52479cf276606beae24920eDRC } 6329b28defe6ac85dd8a52479cf276606beae24920eDRC while(cinfo->next_scanline<cinfo->image_height) 6339b28defe6ac85dd8a52479cf276606beae24920eDRC { 6349b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], 6359b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height-cinfo->next_scanline); 6369b28defe6ac85dd8a52479cf276606beae24920eDRC } 6379b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_compress(cinfo); 6389b28defe6ac85dd8a52479cf276606beae24920eDRC 6399b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 6409b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 641afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 642ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 643afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 6449b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 6459b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 6469b28defe6ac85dd8a52479cf276606beae24920eDRC} 6479b28defe6ac85dd8a52479cf276606beae24920eDRC 6489b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, 6499b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, 6509b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 6519b28defe6ac85dd8a52479cf276606beae24920eDRC{ 6529b28defe6ac85dd8a52479cf276606beae24920eDRC int retval=0; unsigned long size; 6539b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 6549b28defe6ac85dd8a52479cf276606beae24920eDRC { 6559b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC size=tjBufSizeYUV(width, height, jpegSubsamp); 6569b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height, 6579b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp, flags); 6589b28defe6ac85dd8a52479cf276606beae24920eDRC } 6599b28defe6ac85dd8a52479cf276606beae24920eDRC else 6609b28defe6ac85dd8a52479cf276606beae24920eDRC { 6619b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjCompress2(handle, srcBuf, width, pitch, height, 6629b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegSubsamp, jpegQual, 66325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC flags|TJFLAG_NOREALLOC); 6649b28defe6ac85dd8a52479cf276606beae24920eDRC } 6659b28defe6ac85dd8a52479cf276606beae24920eDRC *jpegSize=size; 6669b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 6679b28defe6ac85dd8a52479cf276606beae24920eDRC} 6689b28defe6ac85dd8a52479cf276606beae24920eDRC 6699b28defe6ac85dd8a52479cf276606beae24920eDRC 6709b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, 6719b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, 6729b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 6732e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 67491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC int i, retval=0; JSAMPROW *row_pointer=NULL; 675fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; 676fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; 677fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *outbuf[MAX_COMPONENTS]; 6789b28defe6ac85dd8a52479cf276606beae24920eDRC int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS]; 6799b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPLE *ptr=dstBuf; 680afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned long yuvsize=0; 6819b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr; 682afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 683afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 684afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 6852e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6869b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 6879b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 688007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjEncodeYUV2(): Instance has not been initialized for compression"); 6892e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 690fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 691fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 692fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf[i]=NULL; _tmpbuf[i]=NULL; 693fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; 694fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 695fbb674707e01a61e8b7083faa632dfd46c568b13DRC 6969b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 6979b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0 6989b28defe6ac85dd8a52479cf276606beae24920eDRC || subsamp>=NUMSUBOPT) 6999b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjEncodeYUV2(): Invalid argument"); 7002e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7019b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 7029b28defe6ac85dd8a52479cf276606beae24920eDRC { 7039b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 70491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 70591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 706efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 7072e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7089b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 7092e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 710afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 711afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(pixelFormat!=TJPF_GRAY) 712afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 713afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); 714afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(!rgbBuf) _throw("tjEncodeYUV2(): Memory allocation failure"); 715afc06929e0a9cf64bdf50da30326076235df7b4fDRC srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); 716afc06929e0a9cf64bdf50da30326076235df7b4fDRC pitch=width*RGB_PIXELSIZE; 717afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 718afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 719afc06929e0a9cf64bdf50da30326076235df7b4fDRC 7209b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 7219b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 7222e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 72325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 72425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 72525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 7262e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7279b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC yuvsize=tjBufSizeYUV(width, height, subsamp); 7289b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0); 729f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC if(setCompDefaults(cinfo, pixelFormat, subsamp, -1)==-1) return -1; 7302e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7319b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 7329b28defe6ac85dd8a52479cf276606beae24920eDRC pw=PAD(width, cinfo->max_h_samp_factor); 7339b28defe6ac85dd8a52479cf276606beae24920eDRC ph=PAD(height, cinfo->max_v_samp_factor); 7349b28defe6ac85dd8a52479cf276606beae24920eDRC 7359b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL) 736007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjEncodeYUV2(): Memory allocation failure"); 7379b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 7382e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC { 73925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch]; 7409b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&srcBuf[i*pitch]; 7419b28defe6ac85dd8a52479cf276606beae24920eDRC } 7429b28defe6ac85dd8a52479cf276606beae24920eDRC if(height<ph) 7439b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=height; i<ph; i++) row_pointer[i]=row_pointer[height-1]; 744fbb674707e01a61e8b7083faa632dfd46c568b13DRC 7459b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<cinfo->num_components; i++) 7469b28defe6ac85dd8a52479cf276606beae24920eDRC { 7479b28defe6ac85dd8a52479cf276606beae24920eDRC compptr=&cinfo->comp_info[i]; 7489b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf[i]=(JSAMPLE *)malloc( 7499b28defe6ac85dd8a52479cf276606beae24920eDRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 7509b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16); 751007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!_tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7529b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor); 753007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7549b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<cinfo->max_v_samp_factor; row++) 755fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 7569b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf_aligned= 7579b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf[i], 16); 7589b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=&_tmpbuf_aligned[ 759fbb674707e01a61e8b7083faa632dfd46c568b13DRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 7609b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * row]; 761fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 7629b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16) 7639b28defe6ac85dd8a52479cf276606beae24920eDRC * compptr->v_samp_factor + 16); 764007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!_tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7659b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor); 766007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7679b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<compptr->v_samp_factor; row++) 768fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 7699b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf2_aligned= 7709b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf2[i], 16); 7719b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i][row]=&_tmpbuf2_aligned[ 7729b28defe6ac85dd8a52479cf276606beae24920eDRC PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]; 773fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 7749b28defe6ac85dd8a52479cf276606beae24920eDRC cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor; 7759b28defe6ac85dd8a52479cf276606beae24920eDRC ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor; 7769b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]); 777007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!outbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 7789b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ch[i]; row++) 779fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 7809b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 7819b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=PAD(cw[i], 4); 782fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 7836ee54594591d0ae958b81adc8ba3cacde522e5e3DRC } 7849b28defe6ac85dd8a52479cf276606beae24920eDRC if(yuvsize!=(unsigned long)(ptr-dstBuf)) 7859b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjEncodeYUV2(): Generated image is not the correct size"); 7869b28defe6ac85dd8a52479cf276606beae24920eDRC 7879b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ph; row+=cinfo->max_v_samp_factor) 7889b28defe6ac85dd8a52479cf276606beae24920eDRC { 7899b28defe6ac85dd8a52479cf276606beae24920eDRC (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, 0, 7909b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->max_v_samp_factor); 7919b28defe6ac85dd8a52479cf276606beae24920eDRC (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0); 7929b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++, compptr++) 7939b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], 7949b28defe6ac85dd8a52479cf276606beae24920eDRC row*compptr->v_samp_factor/cinfo->max_v_samp_factor, 7959b28defe6ac85dd8a52479cf276606beae24920eDRC compptr->v_samp_factor, cw[i]); 7969b28defe6ac85dd8a52479cf276606beae24920eDRC } 7979b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->next_scanline+=height; 7989b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_compress(cinfo); 7992e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 80091e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 8019b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 802afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 803ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 804afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 8052e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC if(row_pointer) free(row_pointer); 806fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 807fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 808fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf[i]!=NULL) free(tmpbuf[i]); 80957423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); 810fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); 81157423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); 812fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(outbuf[i]!=NULL) free(outbuf[i]); 813fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 81491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 8152e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 8162e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8179b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, 8189b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, 8199b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 820842416034561f6d5320165a4fe98825e999a4a37DRC{ 8219b28defe6ac85dd8a52479cf276606beae24920eDRC return tjEncodeYUV2(handle, srcBuf, width, pitch, height, 8229b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags); 823842416034561f6d5320165a4fe98825e999a4a37DRC} 824842416034561f6d5320165a4fe98825e999a4a37DRC 825842416034561f6d5320165a4fe98825e999a4a37DRC 8269b28defe6ac85dd8a52479cf276606beae24920eDRC/* Decompressor */ 8272e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8289b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitDecompress(tjinstance *this) 8292e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 8309b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char buffer[1]; 8312e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8329b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 8339b28defe6ac85dd8a52479cf276606beae24920eDRC this->dinfo.err=jpeg_std_error(&this->jerr.pub); 8349b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 8359b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 8362e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8379b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 8389b28defe6ac85dd8a52479cf276606beae24920eDRC { 8399b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 8409b28defe6ac85dd8a52479cf276606beae24920eDRC if(this) free(this); return NULL; 8419e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8439b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_decompress(&this->dinfo); 8449b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the source manager */ 8459b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(&this->dinfo, buffer, 1); 8462e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 847007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=DECOMPRESS; 8489b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 8492e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 8502e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 851890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitDecompress(void) 852890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 8539b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this; 8549b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 855da5220acdd525242bff4e40b1d90324ebb889825DRC { 856007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 857007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitDecompress(): Memory allocation failure"); 858da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 859da5220acdd525242bff4e40b1d90324ebb889825DRC } 860007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 8619b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitDecompress(this); 862890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 863890f1e0413b54c40b663208779d4ea9dae20eaefDRC 8642e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8659b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, 8669b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, 8679b28defe6ac85dd8a52479cf276606beae24920eDRC int *jpegSubsamp) 8681fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC{ 8699b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=0; 8701fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8719b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 8729b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 873007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Instance has not been initialized for decompression"); 8741fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8759b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL 8769b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp==NULL) 8779b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompressHeader2(): Invalid argument"); 8781fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8799b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 8809b28defe6ac85dd8a52479cf276606beae24920eDRC { 8819b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 8821fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC return -1; 8831fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 8841fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8859b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 8869b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 8871fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8889b28defe6ac85dd8a52479cf276606beae24920eDRC *width=dinfo->image_width; 8899b28defe6ac85dd8a52479cf276606beae24920eDRC *height=dinfo->image_height; 8909b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC *jpegSubsamp=getSubsamp(dinfo); 8911fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8929b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_decompress(dinfo); 8931fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 8949b28defe6ac85dd8a52479cf276606beae24920eDRC if(*jpegSubsamp<0) 895007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Could not determine subsampling type for JPEG image"); 896007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(*width<1 || *height<1) 897007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Invalid data returned in header"); 89891e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 89991e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 90091e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 90191e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC} 90291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 9039b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, 9049b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height) 90591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC{ 9069b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegSubsamp; 9079b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, 9089b28defe6ac85dd8a52479cf276606beae24920eDRC &jpegSubsamp); 9091fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC} 9101fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 9111fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 912109a578e89ea8cd2c39d50b012698148dd11dedbDRCDLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors) 913b28fc5710a510410d2b498255a423dd62b353b3aDRC{ 914109a578e89ea8cd2c39d50b012698148dd11dedbDRC if(numscalingfactors==NULL) 915b28fc5710a510410d2b498255a423dd62b353b3aDRC { 9169b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 917007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjGetScalingFactors(): Invalid argument"); 918109a578e89ea8cd2c39d50b012698148dd11dedbDRC return NULL; 919b28fc5710a510410d2b498255a423dd62b353b3aDRC } 920b28fc5710a510410d2b498255a423dd62b353b3aDRC 921109a578e89ea8cd2c39d50b012698148dd11dedbDRC *numscalingfactors=NUMSF; 922109a578e89ea8cd2c39d50b012698148dd11dedbDRC return (tjscalingfactor *)sf; 923b28fc5710a510410d2b498255a423dd62b353b3aDRC} 924b28fc5710a510410d2b498255a423dd62b353b3aDRC 925b28fc5710a510410d2b498255a423dd62b353b3aDRC 9269b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, 9279b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 9289b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelFormat, int flags) 9299b28defe6ac85dd8a52479cf276606beae24920eDRC{ 9309b28defe6ac85dd8a52479cf276606beae24920eDRC int i, retval=0; JSAMPROW *row_pointer=NULL; 9319b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegwidth, jpegheight, scaledw, scaledh; 932afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 933afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *rgbBuf=NULL; 934afc06929e0a9cf64bdf50da30326076235df7b4fDRC unsigned char *_dstBuf=NULL; int _pitch=0; 935afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 9369b28defe6ac85dd8a52479cf276606beae24920eDRC 9379b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 9389b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 939007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Instance has not been initialized for decompression"); 9409b28defe6ac85dd8a52479cf276606beae24920eDRC 9419b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 9429b28defe6ac85dd8a52479cf276606beae24920eDRC || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) 9439b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompress2(): Invalid argument"); 9449b28defe6ac85dd8a52479cf276606beae24920eDRC 94525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 94625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 94725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 9489b28defe6ac85dd8a52479cf276606beae24920eDRC 9499b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 9509b28defe6ac85dd8a52479cf276606beae24920eDRC { 9519b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 9529b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 9539b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 9549b28defe6ac85dd8a52479cf276606beae24920eDRC } 9559b28defe6ac85dd8a52479cf276606beae24920eDRC 9569b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 9579b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 9582eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC if(setDecompDefaults(dinfo, pixelFormat)==-1) 9592eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC { 9602eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC retval=-1; goto bailout; 9612eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC } 9629b28defe6ac85dd8a52479cf276606beae24920eDRC 96325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 9649b28defe6ac85dd8a52479cf276606beae24920eDRC 9659b28defe6ac85dd8a52479cf276606beae24920eDRC jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; 9669b28defe6ac85dd8a52479cf276606beae24920eDRC if(width==0) width=jpegwidth; 9679b28defe6ac85dd8a52479cf276606beae24920eDRC if(height==0) height=jpegheight; 9689b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<NUMSF; i++) 9699b28defe6ac85dd8a52479cf276606beae24920eDRC { 9709b28defe6ac85dd8a52479cf276606beae24920eDRC scaledw=TJSCALED(jpegwidth, sf[i]); 9719b28defe6ac85dd8a52479cf276606beae24920eDRC scaledh=TJSCALED(jpegheight, sf[i]); 9729b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw<=width && scaledh<=height) 9739b28defe6ac85dd8a52479cf276606beae24920eDRC break; 9749b28defe6ac85dd8a52479cf276606beae24920eDRC } 9759b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw>width || scaledh>height) 976007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Could not scale down to desired image dimensions"); 9779b28defe6ac85dd8a52479cf276606beae24920eDRC width=scaledw; height=scaledh; 9789b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_num=sf[i].num; 9799b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_denom=sf[i].denom; 9809b28defe6ac85dd8a52479cf276606beae24920eDRC 9819b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 9829b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; 983afc06929e0a9cf64bdf50da30326076235df7b4fDRC 984afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 985afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(pixelFormat!=TJPF_GRAY && 986afc06929e0a9cf64bdf50da30326076235df7b4fDRC (RGB_RED!=tjRedOffset[pixelFormat] || 987afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_GREEN!=tjGreenOffset[pixelFormat] || 988afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_BLUE!=tjBlueOffset[pixelFormat] || 989afc06929e0a9cf64bdf50da30326076235df7b4fDRC RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) 990afc06929e0a9cf64bdf50da30326076235df7b4fDRC { 991afc06929e0a9cf64bdf50da30326076235df7b4fDRC rgbBuf=(unsigned char *)malloc(width*height*3); 992afc06929e0a9cf64bdf50da30326076235df7b4fDRC if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure"); 993afc06929e0a9cf64bdf50da30326076235df7b4fDRC _pitch=pitch; pitch=width*3; 994afc06929e0a9cf64bdf50da30326076235df7b4fDRC _dstBuf=dstBuf; dstBuf=rgbBuf; 995afc06929e0a9cf64bdf50da30326076235df7b4fDRC } 996afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 997afc06929e0a9cf64bdf50da30326076235df7b4fDRC 9989b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) 9999b28defe6ac85dd8a52479cf276606beae24920eDRC *dinfo->output_height))==NULL) 1000007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Memory allocation failure"); 10019b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<(int)dinfo->output_height; i++) 10029b28defe6ac85dd8a52479cf276606beae24920eDRC { 100325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) 10049b28defe6ac85dd8a52479cf276606beae24920eDRC row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]; 10059b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&dstBuf[i*pitch]; 10069b28defe6ac85dd8a52479cf276606beae24920eDRC } 10079b28defe6ac85dd8a52479cf276606beae24920eDRC while(dinfo->output_scanline<dinfo->output_height) 10089b28defe6ac85dd8a52479cf276606beae24920eDRC { 10099b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], 10109b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->output_height-dinfo->output_scanline); 10119b28defe6ac85dd8a52479cf276606beae24920eDRC } 10129b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 10139b28defe6ac85dd8a52479cf276606beae24920eDRC 1014afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1015afc06929e0a9cf64bdf50da30326076235df7b4fDRC fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); 1016afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 1017afc06929e0a9cf64bdf50da30326076235df7b4fDRC 10189b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 10199b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 1020afc06929e0a9cf64bdf50da30326076235df7b4fDRC #ifndef JCS_EXTENSIONS 1021ea3396a9456fbe403e0defd2991a308d7c400abcDRC if(rgbBuf) free(rgbBuf); 1022afc06929e0a9cf64bdf50da30326076235df7b4fDRC #endif 10239b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 10249b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 10259b28defe6ac85dd8a52479cf276606beae24920eDRC} 10269b28defe6ac85dd8a52479cf276606beae24920eDRC 10279b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, 10289b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 10299b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelSize, int flags) 10309b28defe6ac85dd8a52479cf276606beae24920eDRC{ 10319b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 10329b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags); 10339b28defe6ac85dd8a52479cf276606beae24920eDRC else 10349b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch, 10359b28defe6ac85dd8a52479cf276606beae24920eDRC height, getPixelFormat(pixelSize, flags), flags); 10369b28defe6ac85dd8a52479cf276606beae24920eDRC} 10379b28defe6ac85dd8a52479cf276606beae24920eDRC 10389b28defe6ac85dd8a52479cf276606beae24920eDRC 10399b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, 10409b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, 1041b28fc5710a510410d2b498255a423dd62b353b3aDRC int flags) 10422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 10439b28defe6ac85dd8a52479cf276606beae24920eDRC int i, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS]; 1044f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS], 1045f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; 10469b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPLE *_tmpbuf=NULL, *ptr=dstBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS]; 10472e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 10489b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 10499b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 1050007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Instance has not been initialized for decompression"); 10512e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 1052f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<MAX_COMPONENTS; i++) 1053f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 1054f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbuf[i]=NULL; outbuf[i]=NULL; 1055f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 10569e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC 10579b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL) 10589b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompressToYUV(): Invalid argument"); 10592e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 106025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 106125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 106225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 10630c6a271f974529e4795332c9ad428500ef17fb42DRC 10649b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 10659b28defe6ac85dd8a52479cf276606beae24920eDRC { 10669b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 106791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 106891e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 10699e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 10702e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 10719b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 10729b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 10732e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 10749b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 10759e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 10769b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 10779b28defe6ac85dd8a52479cf276606beae24920eDRC int ih; 10789b28defe6ac85dd8a52479cf276606beae24920eDRC iw[i]=compptr->width_in_blocks*DCTSIZE; 10799b28defe6ac85dd8a52479cf276606beae24920eDRC ih=compptr->height_in_blocks*DCTSIZE; 10809b28defe6ac85dd8a52479cf276606beae24920eDRC cw[i]=PAD(dinfo->image_width, dinfo->max_h_samp_factor) 10819b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->h_samp_factor/dinfo->max_h_samp_factor; 10829b28defe6ac85dd8a52479cf276606beae24920eDRC ch[i]=PAD(dinfo->image_height, dinfo->max_v_samp_factor) 10839b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->v_samp_factor/dinfo->max_v_samp_factor; 10849b28defe6ac85dd8a52479cf276606beae24920eDRC if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1; 10859b28defe6ac85dd8a52479cf276606beae24920eDRC th[i]=compptr->v_samp_factor*DCTSIZE; 10869b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbufsize+=iw[i]*th[i]; 10879b28defe6ac85dd8a52479cf276606beae24920eDRC if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]))==NULL) 1088007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 10899b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ch[i]; row++) 10909e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 10919b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 10929b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=PAD(cw[i], 4); 1093f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 10949b28defe6ac85dd8a52479cf276606beae24920eDRC } 10959b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 10969b28defe6ac85dd8a52479cf276606beae24920eDRC { 10979b28defe6ac85dd8a52479cf276606beae24920eDRC if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL) 1098007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 10999b28defe6ac85dd8a52479cf276606beae24920eDRC ptr=_tmpbuf; 11009b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 1101f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 11029b28defe6ac85dd8a52479cf276606beae24920eDRC if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL) 1103007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 11049b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<th[i]; row++) 1105f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 11069b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=ptr; 11079b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=iw[i]; 11089e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11099e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11109e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11112e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 111225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 11139b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->raw_data_out=TRUE; 11149b28defe6ac85dd8a52479cf276606beae24920eDRC 11159b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 11169b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<(int)dinfo->output_height; 11179b28defe6ac85dd8a52479cf276606beae24920eDRC row+=dinfo->max_v_samp_factor*DCTSIZE) 11188ed7b814039172fe3cbfadfee3922801a3888b73DRC { 11199b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPARRAY yuvptr[MAX_COMPONENTS]; 11209b28defe6ac85dd8a52479cf276606beae24920eDRC int crow[MAX_COMPONENTS]; 11219b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 1122842416034561f6d5320165a4fe98825e999a4a37DRC { 11239b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 11249b28defe6ac85dd8a52479cf276606beae24920eDRC crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_factor; 11259b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) yuvptr[i]=tmpbuf[i]; 11269b28defe6ac85dd8a52479cf276606beae24920eDRC else yuvptr[i]=&outbuf[i][crow[i]]; 1127842416034561f6d5320165a4fe98825e999a4a37DRC } 11289b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_raw_data(dinfo, yuvptr, dinfo->max_v_samp_factor*DCTSIZE); 11299b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 11309e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 11319b28defe6ac85dd8a52479cf276606beae24920eDRC int j; 1132f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<dinfo->num_components; i++) 11339e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 11349b28defe6ac85dd8a52479cf276606beae24920eDRC for(j=0; j<min(th[i], ch[i]-crow[i]); j++) 1135f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 11369b28defe6ac85dd8a52479cf276606beae24920eDRC memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j], cw[i]); 1137f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 11389e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11399e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11409e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 11419b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 11422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 114391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 11449b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 11459e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC for(i=0; i<MAX_COMPONENTS; i++) 1146f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 1147f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(tmpbuf[i]) free(tmpbuf[i]); 11489e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC if(outbuf[i]) free(outbuf[i]); 1149f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 1150f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(_tmpbuf) free(_tmpbuf); 115191e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 11522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 11532e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 11542e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 11559b28defe6ac85dd8a52479cf276606beae24920eDRC/* Transformer */ 1156890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1157890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitTransform(void) 1158890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 11599b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; tjhandle handle=NULL; 11609b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 1161da5220acdd525242bff4e40b1d90324ebb889825DRC { 1162007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 1163007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitTransform(): Memory allocation failure"); 1164da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 1165da5220acdd525242bff4e40b1d90324ebb889825DRC } 1166007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 11679b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitCompress(this); 11689b28defe6ac85dd8a52479cf276606beae24920eDRC if(!handle) return NULL; 11699b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitDecompress(this); 11709b28defe6ac85dd8a52479cf276606beae24920eDRC return handle; 1171890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 1172890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1173890f1e0413b54c40b663208779d4ea9dae20eaefDRC 11749b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf, 11759b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, int n, unsigned char **dstBufs, 11769b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *dstSizes, tjtransform *t, int flags) 1177890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 11780a325197dedd2eede99731c68ae0e0a145473f64DRC jpeg_transform_info *xinfo=NULL; 1179890f1e0413b54c40b663208779d4ea9dae20eaefDRC jvirt_barray_ptr *srccoefs, *dstcoefs; 11809b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=0, i, jpegSubsamp; 1181890f1e0413b54c40b663208779d4ea9dae20eaefDRC 11829b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 11839b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0) 1184007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Instance has not been initialized for transformation"); 1185890f1e0413b54c40b663208779d4ea9dae20eaefDRC 11869b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NULL 11870a325197dedd2eede99731c68ae0e0a145473f64DRC || t==NULL || flags<0) 11889b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjTransform(): Invalid argument"); 1189890f1e0413b54c40b663208779d4ea9dae20eaefDRC 119025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 119125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 119225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 1193890f1e0413b54c40b663208779d4ea9dae20eaefDRC 11949b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 11959b28defe6ac85dd8a52479cf276606beae24920eDRC { 11969b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 1197890f1e0413b54c40b663208779d4ea9dae20eaefDRC retval=-1; 1198890f1e0413b54c40b663208779d4ea9dae20eaefDRC goto bailout; 1199890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1200890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12019b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 1202890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12030a325197dedd2eede99731c68ae0e0a145473f64DRC if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n)) 12040a325197dedd2eede99731c68ae0e0a145473f64DRC ==NULL) 1205007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Memory allocation failure"); 1206007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(xinfo, sizeof(jpeg_transform_info)*n); 1207890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12080a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 1209890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 12100a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].transform=xformtypes[t[i].op]; 121125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].perfect=(t[i].options&TJXOPT_PERFECT)? 1:0; 121225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].trim=(t[i].options&TJXOPT_TRIM)? 1:0; 121325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].force_grayscale=(t[i].options&TJXOPT_GRAY)? 1:0; 121425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].crop=(t[i].options&TJXOPT_CROP)? 1:0; 121525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(n!=1 && t[i].op==TJXOP_HFLIP) xinfo[i].slow_hflip=1; 1216ba5ea5143e48b71234414139e3b4cb244599e875DRC else xinfo[i].slow_hflip=0; 12170a325197dedd2eede99731c68ae0e0a145473f64DRC 12180a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 1219890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 12200a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_xoffset=t[i].r.x; xinfo[i].crop_xoffset_set=JCROP_POS; 12210a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_yoffset=t[i].r.y; xinfo[i].crop_yoffset_set=JCROP_POS; 12220a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.w!=0) 12230a325197dedd2eede99731c68ae0e0a145473f64DRC { 12240a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_width=t[i].r.w; xinfo[i].crop_width_set=JCROP_POS; 12250a325197dedd2eede99731c68ae0e0a145473f64DRC } 1226d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_width=JCROP_UNSET; 12270a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.h!=0) 12280a325197dedd2eede99731c68ae0e0a145473f64DRC { 12290a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_height=t[i].r.h; xinfo[i].crop_height_set=JCROP_POS; 12300a325197dedd2eede99731c68ae0e0a145473f64DRC } 1231d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_height=JCROP_UNSET; 1232890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1233890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1234890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12359b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_markers_setup(dinfo, JCOPYOPT_ALL); 12369b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 12379b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC jpegSubsamp=getSubsamp(dinfo); 12389b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(jpegSubsamp<0) 12399b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjTransform(): Could not determine subsampling type for JPEG image"); 1240890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12410a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 1242890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 12439b28defe6ac85dd8a52479cf276606beae24920eDRC if(!jtransform_request_workspace(dinfo, &xinfo[i])) 1244007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Transform is not perfect"); 12450a325197dedd2eede99731c68ae0e0a145473f64DRC 12460a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 12470a325197dedd2eede99731c68ae0e0a145473f64DRC { 12480a325197dedd2eede99731c68ae0e0a145473f64DRC if((t[i].r.x%xinfo[i].iMCU_sample_width)!=0 12490a325197dedd2eede99731c68ae0e0a145473f64DRC || (t[i].r.y%xinfo[i].iMCU_sample_height)!=0) 12500a325197dedd2eede99731c68ae0e0a145473f64DRC { 12519b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 12520a325197dedd2eede99731c68ae0e0a145473f64DRC "To crop this JPEG image, x must be a multiple of %d\n" 12530a325197dedd2eede99731c68ae0e0a145473f64DRC "and y must be a multiple of %d.\n", 12540a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].iMCU_sample_width, xinfo[i].iMCU_sample_height); 12550a325197dedd2eede99731c68ae0e0a145473f64DRC retval=-1; goto bailout; 12560a325197dedd2eede99731c68ae0e0a145473f64DRC } 12570a325197dedd2eede99731c68ae0e0a145473f64DRC } 1258890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1259890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12609b28defe6ac85dd8a52479cf276606beae24920eDRC srccoefs=jpeg_read_coefficients(dinfo); 1261890f1e0413b54c40b663208779d4ea9dae20eaefDRC 12620a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 1263890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 1264ff78e37595c8462f64fd100f928aa1d08539527eDRC int w, h, alloc=1; 12650a325197dedd2eede99731c68ae0e0a145473f64DRC if(!xinfo[i].crop) 1266890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 12679b28defe6ac85dd8a52479cf276606beae24920eDRC w=dinfo->image_width; h=dinfo->image_height; 1268890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 12690a325197dedd2eede99731c68ae0e0a145473f64DRC else 12700a325197dedd2eede99731c68ae0e0a145473f64DRC { 12710a325197dedd2eede99731c68ae0e0a145473f64DRC w=xinfo[i].crop_width; h=xinfo[i].crop_height; 12720a325197dedd2eede99731c68ae0e0a145473f64DRC } 1273ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 1274ff78e37595c8462f64fd100f928aa1d08539527eDRC { 12759b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC alloc=0; dstSizes[i]=tjBufSize(w, h, jpegSubsamp); 1276ff78e37595c8462f64fd100f928aa1d08539527eDRC } 12777bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) 12787bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_mem_dest_tj(cinfo, &dstBufs[i], &dstSizes[i], alloc); 12799b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_copy_critical_parameters(dinfo, cinfo); 12809b28defe6ac85dd8a52479cf276606beae24920eDRC dstcoefs=jtransform_adjust_parameters(dinfo, cinfo, srccoefs, 12810a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 12827bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) 12837bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 12847bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_write_coefficients(cinfo, dstcoefs); 12857bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL); 12867bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 12877bf04d399ebf9a3b39a6d5b5639d895df618353dDRC else jinit_c_master_control(cinfo, TRUE); 12889b28defe6ac85dd8a52479cf276606beae24920eDRC jtransform_execute_transformation(dinfo, cinfo, srccoefs, 12890a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 12907bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(t[i].customFilter) 12917bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 1292efe28cec4b29b5a7357d9cd1c30a066486d19b12DRC int ci, y; JDIMENSION by; 12937bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(ci=0; ci<cinfo->num_components; ci++) 12947bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 12957bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_component_info *compptr=&cinfo->comp_info[ci]; 12967bf04d399ebf9a3b39a6d5b5639d895df618353dDRC tjregion arrayRegion={0, 0, compptr->width_in_blocks*DCTSIZE, 12977bf04d399ebf9a3b39a6d5b5639d895df618353dDRC DCTSIZE}; 12987bf04d399ebf9a3b39a6d5b5639d895df618353dDRC tjregion planeRegion={0, 0, compptr->width_in_blocks*DCTSIZE, 12997bf04d399ebf9a3b39a6d5b5639d895df618353dDRC compptr->height_in_blocks*DCTSIZE}; 13007bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(by=0; by<compptr->height_in_blocks; by+=compptr->v_samp_factor) 13017bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 13027bf04d399ebf9a3b39a6d5b5639d895df618353dDRC JBLOCKARRAY barray=(dinfo->mem->access_virt_barray) 13037bf04d399ebf9a3b39a6d5b5639d895df618353dDRC ((j_common_ptr)dinfo, dstcoefs[ci], by, compptr->v_samp_factor, 13047bf04d399ebf9a3b39a6d5b5639d895df618353dDRC TRUE); 13057bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(y=0; y<compptr->v_samp_factor; y++) 13067bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 13077bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(t[i].customFilter(barray[y][0], arrayRegion, planeRegion, 1308f5467110763f7a44ca8baf1c035eb39a68c913c6DRC ci, i, &t[i])==-1) 13097bf04d399ebf9a3b39a6d5b5639d895df618353dDRC _throw("tjTransform(): Error in custom filter"); 13107bf04d399ebf9a3b39a6d5b5639d895df618353dDRC arrayRegion.y+=DCTSIZE; 13117bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 13127bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 13137bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 13147bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 13157bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) jpeg_finish_compress(cinfo); 1316890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1317890f1e0413b54c40b663208779d4ea9dae20eaefDRC 13189b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 1319890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1320890f1e0413b54c40b663208779d4ea9dae20eaefDRC bailout: 13219b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 13229b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 13230a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo) free(xinfo); 1324890f1e0413b54c40b663208779d4ea9dae20eaefDRC return retval; 1325890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 1326