turbojpeg.c revision 6b76f75d2c0ebdc462f6bc663289fa4bfde1629a
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> 33fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define JPEG_INTERNALS 342e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jpeglib.h> 352e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jerror.h> 362e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <setjmp.h> 37007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC#include <jinclude.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 1359b28defe6ac85dd8a52479cf276606beae24920eDRCstatic void setCompDefaults(struct jpeg_compress_struct *cinfo, 1369b28defe6ac85dd8a52479cf276606beae24920eDRC int pixelFormat, int subsamp, int jpegQual) 1379b28defe6ac85dd8a52479cf276606beae24920eDRC{ 1389b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 1399b28defe6ac85dd8a52479cf276606beae24920eDRC { 14025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 1419b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_GRAYSCALE; break; 1429b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 14325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 1449b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGB; break; 14525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 1469b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGR; break; 14725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 1489b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_RGBX; break; 14925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 1509b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_BGRX; break; 15125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 1529b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XRGB; break; 15325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 1549b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_EXT_XBGR; break; 1559b28defe6ac85dd8a52479cf276606beae24920eDRC #else 15625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 1579b28defe6ac85dd8a52479cf276606beae24920eDRC if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXELSIZE==3) 1589b28defe6ac85dd8a52479cf276606beae24920eDRC { 1599b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->in_color_space=JCS_RGB; break; 1609b28defe6ac85dd8a52479cf276606beae24920eDRC } 1619b28defe6ac85dd8a52479cf276606beae24920eDRC default: 1629b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("Unsupported pixel format"); 1639b28defe6ac85dd8a52479cf276606beae24920eDRC #endif 1649b28defe6ac85dd8a52479cf276606beae24920eDRC } 1659b28defe6ac85dd8a52479cf276606beae24920eDRC 1669b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->input_components=tjPixelSize[pixelFormat]; 1679b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_defaults(cinfo); 1689b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegQual>=0) 1699b28defe6ac85dd8a52479cf276606beae24920eDRC { 1709b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_quality(cinfo, jpegQual, TRUE); 1719b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegQual>=96) cinfo->dct_method=JDCT_ISLOW; 1729b28defe6ac85dd8a52479cf276606beae24920eDRC else cinfo->dct_method=JDCT_FASTEST; 1739b28defe6ac85dd8a52479cf276606beae24920eDRC } 17425b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(subsamp==TJSAMP_GRAY) 1759b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); 1769b28defe6ac85dd8a52479cf276606beae24920eDRC else 1779b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_set_colorspace(cinfo, JCS_YCbCr); 1789b28defe6ac85dd8a52479cf276606beae24920eDRC 1799b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; 1809b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].h_samp_factor=1; 1819b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].h_samp_factor=1; 1829b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; 1839b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[1].v_samp_factor=1; 1849b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->comp_info[2].v_samp_factor=1; 1859b28defe6ac85dd8a52479cf276606beae24920eDRC} 1869b28defe6ac85dd8a52479cf276606beae24920eDRC 1879b28defe6ac85dd8a52479cf276606beae24920eDRCstatic void setDecompDefaults(struct jpeg_decompress_struct *dinfo, 1889b28defe6ac85dd8a52479cf276606beae24920eDRC int pixelFormat) 1899b28defe6ac85dd8a52479cf276606beae24920eDRC{ 1909b28defe6ac85dd8a52479cf276606beae24920eDRC switch(pixelFormat) 1919b28defe6ac85dd8a52479cf276606beae24920eDRC { 19225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_GRAY: 1939b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_GRAYSCALE; break; 1949b28defe6ac85dd8a52479cf276606beae24920eDRC #if JCS_EXTENSIONS==1 19525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 1969b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGB; break; 19725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGR: 1989b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGR; break; 19925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGBX: 2009b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_RGBX; break; 20125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_BGRX: 2029b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_BGRX; break; 20325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XRGB: 2049b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XRGB; break; 20525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_XBGR: 2069b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_EXT_XBGR; break; 2079b28defe6ac85dd8a52479cf276606beae24920eDRC #else 20825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC case TJPF_RGB: 2099b28defe6ac85dd8a52479cf276606beae24920eDRC if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXELSIZE==3) 2109b28defe6ac85dd8a52479cf276606beae24920eDRC { 2119b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->out_color_space=JCS_RGB; break; 2129b28defe6ac85dd8a52479cf276606beae24920eDRC } 2139b28defe6ac85dd8a52479cf276606beae24920eDRC default: 2149b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("Unsupported pixel format"); 2159b28defe6ac85dd8a52479cf276606beae24920eDRC #endif 2169b28defe6ac85dd8a52479cf276606beae24920eDRC } 2179b28defe6ac85dd8a52479cf276606beae24920eDRC} 2182e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2192e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2209b28defe6ac85dd8a52479cf276606beae24920eDRC/* General API functions */ 2212e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2229b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT char* DLLCALL tjGetErrorStr(void) 2232e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 2249b28defe6ac85dd8a52479cf276606beae24920eDRC return errStr; 2252e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 2262e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2279b28defe6ac85dd8a52479cf276606beae24920eDRC 2289b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDestroy(tjhandle handle) 2292e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 2309b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 2319b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) return -1; 2329b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&COMPRESS) jpeg_destroy_compress(cinfo); 2339b28defe6ac85dd8a52479cf276606beae24920eDRC if(this->init&DECOMPRESS) jpeg_destroy_decompress(dinfo); 2349b28defe6ac85dd8a52479cf276606beae24920eDRC free(this); 2359b28defe6ac85dd8a52479cf276606beae24920eDRC return 0; 2362e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 2372e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2389b28defe6ac85dd8a52479cf276606beae24920eDRC 2396b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC/* These are exposed mainly because Windows can't malloc() and free() across 2406b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC DLL boundaries except when the CRT DLL is used, and we don't use the CRT DLL 2416b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC with turbojpeg.dll for compatibility reasons. However, these functions 2426b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC can potentially be used for other purposes by different implementations. */ 2436b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 2446b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT void DLLCALL tjFree(unsigned char *buf) 2456b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 2466b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC if(buf) free(buf); 2476b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 2486b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 2496b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 2506b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes) 2516b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{ 2526b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC return (unsigned char *)malloc(bytes); 2536b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC} 2546b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 2556b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC 2569b28defe6ac85dd8a52479cf276606beae24920eDRC/* Compressor */ 2579b28defe6ac85dd8a52479cf276606beae24920eDRC 2589b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitCompress(tjinstance *this) 2592e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 2609b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char buffer[1], *buf=buffer; unsigned long size=1; 2619b28defe6ac85dd8a52479cf276606beae24920eDRC 2629b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 2639b28defe6ac85dd8a52479cf276606beae24920eDRC this->cinfo.err=jpeg_std_error(&this->jerr.pub); 2649b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 2659b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 2662e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2679b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 2689b28defe6ac85dd8a52479cf276606beae24920eDRC { 2699b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 2709b28defe6ac85dd8a52479cf276606beae24920eDRC if(this) free(this); return NULL; 271efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 2722e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 2739b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_compress(&this->cinfo); 2749b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the destination manager */ 2759b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); 2762e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 277007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=COMPRESS; 2789b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 2792e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 2802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 281890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitCompress(void) 282890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 2839b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; 2849b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 285da5220acdd525242bff4e40b1d90324ebb889825DRC { 286007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 287007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitCompress(): Memory allocation failure"); 288da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 289da5220acdd525242bff4e40b1d90324ebb889825DRC } 290007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 2919b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitCompress(this); 292890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 293890f1e0413b54c40b663208779d4ea9dae20eaefDRC 294842416034561f6d5320165a4fe98825e999a4a37DRC 2952e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) 2962e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 297f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 298f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1) 299007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("TJBUFSIZE(): Invalid argument"); 300f3cf973e8e51e0078f402ca5547c026967c27321DRC 301f3cf973e8e51e0078f402ca5547c026967c27321DRC // This allows for rare corner cases in which a JPEG image can actually be 302f3cf973e8e51e0078f402ca5547c026967c27321DRC // larger than the uncompressed input (we wouldn't mention it if it hadn't 303b28fc5710a510410d2b498255a423dd62b353b3aDRC // happened before.) 304007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; 305f3cf973e8e51e0078f402ca5547c026967c27321DRC 306f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 307f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 308f3cf973e8e51e0078f402ca5547c026967c27321DRC} 309f3cf973e8e51e0078f402ca5547c026967c27321DRC 310842416034561f6d5320165a4fe98825e999a4a37DRC 311f3cf973e8e51e0078f402ca5547c026967c27321DRCDLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height, 312f3cf973e8e51e0078f402ca5547c026967c27321DRC int subsamp) 313f3cf973e8e51e0078f402ca5547c026967c27321DRC{ 314f3cf973e8e51e0078f402ca5547c026967c27321DRC unsigned long retval=0; 315f3cf973e8e51e0078f402ca5547c026967c27321DRC int pw, ph, cw, ch; 316f3cf973e8e51e0078f402ca5547c026967c27321DRC if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) 317007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("TJBUFSIZEYUV(): Invalid argument"); 3189b28defe6ac85dd8a52479cf276606beae24920eDRC pw=PAD(width, tjMCUWidth[subsamp]/8); 3199b28defe6ac85dd8a52479cf276606beae24920eDRC ph=PAD(height, tjMCUHeight[subsamp]/8); 3209b28defe6ac85dd8a52479cf276606beae24920eDRC cw=pw*8/tjMCUWidth[subsamp]; ch=ph*8/tjMCUHeight[subsamp]; 32125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC retval=PAD(pw, 4)*ph + (subsamp==TJSAMP_GRAY? 0:PAD(cw, 4)*ch*2); 322f3cf973e8e51e0078f402ca5547c026967c27321DRC 323f3cf973e8e51e0078f402ca5547c026967c27321DRC bailout: 324f3cf973e8e51e0078f402ca5547c026967c27321DRC return retval; 3252e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 3262e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 327842416034561f6d5320165a4fe98825e999a4a37DRC 3289b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, 3299b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, 3309b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 3319b28defe6ac85dd8a52479cf276606beae24920eDRC{ 332ff78e37595c8462f64fd100f928aa1d08539527eDRC int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; 3339b28defe6ac85dd8a52479cf276606beae24920eDRC 3349b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle) 3359b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 336007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Instance has not been initialized for compression"); 3379b28defe6ac85dd8a52479cf276606beae24920eDRC 3389b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 3399b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL 3409b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100) 341007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Invalid argument"); 3429b28defe6ac85dd8a52479cf276606beae24920eDRC 3439b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 3449b28defe6ac85dd8a52479cf276606beae24920eDRC { 3459b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 3469b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 3479b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 3489b28defe6ac85dd8a52479cf276606beae24920eDRC } 3499b28defe6ac85dd8a52479cf276606beae24920eDRC 3509b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 3519b28defe6ac85dd8a52479cf276606beae24920eDRC 3529b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 3539b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 3549b28defe6ac85dd8a52479cf276606beae24920eDRC 35525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 35625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 35725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 3589b28defe6ac85dd8a52479cf276606beae24920eDRC 359ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 360ff78e37595c8462f64fd100f928aa1d08539527eDRC { 361ff78e37595c8462f64fd100f928aa1d08539527eDRC alloc=0; *jpegSize=TJBUFSIZE(width, height); 362ff78e37595c8462f64fd100f928aa1d08539527eDRC } 363ff78e37595c8462f64fd100f928aa1d08539527eDRC jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); 3649b28defe6ac85dd8a52479cf276606beae24920eDRC setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual); 3659b28defe6ac85dd8a52479cf276606beae24920eDRC 3669b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 3679b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) 368007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjCompress2(): Memory allocation failure"); 3699b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 3709b28defe6ac85dd8a52479cf276606beae24920eDRC { 37125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch]; 3729b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&srcBuf[i*pitch]; 3739b28defe6ac85dd8a52479cf276606beae24920eDRC } 3749b28defe6ac85dd8a52479cf276606beae24920eDRC while(cinfo->next_scanline<cinfo->image_height) 3759b28defe6ac85dd8a52479cf276606beae24920eDRC { 3769b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], 3779b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height-cinfo->next_scanline); 3789b28defe6ac85dd8a52479cf276606beae24920eDRC } 3799b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_compress(cinfo); 3809b28defe6ac85dd8a52479cf276606beae24920eDRC 3819b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 3829b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 3839b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 3849b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 3859b28defe6ac85dd8a52479cf276606beae24920eDRC} 3869b28defe6ac85dd8a52479cf276606beae24920eDRC 3879b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, 3889b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, 3899b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) 3909b28defe6ac85dd8a52479cf276606beae24920eDRC{ 3919b28defe6ac85dd8a52479cf276606beae24920eDRC int retval=0; unsigned long size; 3929b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 3939b28defe6ac85dd8a52479cf276606beae24920eDRC { 3949b28defe6ac85dd8a52479cf276606beae24920eDRC size=TJBUFSIZEYUV(width, height, jpegSubsamp); 3959b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height, 3969b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp, flags); 3979b28defe6ac85dd8a52479cf276606beae24920eDRC } 3989b28defe6ac85dd8a52479cf276606beae24920eDRC else 3999b28defe6ac85dd8a52479cf276606beae24920eDRC { 4009b28defe6ac85dd8a52479cf276606beae24920eDRC retval=tjCompress2(handle, srcBuf, width, pitch, height, 4019b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegSubsamp, jpegQual, 40225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC flags|TJFLAG_NOREALLOC); 4039b28defe6ac85dd8a52479cf276606beae24920eDRC } 4049b28defe6ac85dd8a52479cf276606beae24920eDRC *jpegSize=size; 4059b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 4069b28defe6ac85dd8a52479cf276606beae24920eDRC} 4079b28defe6ac85dd8a52479cf276606beae24920eDRC 4089b28defe6ac85dd8a52479cf276606beae24920eDRC 4099b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, 4109b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, 4119b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 4122e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 41391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC int i, retval=0; JSAMPROW *row_pointer=NULL; 414fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; 415fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; 416fbb674707e01a61e8b7083faa632dfd46c568b13DRC JSAMPROW *outbuf[MAX_COMPONENTS]; 4179b28defe6ac85dd8a52479cf276606beae24920eDRC int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS]; 4189b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPLE *ptr=dstBuf; 4199b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long yuvsize=0; 4209b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr; 4212e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4229b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 4239b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0) 424007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjEncodeYUV2(): Instance has not been initialized for compression"); 4252e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 426fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 427fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 428fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf[i]=NULL; _tmpbuf[i]=NULL; 429fbb674707e01a61e8b7083faa632dfd46c568b13DRC tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; 430fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 431fbb674707e01a61e8b7083faa632dfd46c568b13DRC 4329b28defe6ac85dd8a52479cf276606beae24920eDRC if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 4339b28defe6ac85dd8a52479cf276606beae24920eDRC || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0 4349b28defe6ac85dd8a52479cf276606beae24920eDRC || subsamp>=NUMSUBOPT) 4359b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjEncodeYUV2(): Invalid argument"); 4362e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4379b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 4389b28defe6ac85dd8a52479cf276606beae24920eDRC { 4399b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 44091e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 44191e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 442efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC } 4432e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4449b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; 4452e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4469b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_width=width; 4479b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->image_height=height; 4482e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 44925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 45025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 45125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 4522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4539b28defe6ac85dd8a52479cf276606beae24920eDRC yuvsize=TJBUFSIZEYUV(width, height, subsamp); 4549b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0); 4559b28defe6ac85dd8a52479cf276606beae24920eDRC setCompDefaults(cinfo, pixelFormat, subsamp, -1); 4562e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 4579b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_compress(cinfo, TRUE); 4589b28defe6ac85dd8a52479cf276606beae24920eDRC pw=PAD(width, cinfo->max_h_samp_factor); 4599b28defe6ac85dd8a52479cf276606beae24920eDRC ph=PAD(height, cinfo->max_v_samp_factor); 4609b28defe6ac85dd8a52479cf276606beae24920eDRC 4619b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL) 462007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjEncodeYUV2(): Memory allocation failure"); 4639b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<height; i++) 4642e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC { 46525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch]; 4669b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&srcBuf[i*pitch]; 4679b28defe6ac85dd8a52479cf276606beae24920eDRC } 4689b28defe6ac85dd8a52479cf276606beae24920eDRC if(height<ph) 4699b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=height; i<ph; i++) row_pointer[i]=row_pointer[height-1]; 470fbb674707e01a61e8b7083faa632dfd46c568b13DRC 4719b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<cinfo->num_components; i++) 4729b28defe6ac85dd8a52479cf276606beae24920eDRC { 4739b28defe6ac85dd8a52479cf276606beae24920eDRC compptr=&cinfo->comp_info[i]; 4749b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf[i]=(JSAMPLE *)malloc( 4759b28defe6ac85dd8a52479cf276606beae24920eDRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 4769b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16); 477007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!_tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 4789b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor); 479007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 4809b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<cinfo->max_v_samp_factor; row++) 481fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 4829b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf_aligned= 4839b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf[i], 16); 4849b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=&_tmpbuf_aligned[ 485fbb674707e01a61e8b7083faa632dfd46c568b13DRC PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) 4869b28defe6ac85dd8a52479cf276606beae24920eDRC /compptr->h_samp_factor, 16) * row]; 487fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 4889b28defe6ac85dd8a52479cf276606beae24920eDRC _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16) 4899b28defe6ac85dd8a52479cf276606beae24920eDRC * compptr->v_samp_factor + 16); 490007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!_tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 4919b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor); 492007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 4939b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<compptr->v_samp_factor; row++) 494fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 4959b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *_tmpbuf2_aligned= 4969b28defe6ac85dd8a52479cf276606beae24920eDRC (unsigned char *)PAD((size_t)_tmpbuf2[i], 16); 4979b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf2[i][row]=&_tmpbuf2_aligned[ 4989b28defe6ac85dd8a52479cf276606beae24920eDRC PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]; 499fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 5009b28defe6ac85dd8a52479cf276606beae24920eDRC cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor; 5019b28defe6ac85dd8a52479cf276606beae24920eDRC ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor; 5029b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]); 503007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(!outbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure"); 5049b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ch[i]; row++) 505fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 5069b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 5079b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=PAD(cw[i], 4); 508fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 5096ee54594591d0ae958b81adc8ba3cacde522e5e3DRC } 5109b28defe6ac85dd8a52479cf276606beae24920eDRC if(yuvsize!=(unsigned long)(ptr-dstBuf)) 5119b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjEncodeYUV2(): Generated image is not the correct size"); 5129b28defe6ac85dd8a52479cf276606beae24920eDRC 5139b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ph; row+=cinfo->max_v_samp_factor) 5149b28defe6ac85dd8a52479cf276606beae24920eDRC { 5159b28defe6ac85dd8a52479cf276606beae24920eDRC (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, 0, 5169b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->max_v_samp_factor); 5179b28defe6ac85dd8a52479cf276606beae24920eDRC (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0); 5189b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++, compptr++) 5199b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], 5209b28defe6ac85dd8a52479cf276606beae24920eDRC row*compptr->v_samp_factor/cinfo->max_v_samp_factor, 5219b28defe6ac85dd8a52479cf276606beae24920eDRC compptr->v_samp_factor, cw[i]); 5229b28defe6ac85dd8a52479cf276606beae24920eDRC } 5239b28defe6ac85dd8a52479cf276606beae24920eDRC cinfo->next_scanline+=height; 5249b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_compress(cinfo); 5252e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 52691e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 5279b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 5282e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC if(row_pointer) free(row_pointer); 529fbb674707e01a61e8b7083faa632dfd46c568b13DRC for(i=0; i<MAX_COMPONENTS; i++) 530fbb674707e01a61e8b7083faa632dfd46c568b13DRC { 531fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf[i]!=NULL) free(tmpbuf[i]); 53257423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); 533fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); 53457423076e6189717441763de3253072dee42ff7eDRC if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); 535fbb674707e01a61e8b7083faa632dfd46c568b13DRC if(outbuf[i]!=NULL) free(outbuf[i]); 536fbb674707e01a61e8b7083faa632dfd46c568b13DRC } 53791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 5382e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 5392e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5409b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, 5419b28defe6ac85dd8a52479cf276606beae24920eDRC int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, 5429b28defe6ac85dd8a52479cf276606beae24920eDRC int subsamp, int flags) 543842416034561f6d5320165a4fe98825e999a4a37DRC{ 5449b28defe6ac85dd8a52479cf276606beae24920eDRC return tjEncodeYUV2(handle, srcBuf, width, pitch, height, 5459b28defe6ac85dd8a52479cf276606beae24920eDRC getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags); 546842416034561f6d5320165a4fe98825e999a4a37DRC} 547842416034561f6d5320165a4fe98825e999a4a37DRC 548842416034561f6d5320165a4fe98825e999a4a37DRC 5499b28defe6ac85dd8a52479cf276606beae24920eDRC/* Decompressor */ 5502e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5519b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitDecompress(tjinstance *this) 5522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 5539b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char buffer[1]; 5542e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5559b28defe6ac85dd8a52479cf276606beae24920eDRC /* This is also straight out of example.c */ 5569b28defe6ac85dd8a52479cf276606beae24920eDRC this->dinfo.err=jpeg_std_error(&this->jerr.pub); 5579b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.error_exit=my_error_exit; 5589b28defe6ac85dd8a52479cf276606beae24920eDRC this->jerr.pub.output_message=my_output_message; 5592e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5609b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 5619b28defe6ac85dd8a52479cf276606beae24920eDRC { 5629b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 5639b28defe6ac85dd8a52479cf276606beae24920eDRC if(this) free(this); return NULL; 5649e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 5652e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5669b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_create_decompress(&this->dinfo); 5679b28defe6ac85dd8a52479cf276606beae24920eDRC /* Make an initial call so it will create the source manager */ 5689b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(&this->dinfo, buffer, 1); 5692e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 570007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC this->init|=DECOMPRESS; 5719b28defe6ac85dd8a52479cf276606beae24920eDRC return (tjhandle)this; 5722e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 5732e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 574890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitDecompress(void) 575890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 5769b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this; 5779b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 578da5220acdd525242bff4e40b1d90324ebb889825DRC { 579007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 580007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitDecompress(): Memory allocation failure"); 581da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 582da5220acdd525242bff4e40b1d90324ebb889825DRC } 583007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 5849b28defe6ac85dd8a52479cf276606beae24920eDRC return _tjInitDecompress(this); 585890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 586890f1e0413b54c40b663208779d4ea9dae20eaefDRC 5872e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 5889b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, 5899b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, 5909b28defe6ac85dd8a52479cf276606beae24920eDRC int *jpegSubsamp) 5911fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC{ 59291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC int i, k, retval=0; 5931fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 5949b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 5959b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 596007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Instance has not been initialized for decompression"); 5971fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 5989b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL 5999b28defe6ac85dd8a52479cf276606beae24920eDRC || jpegSubsamp==NULL) 6009b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompressHeader2(): Invalid argument"); 6011fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6029b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 6039b28defe6ac85dd8a52479cf276606beae24920eDRC { 6049b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 6051fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC return -1; 6061fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 6071fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6089b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 6099b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 6101fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6119b28defe6ac85dd8a52479cf276606beae24920eDRC *width=dinfo->image_width; 6129b28defe6ac85dd8a52479cf276606beae24920eDRC *height=dinfo->image_height; 6139b28defe6ac85dd8a52479cf276606beae24920eDRC *jpegSubsamp=-1; 6141fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC for(i=0; i<NUMSUBOPT; i++) 6151fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC { 6169b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->num_components==pixelsize[i]) 6171fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC { 6189b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8 6199b28defe6ac85dd8a52479cf276606beae24920eDRC && dinfo->comp_info[0].v_samp_factor==tjMCUHeight[i]/8) 6201fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC { 6211fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC int match=0; 6229b28defe6ac85dd8a52479cf276606beae24920eDRC for(k=1; k<dinfo->num_components; k++) 6231fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC { 6249b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->comp_info[k].h_samp_factor==1 6259b28defe6ac85dd8a52479cf276606beae24920eDRC && dinfo->comp_info[k].v_samp_factor==1) 6261fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC match++; 6271fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 6289b28defe6ac85dd8a52479cf276606beae24920eDRC if(match==dinfo->num_components-1) 6291fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC { 6309b28defe6ac85dd8a52479cf276606beae24920eDRC *jpegSubsamp=i; break; 6311fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 6321fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 6331fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 6341fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC } 6351fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6369b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_abort_decompress(dinfo); 6371fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6389b28defe6ac85dd8a52479cf276606beae24920eDRC if(*jpegSubsamp<0) 639007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Could not determine subsampling type for JPEG image"); 640007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC if(*width<1 || *height<1) 641007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressHeader2(): Invalid data returned in header"); 64291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 64391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 64491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 64591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC} 64691e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC 6479b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, 6489b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height) 64991e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC{ 6509b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegSubsamp; 6519b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, 6529b28defe6ac85dd8a52479cf276606beae24920eDRC &jpegSubsamp); 6531fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC} 6541fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 6551fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC 656109a578e89ea8cd2c39d50b012698148dd11dedbDRCDLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors) 657b28fc5710a510410d2b498255a423dd62b353b3aDRC{ 658109a578e89ea8cd2c39d50b012698148dd11dedbDRC if(numscalingfactors==NULL) 659b28fc5710a510410d2b498255a423dd62b353b3aDRC { 6609b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 661007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjGetScalingFactors(): Invalid argument"); 662109a578e89ea8cd2c39d50b012698148dd11dedbDRC return NULL; 663b28fc5710a510410d2b498255a423dd62b353b3aDRC } 664b28fc5710a510410d2b498255a423dd62b353b3aDRC 665109a578e89ea8cd2c39d50b012698148dd11dedbDRC *numscalingfactors=NUMSF; 666109a578e89ea8cd2c39d50b012698148dd11dedbDRC return (tjscalingfactor *)sf; 667b28fc5710a510410d2b498255a423dd62b353b3aDRC} 668b28fc5710a510410d2b498255a423dd62b353b3aDRC 669b28fc5710a510410d2b498255a423dd62b353b3aDRC 6709b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, 6719b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 6729b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelFormat, int flags) 6739b28defe6ac85dd8a52479cf276606beae24920eDRC{ 6749b28defe6ac85dd8a52479cf276606beae24920eDRC int i, retval=0; JSAMPROW *row_pointer=NULL; 6759b28defe6ac85dd8a52479cf276606beae24920eDRC int jpegwidth, jpegheight, scaledw, scaledh; 6769b28defe6ac85dd8a52479cf276606beae24920eDRC 6779b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 6789b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 679007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Instance has not been initialized for decompression"); 6809b28defe6ac85dd8a52479cf276606beae24920eDRC 6819b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 6829b28defe6ac85dd8a52479cf276606beae24920eDRC || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) 6839b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompress2(): Invalid argument"); 6849b28defe6ac85dd8a52479cf276606beae24920eDRC 68525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 68625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 68725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 6889b28defe6ac85dd8a52479cf276606beae24920eDRC 6899b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 6909b28defe6ac85dd8a52479cf276606beae24920eDRC { 6919b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 6929b28defe6ac85dd8a52479cf276606beae24920eDRC retval=-1; 6939b28defe6ac85dd8a52479cf276606beae24920eDRC goto bailout; 6949b28defe6ac85dd8a52479cf276606beae24920eDRC } 6959b28defe6ac85dd8a52479cf276606beae24920eDRC 6969b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 6979b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 6989b28defe6ac85dd8a52479cf276606beae24920eDRC setDecompDefaults(dinfo, pixelFormat); 6999b28defe6ac85dd8a52479cf276606beae24920eDRC 70025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 7019b28defe6ac85dd8a52479cf276606beae24920eDRC 7029b28defe6ac85dd8a52479cf276606beae24920eDRC jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; 7039b28defe6ac85dd8a52479cf276606beae24920eDRC if(width==0) width=jpegwidth; 7049b28defe6ac85dd8a52479cf276606beae24920eDRC if(height==0) height=jpegheight; 7059b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<NUMSF; i++) 7069b28defe6ac85dd8a52479cf276606beae24920eDRC { 7079b28defe6ac85dd8a52479cf276606beae24920eDRC scaledw=TJSCALED(jpegwidth, sf[i]); 7089b28defe6ac85dd8a52479cf276606beae24920eDRC scaledh=TJSCALED(jpegheight, sf[i]); 7099b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw<=width && scaledh<=height) 7109b28defe6ac85dd8a52479cf276606beae24920eDRC break; 7119b28defe6ac85dd8a52479cf276606beae24920eDRC } 7129b28defe6ac85dd8a52479cf276606beae24920eDRC if(scaledw>width || scaledh>height) 713007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Could not scale down to desired image dimensions"); 7149b28defe6ac85dd8a52479cf276606beae24920eDRC width=scaledw; height=scaledh; 7159b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_num=sf[i].num; 7169b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->scale_denom=sf[i].denom; 7179b28defe6ac85dd8a52479cf276606beae24920eDRC 7189b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 7199b28defe6ac85dd8a52479cf276606beae24920eDRC if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; 7209b28defe6ac85dd8a52479cf276606beae24920eDRC if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) 7219b28defe6ac85dd8a52479cf276606beae24920eDRC *dinfo->output_height))==NULL) 722007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompress2(): Memory allocation failure"); 7239b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<(int)dinfo->output_height; i++) 7249b28defe6ac85dd8a52479cf276606beae24920eDRC { 72525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_BOTTOMUP) 7269b28defe6ac85dd8a52479cf276606beae24920eDRC row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]; 7279b28defe6ac85dd8a52479cf276606beae24920eDRC else row_pointer[i]=&dstBuf[i*pitch]; 7289b28defe6ac85dd8a52479cf276606beae24920eDRC } 7299b28defe6ac85dd8a52479cf276606beae24920eDRC while(dinfo->output_scanline<dinfo->output_height) 7309b28defe6ac85dd8a52479cf276606beae24920eDRC { 7319b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], 7329b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->output_height-dinfo->output_scanline); 7339b28defe6ac85dd8a52479cf276606beae24920eDRC } 7349b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 7359b28defe6ac85dd8a52479cf276606beae24920eDRC 7369b28defe6ac85dd8a52479cf276606beae24920eDRC bailout: 7379b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 7389b28defe6ac85dd8a52479cf276606beae24920eDRC if(row_pointer) free(row_pointer); 7399b28defe6ac85dd8a52479cf276606beae24920eDRC return retval; 7409b28defe6ac85dd8a52479cf276606beae24920eDRC} 7419b28defe6ac85dd8a52479cf276606beae24920eDRC 7429b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, 7439b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, 7449b28defe6ac85dd8a52479cf276606beae24920eDRC int height, int pixelSize, int flags) 7459b28defe6ac85dd8a52479cf276606beae24920eDRC{ 7469b28defe6ac85dd8a52479cf276606beae24920eDRC if(flags&TJ_YUV) 7479b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags); 7489b28defe6ac85dd8a52479cf276606beae24920eDRC else 7499b28defe6ac85dd8a52479cf276606beae24920eDRC return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch, 7509b28defe6ac85dd8a52479cf276606beae24920eDRC height, getPixelFormat(pixelSize, flags), flags); 7519b28defe6ac85dd8a52479cf276606beae24920eDRC} 7529b28defe6ac85dd8a52479cf276606beae24920eDRC 7539b28defe6ac85dd8a52479cf276606beae24920eDRC 7549b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, 7559b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, 756b28fc5710a510410d2b498255a423dd62b353b3aDRC int flags) 7572e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{ 7589b28defe6ac85dd8a52479cf276606beae24920eDRC int i, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS]; 759f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS], 760f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; 7619b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPLE *_tmpbuf=NULL, *ptr=dstBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS]; 7622e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7639b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 7649b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&DECOMPRESS)==0) 765007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Instance has not been initialized for decompression"); 7662e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 767f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<MAX_COMPONENTS; i++) 768f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 769f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC tmpbuf[i]=NULL; outbuf[i]=NULL; 770f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 7719e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC 7729b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL) 7739b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjDecompressToYUV(): Invalid argument"); 7742e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 77525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 77625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 77725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 7780c6a271f974529e4795332c9ad428500ef17fb42DRC 7799b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 7809b28defe6ac85dd8a52479cf276606beae24920eDRC { 7819b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 78291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC retval=-1; 78391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC goto bailout; 7849e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 7852e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7869b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 7879b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 7882e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 7899b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 7909e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 7919b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 7929b28defe6ac85dd8a52479cf276606beae24920eDRC int ih; 7939b28defe6ac85dd8a52479cf276606beae24920eDRC iw[i]=compptr->width_in_blocks*DCTSIZE; 7949b28defe6ac85dd8a52479cf276606beae24920eDRC ih=compptr->height_in_blocks*DCTSIZE; 7959b28defe6ac85dd8a52479cf276606beae24920eDRC cw[i]=PAD(dinfo->image_width, dinfo->max_h_samp_factor) 7969b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->h_samp_factor/dinfo->max_h_samp_factor; 7979b28defe6ac85dd8a52479cf276606beae24920eDRC ch[i]=PAD(dinfo->image_height, dinfo->max_v_samp_factor) 7989b28defe6ac85dd8a52479cf276606beae24920eDRC *compptr->v_samp_factor/dinfo->max_v_samp_factor; 7999b28defe6ac85dd8a52479cf276606beae24920eDRC if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1; 8009b28defe6ac85dd8a52479cf276606beae24920eDRC th[i]=compptr->v_samp_factor*DCTSIZE; 8019b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbufsize+=iw[i]*th[i]; 8029b28defe6ac85dd8a52479cf276606beae24920eDRC if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]))==NULL) 803007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 8049b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<ch[i]; row++) 8059e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 8069b28defe6ac85dd8a52479cf276606beae24920eDRC outbuf[i][row]=ptr; 8079b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=PAD(cw[i], 4); 808f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 8099b28defe6ac85dd8a52479cf276606beae24920eDRC } 8109b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 8119b28defe6ac85dd8a52479cf276606beae24920eDRC { 8129b28defe6ac85dd8a52479cf276606beae24920eDRC if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL) 813007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 8149b28defe6ac85dd8a52479cf276606beae24920eDRC ptr=_tmpbuf; 8159b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 816f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 8179b28defe6ac85dd8a52479cf276606beae24920eDRC if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL) 818007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjDecompressToYUV(): Memory allocation failure"); 8199b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<th[i]; row++) 820f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 8219b28defe6ac85dd8a52479cf276606beae24920eDRC tmpbuf[i][row]=ptr; 8229b28defe6ac85dd8a52479cf276606beae24920eDRC ptr+=iw[i]; 8239e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8249e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8259e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8262e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 82725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; 8289b28defe6ac85dd8a52479cf276606beae24920eDRC dinfo->raw_data_out=TRUE; 8299b28defe6ac85dd8a52479cf276606beae24920eDRC 8309b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_start_decompress(dinfo); 8319b28defe6ac85dd8a52479cf276606beae24920eDRC for(row=0; row<(int)dinfo->output_height; 8329b28defe6ac85dd8a52479cf276606beae24920eDRC row+=dinfo->max_v_samp_factor*DCTSIZE) 8338ed7b814039172fe3cbfadfee3922801a3888b73DRC { 8349b28defe6ac85dd8a52479cf276606beae24920eDRC JSAMPARRAY yuvptr[MAX_COMPONENTS]; 8359b28defe6ac85dd8a52479cf276606beae24920eDRC int crow[MAX_COMPONENTS]; 8369b28defe6ac85dd8a52479cf276606beae24920eDRC for(i=0; i<dinfo->num_components; i++) 837842416034561f6d5320165a4fe98825e999a4a37DRC { 8389b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_component_info *compptr=&dinfo->comp_info[i]; 8399b28defe6ac85dd8a52479cf276606beae24920eDRC crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_factor; 8409b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) yuvptr[i]=tmpbuf[i]; 8419b28defe6ac85dd8a52479cf276606beae24920eDRC else yuvptr[i]=&outbuf[i][crow[i]]; 842842416034561f6d5320165a4fe98825e999a4a37DRC } 8439b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_raw_data(dinfo, yuvptr, dinfo->max_v_samp_factor*DCTSIZE); 8449b28defe6ac85dd8a52479cf276606beae24920eDRC if(usetmpbuf) 8459e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 8469b28defe6ac85dd8a52479cf276606beae24920eDRC int j; 847f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC for(i=0; i<dinfo->num_components; i++) 8489e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC { 8499b28defe6ac85dd8a52479cf276606beae24920eDRC for(j=0; j<min(th[i], ch[i]-crow[i]); j++) 850f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 8519b28defe6ac85dd8a52479cf276606beae24920eDRC memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j], cw[i]); 852f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 8539e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8549e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8559e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC } 8569b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 8572e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 85891e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC bailout: 8599b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 8609e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC for(i=0; i<MAX_COMPONENTS; i++) 861f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC { 862f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(tmpbuf[i]) free(tmpbuf[i]); 8639e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC if(outbuf[i]) free(outbuf[i]); 864f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC } 865f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC if(_tmpbuf) free(_tmpbuf); 86691e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC return retval; 8672e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC} 8682e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8692e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC 8709b28defe6ac85dd8a52479cf276606beae24920eDRC/* Transformer */ 871890f1e0413b54c40b663208779d4ea9dae20eaefDRC 872890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitTransform(void) 873890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 8749b28defe6ac85dd8a52479cf276606beae24920eDRC tjinstance *this=NULL; tjhandle handle=NULL; 8759b28defe6ac85dd8a52479cf276606beae24920eDRC if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) 876da5220acdd525242bff4e40b1d90324ebb889825DRC { 877007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC snprintf(errStr, JMSG_LENGTH_MAX, 878007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC "tjInitTransform(): Memory allocation failure"); 879da5220acdd525242bff4e40b1d90324ebb889825DRC return NULL; 880da5220acdd525242bff4e40b1d90324ebb889825DRC } 881007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(this, sizeof(tjinstance)); 8829b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitCompress(this); 8839b28defe6ac85dd8a52479cf276606beae24920eDRC if(!handle) return NULL; 8849b28defe6ac85dd8a52479cf276606beae24920eDRC handle=_tjInitDecompress(this); 8859b28defe6ac85dd8a52479cf276606beae24920eDRC return handle; 886890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 887890f1e0413b54c40b663208779d4ea9dae20eaefDRC 888890f1e0413b54c40b663208779d4ea9dae20eaefDRC 8899b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf, 8909b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long jpegSize, int n, unsigned char **dstBufs, 8919b28defe6ac85dd8a52479cf276606beae24920eDRC unsigned long *dstSizes, tjtransform *t, int flags) 892890f1e0413b54c40b663208779d4ea9dae20eaefDRC{ 8930a325197dedd2eede99731c68ae0e0a145473f64DRC jpeg_transform_info *xinfo=NULL; 894890f1e0413b54c40b663208779d4ea9dae20eaefDRC jvirt_barray_ptr *srccoefs, *dstcoefs; 8950a325197dedd2eede99731c68ae0e0a145473f64DRC int retval=0, i; 896890f1e0413b54c40b663208779d4ea9dae20eaefDRC 8979b28defe6ac85dd8a52479cf276606beae24920eDRC getinstance(handle); 8989b28defe6ac85dd8a52479cf276606beae24920eDRC if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0) 899007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Instance has not been initialized for transformation"); 900890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9019b28defe6ac85dd8a52479cf276606beae24920eDRC if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NULL 9020a325197dedd2eede99731c68ae0e0a145473f64DRC || t==NULL || flags<0) 9039b28defe6ac85dd8a52479cf276606beae24920eDRC _throw("tjTransform(): Invalid argument"); 904890f1e0413b54c40b663208779d4ea9dae20eaefDRC 90525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); 90625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); 90725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); 908890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9099b28defe6ac85dd8a52479cf276606beae24920eDRC if(setjmp(this->jerr.setjmp_buffer)) 9109b28defe6ac85dd8a52479cf276606beae24920eDRC { 9119b28defe6ac85dd8a52479cf276606beae24920eDRC /* If we get here, the JPEG code has signaled an error. */ 912890f1e0413b54c40b663208779d4ea9dae20eaefDRC retval=-1; 913890f1e0413b54c40b663208779d4ea9dae20eaefDRC goto bailout; 914890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 915890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9169b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); 917890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9180a325197dedd2eede99731c68ae0e0a145473f64DRC if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n)) 9190a325197dedd2eede99731c68ae0e0a145473f64DRC ==NULL) 920007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Memory allocation failure"); 921007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC MEMZERO(xinfo, sizeof(jpeg_transform_info)*n); 922890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9230a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 924890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 9250a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].transform=xformtypes[t[i].op]; 92625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].perfect=(t[i].options&TJXOPT_PERFECT)? 1:0; 92725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].trim=(t[i].options&TJXOPT_TRIM)? 1:0; 92825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].force_grayscale=(t[i].options&TJXOPT_GRAY)? 1:0; 92925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC xinfo[i].crop=(t[i].options&TJXOPT_CROP)? 1:0; 93025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC if(n!=1 && t[i].op==TJXOP_HFLIP) xinfo[i].slow_hflip=1; 931ba5ea5143e48b71234414139e3b4cb244599e875DRC else xinfo[i].slow_hflip=0; 9320a325197dedd2eede99731c68ae0e0a145473f64DRC 9330a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 934890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 9350a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_xoffset=t[i].r.x; xinfo[i].crop_xoffset_set=JCROP_POS; 9360a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_yoffset=t[i].r.y; xinfo[i].crop_yoffset_set=JCROP_POS; 9370a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.w!=0) 9380a325197dedd2eede99731c68ae0e0a145473f64DRC { 9390a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_width=t[i].r.w; xinfo[i].crop_width_set=JCROP_POS; 9400a325197dedd2eede99731c68ae0e0a145473f64DRC } 941d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_width=JCROP_UNSET; 9420a325197dedd2eede99731c68ae0e0a145473f64DRC if(t[i].r.h!=0) 9430a325197dedd2eede99731c68ae0e0a145473f64DRC { 9440a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].crop_height=t[i].r.h; xinfo[i].crop_height_set=JCROP_POS; 9450a325197dedd2eede99731c68ae0e0a145473f64DRC } 946d932e582178e2352b7e1da5622183e3e6082f5b3DRC else xinfo[i].crop_height=JCROP_UNSET; 947890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 948890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 949890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9509b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_markers_setup(dinfo, JCOPYOPT_ALL); 9519b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_read_header(dinfo, TRUE); 952890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9530a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 954890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 9559b28defe6ac85dd8a52479cf276606beae24920eDRC if(!jtransform_request_workspace(dinfo, &xinfo[i])) 956007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC _throw("tjTransform(): Transform is not perfect"); 9570a325197dedd2eede99731c68ae0e0a145473f64DRC 9580a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo[i].crop) 9590a325197dedd2eede99731c68ae0e0a145473f64DRC { 9600a325197dedd2eede99731c68ae0e0a145473f64DRC if((t[i].r.x%xinfo[i].iMCU_sample_width)!=0 9610a325197dedd2eede99731c68ae0e0a145473f64DRC || (t[i].r.y%xinfo[i].iMCU_sample_height)!=0) 9620a325197dedd2eede99731c68ae0e0a145473f64DRC { 9639b28defe6ac85dd8a52479cf276606beae24920eDRC snprintf(errStr, JMSG_LENGTH_MAX, 9640a325197dedd2eede99731c68ae0e0a145473f64DRC "To crop this JPEG image, x must be a multiple of %d\n" 9650a325197dedd2eede99731c68ae0e0a145473f64DRC "and y must be a multiple of %d.\n", 9660a325197dedd2eede99731c68ae0e0a145473f64DRC xinfo[i].iMCU_sample_width, xinfo[i].iMCU_sample_height); 9670a325197dedd2eede99731c68ae0e0a145473f64DRC retval=-1; goto bailout; 9680a325197dedd2eede99731c68ae0e0a145473f64DRC } 9690a325197dedd2eede99731c68ae0e0a145473f64DRC } 970890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 971890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9729b28defe6ac85dd8a52479cf276606beae24920eDRC srccoefs=jpeg_read_coefficients(dinfo); 973890f1e0413b54c40b663208779d4ea9dae20eaefDRC 9740a325197dedd2eede99731c68ae0e0a145473f64DRC for(i=0; i<n; i++) 975890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 976ff78e37595c8462f64fd100f928aa1d08539527eDRC int w, h, alloc=1; 9770a325197dedd2eede99731c68ae0e0a145473f64DRC if(!xinfo[i].crop) 978890f1e0413b54c40b663208779d4ea9dae20eaefDRC { 9799b28defe6ac85dd8a52479cf276606beae24920eDRC w=dinfo->image_width; h=dinfo->image_height; 980890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 9810a325197dedd2eede99731c68ae0e0a145473f64DRC else 9820a325197dedd2eede99731c68ae0e0a145473f64DRC { 9830a325197dedd2eede99731c68ae0e0a145473f64DRC w=xinfo[i].crop_width; h=xinfo[i].crop_height; 9840a325197dedd2eede99731c68ae0e0a145473f64DRC } 985ff78e37595c8462f64fd100f928aa1d08539527eDRC if(flags&TJFLAG_NOREALLOC) 986ff78e37595c8462f64fd100f928aa1d08539527eDRC { 987ff78e37595c8462f64fd100f928aa1d08539527eDRC alloc=0; dstSizes[i]=TJBUFSIZE(w, h); 988ff78e37595c8462f64fd100f928aa1d08539527eDRC } 989ff78e37595c8462f64fd100f928aa1d08539527eDRC jpeg_mem_dest_tj(cinfo, &dstBufs[i], &dstSizes[i], alloc); 9909b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_copy_critical_parameters(dinfo, cinfo); 9919b28defe6ac85dd8a52479cf276606beae24920eDRC dstcoefs=jtransform_adjust_parameters(dinfo, cinfo, srccoefs, 9920a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 9939b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_write_coefficients(cinfo, dstcoefs); 9949b28defe6ac85dd8a52479cf276606beae24920eDRC jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL); 9959b28defe6ac85dd8a52479cf276606beae24920eDRC jtransform_execute_transformation(dinfo, cinfo, srccoefs, 9960a325197dedd2eede99731c68ae0e0a145473f64DRC &xinfo[i]); 9979b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_compress(cinfo); 998890f1e0413b54c40b663208779d4ea9dae20eaefDRC } 999890f1e0413b54c40b663208779d4ea9dae20eaefDRC 10009b28defe6ac85dd8a52479cf276606beae24920eDRC jpeg_finish_decompress(dinfo); 1001890f1e0413b54c40b663208779d4ea9dae20eaefDRC 1002890f1e0413b54c40b663208779d4ea9dae20eaefDRC bailout: 10039b28defe6ac85dd8a52479cf276606beae24920eDRC if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); 10049b28defe6ac85dd8a52479cf276606beae24920eDRC if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); 10050a325197dedd2eede99731c68ae0e0a145473f64DRC if(xinfo) free(xinfo); 1006890f1e0413b54c40b663208779d4ea9dae20eaefDRC return retval; 1007890f1e0413b54c40b663208779d4ea9dae20eaefDRC} 1008