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