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