19b28defe6ac85dd8a52479cf276606beae24920eDRC/*
26eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis * Copyright (C)2009-2016 D. R. Commander.  All Rights Reserved.
32e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC *
49b28defe6ac85dd8a52479cf276606beae24920eDRC * Redistribution and use in source and binary forms, with or without
59b28defe6ac85dd8a52479cf276606beae24920eDRC * modification, are permitted provided that the following conditions are met:
62e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC *
79b28defe6ac85dd8a52479cf276606beae24920eDRC * - Redistributions of source code must retain the above copyright notice,
89b28defe6ac85dd8a52479cf276606beae24920eDRC *   this list of conditions and the following disclaimer.
99b28defe6ac85dd8a52479cf276606beae24920eDRC * - Redistributions in binary form must reproduce the above copyright notice,
109b28defe6ac85dd8a52479cf276606beae24920eDRC *   this list of conditions and the following disclaimer in the documentation
119b28defe6ac85dd8a52479cf276606beae24920eDRC *   and/or other materials provided with the distribution.
129b28defe6ac85dd8a52479cf276606beae24920eDRC * - Neither the name of the libjpeg-turbo Project nor the names of its
139b28defe6ac85dd8a52479cf276606beae24920eDRC *   contributors may be used to endorse or promote products derived from this
149b28defe6ac85dd8a52479cf276606beae24920eDRC *   software without specific prior written permission.
159b28defe6ac85dd8a52479cf276606beae24920eDRC *
169b28defe6ac85dd8a52479cf276606beae24920eDRC * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
179b28defe6ac85dd8a52479cf276606beae24920eDRC * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
189b28defe6ac85dd8a52479cf276606beae24920eDRC * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199b28defe6ac85dd8a52479cf276606beae24920eDRC * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
209b28defe6ac85dd8a52479cf276606beae24920eDRC * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
219b28defe6ac85dd8a52479cf276606beae24920eDRC * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
229b28defe6ac85dd8a52479cf276606beae24920eDRC * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
239b28defe6ac85dd8a52479cf276606beae24920eDRC * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
249b28defe6ac85dd8a52479cf276606beae24920eDRC * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
259b28defe6ac85dd8a52479cf276606beae24920eDRC * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
269b28defe6ac85dd8a52479cf276606beae24920eDRC * POSSIBILITY OF SUCH DAMAGE.
272e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC */
282e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
29bdfcb74d509b2c151cdc4c8b388c8a5975a7da65DRC/* TurboJPEG/LJT:  this implements the TurboJPEG API using libjpeg or
30bdfcb74d509b2c151cdc4c8b388c8a5975a7da65DRC   libjpeg-turbo */
312e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
322e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <stdio.h>
332e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <stdlib.h>
340713c1bb542672257c08782a5a930a577eb20167DRC#include <ctype.h>
35296c71ba0ffb034390a3d0b00a0cc6d6fa014b6eDRC#include <jinclude.h>
36fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define JPEG_INTERNALS
372e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jpeglib.h>
382e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <jerror.h>
392e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include <setjmp.h>
402e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC#include "./turbojpeg.h"
41a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#include "./tjutil.h"
42890f1e0413b54c40b663208779d4ea9dae20eaefDRC#include "transupp.h"
43418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC#include "./jpegcomp.h"
442a2e451ddc9e3c093a903ccb5a06962d05c21b67DRC
459b28defe6ac85dd8a52479cf276606beae24920eDRCextern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **,
469b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned long *, boolean);
476eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidisextern void jpeg_mem_src_tj(j_decompress_ptr, const unsigned char *,
486eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	unsigned long);
499b28defe6ac85dd8a52479cf276606beae24920eDRC
50fbb674707e01a61e8b7083faa632dfd46c568b13DRC#define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
51f610d61fcc38b36a8a29879e5c053015164242f8DRC#define isPow2(x) (((x)&(x-1))==0)
522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
532e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
549b28defe6ac85dd8a52479cf276606beae24920eDRC/* Error handling (based on example in example.c) */
552e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
569b28defe6ac85dd8a52479cf276606beae24920eDRCstatic char errStr[JMSG_LENGTH_MAX]="No error";
572e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
589b28defe6ac85dd8a52479cf276606beae24920eDRCstruct my_error_mgr
592e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
602e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC	struct jpeg_error_mgr pub;
619b28defe6ac85dd8a52479cf276606beae24920eDRC	jmp_buf setjmp_buffer;
621f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	void (*emit_message)(j_common_ptr, int);
631f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	boolean warning;
649b28defe6ac85dd8a52479cf276606beae24920eDRC};
659b28defe6ac85dd8a52479cf276606beae24920eDRCtypedef struct my_error_mgr *my_error_ptr;
662e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
672e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCstatic void my_error_exit(j_common_ptr cinfo)
682e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
699b28defe6ac85dd8a52479cf276606beae24920eDRC	my_error_ptr myerr=(my_error_ptr)cinfo->err;
702e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC	(*cinfo->err->output_message)(cinfo);
719b28defe6ac85dd8a52479cf276606beae24920eDRC	longjmp(myerr->setjmp_buffer, 1);
722e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
732e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
749b28defe6ac85dd8a52479cf276606beae24920eDRC/* Based on output_message() in jerror.c */
759b28defe6ac85dd8a52479cf276606beae24920eDRC
762e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCstatic void my_output_message(j_common_ptr cinfo)
772e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
789b28defe6ac85dd8a52479cf276606beae24920eDRC	(*cinfo->err->format_message)(cinfo, errStr);
792e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
811f79c7c8c8c5e993042ea816e1dd161fb69061a3DRCstatic void my_emit_message(j_common_ptr cinfo, int msg_level)
821f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC{
831f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	my_error_ptr myerr=(my_error_ptr)cinfo->err;
841f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	myerr->emit_message(cinfo, msg_level);
851f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(msg_level<0) myerr->warning=TRUE;
861f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC}
871f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC
882e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
899b28defe6ac85dd8a52479cf276606beae24920eDRC/* Global structures, macros, etc. */
902e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
919b28defe6ac85dd8a52479cf276606beae24920eDRCenum {COMPRESS=1, DECOMPRESS=2};
929b28defe6ac85dd8a52479cf276606beae24920eDRC
939b28defe6ac85dd8a52479cf276606beae24920eDRCtypedef struct _tjinstance
942e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
952e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC	struct jpeg_compress_struct cinfo;
962e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC	struct jpeg_decompress_struct dinfo;
979b28defe6ac85dd8a52479cf276606beae24920eDRC	struct my_error_mgr jerr;
98aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	int init, headerRead;
999b28defe6ac85dd8a52479cf276606beae24920eDRC} tjinstance;
1002e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1011f3635c4969f2319a01c9fe561958815b733227fDRCstatic const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3, 3};
1029b28defe6ac85dd8a52479cf276606beae24920eDRC
103007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRCstatic const JXFORM_CODE xformtypes[TJ_NUMXOP]=
104007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC{
105890f1e0413b54c40b663208779d4ea9dae20eaefDRC	JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE,
106890f1e0413b54c40b663208779d4ea9dae20eaefDRC	JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270
107890f1e0413b54c40b663208779d4ea9dae20eaefDRC};
1089b28defe6ac85dd8a52479cf276606beae24920eDRC
109ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC#define NUMSF 16
110109a578e89ea8cd2c39d50b012698148dd11dedbDRCstatic const tjscalingfactor sf[NUMSF]={
111ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{2, 1},
112ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{15, 8},
113ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{7, 4},
114ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{13, 8},
115ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{3, 2},
116ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{11, 8},
117ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{5, 4},
118ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{9, 8},
119109a578e89ea8cd2c39d50b012698148dd11dedbDRC	{1, 1},
120ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{7, 8},
121ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{3, 4},
122ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{5, 8},
123109a578e89ea8cd2c39d50b012698148dd11dedbDRC	{1, 2},
124ab2df6ea1bfd89df619742b3a8f26e2dd7deefdbDRC	{3, 8},
125109a578e89ea8cd2c39d50b012698148dd11dedbDRC	{1, 4},
126109a578e89ea8cd2c39d50b012698148dd11dedbDRC	{1, 8}
127109a578e89ea8cd2c39d50b012698148dd11dedbDRC};
1282e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
129a29294a94637d4d5efac2b03e115eb69aeeb83d0DRC#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m);  \
130da5220acdd525242bff4e40b1d90324ebb889825DRC	retval=-1;  goto bailout;}
1319b28defe6ac85dd8a52479cf276606beae24920eDRC#define getinstance(handle) tjinstance *this=(tjinstance *)handle;  \
1329b28defe6ac85dd8a52479cf276606beae24920eDRC	j_compress_ptr cinfo=NULL;  j_decompress_ptr dinfo=NULL;  \
1339b28defe6ac85dd8a52479cf276606beae24920eDRC	if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle");  \
1349b28defe6ac85dd8a52479cf276606beae24920eDRC		return -1;}  \
1351f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	cinfo=&this->cinfo;  dinfo=&this->dinfo;  \
1361f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	this->jerr.warning=FALSE;
137418616266582fa978d4d1950cf739bbdac7ebee5DRC#define getcinstance(handle) tjinstance *this=(tjinstance *)handle;  \
138418616266582fa978d4d1950cf739bbdac7ebee5DRC	j_compress_ptr cinfo=NULL;  \
139418616266582fa978d4d1950cf739bbdac7ebee5DRC	if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle");  \
140418616266582fa978d4d1950cf739bbdac7ebee5DRC		return -1;}  \
1411f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	cinfo=&this->cinfo;  \
1421f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	this->jerr.warning=FALSE;
143418616266582fa978d4d1950cf739bbdac7ebee5DRC#define getdinstance(handle) tjinstance *this=(tjinstance *)handle;  \
144418616266582fa978d4d1950cf739bbdac7ebee5DRC	j_decompress_ptr dinfo=NULL;  \
145418616266582fa978d4d1950cf739bbdac7ebee5DRC	if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle");  \
146418616266582fa978d4d1950cf739bbdac7ebee5DRC		return -1;}  \
1471f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	dinfo=&this->dinfo;  \
1481f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	this->jerr.warning=FALSE;
1499b28defe6ac85dd8a52479cf276606beae24920eDRC
1509b28defe6ac85dd8a52479cf276606beae24920eDRCstatic int getPixelFormat(int pixelSize, int flags)
1519b28defe6ac85dd8a52479cf276606beae24920eDRC{
15225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC	if(pixelSize==1) return TJPF_GRAY;
1539b28defe6ac85dd8a52479cf276606beae24920eDRC	if(pixelSize==3)
1549b28defe6ac85dd8a52479cf276606beae24920eDRC	{
15525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		if(flags&TJ_BGR) return TJPF_BGR;
15625b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		else return TJPF_RGB;
1579b28defe6ac85dd8a52479cf276606beae24920eDRC	}
1589b28defe6ac85dd8a52479cf276606beae24920eDRC	if(pixelSize==4)
1599b28defe6ac85dd8a52479cf276606beae24920eDRC	{
1609b28defe6ac85dd8a52479cf276606beae24920eDRC		if(flags&TJ_ALPHAFIRST)
1619b28defe6ac85dd8a52479cf276606beae24920eDRC		{
16225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC			if(flags&TJ_BGR) return TJPF_XBGR;
16325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC			else return TJPF_XRGB;
1649b28defe6ac85dd8a52479cf276606beae24920eDRC		}
1659b28defe6ac85dd8a52479cf276606beae24920eDRC		else
1669b28defe6ac85dd8a52479cf276606beae24920eDRC		{
16725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC			if(flags&TJ_BGR) return TJPF_BGRX;
16825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC			else return TJPF_RGBX;
1699b28defe6ac85dd8a52479cf276606beae24920eDRC		}
1709b28defe6ac85dd8a52479cf276606beae24920eDRC	}
1719b28defe6ac85dd8a52479cf276606beae24920eDRC	return -1;
1729b28defe6ac85dd8a52479cf276606beae24920eDRC}
1739b28defe6ac85dd8a52479cf276606beae24920eDRC
174f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setCompDefaults(struct jpeg_compress_struct *cinfo,
17573d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC	int pixelFormat, int subsamp, int jpegQual, int flags)
1769b28defe6ac85dd8a52479cf276606beae24920eDRC{
177f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC	int retval=0;
1780713c1bb542672257c08782a5a930a577eb20167DRC	char *env=NULL;
179f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC
1809b28defe6ac85dd8a52479cf276606beae24920eDRC	switch(pixelFormat)
1819b28defe6ac85dd8a52479cf276606beae24920eDRC	{
18225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_GRAY:
1839b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->in_color_space=JCS_GRAYSCALE;  break;
1849b28defe6ac85dd8a52479cf276606beae24920eDRC		#if JCS_EXTENSIONS==1
18525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_RGB:
1869b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->in_color_space=JCS_EXT_RGB;  break;
18725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_BGR:
1889b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->in_color_space=JCS_EXT_BGR;  break;
18925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_RGBX:
19067ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		case TJPF_RGBA:
1919b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->in_color_space=JCS_EXT_RGBX;  break;
19225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_BGRX:
19367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		case TJPF_BGRA:
1949b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->in_color_space=JCS_EXT_BGRX;  break;
19525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_XRGB:
19667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		case TJPF_ARGB:
1979b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->in_color_space=JCS_EXT_XRGB;  break;
19825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_XBGR:
19967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		case TJPF_ABGR:
2009b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->in_color_space=JCS_EXT_XBGR;  break;
2019b28defe6ac85dd8a52479cf276606beae24920eDRC		#else
20225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_RGB:
203afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGR:
204afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGBX:
205afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGRX:
206afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_XRGB:
207afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_XBGR:
208afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGBA:
209afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGRA:
210afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_ARGB:
211afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_ABGR:
212afc06929e0a9cf64bdf50da30326076235df7b4fDRC			cinfo->in_color_space=JCS_RGB;  pixelFormat=TJPF_RGB;
213afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
2149b28defe6ac85dd8a52479cf276606beae24920eDRC		#endif
215cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		case TJPF_CMYK:
216cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC			cinfo->in_color_space=JCS_CMYK;  break;
2179b28defe6ac85dd8a52479cf276606beae24920eDRC	}
2189b28defe6ac85dd8a52479cf276606beae24920eDRC
2199b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->input_components=tjPixelSize[pixelFormat];
2209b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_set_defaults(cinfo);
2210713c1bb542672257c08782a5a930a577eb20167DRC
222feccdcf8c89f44bd6a139200b6748daac0d39b1eDRC#ifndef NO_GETENV
2230713c1bb542672257c08782a5a930a577eb20167DRC	if((env=getenv("TJ_OPTIMIZE"))!=NULL && strlen(env)>0 && !strcmp(env, "1"))
2240713c1bb542672257c08782a5a930a577eb20167DRC		cinfo->optimize_coding=TRUE;
2250713c1bb542672257c08782a5a930a577eb20167DRC	if((env=getenv("TJ_ARITHMETIC"))!=NULL && strlen(env)>0	&& !strcmp(env, "1"))
2260713c1bb542672257c08782a5a930a577eb20167DRC		cinfo->arith_code=TRUE;
2270713c1bb542672257c08782a5a930a577eb20167DRC	if((env=getenv("TJ_RESTART"))!=NULL && strlen(env)>0)
2280713c1bb542672257c08782a5a930a577eb20167DRC	{
2290713c1bb542672257c08782a5a930a577eb20167DRC		int temp=-1;  char tempc=0;
2300713c1bb542672257c08782a5a930a577eb20167DRC		if(sscanf(env, "%d%c", &temp, &tempc)>=1 && temp>=0 && temp<=65535)
2310713c1bb542672257c08782a5a930a577eb20167DRC		{
2320713c1bb542672257c08782a5a930a577eb20167DRC			if(toupper(tempc)=='B')
2330713c1bb542672257c08782a5a930a577eb20167DRC			{
2340713c1bb542672257c08782a5a930a577eb20167DRC				cinfo->restart_interval=temp;
2350713c1bb542672257c08782a5a930a577eb20167DRC				cinfo->restart_in_rows=0;
2360713c1bb542672257c08782a5a930a577eb20167DRC			}
2370713c1bb542672257c08782a5a930a577eb20167DRC			else
2380713c1bb542672257c08782a5a930a577eb20167DRC				cinfo->restart_in_rows=temp;
2390713c1bb542672257c08782a5a930a577eb20167DRC		}
2400713c1bb542672257c08782a5a930a577eb20167DRC	}
241feccdcf8c89f44bd6a139200b6748daac0d39b1eDRC#endif
2420713c1bb542672257c08782a5a930a577eb20167DRC
2439b28defe6ac85dd8a52479cf276606beae24920eDRC	if(jpegQual>=0)
2449b28defe6ac85dd8a52479cf276606beae24920eDRC	{
2459b28defe6ac85dd8a52479cf276606beae24920eDRC		jpeg_set_quality(cinfo, jpegQual, TRUE);
24673d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC		if(jpegQual>=96 || flags&TJFLAG_ACCURATEDCT) cinfo->dct_method=JDCT_ISLOW;
2479b28defe6ac85dd8a52479cf276606beae24920eDRC		else cinfo->dct_method=JDCT_FASTEST;
2489b28defe6ac85dd8a52479cf276606beae24920eDRC	}
24925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC	if(subsamp==TJSAMP_GRAY)
2509b28defe6ac85dd8a52479cf276606beae24920eDRC		jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
251cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	else if(pixelFormat==TJPF_CMYK)
252cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		jpeg_set_colorspace(cinfo, JCS_YCCK);
253cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	else jpeg_set_colorspace(cinfo, JCS_YCbCr);
2549b28defe6ac85dd8a52479cf276606beae24920eDRC
255feccdcf8c89f44bd6a139200b6748daac0d39b1eDRC#ifndef NO_GETENV
2560713c1bb542672257c08782a5a930a577eb20167DRC	if((env=getenv("TJ_PROGRESSIVE"))!=NULL && strlen(env)>0
2570713c1bb542672257c08782a5a930a577eb20167DRC		&& !strcmp(env, "1"))
2580713c1bb542672257c08782a5a930a577eb20167DRC		jpeg_simple_progression(cinfo);
259feccdcf8c89f44bd6a139200b6748daac0d39b1eDRC#endif
2600713c1bb542672257c08782a5a930a577eb20167DRC
2619b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8;
2629b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->comp_info[1].h_samp_factor=1;
2639b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->comp_info[2].h_samp_factor=1;
264cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	if(cinfo->num_components>3)
265cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		cinfo->comp_info[3].h_samp_factor=tjMCUWidth[subsamp]/8;
2669b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8;
2679b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->comp_info[1].v_samp_factor=1;
2689b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->comp_info[2].v_samp_factor=1;
269cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	if(cinfo->num_components>3)
270cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		cinfo->comp_info[3].v_samp_factor=tjMCUHeight[subsamp]/8;
271f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC
272f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC	return retval;
2739b28defe6ac85dd8a52479cf276606beae24920eDRC}
2749b28defe6ac85dd8a52479cf276606beae24920eDRC
275f12bb305c26a25eb76d4e3d73651ef927b352c2bDRCstatic int setDecompDefaults(struct jpeg_decompress_struct *dinfo,
27673d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC	int pixelFormat, int flags)
2779b28defe6ac85dd8a52479cf276606beae24920eDRC{
278f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC	int retval=0;
279f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC
2809b28defe6ac85dd8a52479cf276606beae24920eDRC	switch(pixelFormat)
2819b28defe6ac85dd8a52479cf276606beae24920eDRC	{
28225b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_GRAY:
2839b28defe6ac85dd8a52479cf276606beae24920eDRC			dinfo->out_color_space=JCS_GRAYSCALE;  break;
2849b28defe6ac85dd8a52479cf276606beae24920eDRC		#if JCS_EXTENSIONS==1
28525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_RGB:
2869b28defe6ac85dd8a52479cf276606beae24920eDRC			dinfo->out_color_space=JCS_EXT_RGB;  break;
28725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_BGR:
2889b28defe6ac85dd8a52479cf276606beae24920eDRC			dinfo->out_color_space=JCS_EXT_BGR;  break;
28925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_RGBX:
2909b28defe6ac85dd8a52479cf276606beae24920eDRC			dinfo->out_color_space=JCS_EXT_RGBX;  break;
29125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_BGRX:
2929b28defe6ac85dd8a52479cf276606beae24920eDRC			dinfo->out_color_space=JCS_EXT_BGRX;  break;
29325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_XRGB:
2949b28defe6ac85dd8a52479cf276606beae24920eDRC			dinfo->out_color_space=JCS_EXT_XRGB;  break;
29525b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_XBGR:
2969b28defe6ac85dd8a52479cf276606beae24920eDRC			dinfo->out_color_space=JCS_EXT_XBGR;  break;
29767ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		#if JCS_ALPHA_EXTENSIONS==1
29867ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		case TJPF_RGBA:
29967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC			dinfo->out_color_space=JCS_EXT_RGBA;  break;
30067ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		case TJPF_BGRA:
30167ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC			dinfo->out_color_space=JCS_EXT_BGRA;  break;
30267ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		case TJPF_ARGB:
30367ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC			dinfo->out_color_space=JCS_EXT_ARGB;  break;
30467ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		case TJPF_ABGR:
30567ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC			dinfo->out_color_space=JCS_EXT_ABGR;  break;
30667ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		#endif
3079b28defe6ac85dd8a52479cf276606beae24920eDRC		#else
30825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		case TJPF_RGB:
309afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGR:
310afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGBX:
311afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGRX:
312afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_XRGB:
313afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_XBGR:
314afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGBA:
315afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGRA:
316afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_ARGB:
317afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_ABGR:
318afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dinfo->out_color_space=JCS_RGB;  break;
31967ce3b2352fe1f7511edbfed74ec6960e41e97dcDRC		#endif
320cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		case TJPF_CMYK:
321cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC			dinfo->out_color_space=JCS_CMYK;  break;
3229b28defe6ac85dd8a52479cf276606beae24920eDRC		default:
3239b28defe6ac85dd8a52479cf276606beae24920eDRC			_throw("Unsupported pixel format");
3249b28defe6ac85dd8a52479cf276606beae24920eDRC	}
325f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC
32673d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC	if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST;
32773d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC
328f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC	bailout:
329f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC	return retval;
3309b28defe6ac85dd8a52479cf276606beae24920eDRC}
3312e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
3322e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
3339b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCstatic int getSubsamp(j_decompress_ptr dinfo)
3349b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{
3359b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	int retval=-1, i, k;
336ea1eea47423df40809f165519094761045e832aeDRC
337ea1eea47423df40809f165519094761045e832aeDRC	/* The sampling factors actually have no meaning with grayscale JPEG files,
338ea1eea47423df40809f165519094761045e832aeDRC	   and in fact it's possible to generate grayscale JPEGs with sampling
339ea1eea47423df40809f165519094761045e832aeDRC	   factors > 1 (even though those sampling factors are ignored by the
340ea1eea47423df40809f165519094761045e832aeDRC	   decompressor.)  Thus, we need to treat grayscale as a special case. */
341ea1eea47423df40809f165519094761045e832aeDRC	if(dinfo->num_components==1 && dinfo->jpeg_color_space==JCS_GRAYSCALE)
342ea1eea47423df40809f165519094761045e832aeDRC		return TJSAMP_GRAY;
343ea1eea47423df40809f165519094761045e832aeDRC
3449b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	for(i=0; i<NUMSUBOPT; i++)
3459b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	{
346cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		if(dinfo->num_components==pixelsize[i]
347cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC			|| ((dinfo->jpeg_color_space==JCS_YCCK
348cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC				|| dinfo->jpeg_color_space==JCS_CMYK)
349cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC					&& pixelsize[i]==3 && dinfo->num_components==4))
3509b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC		{
3519b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC			if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8
3529b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC				&& dinfo->comp_info[0].v_samp_factor==tjMCUHeight[i]/8)
3539b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC			{
3549b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC				int match=0;
3559b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC				for(k=1; k<dinfo->num_components; k++)
3569b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC				{
357cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC					int href=1, vref=1;
358cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC					if(dinfo->jpeg_color_space==JCS_YCCK && k==3)
359cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC					{
360cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC						href=tjMCUWidth[i]/8;  vref=tjMCUHeight[i]/8;
361cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC					}
362cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC					if(dinfo->comp_info[k].h_samp_factor==href
363cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC						&& dinfo->comp_info[k].v_samp_factor==vref)
3649b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC						match++;
3659b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC				}
3669b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC				if(match==dinfo->num_components-1)
3679b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC				{
3689b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC					retval=i;  break;
3699b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC				}
3709b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC			}
3716eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis			/* Handle 4:2:2 and 4:4:0 images whose sampling factors are specified
3726eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis			   in non-standard ways. */
3736eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis			if(dinfo->comp_info[0].h_samp_factor==2 &&
3746eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				dinfo->comp_info[0].v_samp_factor==2 &&
3756eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				(i==TJSAMP_422 || i==TJSAMP_440))
3766eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis			{
3776eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				int match=0;
3786eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				for(k=1; k<dinfo->num_components; k++)
3796eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				{
3806eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis					int href=tjMCUHeight[i]/8, vref=tjMCUWidth[i]/8;
3816eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis					if(dinfo->jpeg_color_space==JCS_YCCK && k==3)
3826eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis					{
3836eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis						href=vref=2;
3846eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis					}
3856eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis					if(dinfo->comp_info[k].h_samp_factor==href
3866eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis						&& dinfo->comp_info[k].v_samp_factor==vref)
3876eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis						match++;
3886eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				}
3896eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				if(match==dinfo->num_components-1)
3906eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				{
3916eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis					retval=i;  break;
3926eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis				}
3936eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis			}
3949b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC		}
3959b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	}
3969b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	return retval;
3979b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC}
3989b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC
3999b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC
400afc06929e0a9cf64bdf50da30326076235df7b4fDRC#ifndef JCS_EXTENSIONS
401afc06929e0a9cf64bdf50da30326076235df7b4fDRC
402afc06929e0a9cf64bdf50da30326076235df7b4fDRC/* Conversion functions to emulate the colorspace extensions.  This allows the
403afc06929e0a9cf64bdf50da30326076235df7b4fDRC   TurboJPEG wrapper to be used with libjpeg */
404afc06929e0a9cf64bdf50da30326076235df7b4fDRC
405afc06929e0a9cf64bdf50da30326076235df7b4fDRC#define TORGB(PS, ROFFSET, GOFFSET, BOFFSET) {  \
406afc06929e0a9cf64bdf50da30326076235df7b4fDRC	int rowPad=pitch-width*PS;  \
407afc06929e0a9cf64bdf50da30326076235df7b4fDRC	while(height--)  \
408afc06929e0a9cf64bdf50da30326076235df7b4fDRC	{  \
409afc06929e0a9cf64bdf50da30326076235df7b4fDRC		unsigned char *endOfRow=src+width*PS;  \
410afc06929e0a9cf64bdf50da30326076235df7b4fDRC		while(src<endOfRow)  \
411afc06929e0a9cf64bdf50da30326076235df7b4fDRC		{  \
412afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dst[RGB_RED]=src[ROFFSET];  \
413afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dst[RGB_GREEN]=src[GOFFSET];  \
414afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dst[RGB_BLUE]=src[BOFFSET];  \
415afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dst+=RGB_PIXELSIZE;  src+=PS;  \
416afc06929e0a9cf64bdf50da30326076235df7b4fDRC		}  \
417afc06929e0a9cf64bdf50da30326076235df7b4fDRC		src+=rowPad;  \
418afc06929e0a9cf64bdf50da30326076235df7b4fDRC	}  \
419afc06929e0a9cf64bdf50da30326076235df7b4fDRC}
420afc06929e0a9cf64bdf50da30326076235df7b4fDRC
421afc06929e0a9cf64bdf50da30326076235df7b4fDRCstatic unsigned char *toRGB(unsigned char *src, int width, int pitch,
422afc06929e0a9cf64bdf50da30326076235df7b4fDRC	int height, int pixelFormat, unsigned char *dst)
423afc06929e0a9cf64bdf50da30326076235df7b4fDRC{
424afc06929e0a9cf64bdf50da30326076235df7b4fDRC	unsigned char *retval=src;
425afc06929e0a9cf64bdf50da30326076235df7b4fDRC	switch(pixelFormat)
426afc06929e0a9cf64bdf50da30326076235df7b4fDRC	{
427afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGB:
428afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3
429afc06929e0a9cf64bdf50da30326076235df7b4fDRC			retval=dst;  TORGB(3, 0, 1, 2);
430afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
431afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
432afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGR:
433afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3
434afc06929e0a9cf64bdf50da30326076235df7b4fDRC			retval=dst;  TORGB(3, 2, 1, 0);
435afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
436afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
437afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGBX:
438afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGBA:
439afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4
440afc06929e0a9cf64bdf50da30326076235df7b4fDRC			retval=dst;  TORGB(4, 0, 1, 2);
441afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
442afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
443afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGRX:
444afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGRA:
445afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4
446afc06929e0a9cf64bdf50da30326076235df7b4fDRC			retval=dst;  TORGB(4, 2, 1, 0);
447afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
448afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
449afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_XRGB:
450afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_ARGB:
451afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4
452afc06929e0a9cf64bdf50da30326076235df7b4fDRC			retval=dst;  TORGB(4, 1, 2, 3);
453afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
454afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
455afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_XBGR:
456afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_ABGR:
457afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4
458afc06929e0a9cf64bdf50da30326076235df7b4fDRC			retval=dst;  TORGB(4, 3, 2, 1);
459afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
460afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
461afc06929e0a9cf64bdf50da30326076235df7b4fDRC	}
462afc06929e0a9cf64bdf50da30326076235df7b4fDRC	return retval;
463afc06929e0a9cf64bdf50da30326076235df7b4fDRC}
464afc06929e0a9cf64bdf50da30326076235df7b4fDRC
465afc06929e0a9cf64bdf50da30326076235df7b4fDRC#define FROMRGB(PS, ROFFSET, GOFFSET, BOFFSET, SETALPHA) {  \
466afc06929e0a9cf64bdf50da30326076235df7b4fDRC	int rowPad=pitch-width*PS;  \
467afc06929e0a9cf64bdf50da30326076235df7b4fDRC	while(height--)  \
468afc06929e0a9cf64bdf50da30326076235df7b4fDRC	{  \
469afc06929e0a9cf64bdf50da30326076235df7b4fDRC		unsigned char *endOfRow=dst+width*PS;  \
470afc06929e0a9cf64bdf50da30326076235df7b4fDRC		while(dst<endOfRow)  \
471afc06929e0a9cf64bdf50da30326076235df7b4fDRC		{  \
472afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dst[ROFFSET]=src[RGB_RED];  \
473afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dst[GOFFSET]=src[RGB_GREEN];  \
474afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dst[BOFFSET]=src[RGB_BLUE];  \
475afc06929e0a9cf64bdf50da30326076235df7b4fDRC			SETALPHA  \
476afc06929e0a9cf64bdf50da30326076235df7b4fDRC			dst+=PS;  src+=RGB_PIXELSIZE;  \
477afc06929e0a9cf64bdf50da30326076235df7b4fDRC		}  \
478afc06929e0a9cf64bdf50da30326076235df7b4fDRC		dst+=rowPad;  \
479afc06929e0a9cf64bdf50da30326076235df7b4fDRC	}  \
480afc06929e0a9cf64bdf50da30326076235df7b4fDRC}
481afc06929e0a9cf64bdf50da30326076235df7b4fDRC
482afc06929e0a9cf64bdf50da30326076235df7b4fDRCstatic void fromRGB(unsigned char *src, unsigned char *dst, int width,
483afc06929e0a9cf64bdf50da30326076235df7b4fDRC	int pitch, int height, int pixelFormat)
484afc06929e0a9cf64bdf50da30326076235df7b4fDRC{
485afc06929e0a9cf64bdf50da30326076235df7b4fDRC	switch(pixelFormat)
486afc06929e0a9cf64bdf50da30326076235df7b4fDRC	{
487afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGB:
488afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3
489afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(3, 0, 1, 2,);
490afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
491afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
492afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGR:
493afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3
494afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(3, 2, 1, 0,);
495afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
496afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
497afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGBX:
498afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4
499afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(4, 0, 1, 2,);
500afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
501afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
502afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_RGBA:
503afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4
504afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(4, 0, 1, 2, dst[3]=0xFF;);
505afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
506afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
507afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGRX:
508afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4
509afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(4, 2, 1, 0,);
510afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
511afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
512afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_BGRA:
513afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4
514afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(4, 2, 1, 0, dst[3]=0xFF;);  return;
515afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
516afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
517afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_XRGB:
518afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4
519afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(4, 1, 2, 3,);  return;
520afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
521afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
522afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_ARGB:
523afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4
524afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(4, 1, 2, 3, dst[0]=0xFF;);  return;
525afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
526afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
527afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_XBGR:
528afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4
529afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(4, 3, 2, 1,);  return;
530afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
531afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
532afc06929e0a9cf64bdf50da30326076235df7b4fDRC		case TJPF_ABGR:
533afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4
534afc06929e0a9cf64bdf50da30326076235df7b4fDRC			FROMRGB(4, 3, 2, 1, dst[0]=0xFF;);  return;
535afc06929e0a9cf64bdf50da30326076235df7b4fDRC			#endif
536afc06929e0a9cf64bdf50da30326076235df7b4fDRC			break;
537afc06929e0a9cf64bdf50da30326076235df7b4fDRC	}
538afc06929e0a9cf64bdf50da30326076235df7b4fDRC}
539afc06929e0a9cf64bdf50da30326076235df7b4fDRC
540afc06929e0a9cf64bdf50da30326076235df7b4fDRC#endif
541afc06929e0a9cf64bdf50da30326076235df7b4fDRC
542afc06929e0a9cf64bdf50da30326076235df7b4fDRC
5439b28defe6ac85dd8a52479cf276606beae24920eDRC/* General API functions */
5442e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
5459b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT char* DLLCALL tjGetErrorStr(void)
5462e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
5479b28defe6ac85dd8a52479cf276606beae24920eDRC	return errStr;
5482e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
5492e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
5509b28defe6ac85dd8a52479cf276606beae24920eDRC
5519b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDestroy(tjhandle handle)
5522e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
5539b28defe6ac85dd8a52479cf276606beae24920eDRC	getinstance(handle);
5549b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer)) return -1;
5559b28defe6ac85dd8a52479cf276606beae24920eDRC	if(this->init&COMPRESS) jpeg_destroy_compress(cinfo);
5569b28defe6ac85dd8a52479cf276606beae24920eDRC	if(this->init&DECOMPRESS) jpeg_destroy_decompress(dinfo);
5579b28defe6ac85dd8a52479cf276606beae24920eDRC	free(this);
5589b28defe6ac85dd8a52479cf276606beae24920eDRC	return 0;
5592e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
5602e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
5619b28defe6ac85dd8a52479cf276606beae24920eDRC
5626b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC/* These are exposed mainly because Windows can't malloc() and free() across
5636b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC   DLL boundaries except when the CRT DLL is used, and we don't use the CRT DLL
5646b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC   with turbojpeg.dll for compatibility reasons.  However, these functions
5656b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC   can potentially be used for other purposes by different implementations. */
5666b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC
5676b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT void DLLCALL tjFree(unsigned char *buf)
5686b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{
5696b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC	if(buf) free(buf);
5706b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC}
5716b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC
5726b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC
5736b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRCDLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes)
5746b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC{
5756b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC	return (unsigned char *)malloc(bytes);
5766b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC}
5776b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC
5786b76f75d2c0ebdc462f6bc663289fa4bfde1629aDRC
5799b28defe6ac85dd8a52479cf276606beae24920eDRC/* Compressor  */
5809b28defe6ac85dd8a52479cf276606beae24920eDRC
5819b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitCompress(tjinstance *this)
5822e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
5836eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	static unsigned char buffer[1];
5846eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	unsigned char *buf=buffer;  unsigned long size=1;
5859b28defe6ac85dd8a52479cf276606beae24920eDRC
5869b28defe6ac85dd8a52479cf276606beae24920eDRC	/* This is also straight out of example.c */
5879b28defe6ac85dd8a52479cf276606beae24920eDRC	this->cinfo.err=jpeg_std_error(&this->jerr.pub);
5889b28defe6ac85dd8a52479cf276606beae24920eDRC	this->jerr.pub.error_exit=my_error_exit;
5899b28defe6ac85dd8a52479cf276606beae24920eDRC	this->jerr.pub.output_message=my_output_message;
5901f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	this->jerr.emit_message=this->jerr.pub.emit_message;
5911f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	this->jerr.pub.emit_message=my_emit_message;
5922e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
5939b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer))
5949b28defe6ac85dd8a52479cf276606beae24920eDRC	{
5959b28defe6ac85dd8a52479cf276606beae24920eDRC		/* If we get here, the JPEG code has signaled an error. */
5966eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		if(this) free(this);
5976eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		return NULL;
598efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC	}
5992e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
6009b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_create_compress(&this->cinfo);
6019b28defe6ac85dd8a52479cf276606beae24920eDRC	/* Make an initial call so it will create the destination manager */
6029b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0);
6032e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
604007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC	this->init|=COMPRESS;
6059b28defe6ac85dd8a52479cf276606beae24920eDRC	return (tjhandle)this;
6062e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
6072e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
608890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitCompress(void)
609890f1e0413b54c40b663208779d4ea9dae20eaefDRC{
6109b28defe6ac85dd8a52479cf276606beae24920eDRC	tjinstance *this=NULL;
6119b28defe6ac85dd8a52479cf276606beae24920eDRC	if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL)
612da5220acdd525242bff4e40b1d90324ebb889825DRC	{
613007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		snprintf(errStr, JMSG_LENGTH_MAX,
614007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC			"tjInitCompress(): Memory allocation failure");
615da5220acdd525242bff4e40b1d90324ebb889825DRC		return NULL;
616da5220acdd525242bff4e40b1d90324ebb889825DRC	}
617007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC	MEMZERO(this, sizeof(tjinstance));
6189b28defe6ac85dd8a52479cf276606beae24920eDRC	return _tjInitCompress(this);
619890f1e0413b54c40b663208779d4ea9dae20eaefDRC}
620890f1e0413b54c40b663208779d4ea9dae20eaefDRC
621842416034561f6d5320165a4fe98825e999a4a37DRC
6229b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height,
6239b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	int jpegSubsamp)
6249b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{
6259b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	unsigned long retval=0;  int mcuw, mcuh, chromasf;
6269b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT)
6279b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC		_throw("tjBufSize(): Invalid argument");
6289b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC
629006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC	/* This allows for rare corner cases in which a JPEG image can actually be
630006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC	   larger than the uncompressed input (we wouldn't mention it if it hadn't
631006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC	   happened before.) */
6329b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	mcuw=tjMCUWidth[jpegSubsamp];
6339b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	mcuh=tjMCUHeight[jpegSubsamp];
6349b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh);
6359b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048;
6369b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC
6379b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	bailout:
6389b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	return retval;
6399b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC}
6409b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC
6412e7b76b28c0a872ae6ca002fd32bbba0769f990eDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height)
6422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
643f3cf973e8e51e0078f402ca5547c026967c27321DRC	unsigned long retval=0;
644f3cf973e8e51e0078f402ca5547c026967c27321DRC	if(width<1 || height<1)
645007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("TJBUFSIZE(): Invalid argument");
646f3cf973e8e51e0078f402ca5547c026967c27321DRC
647006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC	/* This allows for rare corner cases in which a JPEG image can actually be
648006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC	   larger than the uncompressed input (we wouldn't mention it if it hadn't
649006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC	   happened before.) */
650007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC	retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048;
651f3cf973e8e51e0078f402ca5547c026967c27321DRC
652f3cf973e8e51e0078f402ca5547c026967c27321DRC	bailout:
653f3cf973e8e51e0078f402ca5547c026967c27321DRC	return retval;
654f3cf973e8e51e0078f402ca5547c026967c27321DRC}
655f3cf973e8e51e0078f402ca5547c026967c27321DRC
656842416034561f6d5320165a4fe98825e999a4a37DRC
657f610d61fcc38b36a8a29879e5c053015164242f8DRCDLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height,
658f3cf973e8e51e0078f402ca5547c026967c27321DRC	int subsamp)
659f3cf973e8e51e0078f402ca5547c026967c27321DRC{
66040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int retval=0, nc, i;
66140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
66240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(subsamp<0 || subsamp>=NUMSUBOPT)
663f610d61fcc38b36a8a29879e5c053015164242f8DRC		_throw("tjBufSizeYUV2(): Invalid argument");
66440dd3146cde2ba5036fe76a4f09e1125b4592347DRC
66540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	nc=(subsamp==TJSAMP_GRAY? 1:3);
66640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
66740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
66855620c6ef28b02524dc763ba5ffc438c4a08419bDRC		int pw=tjPlaneWidth(i, width, subsamp);
66955620c6ef28b02524dc763ba5ffc438c4a08419bDRC		int stride=PAD(pw, pad);
67040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int ph=tjPlaneHeight(i, height, subsamp);
67155620c6ef28b02524dc763ba5ffc438c4a08419bDRC		if(pw<0 || ph<0) return -1;
67240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		else retval+=stride*ph;
67340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
674f3cf973e8e51e0078f402ca5547c026967c27321DRC
675f3cf973e8e51e0078f402ca5547c026967c27321DRC	bailout:
676f3cf973e8e51e0078f402ca5547c026967c27321DRC	return retval;
6772e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
6782e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
679f610d61fcc38b36a8a29879e5c053015164242f8DRCDLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height,
680f610d61fcc38b36a8a29879e5c053015164242f8DRC	int subsamp)
681f610d61fcc38b36a8a29879e5c053015164242f8DRC{
682f610d61fcc38b36a8a29879e5c053015164242f8DRC	return tjBufSizeYUV2(width, 4, height, subsamp);
683f610d61fcc38b36a8a29879e5c053015164242f8DRC}
684842416034561f6d5320165a4fe98825e999a4a37DRC
6859b49f0e4c77c727648c6d3a4915eefdf5436de4aDRCDLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height,
6869b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	int subsamp)
6879b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC{
6889b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	return tjBufSizeYUV(width, height, subsamp);
6899b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC}
6909b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC
6919b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC
69240dd3146cde2ba5036fe76a4f09e1125b4592347DRCDLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp)
69340dd3146cde2ba5036fe76a4f09e1125b4592347DRC{
69440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int pw, nc, retval=0;
69540dd3146cde2ba5036fe76a4f09e1125b4592347DRC
69640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(width<1 || subsamp<0 || subsamp>=TJ_NUMSAMP)
69740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("tjPlaneWidth(): Invalid argument");
69840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	nc=(subsamp==TJSAMP_GRAY? 1:3);
69940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(componentID<0 || componentID>=nc)
70040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("tjPlaneWidth(): Invalid argument");
70140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
70240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	pw=PAD(width, tjMCUWidth[subsamp]/8);
70340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(componentID==0)
70440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		retval=pw;
70540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	else
70640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		retval=pw*8/tjMCUWidth[subsamp];
70740dd3146cde2ba5036fe76a4f09e1125b4592347DRC
70840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailout:
70940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	return retval;
71040dd3146cde2ba5036fe76a4f09e1125b4592347DRC}
71140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
71240dd3146cde2ba5036fe76a4f09e1125b4592347DRC
71340dd3146cde2ba5036fe76a4f09e1125b4592347DRCDLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp)
71440dd3146cde2ba5036fe76a4f09e1125b4592347DRC{
71540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int ph, nc, retval=0;
71640dd3146cde2ba5036fe76a4f09e1125b4592347DRC
71740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(height<1 || subsamp<0 || subsamp>=TJ_NUMSAMP)
71840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("tjPlaneHeight(): Invalid argument");
71940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	nc=(subsamp==TJSAMP_GRAY? 1:3);
72040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(componentID<0 || componentID>=nc)
72140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("tjPlaneHeight(): Invalid argument");
72240dd3146cde2ba5036fe76a4f09e1125b4592347DRC
72340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	ph=PAD(height, tjMCUHeight[subsamp]/8);
72440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(componentID==0)
72540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		retval=ph;
72640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	else
72740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		retval=ph*8/tjMCUHeight[subsamp];
72840dd3146cde2ba5036fe76a4f09e1125b4592347DRC
72940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailout:
73040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	return retval;
73140dd3146cde2ba5036fe76a4f09e1125b4592347DRC}
73240dd3146cde2ba5036fe76a4f09e1125b4592347DRC
73340dd3146cde2ba5036fe76a4f09e1125b4592347DRC
73440dd3146cde2ba5036fe76a4f09e1125b4592347DRCDLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width,
73540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int stride, int height, int subsamp)
73640dd3146cde2ba5036fe76a4f09e1125b4592347DRC{
73740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	unsigned long retval=0;
73840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int pw, ph;
73940dd3146cde2ba5036fe76a4f09e1125b4592347DRC
74040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT)
74140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("tjPlaneSizeYUV(): Invalid argument");
74240dd3146cde2ba5036fe76a4f09e1125b4592347DRC
74340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	pw=tjPlaneWidth(componentID, width, subsamp);
74440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	ph=tjPlaneHeight(componentID, height, subsamp);
7452240974d5dc23a27ceb513af3cfc18f7298af0dcDRC	if(pw<0 || ph<0) return -1;
74640dd3146cde2ba5036fe76a4f09e1125b4592347DRC
74740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(stride==0) stride=pw;
74840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	else stride=abs(stride);
74940dd3146cde2ba5036fe76a4f09e1125b4592347DRC
75040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	retval=stride*(ph-1)+pw;
75140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
75240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailout:
75340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	return retval;
75440dd3146cde2ba5036fe76a4f09e1125b4592347DRC}
75540dd3146cde2ba5036fe76a4f09e1125b4592347DRC
75640dd3146cde2ba5036fe76a4f09e1125b4592347DRC
7576eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf,
7589b28defe6ac85dd8a52479cf276606beae24920eDRC	int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf,
7599b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags)
7609b28defe6ac85dd8a52479cf276606beae24920eDRC{
761ff78e37595c8462f64fd100f928aa1d08539527eDRC	int i, retval=0, alloc=1;  JSAMPROW *row_pointer=NULL;
762afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
763afc06929e0a9cf64bdf50da30326076235df7b4fDRC	unsigned char *rgbBuf=NULL;
764afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
7659b28defe6ac85dd8a52479cf276606beae24920eDRC
766418616266582fa978d4d1950cf739bbdac7ebee5DRC	getcinstance(handle)
7679b28defe6ac85dd8a52479cf276606beae24920eDRC	if((this->init&COMPRESS)==0)
768007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("tjCompress2(): Instance has not been initialized for compression");
7699b28defe6ac85dd8a52479cf276606beae24920eDRC
7709b28defe6ac85dd8a52479cf276606beae24920eDRC	if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0
7719b28defe6ac85dd8a52479cf276606beae24920eDRC		|| pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL
7729b28defe6ac85dd8a52479cf276606beae24920eDRC		|| jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100)
773007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("tjCompress2(): Invalid argument");
7749b28defe6ac85dd8a52479cf276606beae24920eDRC
7759b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer))
7769b28defe6ac85dd8a52479cf276606beae24920eDRC	{
7779b28defe6ac85dd8a52479cf276606beae24920eDRC		/* If we get here, the JPEG code has signaled an error. */
7789b28defe6ac85dd8a52479cf276606beae24920eDRC		retval=-1;
7799b28defe6ac85dd8a52479cf276606beae24920eDRC		goto bailout;
7809b28defe6ac85dd8a52479cf276606beae24920eDRC	}
7819b28defe6ac85dd8a52479cf276606beae24920eDRC
7829b28defe6ac85dd8a52479cf276606beae24920eDRC	if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
7839b28defe6ac85dd8a52479cf276606beae24920eDRC
784afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
785230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK)
786afc06929e0a9cf64bdf50da30326076235df7b4fDRC	{
787afc06929e0a9cf64bdf50da30326076235df7b4fDRC		rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE);
788afc06929e0a9cf64bdf50da30326076235df7b4fDRC		if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure");
789afc06929e0a9cf64bdf50da30326076235df7b4fDRC		srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf);
790afc06929e0a9cf64bdf50da30326076235df7b4fDRC		pitch=width*RGB_PIXELSIZE;
791afc06929e0a9cf64bdf50da30326076235df7b4fDRC	}
792afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
793afc06929e0a9cf64bdf50da30326076235df7b4fDRC
7949b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->image_width=width;
7959b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->image_height=height;
7969b28defe6ac85dd8a52479cf276606beae24920eDRC
797bec45b162bb77a57c147a9c44113af1968a79be4DRC	if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
798bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
799bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
8009b28defe6ac85dd8a52479cf276606beae24920eDRC
801ff78e37595c8462f64fd100f928aa1d08539527eDRC	if(flags&TJFLAG_NOREALLOC)
802ff78e37595c8462f64fd100f928aa1d08539527eDRC	{
8039b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC		alloc=0;  *jpegSize=tjBufSize(width, height, jpegSubsamp);
804ff78e37595c8462f64fd100f928aa1d08539527eDRC	}
805ff78e37595c8462f64fd100f928aa1d08539527eDRC	jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc);
80673d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC	if(setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual, flags)==-1)
807f12bb305c26a25eb76d4e3d73651ef927b352c2bDRC		return -1;
8089b28defe6ac85dd8a52479cf276606beae24920eDRC
8099b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_start_compress(cinfo, TRUE);
8109b28defe6ac85dd8a52479cf276606beae24920eDRC	if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL)
811007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("tjCompress2(): Memory allocation failure");
8129b28defe6ac85dd8a52479cf276606beae24920eDRC	for(i=0; i<height; i++)
8139b28defe6ac85dd8a52479cf276606beae24920eDRC	{
8146eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		if(flags&TJFLAG_BOTTOMUP)
8156eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis			row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch];
8166eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch];
8179b28defe6ac85dd8a52479cf276606beae24920eDRC	}
8189b28defe6ac85dd8a52479cf276606beae24920eDRC	while(cinfo->next_scanline<cinfo->image_height)
8199b28defe6ac85dd8a52479cf276606beae24920eDRC	{
8209b28defe6ac85dd8a52479cf276606beae24920eDRC		jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline],
8219b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->image_height-cinfo->next_scanline);
8229b28defe6ac85dd8a52479cf276606beae24920eDRC	}
8239b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_finish_compress(cinfo);
8249b28defe6ac85dd8a52479cf276606beae24920eDRC
8259b28defe6ac85dd8a52479cf276606beae24920eDRC	bailout:
8269b28defe6ac85dd8a52479cf276606beae24920eDRC	if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
827afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
828ea3396a9456fbe403e0defd2991a308d7c400abcDRC	if(rgbBuf) free(rgbBuf);
829afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
8309b28defe6ac85dd8a52479cf276606beae24920eDRC	if(row_pointer) free(row_pointer);
8311f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(this->jerr.warning) retval=-1;
8329b28defe6ac85dd8a52479cf276606beae24920eDRC	return retval;
8339b28defe6ac85dd8a52479cf276606beae24920eDRC}
8349b28defe6ac85dd8a52479cf276606beae24920eDRC
8359b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf,
8369b28defe6ac85dd8a52479cf276606beae24920eDRC	int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf,
8379b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags)
8389b28defe6ac85dd8a52479cf276606beae24920eDRC{
8399b28defe6ac85dd8a52479cf276606beae24920eDRC	int retval=0;  unsigned long size;
8409b28defe6ac85dd8a52479cf276606beae24920eDRC	if(flags&TJ_YUV)
8419b28defe6ac85dd8a52479cf276606beae24920eDRC	{
8429b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC		size=tjBufSizeYUV(width, height, jpegSubsamp);
8439b28defe6ac85dd8a52479cf276606beae24920eDRC		retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height,
8449b28defe6ac85dd8a52479cf276606beae24920eDRC			getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp, flags);
8459b28defe6ac85dd8a52479cf276606beae24920eDRC	}
8469b28defe6ac85dd8a52479cf276606beae24920eDRC	else
8479b28defe6ac85dd8a52479cf276606beae24920eDRC	{
8489b28defe6ac85dd8a52479cf276606beae24920eDRC		retval=tjCompress2(handle, srcBuf, width, pitch, height,
8499b28defe6ac85dd8a52479cf276606beae24920eDRC			getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegSubsamp, jpegQual,
85025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC			flags|TJFLAG_NOREALLOC);
8519b28defe6ac85dd8a52479cf276606beae24920eDRC	}
8529b28defe6ac85dd8a52479cf276606beae24920eDRC	*jpegSize=size;
8539b28defe6ac85dd8a52479cf276606beae24920eDRC	return retval;
8549b28defe6ac85dd8a52479cf276606beae24920eDRC}
8559b28defe6ac85dd8a52479cf276606beae24920eDRC
8569b28defe6ac85dd8a52479cf276606beae24920eDRC
8576eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle,
8586eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *srcBuf, int width, int pitch, int height,
8596eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	int pixelFormat, unsigned char **dstPlanes, int *strides, int subsamp,
8606eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	int flags)
8612e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
86291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC	int i, retval=0;  JSAMPROW *row_pointer=NULL;
863fbb674707e01a61e8b7083faa632dfd46c568b13DRC	JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS];
864fbb674707e01a61e8b7083faa632dfd46c568b13DRC	JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS];
865fbb674707e01a61e8b7083faa632dfd46c568b13DRC	JSAMPROW *outbuf[MAX_COMPONENTS];
86640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS];
867aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	JSAMPLE *ptr;
8689b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_component_info *compptr;
869afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
870afc06929e0a9cf64bdf50da30326076235df7b4fDRC	unsigned char *rgbBuf=NULL;
871afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
8722e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
873418616266582fa978d4d1950cf739bbdac7ebee5DRC	getcinstance(handle);
874b51ee895d8266529af7f96cb24fba53df273d32eDRC
875fbb674707e01a61e8b7083faa632dfd46c568b13DRC	for(i=0; i<MAX_COMPONENTS; i++)
876fbb674707e01a61e8b7083faa632dfd46c568b13DRC	{
877fbb674707e01a61e8b7083faa632dfd46c568b13DRC		tmpbuf[i]=NULL;  _tmpbuf[i]=NULL;
878fbb674707e01a61e8b7083faa632dfd46c568b13DRC		tmpbuf2[i]=NULL;  _tmpbuf2[i]=NULL;  outbuf[i]=NULL;
879fbb674707e01a61e8b7083faa632dfd46c568b13DRC	}
880fbb674707e01a61e8b7083faa632dfd46c568b13DRC
881e2f8e694d0d1ec333c18d803cf0ba083e9feb1c0DRC	if((this->init&COMPRESS)==0)
882aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjEncodeYUVPlanes(): Instance has not been initialized for compression");
883e2f8e694d0d1ec333c18d803cf0ba083e9feb1c0DRC
8849b28defe6ac85dd8a52479cf276606beae24920eDRC	if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0
885aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		|| pixelFormat>=TJ_NUMPF || !dstPlanes || !dstPlanes[0] || subsamp<0
886aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		|| subsamp>=NUMSUBOPT)
887aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjEncodeYUVPlanes(): Invalid argument");
888aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(subsamp!=TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2]))
889aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjEncodeYUVPlanes(): Invalid argument");
8902e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
8919b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer))
8929b28defe6ac85dd8a52479cf276606beae24920eDRC	{
8939b28defe6ac85dd8a52479cf276606beae24920eDRC		/* If we get here, the JPEG code has signaled an error. */
89491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC		retval=-1;
89591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC		goto bailout;
896efa4ddcc88783c7b8bf5cba42c6680132eefa628DRC	}
8972e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
898cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	if(pixelFormat==TJPF_CMYK)
899aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels");
900cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC
9019b28defe6ac85dd8a52479cf276606beae24920eDRC	if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
9022e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
903afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
904230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK)
905afc06929e0a9cf64bdf50da30326076235df7b4fDRC	{
906afc06929e0a9cf64bdf50da30326076235df7b4fDRC		rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE);
907aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!rgbBuf) _throw("tjEncodeYUVPlanes(): Memory allocation failure");
908afc06929e0a9cf64bdf50da30326076235df7b4fDRC		srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf);
909afc06929e0a9cf64bdf50da30326076235df7b4fDRC		pitch=width*RGB_PIXELSIZE;
910afc06929e0a9cf64bdf50da30326076235df7b4fDRC	}
911afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
912afc06929e0a9cf64bdf50da30326076235df7b4fDRC
9139b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->image_width=width;
9149b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->image_height=height;
9152e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
916bec45b162bb77a57c147a9c44113af1968a79be4DRC	if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
917bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
918bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
9192e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
92073d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC	if(setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags)==-1) return -1;
9212e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
92238c9970b95f8f83769b5476a9d7e6062714c19f6DRC	/* Execute only the parts of jpeg_start_compress() that we need.  If we
92338c9970b95f8f83769b5476a9d7e6062714c19f6DRC	   were to call the whole jpeg_start_compress() function, then it would try
92438c9970b95f8f83769b5476a9d7e6062714c19f6DRC	   to write the file headers, which could overflow the output buffer if the
92538c9970b95f8f83769b5476a9d7e6062714c19f6DRC	   YUV image were very small. */
92638c9970b95f8f83769b5476a9d7e6062714c19f6DRC	if(cinfo->global_state!=CSTATE_START)
927aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjEncodeYUVPlanes(): libjpeg API is in the wrong state");
92838c9970b95f8f83769b5476a9d7e6062714c19f6DRC	(*cinfo->err->reset_error_mgr)((j_common_ptr)cinfo);
92938c9970b95f8f83769b5476a9d7e6062714c19f6DRC	jinit_c_master_control(cinfo, FALSE);
93038c9970b95f8f83769b5476a9d7e6062714c19f6DRC	jinit_color_converter(cinfo);
93138c9970b95f8f83769b5476a9d7e6062714c19f6DRC	jinit_downsampler(cinfo);
93250cfc464b8fdee7f7388ef14284c632b553c2f4aDRC	(*cinfo->cconvert->start_pass)(cinfo);
93338c9970b95f8f83769b5476a9d7e6062714c19f6DRC
93440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	pw0=PAD(width, cinfo->max_h_samp_factor);
93540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	ph0=PAD(height, cinfo->max_v_samp_factor);
9369b28defe6ac85dd8a52479cf276606beae24920eDRC
93740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph0))==NULL)
938aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjEncodeYUVPlanes(): Memory allocation failure");
9399b28defe6ac85dd8a52479cf276606beae24920eDRC	for(i=0; i<height; i++)
9402e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC	{
9416eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		if(flags&TJFLAG_BOTTOMUP)
9426eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis			row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch];
9436eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch];
9449b28defe6ac85dd8a52479cf276606beae24920eDRC	}
94540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(height<ph0)
94640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1];
947fbb674707e01a61e8b7083faa632dfd46c568b13DRC
9489b28defe6ac85dd8a52479cf276606beae24920eDRC	for(i=0; i<cinfo->num_components; i++)
9499b28defe6ac85dd8a52479cf276606beae24920eDRC	{
9509b28defe6ac85dd8a52479cf276606beae24920eDRC		compptr=&cinfo->comp_info[i];
9519b28defe6ac85dd8a52479cf276606beae24920eDRC		_tmpbuf[i]=(JSAMPLE *)malloc(
9529b28defe6ac85dd8a52479cf276606beae24920eDRC			PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE)
9539b28defe6ac85dd8a52479cf276606beae24920eDRC				/compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16);
954aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!_tmpbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure");
9559b28defe6ac85dd8a52479cf276606beae24920eDRC		tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor);
956aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!tmpbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure");
9579b28defe6ac85dd8a52479cf276606beae24920eDRC		for(row=0; row<cinfo->max_v_samp_factor; row++)
958fbb674707e01a61e8b7083faa632dfd46c568b13DRC		{
9599b28defe6ac85dd8a52479cf276606beae24920eDRC			unsigned char *_tmpbuf_aligned=
9609b28defe6ac85dd8a52479cf276606beae24920eDRC				(unsigned char *)PAD((size_t)_tmpbuf[i], 16);
9619b28defe6ac85dd8a52479cf276606beae24920eDRC			tmpbuf[i][row]=&_tmpbuf_aligned[
962fbb674707e01a61e8b7083faa632dfd46c568b13DRC				PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE)
9639b28defe6ac85dd8a52479cf276606beae24920eDRC					/compptr->h_samp_factor, 16) * row];
964fbb674707e01a61e8b7083faa632dfd46c568b13DRC		}
9659b28defe6ac85dd8a52479cf276606beae24920eDRC		_tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16)
9669b28defe6ac85dd8a52479cf276606beae24920eDRC			* compptr->v_samp_factor + 16);
967aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!_tmpbuf2[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure");
9689b28defe6ac85dd8a52479cf276606beae24920eDRC		tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor);
969aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!tmpbuf2[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure");
9709b28defe6ac85dd8a52479cf276606beae24920eDRC		for(row=0; row<compptr->v_samp_factor; row++)
971fbb674707e01a61e8b7083faa632dfd46c568b13DRC		{
9729b28defe6ac85dd8a52479cf276606beae24920eDRC			unsigned char *_tmpbuf2_aligned=
9739b28defe6ac85dd8a52479cf276606beae24920eDRC				(unsigned char *)PAD((size_t)_tmpbuf2[i], 16);
9749b28defe6ac85dd8a52479cf276606beae24920eDRC			tmpbuf2[i][row]=&_tmpbuf2_aligned[
9759b28defe6ac85dd8a52479cf276606beae24920eDRC				PAD(compptr->width_in_blocks*DCTSIZE, 16) * row];
976fbb674707e01a61e8b7083faa632dfd46c568b13DRC		}
97740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		pw[i]=pw0*compptr->h_samp_factor/cinfo->max_h_samp_factor;
97840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		ph[i]=ph0*compptr->v_samp_factor/cinfo->max_v_samp_factor;
97940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]);
980aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!outbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation failure");
981aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		ptr=dstPlanes[i];
98240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		for(row=0; row<ph[i]; row++)
983fbb674707e01a61e8b7083faa632dfd46c568b13DRC		{
9849b28defe6ac85dd8a52479cf276606beae24920eDRC			outbuf[i][row]=ptr;
98540dd3146cde2ba5036fe76a4f09e1125b4592347DRC			ptr+=(strides && strides[i]!=0)? strides[i]:pw[i];
986fbb674707e01a61e8b7083faa632dfd46c568b13DRC		}
9876ee54594591d0ae958b81adc8ba3cacde522e5e3DRC	}
9889b28defe6ac85dd8a52479cf276606beae24920eDRC
98940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(row=0; row<ph0; row+=cinfo->max_v_samp_factor)
9909b28defe6ac85dd8a52479cf276606beae24920eDRC	{
9919b28defe6ac85dd8a52479cf276606beae24920eDRC		(*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, 0,
9929b28defe6ac85dd8a52479cf276606beae24920eDRC			cinfo->max_v_samp_factor);
9939b28defe6ac85dd8a52479cf276606beae24920eDRC		(cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0);
9949b28defe6ac85dd8a52479cf276606beae24920eDRC		for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++, compptr++)
9959b28defe6ac85dd8a52479cf276606beae24920eDRC			jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i],
9969b28defe6ac85dd8a52479cf276606beae24920eDRC				row*compptr->v_samp_factor/cinfo->max_v_samp_factor,
99740dd3146cde2ba5036fe76a4f09e1125b4592347DRC				compptr->v_samp_factor, pw[i]);
9989b28defe6ac85dd8a52479cf276606beae24920eDRC	}
9999b28defe6ac85dd8a52479cf276606beae24920eDRC	cinfo->next_scanline+=height;
10009b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_abort_compress(cinfo);
10012e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
100291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC	bailout:
10039b28defe6ac85dd8a52479cf276606beae24920eDRC	if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
1004afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
1005ea3396a9456fbe403e0defd2991a308d7c400abcDRC	if(rgbBuf) free(rgbBuf);
1006afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
10072e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC	if(row_pointer) free(row_pointer);
1008fbb674707e01a61e8b7083faa632dfd46c568b13DRC	for(i=0; i<MAX_COMPONENTS; i++)
1009fbb674707e01a61e8b7083faa632dfd46c568b13DRC	{
1010fbb674707e01a61e8b7083faa632dfd46c568b13DRC		if(tmpbuf[i]!=NULL) free(tmpbuf[i]);
101157423076e6189717441763de3253072dee42ff7eDRC		if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]);
1012fbb674707e01a61e8b7083faa632dfd46c568b13DRC		if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]);
101357423076e6189717441763de3253072dee42ff7eDRC		if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]);
1014fbb674707e01a61e8b7083faa632dfd46c568b13DRC		if(outbuf[i]!=NULL) free(outbuf[i]);
1015fbb674707e01a61e8b7083faa632dfd46c568b13DRC	}
10161f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(this->jerr.warning) retval=-1;
101791e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC	return retval;
10182e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
10192e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
10206eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle,
10216eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *srcBuf, int width, int pitch, int height,
10226eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	int pixelFormat, unsigned char *dstBuf, int pad, int subsamp, int flags)
1023aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC{
1024aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	unsigned char *dstPlanes[3];
102540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int pw0, ph0, strides[3], retval=-1;
1026aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1027aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(width<=0 || height<=0 || dstBuf==NULL || pad<0 || !isPow2(pad)
1028aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		|| subsamp<0 || subsamp>=NUMSUBOPT)
1029aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjEncodeYUV3(): Invalid argument");
1030aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
103140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	pw0=tjPlaneWidth(0, width, subsamp);
103240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	ph0=tjPlaneHeight(0, height, subsamp);
1033aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	dstPlanes[0]=dstBuf;
103440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	strides[0]=PAD(pw0, pad);
103540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(subsamp==TJSAMP_GRAY)
103640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
103740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		strides[1]=strides[2]=0;
103840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes[1]=dstPlanes[2]=NULL;
103940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
104040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	else
104140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
104240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int pw1=tjPlaneWidth(1, width, subsamp);
104340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int ph1=tjPlaneHeight(1, height, subsamp);
104440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		strides[1]=strides[2]=PAD(pw1, pad);
104540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes[1]=dstPlanes[0]+strides[0]*ph0;
104640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes[2]=dstPlanes[1]+strides[1]*ph1;
104740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
1048aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1049aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	return tjEncodeYUVPlanes(handle, srcBuf, width, pitch, height, pixelFormat,
1050aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		dstPlanes, strides, subsamp, flags);
1051aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1052aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	bailout:
1053aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	return retval;
1054aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC}
1055aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1056f610d61fcc38b36a8a29879e5c053015164242f8DRCDLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
1057f610d61fcc38b36a8a29879e5c053015164242f8DRC	int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf,
1058f610d61fcc38b36a8a29879e5c053015164242f8DRC	int subsamp, int flags)
1059f610d61fcc38b36a8a29879e5c053015164242f8DRC{
1060f610d61fcc38b36a8a29879e5c053015164242f8DRC	return tjEncodeYUV3(handle, srcBuf, width, pitch, height, pixelFormat,
1061f610d61fcc38b36a8a29879e5c053015164242f8DRC		dstBuf, 4, subsamp, flags);
1062f610d61fcc38b36a8a29879e5c053015164242f8DRC}
1063f610d61fcc38b36a8a29879e5c053015164242f8DRC
10649b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf,
10659b28defe6ac85dd8a52479cf276606beae24920eDRC	int width, int pitch, int height, int pixelSize, unsigned char *dstBuf,
10669b28defe6ac85dd8a52479cf276606beae24920eDRC	int subsamp, int flags)
1067842416034561f6d5320165a4fe98825e999a4a37DRC{
10689b28defe6ac85dd8a52479cf276606beae24920eDRC	return tjEncodeYUV2(handle, srcBuf, width, pitch, height,
10699b28defe6ac85dd8a52479cf276606beae24920eDRC		getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags);
1070842416034561f6d5320165a4fe98825e999a4a37DRC}
1071842416034561f6d5320165a4fe98825e999a4a37DRC
1072842416034561f6d5320165a4fe98825e999a4a37DRC
1073aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRCDLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle,
10746eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char **srcPlanes, int width, const int *strides, int height,
10756eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	int subsamp, unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQual,
10766eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	int flags)
1077910a35725cb52913c248f39e3f273a4baadbd7ddDRC{
1078910a35725cb52913c248f39e3f273a4baadbd7ddDRC	int i, row, retval=0, alloc=1;  JSAMPROW *inbuf[MAX_COMPONENTS];
107940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS],
1080910a35725cb52913c248f39e3f273a4baadbd7ddDRC		tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS];
1081aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	JSAMPLE *_tmpbuf=NULL, *ptr;  JSAMPROW *tmpbuf[MAX_COMPONENTS];
1082910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1083418616266582fa978d4d1950cf739bbdac7ebee5DRC	getcinstance(handle)
1084b51ee895d8266529af7f96cb24fba53df273d32eDRC
1085910a35725cb52913c248f39e3f273a4baadbd7ddDRC	for(i=0; i<MAX_COMPONENTS; i++)
1086910a35725cb52913c248f39e3f273a4baadbd7ddDRC	{
1087910a35725cb52913c248f39e3f273a4baadbd7ddDRC		tmpbuf[i]=NULL;  inbuf[i]=NULL;
1088910a35725cb52913c248f39e3f273a4baadbd7ddDRC	}
1089910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1090910a35725cb52913c248f39e3f273a4baadbd7ddDRC	if((this->init&COMPRESS)==0)
1091aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjCompressFromYUVPlanes(): Instance has not been initialized for compression");
1092910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1093aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(!srcPlanes || !srcPlanes[0] || width<=0 || height<=0 || subsamp<0
1094910a35725cb52913c248f39e3f273a4baadbd7ddDRC		|| subsamp>=NUMSUBOPT || jpegBuf==NULL || jpegSize==NULL || jpegQual<0
1095910a35725cb52913c248f39e3f273a4baadbd7ddDRC		|| jpegQual>100)
1096aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjCompressFromYUVPlanes(): Invalid argument");
1097aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(subsamp!=TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2]))
1098aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjCompressFromYUVPlanes(): Invalid argument");
1099910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1100910a35725cb52913c248f39e3f273a4baadbd7ddDRC	if(setjmp(this->jerr.setjmp_buffer))
1101910a35725cb52913c248f39e3f273a4baadbd7ddDRC	{
1102910a35725cb52913c248f39e3f273a4baadbd7ddDRC		/* If we get here, the JPEG code has signaled an error. */
1103910a35725cb52913c248f39e3f273a4baadbd7ddDRC		retval=-1;
1104910a35725cb52913c248f39e3f273a4baadbd7ddDRC		goto bailout;
1105910a35725cb52913c248f39e3f273a4baadbd7ddDRC	}
1106910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1107910a35725cb52913c248f39e3f273a4baadbd7ddDRC	cinfo->image_width=width;
1108910a35725cb52913c248f39e3f273a4baadbd7ddDRC	cinfo->image_height=height;
1109910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1110bec45b162bb77a57c147a9c44113af1968a79be4DRC	if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
1111bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
1112bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
1113910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1114910a35725cb52913c248f39e3f273a4baadbd7ddDRC	if(flags&TJFLAG_NOREALLOC)
1115910a35725cb52913c248f39e3f273a4baadbd7ddDRC	{
1116910a35725cb52913c248f39e3f273a4baadbd7ddDRC		alloc=0;  *jpegSize=tjBufSize(width, height, subsamp);
1117910a35725cb52913c248f39e3f273a4baadbd7ddDRC	}
1118910a35725cb52913c248f39e3f273a4baadbd7ddDRC	jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc);
1119910a35725cb52913c248f39e3f273a4baadbd7ddDRC	if(setCompDefaults(cinfo, TJPF_RGB, subsamp, jpegQual, flags)==-1)
1120910a35725cb52913c248f39e3f273a4baadbd7ddDRC		return -1;
1121910a35725cb52913c248f39e3f273a4baadbd7ddDRC	cinfo->raw_data_in=TRUE;
1122910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1123910a35725cb52913c248f39e3f273a4baadbd7ddDRC	jpeg_start_compress(cinfo, TRUE);
1124910a35725cb52913c248f39e3f273a4baadbd7ddDRC	for(i=0; i<cinfo->num_components; i++)
1125910a35725cb52913c248f39e3f273a4baadbd7ddDRC	{
1126910a35725cb52913c248f39e3f273a4baadbd7ddDRC		jpeg_component_info *compptr=&cinfo->comp_info[i];
1127910a35725cb52913c248f39e3f273a4baadbd7ddDRC		int ih;
1128910a35725cb52913c248f39e3f273a4baadbd7ddDRC		iw[i]=compptr->width_in_blocks*DCTSIZE;
1129910a35725cb52913c248f39e3f273a4baadbd7ddDRC		ih=compptr->height_in_blocks*DCTSIZE;
113040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		pw[i]=PAD(cinfo->image_width, cinfo->max_h_samp_factor)
1131910a35725cb52913c248f39e3f273a4baadbd7ddDRC			*compptr->h_samp_factor/cinfo->max_h_samp_factor;
113240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		ph[i]=PAD(cinfo->image_height, cinfo->max_v_samp_factor)
1133910a35725cb52913c248f39e3f273a4baadbd7ddDRC			*compptr->v_samp_factor/cinfo->max_v_samp_factor;
113440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(iw[i]!=pw[i] || ih!=ph[i]) usetmpbuf=1;
1135910a35725cb52913c248f39e3f273a4baadbd7ddDRC		th[i]=compptr->v_samp_factor*DCTSIZE;
1136910a35725cb52913c248f39e3f273a4baadbd7ddDRC		tmpbufsize+=iw[i]*th[i];
113740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if((inbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]))==NULL)
1138aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC			_throw("tjCompressFromYUVPlanes(): Memory allocation failure");
11396eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		ptr=(JSAMPLE *)srcPlanes[i];
114040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		for(row=0; row<ph[i]; row++)
1141910a35725cb52913c248f39e3f273a4baadbd7ddDRC		{
1142910a35725cb52913c248f39e3f273a4baadbd7ddDRC			inbuf[i][row]=ptr;
114340dd3146cde2ba5036fe76a4f09e1125b4592347DRC			ptr+=(strides && strides[i]!=0)? strides[i]:pw[i];
1144910a35725cb52913c248f39e3f273a4baadbd7ddDRC		}
1145910a35725cb52913c248f39e3f273a4baadbd7ddDRC	}
1146910a35725cb52913c248f39e3f273a4baadbd7ddDRC	if(usetmpbuf)
1147910a35725cb52913c248f39e3f273a4baadbd7ddDRC	{
1148910a35725cb52913c248f39e3f273a4baadbd7ddDRC		if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL)
1149aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC			_throw("tjCompressFromYUVPlanes(): Memory allocation failure");
1150910a35725cb52913c248f39e3f273a4baadbd7ddDRC		ptr=_tmpbuf;
1151910a35725cb52913c248f39e3f273a4baadbd7ddDRC		for(i=0; i<cinfo->num_components; i++)
1152910a35725cb52913c248f39e3f273a4baadbd7ddDRC		{
1153910a35725cb52913c248f39e3f273a4baadbd7ddDRC			if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL)
1154aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC				_throw("tjCompressFromYUVPlanes(): Memory allocation failure");
1155910a35725cb52913c248f39e3f273a4baadbd7ddDRC			for(row=0; row<th[i]; row++)
1156910a35725cb52913c248f39e3f273a4baadbd7ddDRC			{
1157910a35725cb52913c248f39e3f273a4baadbd7ddDRC				tmpbuf[i][row]=ptr;
1158910a35725cb52913c248f39e3f273a4baadbd7ddDRC				ptr+=iw[i];
1159910a35725cb52913c248f39e3f273a4baadbd7ddDRC			}
1160910a35725cb52913c248f39e3f273a4baadbd7ddDRC		}
1161910a35725cb52913c248f39e3f273a4baadbd7ddDRC	}
1162910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1163910a35725cb52913c248f39e3f273a4baadbd7ddDRC	for(row=0; row<(int)cinfo->image_height;
1164910a35725cb52913c248f39e3f273a4baadbd7ddDRC		row+=cinfo->max_v_samp_factor*DCTSIZE)
1165910a35725cb52913c248f39e3f273a4baadbd7ddDRC	{
1166910a35725cb52913c248f39e3f273a4baadbd7ddDRC		JSAMPARRAY yuvptr[MAX_COMPONENTS];
1167910a35725cb52913c248f39e3f273a4baadbd7ddDRC		int crow[MAX_COMPONENTS];
1168910a35725cb52913c248f39e3f273a4baadbd7ddDRC		for(i=0; i<cinfo->num_components; i++)
1169910a35725cb52913c248f39e3f273a4baadbd7ddDRC		{
1170910a35725cb52913c248f39e3f273a4baadbd7ddDRC			jpeg_component_info *compptr=&cinfo->comp_info[i];
1171910a35725cb52913c248f39e3f273a4baadbd7ddDRC			crow[i]=row*compptr->v_samp_factor/cinfo->max_v_samp_factor;
1172910a35725cb52913c248f39e3f273a4baadbd7ddDRC			if(usetmpbuf)
1173910a35725cb52913c248f39e3f273a4baadbd7ddDRC			{
1174910a35725cb52913c248f39e3f273a4baadbd7ddDRC				int j, k;
117540dd3146cde2ba5036fe76a4f09e1125b4592347DRC				for(j=0; j<min(th[i], ph[i]-crow[i]); j++)
1176910a35725cb52913c248f39e3f273a4baadbd7ddDRC				{
117740dd3146cde2ba5036fe76a4f09e1125b4592347DRC					memcpy(tmpbuf[i][j], inbuf[i][crow[i]+j], pw[i]);
1178006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC					/* Duplicate last sample in row to fill out MCU */
117940dd3146cde2ba5036fe76a4f09e1125b4592347DRC					for(k=pw[i]; k<iw[i]; k++) tmpbuf[i][j][k]=tmpbuf[i][j][pw[i]-1];
1180910a35725cb52913c248f39e3f273a4baadbd7ddDRC				}
1181006bc58dd6a8c68f4b3a26511e8684f5f3f1508aDRC				/* Duplicate last row to fill out MCU */
118240dd3146cde2ba5036fe76a4f09e1125b4592347DRC				for(j=ph[i]-crow[i]; j<th[i]; j++)
118340dd3146cde2ba5036fe76a4f09e1125b4592347DRC					memcpy(tmpbuf[i][j], tmpbuf[i][ph[i]-crow[i]-1], iw[i]);
1184910a35725cb52913c248f39e3f273a4baadbd7ddDRC				yuvptr[i]=tmpbuf[i];
1185910a35725cb52913c248f39e3f273a4baadbd7ddDRC			}
1186910a35725cb52913c248f39e3f273a4baadbd7ddDRC			else
1187910a35725cb52913c248f39e3f273a4baadbd7ddDRC				yuvptr[i]=&inbuf[i][crow[i]];
1188910a35725cb52913c248f39e3f273a4baadbd7ddDRC		}
1189910a35725cb52913c248f39e3f273a4baadbd7ddDRC		jpeg_write_raw_data(cinfo, yuvptr, cinfo->max_v_samp_factor*DCTSIZE);
1190910a35725cb52913c248f39e3f273a4baadbd7ddDRC	}
1191910a35725cb52913c248f39e3f273a4baadbd7ddDRC	jpeg_finish_compress(cinfo);
1192910a35725cb52913c248f39e3f273a4baadbd7ddDRC
1193910a35725cb52913c248f39e3f273a4baadbd7ddDRC	bailout:
1194910a35725cb52913c248f39e3f273a4baadbd7ddDRC	if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
1195910a35725cb52913c248f39e3f273a4baadbd7ddDRC	for(i=0; i<MAX_COMPONENTS; i++)
1196910a35725cb52913c248f39e3f273a4baadbd7ddDRC	{
1197910a35725cb52913c248f39e3f273a4baadbd7ddDRC		if(tmpbuf[i]) free(tmpbuf[i]);
1198910a35725cb52913c248f39e3f273a4baadbd7ddDRC		if(inbuf[i]) free(inbuf[i]);
1199910a35725cb52913c248f39e3f273a4baadbd7ddDRC	}
1200910a35725cb52913c248f39e3f273a4baadbd7ddDRC	if(_tmpbuf) free(_tmpbuf);
12011f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(this->jerr.warning) retval=-1;
1202910a35725cb52913c248f39e3f273a4baadbd7ddDRC	return retval;
1203910a35725cb52913c248f39e3f273a4baadbd7ddDRC}
1204910a35725cb52913c248f39e3f273a4baadbd7ddDRC
12056eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle,
12066eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *srcBuf, int width, int pad, int height, int subsamp,
12076eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQual, int flags)
1208aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC{
12096eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *srcPlanes[3];
121040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int pw0, ph0, strides[3], retval=-1;
1211aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1212aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(srcBuf==NULL || width<=0 || pad<1 || height<=0 || subsamp<0
1213aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		|| subsamp>=NUMSUBOPT)
1214aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjCompressFromYUV(): Invalid argument");
1215aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
121640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	pw0=tjPlaneWidth(0, width, subsamp);
121740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	ph0=tjPlaneHeight(0, height, subsamp);
1218aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	srcPlanes[0]=srcBuf;
121940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	strides[0]=PAD(pw0, pad);
122040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(subsamp==TJSAMP_GRAY)
122140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
122240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		strides[1]=strides[2]=0;
122340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		srcPlanes[1]=srcPlanes[2]=NULL;
122440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
122540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	else
122640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
122740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int pw1=tjPlaneWidth(1, width, subsamp);
122840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int ph1=tjPlaneHeight(1, height, subsamp);
122940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		strides[1]=strides[2]=PAD(pw1, pad);
123040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		srcPlanes[1]=srcPlanes[0]+strides[0]*ph0;
123140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		srcPlanes[2]=srcPlanes[1]+strides[1]*ph1;
123240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
1233aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1234aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	return tjCompressFromYUVPlanes(handle, srcPlanes, width, strides, height,
1235aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		subsamp, jpegBuf, jpegSize, jpegQual, flags);
1236aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1237aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	bailout:
1238aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	return retval;
1239aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC}
1240aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1241910a35725cb52913c248f39e3f273a4baadbd7ddDRC
12429b28defe6ac85dd8a52479cf276606beae24920eDRC/* Decompressor */
12432e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
12449b28defe6ac85dd8a52479cf276606beae24920eDRCstatic tjhandle _tjInitDecompress(tjinstance *this)
12452e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
12466eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	static unsigned char buffer[1];
12472e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
12489b28defe6ac85dd8a52479cf276606beae24920eDRC	/* This is also straight out of example.c */
12499b28defe6ac85dd8a52479cf276606beae24920eDRC	this->dinfo.err=jpeg_std_error(&this->jerr.pub);
12509b28defe6ac85dd8a52479cf276606beae24920eDRC	this->jerr.pub.error_exit=my_error_exit;
12519b28defe6ac85dd8a52479cf276606beae24920eDRC	this->jerr.pub.output_message=my_output_message;
12521f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	this->jerr.emit_message=this->jerr.pub.emit_message;
12531f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	this->jerr.pub.emit_message=my_emit_message;
12542e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
12559b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer))
12569b28defe6ac85dd8a52479cf276606beae24920eDRC	{
12579b28defe6ac85dd8a52479cf276606beae24920eDRC		/* If we get here, the JPEG code has signaled an error. */
12586eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		if(this) free(this);
12596eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		return NULL;
12609e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC	}
12612e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
12629b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_create_decompress(&this->dinfo);
12639b28defe6ac85dd8a52479cf276606beae24920eDRC	/* Make an initial call so it will create the source manager */
12649b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_mem_src_tj(&this->dinfo, buffer, 1);
12652e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1266007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC	this->init|=DECOMPRESS;
12679b28defe6ac85dd8a52479cf276606beae24920eDRC	return (tjhandle)this;
12682e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
12692e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1270890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitDecompress(void)
1271890f1e0413b54c40b663208779d4ea9dae20eaefDRC{
12729b28defe6ac85dd8a52479cf276606beae24920eDRC	tjinstance *this;
12739b28defe6ac85dd8a52479cf276606beae24920eDRC	if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL)
1274da5220acdd525242bff4e40b1d90324ebb889825DRC	{
1275007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		snprintf(errStr, JMSG_LENGTH_MAX,
1276007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC			"tjInitDecompress(): Memory allocation failure");
1277da5220acdd525242bff4e40b1d90324ebb889825DRC		return NULL;
1278da5220acdd525242bff4e40b1d90324ebb889825DRC	}
1279007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC	MEMZERO(this, sizeof(tjinstance));
12809b28defe6ac85dd8a52479cf276606beae24920eDRC	return _tjInitDecompress(this);
1281890f1e0413b54c40b663208779d4ea9dae20eaefDRC}
1282890f1e0413b54c40b663208779d4ea9dae20eaefDRC
12832e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1284cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRCDLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle,
12856eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *jpegBuf, unsigned long jpegSize, int *width,
12866eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	int *height, int *jpegSubsamp, int *jpegColorspace)
12871fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC{
12889b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	int retval=0;
12891fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
1290418616266582fa978d4d1950cf739bbdac7ebee5DRC	getdinstance(handle);
12919b28defe6ac85dd8a52479cf276606beae24920eDRC	if((this->init&DECOMPRESS)==0)
1292cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		_throw("tjDecompressHeader3(): Instance has not been initialized for decompression");
12931fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
12949b28defe6ac85dd8a52479cf276606beae24920eDRC	if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL
1295cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		|| jpegSubsamp==NULL || jpegColorspace==NULL)
1296cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		_throw("tjDecompressHeader3(): Invalid argument");
12971fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
12989b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer))
12999b28defe6ac85dd8a52479cf276606beae24920eDRC	{
13009b28defe6ac85dd8a52479cf276606beae24920eDRC		/* If we get here, the JPEG code has signaled an error. */
13011fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC		return -1;
13021fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC	}
13031fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
13049b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
13059b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_read_header(dinfo, TRUE);
13061fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
13079b28defe6ac85dd8a52479cf276606beae24920eDRC	*width=dinfo->image_width;
13089b28defe6ac85dd8a52479cf276606beae24920eDRC	*height=dinfo->image_height;
13099b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	*jpegSubsamp=getSubsamp(dinfo);
1310cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	switch(dinfo->jpeg_color_space)
1311cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	{
1312cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		case JCS_GRAYSCALE:  *jpegColorspace=TJCS_GRAY;  break;
1313cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		case JCS_RGB:        *jpegColorspace=TJCS_RGB;  break;
1314cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		case JCS_YCbCr:      *jpegColorspace=TJCS_YCbCr;  break;
1315cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		case JCS_CMYK:       *jpegColorspace=TJCS_CMYK;  break;
1316cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		case JCS_YCCK:       *jpegColorspace=TJCS_YCCK;  break;
1317cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		default:             *jpegColorspace=-1;  break;
1318cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	}
13191fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
13209b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_abort_decompress(dinfo);
13211fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
13229b28defe6ac85dd8a52479cf276606beae24920eDRC	if(*jpegSubsamp<0)
1323cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		_throw("tjDecompressHeader3(): Could not determine subsampling type for JPEG image");
1324cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	if(*jpegColorspace<0)
1325cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		_throw("tjDecompressHeader3(): Could not determine colorspace of JPEG image");
1326007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC	if(*width<1 || *height<1)
1327cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		_throw("tjDecompressHeader3(): Invalid data returned in header");
132891e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC
132991e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC	bailout:
13301f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(this->jerr.warning) retval=-1;
133191e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC	return retval;
133291e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC}
133391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC
1334cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRCDLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
1335cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,
1336cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	int *jpegSubsamp)
1337cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC{
1338cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	int jpegColorspace;
1339cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	return tjDecompressHeader3(handle, jpegBuf, jpegSize, width, height,
1340cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC		jpegSubsamp, &jpegColorspace);
1341cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC}
1342cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC
13439b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle,
13449b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height)
134591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC{
13469b28defe6ac85dd8a52479cf276606beae24920eDRC	int jpegSubsamp;
13479b28defe6ac85dd8a52479cf276606beae24920eDRC	return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height,
13489b28defe6ac85dd8a52479cf276606beae24920eDRC		&jpegSubsamp);
13491fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC}
13501fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
13511fe80f80f57a975d5de01f2cae48f0981d9fd8d7DRC
1352109a578e89ea8cd2c39d50b012698148dd11dedbDRCDLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors)
1353b28fc5710a510410d2b498255a423dd62b353b3aDRC{
1354109a578e89ea8cd2c39d50b012698148dd11dedbDRC	if(numscalingfactors==NULL)
1355b28fc5710a510410d2b498255a423dd62b353b3aDRC	{
13569b28defe6ac85dd8a52479cf276606beae24920eDRC		snprintf(errStr, JMSG_LENGTH_MAX,
1357007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC			"tjGetScalingFactors(): Invalid argument");
1358109a578e89ea8cd2c39d50b012698148dd11dedbDRC		return NULL;
1359b28fc5710a510410d2b498255a423dd62b353b3aDRC	}
1360b28fc5710a510410d2b498255a423dd62b353b3aDRC
1361109a578e89ea8cd2c39d50b012698148dd11dedbDRC	*numscalingfactors=NUMSF;
1362109a578e89ea8cd2c39d50b012698148dd11dedbDRC	return (tjscalingfactor *)sf;
1363b28fc5710a510410d2b498255a423dd62b353b3aDRC}
1364b28fc5710a510410d2b498255a423dd62b353b3aDRC
1365b28fc5710a510410d2b498255a423dd62b353b3aDRC
13666eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjDecompress2(tjhandle handle,
13676eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
13686eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	int width, int pitch, int height, int pixelFormat, int flags)
13699b28defe6ac85dd8a52479cf276606beae24920eDRC{
13709b28defe6ac85dd8a52479cf276606beae24920eDRC	int i, retval=0;  JSAMPROW *row_pointer=NULL;
13719b28defe6ac85dd8a52479cf276606beae24920eDRC	int jpegwidth, jpegheight, scaledw, scaledh;
1372afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
1373afc06929e0a9cf64bdf50da30326076235df7b4fDRC	unsigned char *rgbBuf=NULL;
1374afc06929e0a9cf64bdf50da30326076235df7b4fDRC	unsigned char *_dstBuf=NULL;  int _pitch=0;
1375afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
13769b28defe6ac85dd8a52479cf276606beae24920eDRC
1377418616266582fa978d4d1950cf739bbdac7ebee5DRC	getdinstance(handle);
13789b28defe6ac85dd8a52479cf276606beae24920eDRC	if((this->init&DECOMPRESS)==0)
1379007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("tjDecompress2(): Instance has not been initialized for decompression");
13809b28defe6ac85dd8a52479cf276606beae24920eDRC
13819b28defe6ac85dd8a52479cf276606beae24920eDRC	if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0
13829b28defe6ac85dd8a52479cf276606beae24920eDRC		|| height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF)
13839b28defe6ac85dd8a52479cf276606beae24920eDRC		_throw("tjDecompress2(): Invalid argument");
13849b28defe6ac85dd8a52479cf276606beae24920eDRC
1385bec45b162bb77a57c147a9c44113af1968a79be4DRC	if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
1386bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
1387bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
13889b28defe6ac85dd8a52479cf276606beae24920eDRC
13899b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer))
13909b28defe6ac85dd8a52479cf276606beae24920eDRC	{
13919b28defe6ac85dd8a52479cf276606beae24920eDRC		/* If we get here, the JPEG code has signaled an error. */
13929b28defe6ac85dd8a52479cf276606beae24920eDRC		retval=-1;
13939b28defe6ac85dd8a52479cf276606beae24920eDRC		goto bailout;
13949b28defe6ac85dd8a52479cf276606beae24920eDRC	}
13959b28defe6ac85dd8a52479cf276606beae24920eDRC
13969b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
13979b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_read_header(dinfo, TRUE);
139873d74c132b399fc761ebd9a5b2f60ae2a25f5955DRC	if(setDecompDefaults(dinfo, pixelFormat, flags)==-1)
13992eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC	{
14002eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC		retval=-1;  goto bailout;
14012eda8212e4b01c9b4d343dd0eaa579f0bba036e7DRC	}
14029b28defe6ac85dd8a52479cf276606beae24920eDRC
140325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC	if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE;
14049b28defe6ac85dd8a52479cf276606beae24920eDRC
14059b28defe6ac85dd8a52479cf276606beae24920eDRC	jpegwidth=dinfo->image_width;  jpegheight=dinfo->image_height;
14069b28defe6ac85dd8a52479cf276606beae24920eDRC	if(width==0) width=jpegwidth;
14079b28defe6ac85dd8a52479cf276606beae24920eDRC	if(height==0) height=jpegheight;
14089b28defe6ac85dd8a52479cf276606beae24920eDRC	for(i=0; i<NUMSF; i++)
14099b28defe6ac85dd8a52479cf276606beae24920eDRC	{
14109b28defe6ac85dd8a52479cf276606beae24920eDRC		scaledw=TJSCALED(jpegwidth, sf[i]);
14119b28defe6ac85dd8a52479cf276606beae24920eDRC		scaledh=TJSCALED(jpegheight, sf[i]);
14129b28defe6ac85dd8a52479cf276606beae24920eDRC		if(scaledw<=width && scaledh<=height)
1413f610d61fcc38b36a8a29879e5c053015164242f8DRC			break;
14149b28defe6ac85dd8a52479cf276606beae24920eDRC	}
141558ae401e503ac61babb9d66be8fc06bfb0445dbfDRC	if(i>=NUMSF)
1416007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("tjDecompress2(): Could not scale down to desired image dimensions");
14179b28defe6ac85dd8a52479cf276606beae24920eDRC	width=scaledw;  height=scaledh;
14189b28defe6ac85dd8a52479cf276606beae24920eDRC	dinfo->scale_num=sf[i].num;
14199b28defe6ac85dd8a52479cf276606beae24920eDRC	dinfo->scale_denom=sf[i].denom;
14209b28defe6ac85dd8a52479cf276606beae24920eDRC
14219b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_start_decompress(dinfo);
14229b28defe6ac85dd8a52479cf276606beae24920eDRC	if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat];
1423afc06929e0a9cf64bdf50da30326076235df7b4fDRC
1424afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
1425230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK &&
1426afc06929e0a9cf64bdf50da30326076235df7b4fDRC		(RGB_RED!=tjRedOffset[pixelFormat] ||
1427afc06929e0a9cf64bdf50da30326076235df7b4fDRC			RGB_GREEN!=tjGreenOffset[pixelFormat] ||
1428afc06929e0a9cf64bdf50da30326076235df7b4fDRC			RGB_BLUE!=tjBlueOffset[pixelFormat] ||
1429afc06929e0a9cf64bdf50da30326076235df7b4fDRC			RGB_PIXELSIZE!=tjPixelSize[pixelFormat]))
1430afc06929e0a9cf64bdf50da30326076235df7b4fDRC	{
1431afc06929e0a9cf64bdf50da30326076235df7b4fDRC		rgbBuf=(unsigned char *)malloc(width*height*3);
1432afc06929e0a9cf64bdf50da30326076235df7b4fDRC		if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure");
1433afc06929e0a9cf64bdf50da30326076235df7b4fDRC		_pitch=pitch;  pitch=width*3;
1434afc06929e0a9cf64bdf50da30326076235df7b4fDRC		_dstBuf=dstBuf;  dstBuf=rgbBuf;
1435afc06929e0a9cf64bdf50da30326076235df7b4fDRC	}
1436afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
1437afc06929e0a9cf64bdf50da30326076235df7b4fDRC
14389b28defe6ac85dd8a52479cf276606beae24920eDRC	if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)
14399b28defe6ac85dd8a52479cf276606beae24920eDRC		*dinfo->output_height))==NULL)
1440007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("tjDecompress2(): Memory allocation failure");
14419b28defe6ac85dd8a52479cf276606beae24920eDRC	for(i=0; i<(int)dinfo->output_height; i++)
14429b28defe6ac85dd8a52479cf276606beae24920eDRC	{
144325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		if(flags&TJFLAG_BOTTOMUP)
14449b28defe6ac85dd8a52479cf276606beae24920eDRC			row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch];
14459b28defe6ac85dd8a52479cf276606beae24920eDRC		else row_pointer[i]=&dstBuf[i*pitch];
14469b28defe6ac85dd8a52479cf276606beae24920eDRC	}
14479b28defe6ac85dd8a52479cf276606beae24920eDRC	while(dinfo->output_scanline<dinfo->output_height)
14489b28defe6ac85dd8a52479cf276606beae24920eDRC	{
14499b28defe6ac85dd8a52479cf276606beae24920eDRC		jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline],
14509b28defe6ac85dd8a52479cf276606beae24920eDRC			dinfo->output_height-dinfo->output_scanline);
14519b28defe6ac85dd8a52479cf276606beae24920eDRC	}
14529b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_finish_decompress(dinfo);
14539b28defe6ac85dd8a52479cf276606beae24920eDRC
1454afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
1455afc06929e0a9cf64bdf50da30326076235df7b4fDRC	fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat);
1456afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
1457afc06929e0a9cf64bdf50da30326076235df7b4fDRC
14589b28defe6ac85dd8a52479cf276606beae24920eDRC	bailout:
14599b28defe6ac85dd8a52479cf276606beae24920eDRC	if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
1460afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#ifndef JCS_EXTENSIONS
1461ea3396a9456fbe403e0defd2991a308d7c400abcDRC	if(rgbBuf) free(rgbBuf);
1462afc06929e0a9cf64bdf50da30326076235df7b4fDRC	#endif
14639b28defe6ac85dd8a52479cf276606beae24920eDRC	if(row_pointer) free(row_pointer);
14641f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(this->jerr.warning) retval=-1;
14659b28defe6ac85dd8a52479cf276606beae24920eDRC	return retval;
14669b28defe6ac85dd8a52479cf276606beae24920eDRC}
14679b28defe6ac85dd8a52479cf276606beae24920eDRC
14689b28defe6ac85dd8a52479cf276606beae24920eDRCDLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf,
14699b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch,
14709b28defe6ac85dd8a52479cf276606beae24920eDRC	int height, int pixelSize, int flags)
14719b28defe6ac85dd8a52479cf276606beae24920eDRC{
14729b28defe6ac85dd8a52479cf276606beae24920eDRC	if(flags&TJ_YUV)
14739b28defe6ac85dd8a52479cf276606beae24920eDRC		return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags);
14749b28defe6ac85dd8a52479cf276606beae24920eDRC	else
14759b28defe6ac85dd8a52479cf276606beae24920eDRC		return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch,
14769b28defe6ac85dd8a52479cf276606beae24920eDRC			height, getPixelFormat(pixelSize, flags), flags);
14779b28defe6ac85dd8a52479cf276606beae24920eDRC}
14789b28defe6ac85dd8a52479cf276606beae24920eDRC
14799b28defe6ac85dd8a52479cf276606beae24920eDRC
148034dca052271f4a75b3c0f7b11a2c5024159628d4DRCstatic int setDecodeDefaults(struct jpeg_decompress_struct *dinfo,
148134dca052271f4a75b3c0f7b11a2c5024159628d4DRC	int pixelFormat, int subsamp, int flags)
148234dca052271f4a75b3c0f7b11a2c5024159628d4DRC{
1483895fd6d0d370d64df9dbb1bc53342c734a6933fcDRC	int i;
1484895fd6d0d370d64df9dbb1bc53342c734a6933fcDRC
148534dca052271f4a75b3c0f7b11a2c5024159628d4DRC	dinfo->scale_num=dinfo->scale_denom=1;
148634dca052271f4a75b3c0f7b11a2c5024159628d4DRC
148734dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(subsamp==TJSAMP_GRAY)
148834dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
1489c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC		dinfo->num_components=dinfo->comps_in_scan=1;
149034dca052271f4a75b3c0f7b11a2c5024159628d4DRC		dinfo->jpeg_color_space=JCS_GRAYSCALE;
149134dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
149234dca052271f4a75b3c0f7b11a2c5024159628d4DRC	else
149334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
1494c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC		dinfo->num_components=dinfo->comps_in_scan=3;
149534dca052271f4a75b3c0f7b11a2c5024159628d4DRC		dinfo->jpeg_color_space=JCS_YCbCr;
149634dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
149734dca052271f4a75b3c0f7b11a2c5024159628d4DRC
149834dca052271f4a75b3c0f7b11a2c5024159628d4DRC	dinfo->comp_info=(jpeg_component_info *)
149934dca052271f4a75b3c0f7b11a2c5024159628d4DRC		(*dinfo->mem->alloc_small)((j_common_ptr)dinfo, JPOOL_IMAGE,
15005de454b291f48382648a5d1dc2aa0fca8b5786d4DRC			dinfo->num_components*sizeof(jpeg_component_info));
150134dca052271f4a75b3c0f7b11a2c5024159628d4DRC
15022bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC	for(i=0; i<dinfo->num_components; i++)
150334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
15042bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC		jpeg_component_info *compptr=&dinfo->comp_info[i];
15052bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC		compptr->h_samp_factor=(i==0)? tjMCUWidth[subsamp]/8:1;
15062bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC		compptr->v_samp_factor=(i==0)? tjMCUHeight[subsamp]/8:1;
15072bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC		compptr->component_index=i;
150815c0876191b927cbe4d797b9ef89b51b08a12cc2DRC		compptr->component_id=i+1;
15092bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC		compptr->quant_tbl_no=compptr->dc_tbl_no=compptr->ac_tbl_no=
15102bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC			(i==0)? 0:1;
15112bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC		dinfo->cur_comp_info[i]=compptr;
151234dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
1513c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC	dinfo->data_precision=8;
1514c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC	for(i=0; i<2; i++)
1515c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC	{
1516c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC		if(dinfo->quant_tbl_ptrs[i]==NULL)
1517c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC			dinfo->quant_tbl_ptrs[i]=jpeg_alloc_quant_table((j_common_ptr)dinfo);
1518c90144950ffc9e58f942f1be7fc18e7820a14eb7DRC	}
151934dca052271f4a75b3c0f7b11a2c5024159628d4DRC
152034dca052271f4a75b3c0f7b11a2c5024159628d4DRC	return 0;
152134dca052271f4a75b3c0f7b11a2c5024159628d4DRC}
152234dca052271f4a75b3c0f7b11a2c5024159628d4DRC
152334dca052271f4a75b3c0f7b11a2c5024159628d4DRC
152434dca052271f4a75b3c0f7b11a2c5024159628d4DRCint my_read_markers(j_decompress_ptr dinfo)
152534dca052271f4a75b3c0f7b11a2c5024159628d4DRC{
152634dca052271f4a75b3c0f7b11a2c5024159628d4DRC	return JPEG_REACHED_SOS;
152734dca052271f4a75b3c0f7b11a2c5024159628d4DRC}
152834dca052271f4a75b3c0f7b11a2c5024159628d4DRC
152934dca052271f4a75b3c0f7b11a2c5024159628d4DRCvoid my_reset_marker_reader(j_decompress_ptr dinfo)
153034dca052271f4a75b3c0f7b11a2c5024159628d4DRC{
153134dca052271f4a75b3c0f7b11a2c5024159628d4DRC}
153234dca052271f4a75b3c0f7b11a2c5024159628d4DRC
1533aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRCDLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle,
15346eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char **srcPlanes, const int *strides, int subsamp,
15356eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat,
15366eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	int flags)
153734dca052271f4a75b3c0f7b11a2c5024159628d4DRC{
153834dca052271f4a75b3c0f7b11a2c5024159628d4DRC	int i, retval=0;  JSAMPROW *row_pointer=NULL;
153934dca052271f4a75b3c0f7b11a2c5024159628d4DRC	JSAMPLE *_tmpbuf[MAX_COMPONENTS];
154034dca052271f4a75b3c0f7b11a2c5024159628d4DRC	JSAMPROW *tmpbuf[MAX_COMPONENTS], *inbuf[MAX_COMPONENTS];
154140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS];
1542aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	JSAMPLE *ptr;
154334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	jpeg_component_info *compptr;
154434dca052271f4a75b3c0f7b11a2c5024159628d4DRC	#ifndef JCS_EXTENSIONS
154534dca052271f4a75b3c0f7b11a2c5024159628d4DRC	unsigned char *rgbBuf=NULL;
1546230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	unsigned char *_dstBuf=NULL;  int _pitch=0;
154734dca052271f4a75b3c0f7b11a2c5024159628d4DRC	#endif
1548bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC	int (*old_read_markers)(j_decompress_ptr);
1549bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC	void (*old_reset_marker_reader)(j_decompress_ptr);
155034dca052271f4a75b3c0f7b11a2c5024159628d4DRC
1551418616266582fa978d4d1950cf739bbdac7ebee5DRC	getdinstance(handle);
155234dca052271f4a75b3c0f7b11a2c5024159628d4DRC
155334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	for(i=0; i<MAX_COMPONENTS; i++)
155434dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
155534dca052271f4a75b3c0f7b11a2c5024159628d4DRC		tmpbuf[i]=NULL;  _tmpbuf[i]=NULL;  inbuf[i]=NULL;
155634dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
155734dca052271f4a75b3c0f7b11a2c5024159628d4DRC
155834dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if((this->init&DECOMPRESS)==0)
1559aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecodeYUVPlanes(): Instance has not been initialized for decompression");
156034dca052271f4a75b3c0f7b11a2c5024159628d4DRC
1561aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(!srcPlanes || !srcPlanes[0] || subsamp<0 || subsamp>=NUMSUBOPT
156234dca052271f4a75b3c0f7b11a2c5024159628d4DRC		|| dstBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0
156334dca052271f4a75b3c0f7b11a2c5024159628d4DRC		|| pixelFormat>=TJ_NUMPF)
1564aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecodeYUVPlanes(): Invalid argument");
1565aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(subsamp!=TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2]))
1566aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecodeYUVPlanes(): Invalid argument");
156734dca052271f4a75b3c0f7b11a2c5024159628d4DRC
156834dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(setjmp(this->jerr.setjmp_buffer))
156934dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
157034dca052271f4a75b3c0f7b11a2c5024159628d4DRC		/* If we get here, the JPEG code has signaled an error. */
157134dca052271f4a75b3c0f7b11a2c5024159628d4DRC		retval=-1;
157234dca052271f4a75b3c0f7b11a2c5024159628d4DRC		goto bailout;
157334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
157434dca052271f4a75b3c0f7b11a2c5024159628d4DRC
157534dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(pixelFormat==TJPF_CMYK)
1576aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK pixels.");
157734dca052271f4a75b3c0f7b11a2c5024159628d4DRC
157834dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
157934dca052271f4a75b3c0f7b11a2c5024159628d4DRC	dinfo->image_width=width;
158034dca052271f4a75b3c0f7b11a2c5024159628d4DRC	dinfo->image_height=height;
158134dca052271f4a75b3c0f7b11a2c5024159628d4DRC
1582bec45b162bb77a57c147a9c44113af1968a79be4DRC	if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
1583bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
1584bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
158534dca052271f4a75b3c0f7b11a2c5024159628d4DRC
158634dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(setDecodeDefaults(dinfo, pixelFormat, subsamp, flags)==-1)
158734dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
158834dca052271f4a75b3c0f7b11a2c5024159628d4DRC		retval=-1;  goto bailout;
158934dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
159034dca052271f4a75b3c0f7b11a2c5024159628d4DRC	old_read_markers=dinfo->marker->read_markers;
159134dca052271f4a75b3c0f7b11a2c5024159628d4DRC	dinfo->marker->read_markers=my_read_markers;
159234dca052271f4a75b3c0f7b11a2c5024159628d4DRC	old_reset_marker_reader=dinfo->marker->reset_marker_reader;
159334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	dinfo->marker->reset_marker_reader=my_reset_marker_reader;
159434dca052271f4a75b3c0f7b11a2c5024159628d4DRC	jpeg_read_header(dinfo, TRUE);
159534dca052271f4a75b3c0f7b11a2c5024159628d4DRC	dinfo->marker->read_markers=old_read_markers;
159634dca052271f4a75b3c0f7b11a2c5024159628d4DRC	dinfo->marker->reset_marker_reader=old_reset_marker_reader;
159734dca052271f4a75b3c0f7b11a2c5024159628d4DRC
159834dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(setDecompDefaults(dinfo, pixelFormat, flags)==-1)
159934dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
160034dca052271f4a75b3c0f7b11a2c5024159628d4DRC		retval=-1;  goto bailout;
160134dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
16027d9f758e5251e129431b03cdab1160710d4b3fb8DRC	dinfo->do_fancy_upsampling=FALSE;
1603db6d8fca591c924ba3da8ef525925b92e261e66aDRC	dinfo->Se=DCTSIZE2-1;
16042bdc0425df6d014a9f64549da4f7c2a4aa6b82b3DRC	jinit_master_decompress(dinfo);
160534dca052271f4a75b3c0f7b11a2c5024159628d4DRC	(*dinfo->upsample->start_pass)(dinfo);
160634dca052271f4a75b3c0f7b11a2c5024159628d4DRC
160740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	pw0=PAD(width, dinfo->max_h_samp_factor);
160840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	ph0=PAD(height, dinfo->max_v_samp_factor);
160934dca052271f4a75b3c0f7b11a2c5024159628d4DRC
161034dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat];
161134dca052271f4a75b3c0f7b11a2c5024159628d4DRC
1612230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	#ifndef JCS_EXTENSIONS
1613230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK &&
1614230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC		(RGB_RED!=tjRedOffset[pixelFormat] ||
1615230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC			RGB_GREEN!=tjGreenOffset[pixelFormat] ||
1616230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC			RGB_BLUE!=tjBlueOffset[pixelFormat] ||
1617230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC			RGB_PIXELSIZE!=tjPixelSize[pixelFormat]))
1618230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	{
1619230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC		rgbBuf=(unsigned char *)malloc(width*height*3);
1620aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!rgbBuf) _throw("tjDecodeYUVPlanes(): Memory allocation failure");
1621230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC		_pitch=pitch;  pitch=width*3;
1622230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC		_dstBuf=dstBuf;  dstBuf=rgbBuf;
1623230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	}
1624230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	#endif
1625230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC
162640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph0))==NULL)
1627aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecodeYUVPlanes(): Memory allocation failure");
162834dca052271f4a75b3c0f7b11a2c5024159628d4DRC	for(i=0; i<height; i++)
162934dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
163034dca052271f4a75b3c0f7b11a2c5024159628d4DRC		if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&dstBuf[(height-i-1)*pitch];
163134dca052271f4a75b3c0f7b11a2c5024159628d4DRC		else row_pointer[i]=&dstBuf[i*pitch];
163234dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
163340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(height<ph0)
163440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1];
163534dca052271f4a75b3c0f7b11a2c5024159628d4DRC
163634dca052271f4a75b3c0f7b11a2c5024159628d4DRC	for(i=0; i<dinfo->num_components; i++)
163734dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
163834dca052271f4a75b3c0f7b11a2c5024159628d4DRC		compptr=&dinfo->comp_info[i];
163934dca052271f4a75b3c0f7b11a2c5024159628d4DRC		_tmpbuf[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16)
164034dca052271f4a75b3c0f7b11a2c5024159628d4DRC			* compptr->v_samp_factor + 16);
1641aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!_tmpbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation failure");
164234dca052271f4a75b3c0f7b11a2c5024159628d4DRC		tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor);
1643aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!tmpbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation failure");
164434dca052271f4a75b3c0f7b11a2c5024159628d4DRC		for(row=0; row<compptr->v_samp_factor; row++)
164534dca052271f4a75b3c0f7b11a2c5024159628d4DRC		{
164634dca052271f4a75b3c0f7b11a2c5024159628d4DRC			unsigned char *_tmpbuf_aligned=
164734dca052271f4a75b3c0f7b11a2c5024159628d4DRC				(unsigned char *)PAD((size_t)_tmpbuf[i], 16);
164834dca052271f4a75b3c0f7b11a2c5024159628d4DRC			tmpbuf[i][row]=&_tmpbuf_aligned[
164934dca052271f4a75b3c0f7b11a2c5024159628d4DRC				PAD(compptr->width_in_blocks*DCTSIZE, 16) * row];
165034dca052271f4a75b3c0f7b11a2c5024159628d4DRC		}
165140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		pw[i]=pw0*compptr->h_samp_factor/dinfo->max_h_samp_factor;
165240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		ph[i]=ph0*compptr->v_samp_factor/dinfo->max_v_samp_factor;
165340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		inbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]);
1654aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(!inbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation failure");
16556eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		ptr=(JSAMPLE *)srcPlanes[i];
165640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		for(row=0; row<ph[i]; row++)
165734dca052271f4a75b3c0f7b11a2c5024159628d4DRC		{
165834dca052271f4a75b3c0f7b11a2c5024159628d4DRC			inbuf[i][row]=ptr;
165940dd3146cde2ba5036fe76a4f09e1125b4592347DRC			ptr+=(strides && strides[i]!=0)? strides[i]:pw[i];
166034dca052271f4a75b3c0f7b11a2c5024159628d4DRC		}
166134dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
166234dca052271f4a75b3c0f7b11a2c5024159628d4DRC
166340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(row=0; row<ph0; row+=dinfo->max_v_samp_factor)
166434dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
166534dca052271f4a75b3c0f7b11a2c5024159628d4DRC		JDIMENSION inrow=0, outrow=0;
166634dca052271f4a75b3c0f7b11a2c5024159628d4DRC		for(i=0, compptr=dinfo->comp_info; i<dinfo->num_components; i++, compptr++)
166734dca052271f4a75b3c0f7b11a2c5024159628d4DRC			jcopy_sample_rows(inbuf[i],
166834dca052271f4a75b3c0f7b11a2c5024159628d4DRC				row*compptr->v_samp_factor/dinfo->max_v_samp_factor, tmpbuf[i], 0,
166940dd3146cde2ba5036fe76a4f09e1125b4592347DRC				compptr->v_samp_factor, pw[i]);
167034dca052271f4a75b3c0f7b11a2c5024159628d4DRC		(dinfo->upsample->upsample)(dinfo, tmpbuf, &inrow,
167134dca052271f4a75b3c0f7b11a2c5024159628d4DRC			dinfo->max_v_samp_factor, &row_pointer[row], &outrow,
167234dca052271f4a75b3c0f7b11a2c5024159628d4DRC			dinfo->max_v_samp_factor);
167334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
167434dca052271f4a75b3c0f7b11a2c5024159628d4DRC	jpeg_abort_decompress(dinfo);
167534dca052271f4a75b3c0f7b11a2c5024159628d4DRC
1676230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	#ifndef JCS_EXTENSIONS
1677230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat);
1678230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC	#endif
1679230d09dbed4b7f2dfb52b9009770b2979b2aeb8fDRC
168034dca052271f4a75b3c0f7b11a2c5024159628d4DRC	bailout:
168134dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
168234dca052271f4a75b3c0f7b11a2c5024159628d4DRC	#ifndef JCS_EXTENSIONS
168334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(rgbBuf) free(rgbBuf);
168434dca052271f4a75b3c0f7b11a2c5024159628d4DRC	#endif
168534dca052271f4a75b3c0f7b11a2c5024159628d4DRC	if(row_pointer) free(row_pointer);
168634dca052271f4a75b3c0f7b11a2c5024159628d4DRC	for(i=0; i<MAX_COMPONENTS; i++)
168734dca052271f4a75b3c0f7b11a2c5024159628d4DRC	{
168834dca052271f4a75b3c0f7b11a2c5024159628d4DRC		if(tmpbuf[i]!=NULL) free(tmpbuf[i]);
168934dca052271f4a75b3c0f7b11a2c5024159628d4DRC		if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]);
169034dca052271f4a75b3c0f7b11a2c5024159628d4DRC		if(inbuf[i]!=NULL) free(inbuf[i]);
169134dca052271f4a75b3c0f7b11a2c5024159628d4DRC	}
16921f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(this->jerr.warning) retval=-1;
169334dca052271f4a75b3c0f7b11a2c5024159628d4DRC	return retval;
169434dca052271f4a75b3c0f7b11a2c5024159628d4DRC}
169534dca052271f4a75b3c0f7b11a2c5024159628d4DRC
16966eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf,
1697aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	int pad, int subsamp, unsigned char *dstBuf, int width, int pitch,
1698aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	int height, int pixelFormat, int flags)
1699aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC{
17006eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *srcPlanes[3];
170140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int pw0, ph0, strides[3], retval=-1;
170234dca052271f4a75b3c0f7b11a2c5024159628d4DRC
1703aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(srcBuf==NULL || pad<0 || !isPow2(pad) || subsamp<0 || subsamp>=NUMSUBOPT
1704aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		|| width<=0 || height<=0)
1705aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecodeYUV(): Invalid argument");
1706aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
170740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	pw0=tjPlaneWidth(0, width, subsamp);
170840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	ph0=tjPlaneHeight(0, height, subsamp);
1709aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	srcPlanes[0]=srcBuf;
171040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	strides[0]=PAD(pw0, pad);
171140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(subsamp==TJSAMP_GRAY)
171240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
171340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		strides[1]=strides[2]=0;
171440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		srcPlanes[1]=srcPlanes[2]=NULL;
171540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
171640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	else
171740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
171840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int pw1=tjPlaneWidth(1, width, subsamp);
171940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int ph1=tjPlaneHeight(1, height, subsamp);
172040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		strides[1]=strides[2]=PAD(pw1, pad);
172140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		srcPlanes[1]=srcPlanes[0]+strides[0]*ph0;
172240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		srcPlanes[2]=srcPlanes[1]+strides[1]*ph1;
172340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
1724aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1725aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	return tjDecodeYUVPlanes(handle, srcPlanes, strides, subsamp, dstBuf, width,
1726aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		pitch, height, pixelFormat, flags);
1727aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1728aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	bailout:
1729aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	return retval;
1730aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC}
1731aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1732aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRCDLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle,
17336eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *jpegBuf, unsigned long jpegSize,
17346eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	unsigned char **dstPlanes, int width, int *strides, int height, int flags)
17352e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC{
1736f610d61fcc38b36a8a29879e5c053015164242f8DRC	int i, sfi, row, retval=0;  JSAMPROW *outbuf[MAX_COMPONENTS];
1737418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC	int jpegwidth, jpegheight, jpegSubsamp, scaledw, scaledh;
173840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS],
1739f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC		tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS];
1740aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	JSAMPLE *_tmpbuf=NULL, *ptr;  JSAMPROW *tmpbuf[MAX_COMPONENTS];
1741418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC	int dctsize;
17422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1743418616266582fa978d4d1950cf739bbdac7ebee5DRC	getdinstance(handle);
1744b51ee895d8266529af7f96cb24fba53df273d32eDRC
1745f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC	for(i=0; i<MAX_COMPONENTS; i++)
1746f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC	{
1747f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC		tmpbuf[i]=NULL;  outbuf[i]=NULL;
1748f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC	}
17499e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC
1750e2f8e694d0d1ec333c18d803cf0ba083e9feb1c0DRC	if((this->init&DECOMPRESS)==0)
1751aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUVPlanes(): Instance has not been initialized for decompression");
1752e2f8e694d0d1ec333c18d803cf0ba083e9feb1c0DRC
1753aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(jpegBuf==NULL || jpegSize<=0 || !dstPlanes || !dstPlanes[0] || width<0
1754aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		|| height<0)
1755aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUVPlanes(): Invalid argument");
17562e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1757bec45b162bb77a57c147a9c44113af1968a79be4DRC	if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
1758bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
1759bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
17600c6a271f974529e4795332c9ad428500ef17fb42DRC
17619b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer))
17629b28defe6ac85dd8a52479cf276606beae24920eDRC	{
17639b28defe6ac85dd8a52479cf276606beae24920eDRC		/* If we get here, the JPEG code has signaled an error. */
176491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC		retval=-1;
176591e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC		goto bailout;
17669e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC	}
17672e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1768aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(!this->headerRead)
1769aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	{
1770aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
1771aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		jpeg_read_header(dinfo, TRUE);
1772aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	}
1773aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	this->headerRead=0;
1774418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC	jpegSubsamp=getSubsamp(dinfo);
1775418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC	if(jpegSubsamp<0)
1776aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUVPlanes(): Could not determine subsampling type for JPEG image");
1777aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1778aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(jpegSubsamp!=TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2]))
1779aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUVPlanes(): Invalid argument");
17802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1781f610d61fcc38b36a8a29879e5c053015164242f8DRC	jpegwidth=dinfo->image_width;  jpegheight=dinfo->image_height;
1782f610d61fcc38b36a8a29879e5c053015164242f8DRC	if(width==0) width=jpegwidth;
1783f610d61fcc38b36a8a29879e5c053015164242f8DRC	if(height==0) height=jpegheight;
1784f610d61fcc38b36a8a29879e5c053015164242f8DRC	for(i=0; i<NUMSF; i++)
1785f610d61fcc38b36a8a29879e5c053015164242f8DRC	{
1786f610d61fcc38b36a8a29879e5c053015164242f8DRC		scaledw=TJSCALED(jpegwidth, sf[i]);
1787f610d61fcc38b36a8a29879e5c053015164242f8DRC		scaledh=TJSCALED(jpegheight, sf[i]);
1788f610d61fcc38b36a8a29879e5c053015164242f8DRC		if(scaledw<=width && scaledh<=height)
1789f610d61fcc38b36a8a29879e5c053015164242f8DRC			break;
1790f610d61fcc38b36a8a29879e5c053015164242f8DRC	}
179158ae401e503ac61babb9d66be8fc06bfb0445dbfDRC	if(i>=NUMSF)
1792aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUVPlanes(): Could not scale down to desired image dimensions");
1793cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC	if(dinfo->num_components>3)
1794aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUVPlanes(): JPEG image must have 3 or fewer components");
1795cd7c3e6672cce3779450c6dd10d0d70b0c2278b2DRC
1796f610d61fcc38b36a8a29879e5c053015164242f8DRC	width=scaledw;  height=scaledh;
1797f610d61fcc38b36a8a29879e5c053015164242f8DRC	dinfo->scale_num=sf[i].num;
1798f610d61fcc38b36a8a29879e5c053015164242f8DRC	dinfo->scale_denom=sf[i].denom;
1799f610d61fcc38b36a8a29879e5c053015164242f8DRC	sfi=i;
1800f610d61fcc38b36a8a29879e5c053015164242f8DRC	jpeg_calc_output_dimensions(dinfo);
1801f610d61fcc38b36a8a29879e5c053015164242f8DRC
1802418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC	dctsize=DCTSIZE*sf[sfi].num/sf[sfi].denom;
1803418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC
18049b28defe6ac85dd8a52479cf276606beae24920eDRC	for(i=0; i<dinfo->num_components; i++)
18059e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC	{
18069b28defe6ac85dd8a52479cf276606beae24920eDRC		jpeg_component_info *compptr=&dinfo->comp_info[i];
18079b28defe6ac85dd8a52479cf276606beae24920eDRC		int ih;
1808418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC		iw[i]=compptr->width_in_blocks*dctsize;
1809418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC		ih=compptr->height_in_blocks*dctsize;
181040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		pw[i]=PAD(dinfo->output_width, dinfo->max_h_samp_factor)
18119b28defe6ac85dd8a52479cf276606beae24920eDRC			*compptr->h_samp_factor/dinfo->max_h_samp_factor;
181240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		ph[i]=PAD(dinfo->output_height, dinfo->max_v_samp_factor)
18139b28defe6ac85dd8a52479cf276606beae24920eDRC			*compptr->v_samp_factor/dinfo->max_v_samp_factor;
181440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(iw[i]!=pw[i] || ih!=ph[i]) usetmpbuf=1;
1815418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC		th[i]=compptr->v_samp_factor*dctsize;
18169b28defe6ac85dd8a52479cf276606beae24920eDRC		tmpbufsize+=iw[i]*th[i];
181740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]))==NULL)
1818aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC			_throw("tjDecompressToYUVPlanes(): Memory allocation failure");
1819aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		ptr=dstPlanes[i];
182040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		for(row=0; row<ph[i]; row++)
18219e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC		{
18229b28defe6ac85dd8a52479cf276606beae24920eDRC			outbuf[i][row]=ptr;
182340dd3146cde2ba5036fe76a4f09e1125b4592347DRC			ptr+=(strides && strides[i]!=0)? strides[i]:pw[i];
1824f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC		}
18259b28defe6ac85dd8a52479cf276606beae24920eDRC	}
18269b28defe6ac85dd8a52479cf276606beae24920eDRC	if(usetmpbuf)
18279b28defe6ac85dd8a52479cf276606beae24920eDRC	{
18289b28defe6ac85dd8a52479cf276606beae24920eDRC		if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL)
1829aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC			_throw("tjDecompressToYUVPlanes(): Memory allocation failure");
18309b28defe6ac85dd8a52479cf276606beae24920eDRC		ptr=_tmpbuf;
18319b28defe6ac85dd8a52479cf276606beae24920eDRC		for(i=0; i<dinfo->num_components; i++)
1832f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC		{
18339b28defe6ac85dd8a52479cf276606beae24920eDRC			if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL)
1834aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC				_throw("tjDecompressToYUVPlanes(): Memory allocation failure");
18359b28defe6ac85dd8a52479cf276606beae24920eDRC			for(row=0; row<th[i]; row++)
1836f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC			{
18379b28defe6ac85dd8a52479cf276606beae24920eDRC				tmpbuf[i][row]=ptr;
18389b28defe6ac85dd8a52479cf276606beae24920eDRC				ptr+=iw[i];
18399e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC			}
18409e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC		}
18419e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC	}
18422e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
184325b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC	if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE;
1844e0419b530b3cecb9d7546893d893489a24d21032DRC	if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST;
18459b28defe6ac85dd8a52479cf276606beae24920eDRC	dinfo->raw_data_out=TRUE;
18469b28defe6ac85dd8a52479cf276606beae24920eDRC
18479b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_start_decompress(dinfo);
18489b28defe6ac85dd8a52479cf276606beae24920eDRC	for(row=0; row<(int)dinfo->output_height;
1849418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC		row+=dinfo->max_v_samp_factor*dinfo->_min_DCT_scaled_size)
18508ed7b814039172fe3cbfadfee3922801a3888b73DRC	{
18519b28defe6ac85dd8a52479cf276606beae24920eDRC		JSAMPARRAY yuvptr[MAX_COMPONENTS];
18529b28defe6ac85dd8a52479cf276606beae24920eDRC		int crow[MAX_COMPONENTS];
18539b28defe6ac85dd8a52479cf276606beae24920eDRC		for(i=0; i<dinfo->num_components; i++)
1854842416034561f6d5320165a4fe98825e999a4a37DRC		{
18559b28defe6ac85dd8a52479cf276606beae24920eDRC			jpeg_component_info *compptr=&dinfo->comp_info[i];
1856418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC			if(jpegSubsamp==TJ_420)
1857418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC			{
1858418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				/* When 4:2:0 subsampling is used with IDCT scaling, libjpeg will try
1859418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   to be clever and use the IDCT to perform upsampling on the U and V
1860418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   planes.  For instance, if the output image is to be scaled by 1/2
1861418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   relative to the JPEG image, then the scaling factor and upsampling
1862418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   effectively cancel each other, so a normal 8x8 IDCT can be used.
1863418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   However, this is not desirable when using the decompress-to-YUV
1864418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   functionality in TurboJPEG, since we want to output the U and V
1865418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   planes in their subsampled form.  Thus, we have to override some
1866418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   internal libjpeg parameters to force it to use the "scaled" IDCT
1867418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				   functions on the U and V planes. */
1868418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				compptr->_DCT_scaled_size=dctsize;
1869418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				compptr->MCU_sample_width=tjMCUWidth[jpegSubsamp]*
1870418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC					sf[sfi].num/sf[sfi].denom*
1871418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC					compptr->v_samp_factor/dinfo->max_v_samp_factor;
1872418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC				dinfo->idct->inverse_DCT[i] = dinfo->idct->inverse_DCT[0];
1873418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC			}
18749b28defe6ac85dd8a52479cf276606beae24920eDRC			crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_factor;
18759b28defe6ac85dd8a52479cf276606beae24920eDRC			if(usetmpbuf) yuvptr[i]=tmpbuf[i];
18769b28defe6ac85dd8a52479cf276606beae24920eDRC			else yuvptr[i]=&outbuf[i][crow[i]];
1877842416034561f6d5320165a4fe98825e999a4a37DRC		}
1878f610d61fcc38b36a8a29879e5c053015164242f8DRC		jpeg_read_raw_data(dinfo, yuvptr,
1879418fe286c2fe90dcd3338f1f1d2f221c0e0e2bf3DRC			dinfo->max_v_samp_factor*dinfo->_min_DCT_scaled_size);
18809b28defe6ac85dd8a52479cf276606beae24920eDRC		if(usetmpbuf)
18819e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC		{
18829b28defe6ac85dd8a52479cf276606beae24920eDRC			int j;
1883f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC			for(i=0; i<dinfo->num_components; i++)
18849e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC			{
188540dd3146cde2ba5036fe76a4f09e1125b4592347DRC				for(j=0; j<min(th[i], ph[i]-crow[i]); j++)
1886f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC				{
188740dd3146cde2ba5036fe76a4f09e1125b4592347DRC					memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j], pw[i]);
1888f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC				}
18899e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC			}
18909e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC		}
18919e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC	}
18929b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_finish_decompress(dinfo);
18932e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
189491e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC	bailout:
18959b28defe6ac85dd8a52479cf276606beae24920eDRC	if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
18969e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC	for(i=0; i<MAX_COMPONENTS; i++)
1897f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC	{
1898f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC		if(tmpbuf[i]) free(tmpbuf[i]);
18999e17f7d9bcfe77c82550d90ea674b795baef5a5aDRC		if(outbuf[i]) free(outbuf[i]);
1900f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC	}
1901f9cf5c799d76cfb1652b75b10c8a51e28546170dDRC	if(_tmpbuf) free(_tmpbuf);
19021f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(this->jerr.warning) retval=-1;
190391e86ba6cf9bf73bfd0a09d75b3a3845d64d4046DRC	return retval;
19042e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC}
19052e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
1906aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRCDLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle,
19076eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
1908aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	int width, int pad, int height, int flags)
1909aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC{
1910aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	unsigned char *dstPlanes[3];
191140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int pw0, ph0, strides[3], retval=-1, jpegSubsamp=-1;
1912aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	int i, jpegwidth, jpegheight, scaledw, scaledh;
1913aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1914aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	getdinstance(handle);
1915aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1916aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pad<1
1917aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		|| !isPow2(pad) || height<0)
1918aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUV2(): Invalid argument");
1919aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
19206eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	if(setjmp(this->jerr.setjmp_buffer))
19216eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	{
19226eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		/* If we get here, the JPEG code has signaled an error. */
19236eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis		return -1;
19246eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	}
19256eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis
1926aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
1927aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	jpeg_read_header(dinfo, TRUE);
1928aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	jpegSubsamp=getSubsamp(dinfo);
1929aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(jpegSubsamp<0)
1930aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUV2(): Could not determine subsampling type for JPEG image");
1931aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1932aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	jpegwidth=dinfo->image_width;  jpegheight=dinfo->image_height;
1933aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(width==0) width=jpegwidth;
1934aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	if(height==0) height=jpegheight;
1935aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1936aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	for(i=0; i<NUMSF; i++)
1937aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	{
1938aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		scaledw=TJSCALED(jpegwidth, sf[i]);
1939aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		scaledh=TJSCALED(jpegheight, sf[i]);
1940aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		if(scaledw<=width && scaledh<=height)
1941aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC			break;
1942aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	}
194358ae401e503ac61babb9d66be8fc06bfb0445dbfDRC	if(i>=NUMSF)
1944aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		_throw("tjDecompressToYUV2(): Could not scale down to desired image dimensions");
1945aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
194640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	pw0=tjPlaneWidth(0, width, jpegSubsamp);
194740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	ph0=tjPlaneHeight(0, height, jpegSubsamp);
1948aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	dstPlanes[0]=dstBuf;
194940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	strides[0]=PAD(pw0, pad);
195040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(jpegSubsamp==TJSAMP_GRAY)
195140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
195240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		strides[1]=strides[2]=0;
195340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes[1]=dstPlanes[2]=NULL;
195440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
195540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	else
195640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
195740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int pw1=tjPlaneWidth(1, width, jpegSubsamp);
195840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int ph1=tjPlaneHeight(1, height, jpegSubsamp);
195940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		strides[1]=strides[2]=PAD(pw1, pad);
196040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes[1]=dstPlanes[0]+strides[0]*ph0;
196140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes[2]=dstPlanes[1]+strides[1]*ph1;
196240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
1963aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1964aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	this->headerRead=1;
1965aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	return tjDecompressToYUVPlanes(handle, jpegBuf, jpegSize, dstPlanes, width,
1966aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC		strides, height, flags);
1967aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1968aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	bailout:
1969aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC	return retval;
1970aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1971aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC}
1972aecea388c7b3c22cb2ed1747acbcaefb8fd8e9a8DRC
1973f610d61fcc38b36a8a29879e5c053015164242f8DRCDLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
1974f610d61fcc38b36a8a29879e5c053015164242f8DRC	unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
1975f610d61fcc38b36a8a29879e5c053015164242f8DRC	int flags)
1976f610d61fcc38b36a8a29879e5c053015164242f8DRC{
1977f610d61fcc38b36a8a29879e5c053015164242f8DRC	return tjDecompressToYUV2(handle, jpegBuf, jpegSize, dstBuf, 0, 4, 0, flags);
1978f610d61fcc38b36a8a29879e5c053015164242f8DRC}
1979f610d61fcc38b36a8a29879e5c053015164242f8DRC
19802e7b76b28c0a872ae6ca002fd32bbba0769f990eDRC
19819b28defe6ac85dd8a52479cf276606beae24920eDRC/* Transformer */
1982890f1e0413b54c40b663208779d4ea9dae20eaefDRC
1983890f1e0413b54c40b663208779d4ea9dae20eaefDRCDLLEXPORT tjhandle DLLCALL tjInitTransform(void)
1984890f1e0413b54c40b663208779d4ea9dae20eaefDRC{
19859b28defe6ac85dd8a52479cf276606beae24920eDRC	tjinstance *this=NULL;  tjhandle handle=NULL;
19869b28defe6ac85dd8a52479cf276606beae24920eDRC	if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL)
1987da5220acdd525242bff4e40b1d90324ebb889825DRC	{
1988007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		snprintf(errStr, JMSG_LENGTH_MAX,
1989007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC			"tjInitTransform(): Memory allocation failure");
1990da5220acdd525242bff4e40b1d90324ebb889825DRC		return NULL;
1991da5220acdd525242bff4e40b1d90324ebb889825DRC	}
1992007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC	MEMZERO(this, sizeof(tjinstance));
19939b28defe6ac85dd8a52479cf276606beae24920eDRC	handle=_tjInitCompress(this);
19949b28defe6ac85dd8a52479cf276606beae24920eDRC	if(!handle) return NULL;
19959b28defe6ac85dd8a52479cf276606beae24920eDRC	handle=_tjInitDecompress(this);
19969b28defe6ac85dd8a52479cf276606beae24920eDRC	return handle;
1997890f1e0413b54c40b663208779d4ea9dae20eaefDRC}
1998890f1e0413b54c40b663208779d4ea9dae20eaefDRC
1999890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20006eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex NaidisDLLEXPORT int DLLCALL tjTransform(tjhandle handle,
20016eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	const unsigned char *jpegBuf, unsigned long jpegSize, int n,
20026eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis	unsigned char **dstBufs, unsigned long *dstSizes, tjtransform *t, int flags)
2003890f1e0413b54c40b663208779d4ea9dae20eaefDRC{
20040a325197dedd2eede99731c68ae0e0a145473f64DRC	jpeg_transform_info *xinfo=NULL;
2005890f1e0413b54c40b663208779d4ea9dae20eaefDRC	jvirt_barray_ptr *srccoefs, *dstcoefs;
20069b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	int retval=0, i, jpegSubsamp;
2007890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20089b28defe6ac85dd8a52479cf276606beae24920eDRC	getinstance(handle);
20099b28defe6ac85dd8a52479cf276606beae24920eDRC	if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0)
2010007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("tjTransform(): Instance has not been initialized for transformation");
2011890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20129b28defe6ac85dd8a52479cf276606beae24920eDRC	if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NULL
20130a325197dedd2eede99731c68ae0e0a145473f64DRC		|| t==NULL || flags<0)
20149b28defe6ac85dd8a52479cf276606beae24920eDRC		_throw("tjTransform(): Invalid argument");
2015890f1e0413b54c40b663208779d4ea9dae20eaefDRC
2016bec45b162bb77a57c147a9c44113af1968a79be4DRC	if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
2017bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
2018bec45b162bb77a57c147a9c44113af1968a79be4DRC	else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
2019890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20209b28defe6ac85dd8a52479cf276606beae24920eDRC	if(setjmp(this->jerr.setjmp_buffer))
20219b28defe6ac85dd8a52479cf276606beae24920eDRC	{
20229b28defe6ac85dd8a52479cf276606beae24920eDRC		/* If we get here, the JPEG code has signaled an error. */
2023890f1e0413b54c40b663208779d4ea9dae20eaefDRC		retval=-1;
2024890f1e0413b54c40b663208779d4ea9dae20eaefDRC		goto bailout;
2025890f1e0413b54c40b663208779d4ea9dae20eaefDRC	}
2026890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20279b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
2028890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20290a325197dedd2eede99731c68ae0e0a145473f64DRC	if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n))
20300a325197dedd2eede99731c68ae0e0a145473f64DRC		==NULL)
2031007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC		_throw("tjTransform(): Memory allocation failure");
2032007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC	MEMZERO(xinfo, sizeof(jpeg_transform_info)*n);
2033890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20340a325197dedd2eede99731c68ae0e0a145473f64DRC	for(i=0; i<n; i++)
2035890f1e0413b54c40b663208779d4ea9dae20eaefDRC	{
20360a325197dedd2eede99731c68ae0e0a145473f64DRC		xinfo[i].transform=xformtypes[t[i].op];
203725b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		xinfo[i].perfect=(t[i].options&TJXOPT_PERFECT)? 1:0;
203825b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		xinfo[i].trim=(t[i].options&TJXOPT_TRIM)? 1:0;
203925b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		xinfo[i].force_grayscale=(t[i].options&TJXOPT_GRAY)? 1:0;
204025b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		xinfo[i].crop=(t[i].options&TJXOPT_CROP)? 1:0;
204125b995ad4dd93d7f0dd2593fac10b8cb42c86209DRC		if(n!=1 && t[i].op==TJXOP_HFLIP) xinfo[i].slow_hflip=1;
2042ba5ea5143e48b71234414139e3b4cb244599e875DRC		else xinfo[i].slow_hflip=0;
20430a325197dedd2eede99731c68ae0e0a145473f64DRC
20440a325197dedd2eede99731c68ae0e0a145473f64DRC		if(xinfo[i].crop)
2045890f1e0413b54c40b663208779d4ea9dae20eaefDRC		{
20460a325197dedd2eede99731c68ae0e0a145473f64DRC			xinfo[i].crop_xoffset=t[i].r.x;  xinfo[i].crop_xoffset_set=JCROP_POS;
20470a325197dedd2eede99731c68ae0e0a145473f64DRC			xinfo[i].crop_yoffset=t[i].r.y;  xinfo[i].crop_yoffset_set=JCROP_POS;
20480a325197dedd2eede99731c68ae0e0a145473f64DRC			if(t[i].r.w!=0)
20490a325197dedd2eede99731c68ae0e0a145473f64DRC			{
20500a325197dedd2eede99731c68ae0e0a145473f64DRC				xinfo[i].crop_width=t[i].r.w;  xinfo[i].crop_width_set=JCROP_POS;
20510a325197dedd2eede99731c68ae0e0a145473f64DRC			}
2052d932e582178e2352b7e1da5622183e3e6082f5b3DRC			else xinfo[i].crop_width=JCROP_UNSET;
20530a325197dedd2eede99731c68ae0e0a145473f64DRC			if(t[i].r.h!=0)
20540a325197dedd2eede99731c68ae0e0a145473f64DRC			{
20550a325197dedd2eede99731c68ae0e0a145473f64DRC				xinfo[i].crop_height=t[i].r.h;  xinfo[i].crop_height_set=JCROP_POS;
20560a325197dedd2eede99731c68ae0e0a145473f64DRC			}
2057d932e582178e2352b7e1da5622183e3e6082f5b3DRC			else xinfo[i].crop_height=JCROP_UNSET;
2058890f1e0413b54c40b663208779d4ea9dae20eaefDRC		}
2059890f1e0413b54c40b663208779d4ea9dae20eaefDRC	}
2060890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20619b28defe6ac85dd8a52479cf276606beae24920eDRC	jcopy_markers_setup(dinfo, JCOPYOPT_ALL);
20629b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_read_header(dinfo, TRUE);
20639b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	jpegSubsamp=getSubsamp(dinfo);
20649b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	if(jpegSubsamp<0)
20659b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC		_throw("tjTransform(): Could not determine subsampling type for JPEG image");
2066890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20670a325197dedd2eede99731c68ae0e0a145473f64DRC	for(i=0; i<n; i++)
2068890f1e0413b54c40b663208779d4ea9dae20eaefDRC	{
20699b28defe6ac85dd8a52479cf276606beae24920eDRC		if(!jtransform_request_workspace(dinfo, &xinfo[i]))
2070007a42cda4d3b6c4ec614aef0d46536ef2dfb8d4DRC			_throw("tjTransform(): Transform is not perfect");
20710a325197dedd2eede99731c68ae0e0a145473f64DRC
20720a325197dedd2eede99731c68ae0e0a145473f64DRC		if(xinfo[i].crop)
20730a325197dedd2eede99731c68ae0e0a145473f64DRC		{
20740a325197dedd2eede99731c68ae0e0a145473f64DRC			if((t[i].r.x%xinfo[i].iMCU_sample_width)!=0
20750a325197dedd2eede99731c68ae0e0a145473f64DRC				|| (t[i].r.y%xinfo[i].iMCU_sample_height)!=0)
20760a325197dedd2eede99731c68ae0e0a145473f64DRC			{
20779b28defe6ac85dd8a52479cf276606beae24920eDRC				snprintf(errStr, JMSG_LENGTH_MAX,
20780a325197dedd2eede99731c68ae0e0a145473f64DRC					"To crop this JPEG image, x must be a multiple of %d\n"
20790a325197dedd2eede99731c68ae0e0a145473f64DRC					"and y must be a multiple of %d.\n",
20800a325197dedd2eede99731c68ae0e0a145473f64DRC					xinfo[i].iMCU_sample_width, xinfo[i].iMCU_sample_height);
20810a325197dedd2eede99731c68ae0e0a145473f64DRC				retval=-1;  goto bailout;
20820a325197dedd2eede99731c68ae0e0a145473f64DRC			}
20830a325197dedd2eede99731c68ae0e0a145473f64DRC		}
2084890f1e0413b54c40b663208779d4ea9dae20eaefDRC	}
2085890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20869b28defe6ac85dd8a52479cf276606beae24920eDRC	srccoefs=jpeg_read_coefficients(dinfo);
2087890f1e0413b54c40b663208779d4ea9dae20eaefDRC
20880a325197dedd2eede99731c68ae0e0a145473f64DRC	for(i=0; i<n; i++)
2089890f1e0413b54c40b663208779d4ea9dae20eaefDRC	{
2090ff78e37595c8462f64fd100f928aa1d08539527eDRC		int w, h, alloc=1;
20910a325197dedd2eede99731c68ae0e0a145473f64DRC		if(!xinfo[i].crop)
2092890f1e0413b54c40b663208779d4ea9dae20eaefDRC		{
20939b28defe6ac85dd8a52479cf276606beae24920eDRC			w=dinfo->image_width;  h=dinfo->image_height;
2094890f1e0413b54c40b663208779d4ea9dae20eaefDRC		}
20950a325197dedd2eede99731c68ae0e0a145473f64DRC		else
20960a325197dedd2eede99731c68ae0e0a145473f64DRC		{
20970a325197dedd2eede99731c68ae0e0a145473f64DRC			w=xinfo[i].crop_width;  h=xinfo[i].crop_height;
20980a325197dedd2eede99731c68ae0e0a145473f64DRC		}
2099ff78e37595c8462f64fd100f928aa1d08539527eDRC		if(flags&TJFLAG_NOREALLOC)
2100ff78e37595c8462f64fd100f928aa1d08539527eDRC		{
21019b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC			alloc=0;  dstSizes[i]=tjBufSize(w, h, jpegSubsamp);
2102ff78e37595c8462f64fd100f928aa1d08539527eDRC		}
21037bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		if(!(t[i].options&TJXOPT_NOOUTPUT))
21047bf04d399ebf9a3b39a6d5b5639d895df618353dDRC			jpeg_mem_dest_tj(cinfo, &dstBufs[i], &dstSizes[i], alloc);
21059b28defe6ac85dd8a52479cf276606beae24920eDRC		jpeg_copy_critical_parameters(dinfo, cinfo);
21069b28defe6ac85dd8a52479cf276606beae24920eDRC		dstcoefs=jtransform_adjust_parameters(dinfo, cinfo, srccoefs,
21070a325197dedd2eede99731c68ae0e0a145473f64DRC			&xinfo[i]);
21087bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		if(!(t[i].options&TJXOPT_NOOUTPUT))
21097bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		{
21107bf04d399ebf9a3b39a6d5b5639d895df618353dDRC			jpeg_write_coefficients(cinfo, dstcoefs);
21117bf04d399ebf9a3b39a6d5b5639d895df618353dDRC			jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL);
21127bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		}
21137bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		else jinit_c_master_control(cinfo, TRUE);
21149b28defe6ac85dd8a52479cf276606beae24920eDRC		jtransform_execute_transformation(dinfo, cinfo, srccoefs,
21150a325197dedd2eede99731c68ae0e0a145473f64DRC			&xinfo[i]);
21167bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		if(t[i].customFilter)
21177bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		{
2118efe28cec4b29b5a7357d9cd1c30a066486d19b12DRC			int ci, y;  JDIMENSION by;
21197bf04d399ebf9a3b39a6d5b5639d895df618353dDRC			for(ci=0; ci<cinfo->num_components; ci++)
21207bf04d399ebf9a3b39a6d5b5639d895df618353dDRC			{
21217bf04d399ebf9a3b39a6d5b5639d895df618353dDRC				jpeg_component_info *compptr=&cinfo->comp_info[ci];
21227bf04d399ebf9a3b39a6d5b5639d895df618353dDRC				tjregion arrayRegion={0, 0, compptr->width_in_blocks*DCTSIZE,
21237bf04d399ebf9a3b39a6d5b5639d895df618353dDRC					DCTSIZE};
21247bf04d399ebf9a3b39a6d5b5639d895df618353dDRC				tjregion planeRegion={0, 0, compptr->width_in_blocks*DCTSIZE,
21257bf04d399ebf9a3b39a6d5b5639d895df618353dDRC					compptr->height_in_blocks*DCTSIZE};
21267bf04d399ebf9a3b39a6d5b5639d895df618353dDRC				for(by=0; by<compptr->height_in_blocks; by+=compptr->v_samp_factor)
21277bf04d399ebf9a3b39a6d5b5639d895df618353dDRC				{
21287bf04d399ebf9a3b39a6d5b5639d895df618353dDRC					JBLOCKARRAY barray=(dinfo->mem->access_virt_barray)
21297bf04d399ebf9a3b39a6d5b5639d895df618353dDRC						((j_common_ptr)dinfo, dstcoefs[ci], by, compptr->v_samp_factor,
21307bf04d399ebf9a3b39a6d5b5639d895df618353dDRC						TRUE);
21317bf04d399ebf9a3b39a6d5b5639d895df618353dDRC					for(y=0; y<compptr->v_samp_factor; y++)
21327bf04d399ebf9a3b39a6d5b5639d895df618353dDRC					{
21337bf04d399ebf9a3b39a6d5b5639d895df618353dDRC						if(t[i].customFilter(barray[y][0], arrayRegion, planeRegion,
2134f5467110763f7a44ca8baf1c035eb39a68c913c6DRC							ci, i, &t[i])==-1)
21357bf04d399ebf9a3b39a6d5b5639d895df618353dDRC							_throw("tjTransform(): Error in custom filter");
21367bf04d399ebf9a3b39a6d5b5639d895df618353dDRC						arrayRegion.y+=DCTSIZE;
21377bf04d399ebf9a3b39a6d5b5639d895df618353dDRC					}
21387bf04d399ebf9a3b39a6d5b5639d895df618353dDRC				}
21397bf04d399ebf9a3b39a6d5b5639d895df618353dDRC			}
21407bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		}
21417bf04d399ebf9a3b39a6d5b5639d895df618353dDRC		if(!(t[i].options&TJXOPT_NOOUTPUT)) jpeg_finish_compress(cinfo);
2142890f1e0413b54c40b663208779d4ea9dae20eaefDRC	}
2143890f1e0413b54c40b663208779d4ea9dae20eaefDRC
21449b28defe6ac85dd8a52479cf276606beae24920eDRC	jpeg_finish_decompress(dinfo);
2145890f1e0413b54c40b663208779d4ea9dae20eaefDRC
2146890f1e0413b54c40b663208779d4ea9dae20eaefDRC	bailout:
21479b28defe6ac85dd8a52479cf276606beae24920eDRC	if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
21489b28defe6ac85dd8a52479cf276606beae24920eDRC	if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
21490a325197dedd2eede99731c68ae0e0a145473f64DRC	if(xinfo) free(xinfo);
21501f79c7c8c8c5e993042ea816e1dd161fb69061a3DRC	if(this->jerr.warning) retval=-1;
2151890f1e0413b54c40b663208779d4ea9dae20eaefDRC	return retval;
2152890f1e0413b54c40b663208779d4ea9dae20eaefDRC}
2153