turbojpeg.c revision 67ce3b2352fe1f7511edbfed74ec6960e41e97dc
19b28defe6ac85dd8a52479cf276606beae24920eDRC/* 29b28defe6ac85dd8a52479cf276606beae24920eDRC * Copyright (C)2009-2011 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 95109a578e89ea8cd2c39d50b012698148dd11dedbDRC#define NUMSF 4 96109a578e89ea8cd2c39d50b012698148dd11dedbDRCstatic const tjscalingfactor sf[NUMSF]={ 97109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 1}, 98109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 2}, 99109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 4}, 100109a578e89ea8cd2c39d50b012698148dd11dedbDRC {1, 8} 101109a578e89ea8cd2c39d50b012698148dd11dedbDRC}; 1022e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 103a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ 104da5220acdd525242bff4e40b1d90324ebb889825DRC retval=-1; goto bailout;} 1059b28defe6ac85dd8a52479cf276606beae24920eDRC#define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ 1069b28defe6ac85dd8a52479cf276606beae24920eDRC j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ 1079b28defe6ac85dd8a52479cf276606beae24920eDRC if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ 1089b28defe6ac85dd8a52479cf276606beae24920eDRC return -1;} \ 1099b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo=&this->cinfo; dinfo=&this->dinfo; 1109b28defe6ac85dd8a52479cf276606beae24920eDRC 1119b28defe6ac85dd8a52479cf276606beae24920eDRCstatic int getPixelFormat(int pixelSize, int flags) 1129b28defe6ac85dd8a52479cf276606beae24920eDRC{ 11325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(pixelSize==1) return TJPF_GRAY; 1149b28defe6ac85dd8a52479cf276606beae24920eDRC if(pixelSize==3) 1159b28defe6ac85dd8a52479cf276606beae24920eDRC { 11625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_BGR; 11725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_RGB; 1189b28defe6ac85dd8a52479cf276606beae24920eDRC } 1199b28defe6ac85dd8a52479cf276606beae24920eDRC if(pixelSize==4) 1209b28defe6ac85dd8a52479cf276606beae24920eDRC { 1219b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_ALPHAFIRST) 1229b28defe6ac85dd8a52479cf276606beae24920eDRC { 12325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_XBGR; 12425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_XRGB; 1259b28defe6ac85dd8a52479cf276606beae24920eDRC } 1269b28defe6ac85dd8a52479cf276606beae24920eDRC else 1279b28defe6ac85dd8a52479cf276606beae24920eDRC { 12825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJ_BGR) return TJPF_BGRX; 12925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else return TJPF_RGBX; 1309b28defe6ac85dd8a52479cf276606beae24920eDRC } 1319b28defe6ac85dd8a52479cf276606beae24920eDRC } 1329b28defe6ac85dd8a52479cf276606beae24920eDRC return -1; 1339b28defe6ac85dd8a52479cf276606beae24920eDRC} 1349b28defe6ac85dd8a52479cf276606beae24920eDRC 135f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setCompDefaults(struct jpeg_compress_struct *cinfo, 1369b28defe6ac85dd8a52479cf276606beae24920eDRC int pixelFormat, int subsamp, int jpegQual) 1379b28defe6ac85dd8a52479cf276606beae24920eDRC{ 138f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC int retval=0; 139f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 1409b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 1419b28defe6ac85dd8a52479cf276606beae24920eDRC { 14225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 1439b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_GRAYSCALE; break; 1449b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 14525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 1469b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGB; break; 14725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 1489b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGR; break; 14925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 15067ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_RGBA: 1519b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGBX; break; 15225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 15367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_BGRA: 1549b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGRX; break; 15525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 15667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ARGB: 1579b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XRGB; break; 15825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 15967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ABGR: 1609b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XBGR; break; 1619b28defe6ac85dd8a52479cf276606beae24920eDRC #else 16225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 1639b28defe6ac85dd8a52479cf276606beae24920eDRC if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXELSIZE==3) 1649b28defe6ac85dd8a52479cf276606beae24920eDRC { 1659b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_RGB; break; 1669b28defe6ac85dd8a52479cf276606beae24920eDRC } 1679b28defe6ac85dd8a52479cf276606beae24920eDRC default: 1689b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("Unsupported pixel format"); 1699b28defe6ac85dd8a52479cf276606beae24920eDRC #endif 1709b28defe6ac85dd8a52479cf276606beae24920eDRC } 1719b28defe6ac85dd8a52479cf276606beae24920eDRC 1729b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->input_components=tjPixelSize[pixelFormat]; 1739b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_defaults(cinfo); 1749b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegQual>=0) 1759b28defe6ac85dd8a52479cf276606beae24920eDRC { 1769b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_quality(cinfo, jpegQual, TRUE); 1779b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegQual>=96) cinfo->dct_method=JDCT_ISLOW; 1789b28defe6ac85dd8a52479cf276606beae24920eDRC else cinfo->dct_method=JDCT_FASTEST; 1799b28defe6ac85dd8a52479cf276606beae24920eDRC } 18025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(subsamp==TJSAMP_GRAY) 1819b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); 1829b28defe6ac85dd8a52479cf276606beae24920eDRC else 1839b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_YCbCr); 1849b28defe6ac85dd8a52479cf276606beae24920eDRC 1859b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; 1869b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].h_samp_factor=1; 1879b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].h_samp_factor=1; 1889b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; 1899b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].v_samp_factor=1; 1909b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].v_samp_factor=1; 191f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 192f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC #if JCS_EXTENSIONS!=1 193f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC bailout: 194f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC #endif 195f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return retval; 1969b28defe6ac85dd8a52479cf276606beae24920eDRC} 1979b28defe6ac85dd8a52479cf276606beae24920eDRC 198f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setDecompDefaults(struct jpeg_decompress_struct *dinfo, 1999b28defe6ac85dd8a52479cf276606beae24920eDRC int pixelFormat) 2009b28defe6ac85dd8a52479cf276606beae24920eDRC{ 201f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC int retval=0; 202f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 2039b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 2049b28defe6ac85dd8a52479cf276606beae24920eDRC { 20525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 2069b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_GRAYSCALE; break; 2079b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 20825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 2099b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGB; break; 21025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 2119b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGR; break; 21225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 2139b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGBX; break; 21425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 2159b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGRX; break; 21625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 2179b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XRGB; break; 21825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 2199b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XBGR; break; 22067ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #if JCS_ALPHA_EXTENSIONS==1 22167ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_RGBA: 22267ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_RGBA; break; 22367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_BGRA: 22467ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_BGRA; break; 22567ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ARGB: 22667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_ARGB; break; 22767ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC case TJPF_ABGR: 22867ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC dinfo->out_color_space=JCS_EXT_ABGR; break; 22967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #endif 2309b28defe6ac85dd8a52479cf276606beae24920eDRC #else 23125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 2329b28defe6ac85dd8a52479cf276606beae24920eDRC if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXELSIZE==3) 2339b28defe6ac85dd8a52479cf276606beae24920eDRC { 2349b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_RGB; break; 2359b28defe6ac85dd8a52479cf276606beae24920eDRC } 23667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC #endif 2379b28defe6ac85dd8a52479cf276606beae24920eDRC default: 2389b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("Unsupported pixel format"); 2399b28defe6ac85dd8a52479cf276606beae24920eDRC } 240f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC 241f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC bailout: 242f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return retval; 2439b28defe6ac85dd8a52479cf276606beae24920eDRC} 2442e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2452e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2469b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCstatic int getSubsamp(j_decompress_ptr dinfo) 2479b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 2489b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=-1, i, k; 2499b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC for(i=0; i<NUMSUBOPT; i++) 2509b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2519b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->num_components==pixelsize[i]) 2529b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2539b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8 2549b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC && dinfo->comp_info[0].v_samp_factor==tjMCUHeight[i]/8) 2559b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2569b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int match=0; 2579b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC for(k=1; k<dinfo->num_components; k++) 2589b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2599b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(dinfo->comp_info[k].h_samp_factor==1 2609b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC && dinfo->comp_info[k].v_samp_factor==1) 2619b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC match++; 2629b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2639b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(match==dinfo->num_components-1) 2649b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC { 2659b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC retval=i; break; 2669b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2679b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2689b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2699b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC } 2709b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return retval; 2719b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 2729b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 2739b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 2749b28defe6ac85dd8a52479cf276606beae24920eDRC/* General API functions */ 2752e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2769b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT char* DLLCALL tjGetErrorStr(void) 2772e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 2789b28defe6ac85dd8a52479cf276606beae24920eDRC return errStr; 2792e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 2802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2819b28defe6ac85dd8a52479cf276606beae24920eDRC 2829b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDestroy(tjhandle handle) 2832e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 2849b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 2859b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) return -1; 2869b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&COMPRESS) jpeg_destroy_compress(cinfo); 2879b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&DECOMPRESS) jpeg_destroy_decompress(dinfo); 2889b28defe6ac85dd8a52479cf276606beae24920eDRC free(this); 2899b28defe6ac85dd8a52479cf276606beae24920eDRC return 0; 2902e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 2912e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2929b28defe6ac85dd8a52479cf276606beae24920eDRC 2936b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC/* These are exposed mainly because Windows can't malloc() and free() across 2946b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC DLL boundaries except when the CRT DLL is used, and we don't use the CRT DLL 2956b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC with turbojpeg.dll for compatibility reasons. However, these functions 2966b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC can potentially be used for other purposes by different implementations. */ 2976b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 2986b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT void DLLCALL tjFree(unsigned char *buf) 2996b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 3006b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC if(buf) free(buf); 3016b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 3026b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 3036b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 3046b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes) 3056b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 3066b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC return (unsigned char *)malloc(bytes); 3076b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 3086b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 3096b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 3109b28defe6ac85dd8a52479cf276606beae24920eDRC/* Compressor */ 3119b28defe6ac85dd8a52479cf276606beae24920eDRC 3129b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitCompress(tjinstance *this) 3132e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 3149b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char buffer[1], *buf=buffer; unsigned long size=1; 3159b28defe6ac85dd8a52479cf276606beae24920eDRC 3169b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 3179b28defe6ac85dd8a52479cf276606beae24920eDRC this->cinfo.err=jpeg_std_error(&this->jerr.pub); 3189b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 3199b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 3202e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 3219b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 3229b28defe6ac85dd8a52479cf276606beae24920eDRC { 3239b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 3249b28defe6ac85dd8a52479cf276606beae24920eDRC if(this) free(this); return NULL; 325efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 3262e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 3279b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_compress(&this->cinfo); 3289b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the destination manager */ 3299b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); 3302e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 331007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=COMPRESS; 3329b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 3332e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 3342e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 335890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitCompress(void) 336890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 3379b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; 3389b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 339da5220acdd525242bff4e40b1d90324ebb889825DRC { 340007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 341007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitCompress(): Memory allocation failure"); 342da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 343da5220acdd525242bff4e40b1d90324ebb889825DRC } 344007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 3459b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitCompress(this); 346890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 347890f1e0413b54c40b663208779d4ea9dae20eaefDRC 348842416034561f6d5320165a4fe98825e999a4a37DRC 3499b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, 3509b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int jpegSubsamp) 3519b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 3529b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC unsigned long retval=0; int mcuw, mcuh, chromasf; 3539b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT) 3549b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjBufSize(): Invalid argument"); 3559b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 3569b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // This allows for rare corner cases in which a JPEG image can actually be 3579b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // larger than the uncompressed input (we wouldn't mention it if it hadn't 3589b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC // happened before.) 3599b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC mcuw=tjMCUWidth[jpegSubsamp]; 3609b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC mcuh=tjMCUHeight[jpegSubsamp]; 3619b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh); 3629b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048; 3639b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 3649b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC bailout: 3659b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return retval; 3669b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 3679b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 3689b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 3692e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) 3702e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 371f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 372f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1) 373007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("TJBUFSIZE(): Invalid argument"); 374f3cf973e8e51e0078f402ca5547c026967c27321DRC 375f3cf973e8e51e0078f402ca5547c026967c27321DRC // This allows for rare corner cases in which a JPEG image can actually be 376f3cf973e8e51e0078f402ca5547c026967c27321DRC // larger than the uncompressed input (we wouldn't mention it if it hadn't 377b28fc5710a510410d2b498255a423dd62b353b3aDRC // happened before.) 378007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; 379f3cf973e8e51e0078f402ca5547c026967c27321DRC 380f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 381f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 382f3cf973e8e51e0078f402ca5547c026967c27321DRC} 383f3cf973e8e51e0078f402ca5547c026967c27321DRC 384842416034561f6d5320165a4fe98825e999a4a37DRC 3859b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, 386f3cf973e8e51e0078f402ca5547c026967c27321DRC int subsamp) 387f3cf973e8e51e0078f402ca5547c026967c27321DRC{ 388f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 389f3cf973e8e51e0078f402ca5547c026967c27321DRC int pw, ph, cw, ch; 390f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) 3919b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjBufSizeYUV(): Invalid argument"); 3929b28defe6ac85dd8a52479cf276606beae24920eDRC pw=PAD(width, tjMCUWidth[subsamp]/8); 3939b28defe6ac85dd8a52479cf276606beae24920eDRC ph=PAD(height, tjMCUHeight[subsamp]/8); 3949b28defe6ac85dd8a52479cf276606beae24920eDRC cw=pw*8/tjMCUWidth[subsamp]; ch=ph*8/tjMCUHeight[subsamp]; 39525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC retval=PAD(pw, 4)*ph + (subsamp==TJSAMP_GRAY? 0:PAD(cw, 4)*ch*2); 396f3cf973e8e51e0078f402ca5547c026967c27321DRC 397f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 398f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 3992e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 4002e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 401842416034561f6d5320165a4fe98825e999a4a37DRC 4029b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height, 4039b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int subsamp) 4049b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{ 4059b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC return tjBufSizeYUV(width, height, subsamp); 4069b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC} 4079b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 4089b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC 4099b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, 4109b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, 4119b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 4129b28defe6ac85dd8a52479cf276606beae24920eDRC{ 413ff78e37595c8462f64fd100f928aa1d08539527eDRC int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; 4149b28defe6ac85dd8a52479cf276606beae24920eDRC 4159b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle) 4169b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 417007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Instance has not been initialized for compression"); 4189b28defe6ac85dd8a52479cf276606beae24920eDRC 4199b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 4209b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL 4219b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100) 422007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Invalid argument"); 4239b28defe6ac85dd8a52479cf276606beae24920eDRC 4249b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 4259b28defe6ac85dd8a52479cf276606beae24920eDRC { 4269b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 4279b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 4289b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 4299b28defe6ac85dd8a52479cf276606beae24920eDRC } 4309b28defe6ac85dd8a52479cf276606beae24920eDRC 4319b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 4329b28defe6ac85dd8a52479cf276606beae24920eDRC 4339b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 4349b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 4359b28defe6ac85dd8a52479cf276606beae24920eDRC 43625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 43725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 43825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 4399b28defe6ac85dd8a52479cf276606beae24920eDRC 440ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 441ff78e37595c8462f64fd100f928aa1d08539527eDRC { 4429b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp); 443ff78e37595c8462f64fd100f928aa1d08539527eDRC } 444ff78e37595c8462f64fd100f928aa1d08539527eDRC jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); 445f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC if(setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual)==-1) 446f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC return -1; 4479b28defe6ac85dd8a52479cf276606beae24920eDRC 4489b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 4499b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) 450007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Memory allocation failure"); 4519b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 4529b28defe6ac85dd8a52479cf276606beae24920eDRC { 45325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch]; 4549b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&srcBuf[i*pitch]; 4559b28defe6ac85dd8a52479cf276606beae24920eDRC } 4569b28defe6ac85dd8a52479cf276606beae24920eDRC while(cinfo->next_scanline<cinfo->image_height) 4579b28defe6ac85dd8a52479cf276606beae24920eDRC { 4589b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], 4599b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height-cinfo->next_scanline); 4609b28defe6ac85dd8a52479cf276606beae24920eDRC } 4619b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_compress(cinfo); 4629b28defe6ac85dd8a52479cf276606beae24920eDRC 4639b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 4649b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 4659b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 4669b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 4679b28defe6ac85dd8a52479cf276606beae24920eDRC} 4689b28defe6ac85dd8a52479cf276606beae24920eDRC 4699b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, 4709b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, 4719b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 4729b28defe6ac85dd8a52479cf276606beae24920eDRC{ 4739b28defe6ac85dd8a52479cf276606beae24920eDRC int retval=0; unsigned long size; 4749b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 4759b28defe6ac85dd8a52479cf276606beae24920eDRC { 4769b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC size=tjBufSizeYUV(width, height, jpegSubsamp); 4779b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height, 4789b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp, flags); 4799b28defe6ac85dd8a52479cf276606beae24920eDRC } 4809b28defe6ac85dd8a52479cf276606beae24920eDRC else 4819b28defe6ac85dd8a52479cf276606beae24920eDRC { 4829b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjCompress2(handle, srcBuf, width, pitch, height, 4839b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegSubsamp, jpegQual, 48425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC flags|TJFLAG_NOREALLOC); 4859b28defe6ac85dd8a52479cf276606beae24920eDRC } 4869b28defe6ac85dd8a52479cf276606beae24920eDRC *jpegSize=size; 4879b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 4889b28defe6ac85dd8a52479cf276606beae24920eDRC} 4899b28defe6ac85dd8a52479cf276606beae24920eDRC 4909b28defe6ac85dd8a52479cf276606beae24920eDRC 4919b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, 4929b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, 4939b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 4942e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 49591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC int i, retval=0; JSAMPROW *row_pointer=NULL; 496fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; 497fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; 498fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *outbuf[MAX_COMPONENTS]; 4999b28defe6ac85dd8a52479cf276606beae24920eDRC int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS]; 5009b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPLE *ptr=dstBuf; 5019b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long yuvsize=0; 5029b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr; 5032e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5049b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 5059b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 506007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjEncodeYUV2(): Instance has not been initialized for compression"); 5072e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 508fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 509fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 510fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf[i]=NULL; _tmpbuf[i]=NULL; 511fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; 512fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 513fbb674707e01a61e8b7083faa632dfd46c568b13DRC 5149b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 5159b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0 5169b28defe6ac85dd8a52479cf276606beae24920eDRC || subsamp>=NUMSUBOPT) 5179b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjEncodeYUV2(): Invalid argument"); 5182e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5199b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 5209b28defe6ac85dd8a52479cf276606beae24920eDRC { 5219b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 52291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 52391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 524efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 5252e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5269b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 5272e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5289b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 5299b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 5302e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 53125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 53225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 53325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 5342e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5359b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC yuvsize=tjBufSizeYUV(width, height, subsamp); 5369b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0); 537f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC if(setCompDefaults(cinfo, pixelFormat, subsamp, -1)==-1) return -1; 5382e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5399b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 5409b28defe6ac85dd8a52479cf276606beae24920eDRC pw=PAD(width, cinfo->max_h_samp_factor); 5419b28defe6ac85dd8a52479cf276606beae24920eDRC ph=PAD(height, cinfo->max_v_samp_factor); 5429b28defe6ac85dd8a52479cf276606beae24920eDRC 5439b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL) 544007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjEncodeYUV2(): Memory allocation failure"); 5459b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 5462e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC { 54725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch]; 5489b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&srcBuf[i*pitch]; 5499b28defe6ac85dd8a52479cf276606beae24920eDRC } 5509b28defe6ac85dd8a52479cf276606beae24920eDRC if(height<ph) 5519b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=height; i<ph; i++) row_pointer[i]=row_pointer[height-1]; 552fbb674707e01a61e8b7083faa632dfd46c568b13DRC 5539b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<cinfo->num_components; i++) 5549b28defe6ac85dd8a52479cf276606beae24920eDRC { 5559b28defe6ac85dd8a52479cf276606beae24920eDRC compptr=&cinfo->comp_info[i]; 5569b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf[i]=(JSAMPLE *)malloc( 5579b28defe6ac85dd8a52479cf276606beae24920eDRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 5589b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16); 559007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!_tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 5609b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor); 561007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 5629b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<cinfo->max_v_samp_factor; row++) 563fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 5649b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf_aligned= 5659b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf[i], 16); 5669b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=&_tmpbuf_aligned[ 567fbb674707e01a61e8b7083faa632dfd46c568b13DRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 5689b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * row]; 569fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 5709b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16) 5719b28defe6ac85dd8a52479cf276606beae24920eDRC * compptr->v_samp_factor + 16); 572007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!_tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 5739b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor); 574007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 5759b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<compptr->v_samp_factor; row++) 576fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 5779b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf2_aligned= 5789b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf2[i], 16); 5799b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i][row]=&_tmpbuf2_aligned[ 5809b28defe6ac85dd8a52479cf276606beae24920eDRC PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]; 581fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 5829b28defe6ac85dd8a52479cf276606beae24920eDRC cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor; 5839b28defe6ac85dd8a52479cf276606beae24920eDRC ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor; 5849b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]); 585007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!outbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 5869b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ch[i]; row++) 587fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 5889b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 5899b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=PAD(cw[i], 4); 590fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 5916ee54594591d0ae958b81adc8ba3cacde522e5e3DRC } 5929b28defe6ac85dd8a52479cf276606beae24920eDRC if(yuvsize!=(unsigned long)(ptr-dstBuf)) 5939b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjEncodeYUV2(): Generated image is not the correct size"); 5949b28defe6ac85dd8a52479cf276606beae24920eDRC 5959b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ph; row+=cinfo->max_v_samp_factor) 5969b28defe6ac85dd8a52479cf276606beae24920eDRC { 5979b28defe6ac85dd8a52479cf276606beae24920eDRC (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, 0, 5989b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->max_v_samp_factor); 5999b28defe6ac85dd8a52479cf276606beae24920eDRC (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0); 6009b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++, compptr++) 6019b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], 6029b28defe6ac85dd8a52479cf276606beae24920eDRC row*compptr->v_samp_factor/cinfo->max_v_samp_factor, 6039b28defe6ac85dd8a52479cf276606beae24920eDRC compptr->v_samp_factor, cw[i]); 6049b28defe6ac85dd8a52479cf276606beae24920eDRC } 6059b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->next_scanline+=height; 6069b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_compress(cinfo); 6072e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 60891e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 6099b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 6102e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC if(row_pointer) free(row_pointer); 611fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 612fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 613fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf[i]!=NULL) free(tmpbuf[i]); 61457423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); 615fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); 61657423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); 617fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(outbuf[i]!=NULL) free(outbuf[i]); 618fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 61991e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 6202e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 6212e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6229b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, 6239b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, 6249b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 625842416034561f6d5320165a4fe98825e999a4a37DRC{ 6269b28defe6ac85dd8a52479cf276606beae24920eDRC return tjEncodeYUV2(handle, srcBuf, width, pitch, height, 6279b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags); 628842416034561f6d5320165a4fe98825e999a4a37DRC} 629842416034561f6d5320165a4fe98825e999a4a37DRC 630842416034561f6d5320165a4fe98825e999a4a37DRC 6319b28defe6ac85dd8a52479cf276606beae24920eDRC/* Decompressor */ 6322e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6339b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitDecompress(tjinstance *this) 6342e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 6359b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char buffer[1]; 6362e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6379b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 6389b28defe6ac85dd8a52479cf276606beae24920eDRC this->dinfo.err=jpeg_std_error(&this->jerr.pub); 6399b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 6409b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 6412e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6429b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 6439b28defe6ac85dd8a52479cf276606beae24920eDRC { 6449b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 6459b28defe6ac85dd8a52479cf276606beae24920eDRC if(this) free(this); return NULL; 6469e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 6472e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6489b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_decompress(&this->dinfo); 6499b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the source manager */ 6509b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(&this->dinfo, buffer, 1); 6512e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 652007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=DECOMPRESS; 6539b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 6542e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 6552e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 656890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitDecompress(void) 657890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 6589b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this; 6599b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 660da5220acdd525242bff4e40b1d90324ebb889825DRC { 661007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 662007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitDecompress(): Memory allocation failure"); 663da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 664da5220acdd525242bff4e40b1d90324ebb889825DRC } 665007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 6669b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitDecompress(this); 667890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 668890f1e0413b54c40b663208779d4ea9dae20eaefDRC 6692e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 6709b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, 6719b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, 6729b28defe6ac85dd8a52479cf276606beae24920eDRC int *jpegSubsamp) 6731fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC{ 6749b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=0; 6751fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6769b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 6779b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 678007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Instance has not been initialized for decompression"); 6791fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6809b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL 6819b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp==NULL) 6829b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompressHeader2(): Invalid argument"); 6831fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6849b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 6859b28defe6ac85dd8a52479cf276606beae24920eDRC { 6869b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 6871fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC return -1; 6881fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 6891fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6909b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 6919b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 6921fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6939b28defe6ac85dd8a52479cf276606beae24920eDRC *width=dinfo->image_width; 6949b28defe6ac85dd8a52479cf276606beae24920eDRC *height=dinfo->image_height; 6959b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC *jpegSubsamp=getSubsamp(dinfo); 6961fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6979b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_decompress(dinfo); 6981fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6999b28defe6ac85dd8a52479cf276606beae24920eDRC if(*jpegSubsamp<0) 700007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Could not determine subsampling type for JPEG image"); 701007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(*width<1 || *height<1) 702007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Invalid data returned in header"); 70391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 70491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 70591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 70691e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC} 70791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 7089b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, 7099b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height) 71091e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC{ 7119b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegSubsamp; 7129b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, 7139b28defe6ac85dd8a52479cf276606beae24920eDRC &jpegSubsamp); 7141fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC} 7151fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 7161fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 717109a578e89ea8cd2c39d50b012698148dd11dedbDRCDLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors) 718b28fc5710a510410d2b498255a423dd62b353b3aDRC{ 719109a578e89ea8cd2c39d50b012698148dd11dedbDRC if(numscalingfactors==NULL) 720b28fc5710a510410d2b498255a423dd62b353b3aDRC { 7219b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 722007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjGetScalingFactors(): Invalid argument"); 723109a578e89ea8cd2c39d50b012698148dd11dedbDRC return NULL; 724b28fc5710a510410d2b498255a423dd62b353b3aDRC } 725b28fc5710a510410d2b498255a423dd62b353b3aDRC 726109a578e89ea8cd2c39d50b012698148dd11dedbDRC *numscalingfactors=NUMSF; 727109a578e89ea8cd2c39d50b012698148dd11dedbDRC return (tjscalingfactor *)sf; 728b28fc5710a510410d2b498255a423dd62b353b3aDRC} 729b28fc5710a510410d2b498255a423dd62b353b3aDRC 730b28fc5710a510410d2b498255a423dd62b353b3aDRC 7319b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, 7329b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 7339b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelFormat, int flags) 7349b28defe6ac85dd8a52479cf276606beae24920eDRC{ 7359b28defe6ac85dd8a52479cf276606beae24920eDRC int i, retval=0; JSAMPROW *row_pointer=NULL; 7369b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegwidth, jpegheight, scaledw, scaledh; 7379b28defe6ac85dd8a52479cf276606beae24920eDRC 7389b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 7399b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 740007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Instance has not been initialized for decompression"); 7419b28defe6ac85dd8a52479cf276606beae24920eDRC 7429b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 7439b28defe6ac85dd8a52479cf276606beae24920eDRC || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) 7449b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompress2(): Invalid argument"); 7459b28defe6ac85dd8a52479cf276606beae24920eDRC 74625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 74725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 74825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 7499b28defe6ac85dd8a52479cf276606beae24920eDRC 7509b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 7519b28defe6ac85dd8a52479cf276606beae24920eDRC { 7529b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 7539b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 7549b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 7559b28defe6ac85dd8a52479cf276606beae24920eDRC } 7569b28defe6ac85dd8a52479cf276606beae24920eDRC 7579b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 7589b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 759f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC if(setDecompDefaults(dinfo, pixelFormat)==-1) return -1; 7609b28defe6ac85dd8a52479cf276606beae24920eDRC 76125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 7629b28defe6ac85dd8a52479cf276606beae24920eDRC 7639b28defe6ac85dd8a52479cf276606beae24920eDRC jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; 7649b28defe6ac85dd8a52479cf276606beae24920eDRC if(width==0) width=jpegwidth; 7659b28defe6ac85dd8a52479cf276606beae24920eDRC if(height==0) height=jpegheight; 7669b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<NUMSF; i++) 7679b28defe6ac85dd8a52479cf276606beae24920eDRC { 7689b28defe6ac85dd8a52479cf276606beae24920eDRC scaledw=TJSCALED(jpegwidth, sf[i]); 7699b28defe6ac85dd8a52479cf276606beae24920eDRC scaledh=TJSCALED(jpegheight, sf[i]); 7709b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw<=width && scaledh<=height) 7719b28defe6ac85dd8a52479cf276606beae24920eDRC break; 7729b28defe6ac85dd8a52479cf276606beae24920eDRC } 7739b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw>width || scaledh>height) 774007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Could not scale down to desired image dimensions"); 7759b28defe6ac85dd8a52479cf276606beae24920eDRC width=scaledw; height=scaledh; 7769b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_num=sf[i].num; 7779b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_denom=sf[i].denom; 7789b28defe6ac85dd8a52479cf276606beae24920eDRC 7799b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 7809b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; 7819b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) 7829b28defe6ac85dd8a52479cf276606beae24920eDRC *dinfo->output_height))==NULL) 783007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Memory allocation failure"); 7849b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<(int)dinfo->output_height; i++) 7859b28defe6ac85dd8a52479cf276606beae24920eDRC { 78625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) 7879b28defe6ac85dd8a52479cf276606beae24920eDRC row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]; 7889b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&dstBuf[i*pitch]; 7899b28defe6ac85dd8a52479cf276606beae24920eDRC } 7909b28defe6ac85dd8a52479cf276606beae24920eDRC while(dinfo->output_scanline<dinfo->output_height) 7919b28defe6ac85dd8a52479cf276606beae24920eDRC { 7929b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], 7939b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->output_height-dinfo->output_scanline); 7949b28defe6ac85dd8a52479cf276606beae24920eDRC } 7959b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 7969b28defe6ac85dd8a52479cf276606beae24920eDRC 7979b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 7989b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 7999b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 8009b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 8019b28defe6ac85dd8a52479cf276606beae24920eDRC} 8029b28defe6ac85dd8a52479cf276606beae24920eDRC 8039b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, 8049b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 8059b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelSize, int flags) 8069b28defe6ac85dd8a52479cf276606beae24920eDRC{ 8079b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 8089b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags); 8099b28defe6ac85dd8a52479cf276606beae24920eDRC else 8109b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch, 8119b28defe6ac85dd8a52479cf276606beae24920eDRC height, getPixelFormat(pixelSize, flags), flags); 8129b28defe6ac85dd8a52479cf276606beae24920eDRC} 8139b28defe6ac85dd8a52479cf276606beae24920eDRC 8149b28defe6ac85dd8a52479cf276606beae24920eDRC 8159b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, 8169b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, 817b28fc5710a510410d2b498255a423dd62b353b3aDRC int flags) 8182e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 8199b28defe6ac85dd8a52479cf276606beae24920eDRC int i, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS]; 820f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS], 821f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; 8229b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPLE *_tmpbuf=NULL, *ptr=dstBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS]; 8232e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8249b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 8259b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 826007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Instance has not been initialized for decompression"); 8272e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 828f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<MAX_COMPONENTS; i++) 829f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 830f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbuf[i]=NULL; outbuf[i]=NULL; 831f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 8329e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC 8339b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL) 8349b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompressToYUV(): Invalid argument"); 8352e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 83625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 83725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 83825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 8390c6a271f974529e4795332c9ad428500ef17fb42DRC 8409b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 8419b28defe6ac85dd8a52479cf276606beae24920eDRC { 8429b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 84391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 84491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 8459e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8462e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8479b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 8489b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 8492e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8509b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 8519e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 8529b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 8539b28defe6ac85dd8a52479cf276606beae24920eDRC int ih; 8549b28defe6ac85dd8a52479cf276606beae24920eDRC iw[i]=compptr->width_in_blocks*DCTSIZE; 8559b28defe6ac85dd8a52479cf276606beae24920eDRC ih=compptr->height_in_blocks*DCTSIZE; 8569b28defe6ac85dd8a52479cf276606beae24920eDRC cw[i]=PAD(dinfo->image_width, dinfo->max_h_samp_factor) 8579b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->h_samp_factor/dinfo->max_h_samp_factor; 8589b28defe6ac85dd8a52479cf276606beae24920eDRC ch[i]=PAD(dinfo->image_height, dinfo->max_v_samp_factor) 8599b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->v_samp_factor/dinfo->max_v_samp_factor; 8609b28defe6ac85dd8a52479cf276606beae24920eDRC if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1; 8619b28defe6ac85dd8a52479cf276606beae24920eDRC th[i]=compptr->v_samp_factor*DCTSIZE; 8629b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbufsize+=iw[i]*th[i]; 8639b28defe6ac85dd8a52479cf276606beae24920eDRC if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]))==NULL) 864007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 8659b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ch[i]; row++) 8669e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 8679b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 8689b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=PAD(cw[i], 4); 869f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 8709b28defe6ac85dd8a52479cf276606beae24920eDRC } 8719b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 8729b28defe6ac85dd8a52479cf276606beae24920eDRC { 8739b28defe6ac85dd8a52479cf276606beae24920eDRC if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL) 874007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 8759b28defe6ac85dd8a52479cf276606beae24920eDRC ptr=_tmpbuf; 8769b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 877f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 8789b28defe6ac85dd8a52479cf276606beae24920eDRC if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL) 879007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 8809b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<th[i]; row++) 881f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 8829b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=ptr; 8839b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=iw[i]; 8849e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8859e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8869e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8872e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 88825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 8899b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->raw_data_out=TRUE; 8909b28defe6ac85dd8a52479cf276606beae24920eDRC 8919b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 8929b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<(int)dinfo->output_height; 8939b28defe6ac85dd8a52479cf276606beae24920eDRC row+=dinfo->max_v_samp_factor*DCTSIZE) 8948ed7b814039172fe3cbfadfee3922801a3888b73DRC { 8959b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPARRAY yuvptr[MAX_COMPONENTS]; 8969b28defe6ac85dd8a52479cf276606beae24920eDRC int crow[MAX_COMPONENTS]; 8979b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 898842416034561f6d5320165a4fe98825e999a4a37DRC { 8999b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 9009b28defe6ac85dd8a52479cf276606beae24920eDRC crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_factor; 9019b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) yuvptr[i]=tmpbuf[i]; 9029b28defe6ac85dd8a52479cf276606beae24920eDRC else yuvptr[i]=&outbuf[i][crow[i]]; 903842416034561f6d5320165a4fe98825e999a4a37DRC } 9049b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_raw_data(dinfo, yuvptr, dinfo->max_v_samp_factor*DCTSIZE); 9059b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 9069e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 9079b28defe6ac85dd8a52479cf276606beae24920eDRC int j; 908f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<dinfo->num_components; i++) 9099e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 9109b28defe6ac85dd8a52479cf276606beae24920eDRC for(j=0; j<min(th[i], ch[i]-crow[i]); j++) 911f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 9129b28defe6ac85dd8a52479cf276606beae24920eDRC memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j], cw[i]); 913f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 9149e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 9159e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 9169e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 9179b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 9182e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 91991e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 9209b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 9219e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC for(i=0; i<MAX_COMPONENTS; i++) 922f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 923f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(tmpbuf[i]) free(tmpbuf[i]); 9249e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC if(outbuf[i]) free(outbuf[i]); 925f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 926f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(_tmpbuf) free(_tmpbuf); 92791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 9282e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 9292e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 9302e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 9319b28defe6ac85dd8a52479cf276606beae24920eDRC/* Transformer */ 932890f1e0413b54c40b663208779d4ea9dae20eaefDRC 933890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitTransform(void) 934890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 9359b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; tjhandle handle=NULL; 9369b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 937da5220acdd525242bff4e40b1d90324ebb889825DRC { 938007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 939007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitTransform(): Memory allocation failure"); 940da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 941da5220acdd525242bff4e40b1d90324ebb889825DRC } 942007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 9439b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitCompress(this); 9449b28defe6ac85dd8a52479cf276606beae24920eDRC if(!handle) return NULL; 9459b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitDecompress(this); 9469b28defe6ac85dd8a52479cf276606beae24920eDRC return handle; 947890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 948890f1e0413b54c40b663208779d4ea9dae20eaefDRC 949890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9509b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf, 9519b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, int n, unsigned char **dstBufs, 9529b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *dstSizes, tjtransform *t, int flags) 953890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 9540a325197dedd2eede99731c68ae0e0a145473f64DRC jpeg_transform_info *xinfo=NULL; 955890f1e0413b54c40b663208779d4ea9dae20eaefDRC jvirt_barray_ptr *srccoefs, *dstcoefs; 9569b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC int retval=0, i, jpegSubsamp; 957890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9589b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 9599b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0) 960007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Instance has not been initialized for transformation"); 961890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9629b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NULL 9630a325197dedd2eede99731c68ae0e0a145473f64DRC || t==NULL || flags<0) 9649b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjTransform(): Invalid argument"); 965890f1e0413b54c40b663208779d4ea9dae20eaefDRC 96625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 96725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 96825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 969890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9709b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 9719b28defe6ac85dd8a52479cf276606beae24920eDRC { 9729b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 973890f1e0413b54c40b663208779d4ea9dae20eaefDRC retval=-1; 974890f1e0413b54c40b663208779d4ea9dae20eaefDRC goto bailout; 975890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 976890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9779b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 978890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9790a325197dedd2eede99731c68ae0e0a145473f64DRC if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n)) 9800a325197dedd2eede99731c68ae0e0a145473f64DRC ==NULL) 981007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Memory allocation failure"); 982007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(xinfo, sizeof(jpeg_transform_info)*n); 983890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9840a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 985890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 9860a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].transform=xformtypes[t[i].op]; 98725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].perfect=(t[i].options&TJXOPT_PERFECT)? 1:0; 98825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].trim=(t[i].options&TJXOPT_TRIM)? 1:0; 98925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].force_grayscale=(t[i].options&TJXOPT_GRAY)? 1:0; 99025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].crop=(t[i].options&TJXOPT_CROP)? 1:0; 99125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(n!=1 && t[i].op==TJXOP_HFLIP) xinfo[i].slow_hflip=1; 992ba5ea5143e48b71234414139e3b4cb244599e875DRC else xinfo[i].slow_hflip=0; 9930a325197dedd2eede99731c68ae0e0a145473f64DRC 9940a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 995890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 9960a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_xoffset=t[i].r.x; xinfo[i].crop_xoffset_set=JCROP_POS; 9970a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_yoffset=t[i].r.y; xinfo[i].crop_yoffset_set=JCROP_POS; 9980a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.w!=0) 9990a325197dedd2eede99731c68ae0e0a145473f64DRC { 10000a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_width=t[i].r.w; xinfo[i].crop_width_set=JCROP_POS; 10010a325197dedd2eede99731c68ae0e0a145473f64DRC } 1002d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_width=JCROP_UNSET; 10030a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.h!=0) 10040a325197dedd2eede99731c68ae0e0a145473f64DRC { 10050a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_height=t[i].r.h; xinfo[i].crop_height_set=JCROP_POS; 10060a325197dedd2eede99731c68ae0e0a145473f64DRC } 1007d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_height=JCROP_UNSET; 1008890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1009890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1010890f1e0413b54c40b663208779d4ea9dae20eaefDRC 10119b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_markers_setup(dinfo, JCOPYOPT_ALL); 10129b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 10139b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC jpegSubsamp=getSubsamp(dinfo); 10149b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC if(jpegSubsamp<0) 10159b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC _throw("tjTransform(): Could not determine subsampling type for JPEG image"); 1016890f1e0413b54c40b663208779d4ea9dae20eaefDRC 10170a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 1018890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 10199b28defe6ac85dd8a52479cf276606beae24920eDRC if(!jtransform_request_workspace(dinfo, &xinfo[i])) 1020007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Transform is not perfect"); 10210a325197dedd2eede99731c68ae0e0a145473f64DRC 10220a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 10230a325197dedd2eede99731c68ae0e0a145473f64DRC { 10240a325197dedd2eede99731c68ae0e0a145473f64DRC if((t[i].r.x%xinfo[i].iMCU_sample_width)!=0 10250a325197dedd2eede99731c68ae0e0a145473f64DRC || (t[i].r.y%xinfo[i].iMCU_sample_height)!=0) 10260a325197dedd2eede99731c68ae0e0a145473f64DRC { 10279b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 10280a325197dedd2eede99731c68ae0e0a145473f64DRC "To crop this JPEG image, x must be a multiple of %d\n" 10290a325197dedd2eede99731c68ae0e0a145473f64DRC "and y must be a multiple of %d.\n", 10300a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].iMCU_sample_width, xinfo[i].iMCU_sample_height); 10310a325197dedd2eede99731c68ae0e0a145473f64DRC retval=-1; goto bailout; 10320a325197dedd2eede99731c68ae0e0a145473f64DRC } 10330a325197dedd2eede99731c68ae0e0a145473f64DRC } 1034890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1035890f1e0413b54c40b663208779d4ea9dae20eaefDRC 10369b28defe6ac85dd8a52479cf276606beae24920eDRC srccoefs=jpeg_read_coefficients(dinfo); 1037890f1e0413b54c40b663208779d4ea9dae20eaefDRC 10380a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 1039890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 1040ff78e37595c8462f64fd100f928aa1d08539527eDRC int w, h, alloc=1; 10410a325197dedd2eede99731c68ae0e0a145473f64DRC if(!xinfo[i].crop) 1042890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 10439b28defe6ac85dd8a52479cf276606beae24920eDRC w=dinfo->image_width; h=dinfo->image_height; 1044890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 10450a325197dedd2eede99731c68ae0e0a145473f64DRC else 10460a325197dedd2eede99731c68ae0e0a145473f64DRC { 10470a325197dedd2eede99731c68ae0e0a145473f64DRC w=xinfo[i].crop_width; h=xinfo[i].crop_height; 10480a325197dedd2eede99731c68ae0e0a145473f64DRC } 1049ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 1050ff78e37595c8462f64fd100f928aa1d08539527eDRC { 10519b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC alloc=0; dstSizes[i]=tjBufSize(w, h, jpegSubsamp); 1052ff78e37595c8462f64fd100f928aa1d08539527eDRC } 10537bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) 10547bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_mem_dest_tj(cinfo, &dstBufs[i], &dstSizes[i], alloc); 10559b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_copy_critical_parameters(dinfo, cinfo); 10569b28defe6ac85dd8a52479cf276606beae24920eDRC dstcoefs=jtransform_adjust_parameters(dinfo, cinfo, srccoefs, 10570a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 10587bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) 10597bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 10607bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_write_coefficients(cinfo, dstcoefs); 10617bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL); 10627bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 10637bf04d399ebf9a3b39a6d5b5639d895df618353dDRC else jinit_c_master_control(cinfo, TRUE); 10649b28defe6ac85dd8a52479cf276606beae24920eDRC jtransform_execute_transformation(dinfo, cinfo, srccoefs, 10650a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 10667bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(t[i].customFilter) 10677bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 10687bf04d399ebf9a3b39a6d5b5639d895df618353dDRC int ci, by, y; 10697bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(ci=0; ci<cinfo->num_components; ci++) 10707bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 10717bf04d399ebf9a3b39a6d5b5639d895df618353dDRC jpeg_component_info *compptr=&cinfo->comp_info[ci]; 10727bf04d399ebf9a3b39a6d5b5639d895df618353dDRC tjregion arrayRegion={0, 0, compptr->width_in_blocks*DCTSIZE, 10737bf04d399ebf9a3b39a6d5b5639d895df618353dDRC DCTSIZE}; 10747bf04d399ebf9a3b39a6d5b5639d895df618353dDRC tjregion planeRegion={0, 0, compptr->width_in_blocks*DCTSIZE, 10757bf04d399ebf9a3b39a6d5b5639d895df618353dDRC compptr->height_in_blocks*DCTSIZE}; 10767bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(by=0; by<compptr->height_in_blocks; by+=compptr->v_samp_factor) 10777bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 10787bf04d399ebf9a3b39a6d5b5639d895df618353dDRC JBLOCKARRAY barray=(dinfo->mem->access_virt_barray) 10797bf04d399ebf9a3b39a6d5b5639d895df618353dDRC ((j_common_ptr)dinfo, dstcoefs[ci], by, compptr->v_samp_factor, 10807bf04d399ebf9a3b39a6d5b5639d895df618353dDRC TRUE); 10817bf04d399ebf9a3b39a6d5b5639d895df618353dDRC for(y=0; y<compptr->v_samp_factor; y++) 10827bf04d399ebf9a3b39a6d5b5639d895df618353dDRC { 10837bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(t[i].customFilter(barray[y][0], arrayRegion, planeRegion, 1084f5467110763f7a44ca8baf1c035eb39a68c913c6DRC ci, i, &t[i])==-1) 10857bf04d399ebf9a3b39a6d5b5639d895df618353dDRC _throw("tjTransform(): Error in custom filter"); 10867bf04d399ebf9a3b39a6d5b5639d895df618353dDRC arrayRegion.y+=DCTSIZE; 10877bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 10887bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 10897bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 10907bf04d399ebf9a3b39a6d5b5639d895df618353dDRC } 10917bf04d399ebf9a3b39a6d5b5639d895df618353dDRC if(!(t[i].options&TJXOPT_NOOUTPUT)) jpeg_finish_compress(cinfo); 1092890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 1093890f1e0413b54c40b663208779d4ea9dae20eaefDRC 10949b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 1095890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1096890f1e0413b54c40b663208779d4ea9dae20eaefDRC bailout: 10979b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 10989b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 10990a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo) free(xinfo); 1100890f1e0413b54c40b663208779d4ea9dae20eaefDRC return retval; 1101890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 1102