1f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC/*
2fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC * Copyright (C)2011-2014 D. R. Commander.  All Rights Reserved.
3f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC *
4f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * Redistribution and use in source and binary forms, with or without
5f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * modification, are permitted provided that the following conditions are met:
6f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC *
7f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * - Redistributions of source code must retain the above copyright notice,
8f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC *   this list of conditions and the following disclaimer.
9f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * - Redistributions in binary form must reproduce the above copyright notice,
10f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC *   this list of conditions and the following disclaimer in the documentation
11f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC *   and/or other materials provided with the distribution.
12f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * - Neither the name of the libjpeg-turbo Project nor the names of its
13f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC *   contributors may be used to endorse or promote products derived from this
14f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC *   software without specific prior written permission.
15f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC *
16f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
17f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC * POSSIBILITY OF SUCH DAMAGE.
27f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC */
28f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
29e85730157e0b4fb12b0500d1a41b3e370874a74dDRC#include <stdlib.h>
30e85730157e0b4fb12b0500d1a41b3e370874a74dDRC#include <string.h>
31f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC#include "turbojpeg.h"
32bc2e66cb433c04514f61d9b58be23e667bd8f8d8DRC#ifdef WIN32
33bc2e66cb433c04514f61d9b58be23e667bd8f8d8DRC#include "tjutil.h"
34bc2e66cb433c04514f61d9b58be23e667bd8f8d8DRC#endif
35f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC#include <jni.h>
36c5a419970eb91c85844002901210484b29e25fb1DRC#include "java/org_libjpegturbo_turbojpeg_TJCompressor.h"
37c5a419970eb91c85844002901210484b29e25fb1DRC#include "java/org_libjpegturbo_turbojpeg_TJDecompressor.h"
38c5a419970eb91c85844002901210484b29e25fb1DRC#include "java/org_libjpegturbo_turbojpeg_TJ.h"
39f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
4040dd3146cde2ba5036fe76a4f09e1125b4592347DRC#define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
4140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
42f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC#define _throw(msg) {  \
43f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	jclass _exccls=(*env)->FindClass(env, "java/lang/Exception");  \
44f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	if(!_exccls) goto bailout;  \
45f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	(*env)->ThrowNew(env, _exccls, msg);  \
46f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	goto bailout;  \
47f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
48f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
49fac3bea8dae8664110951427434d94bcd139d17bDRC#define bailif0(f) {if(!(f)) {  \
50fac3bea8dae8664110951427434d94bcd139d17bDRC	char temps[80];  \
51fac3bea8dae8664110951427434d94bcd139d17bDRC	snprintf(temps, 80, "Unexpected NULL condition in line %d", __LINE__);  \
52fac3bea8dae8664110951427434d94bcd139d17bDRC	_throw(temps);  \
53fac3bea8dae8664110951427434d94bcd139d17bDRC}}
54f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
553bad53fa04699ce22a7d2ba6763d7a357ef30540DRC#define gethandle()  \
56f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	jclass _cls=(*env)->GetObjectClass(env, obj);  \
57f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	jfieldID _fid;  \
58f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	if(!_cls) goto bailout;  \
59f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "handle", "J"));  \
6046a0392cf37a58183a7aa3852e51b57777ba002cDRC	handle=(tjhandle)(size_t)(*env)->GetLongField(env, obj, _fid);  \
61f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
62bdb36e1a140cd0c3be8158263afe1d02793117ceDRC#ifdef _WIN32
63bdb36e1a140cd0c3be8158263afe1d02793117ceDRC#define setenv(envvar, value, dummy) _putenv_s(envvar, value)
64bdb36e1a140cd0c3be8158263afe1d02793117ceDRC#endif
65bdb36e1a140cd0c3be8158263afe1d02793117ceDRC
660713c1bb542672257c08782a5a930a577eb20167DRC#define prop2env(property, envvar)  \
670713c1bb542672257c08782a5a930a577eb20167DRC{  \
680713c1bb542672257c08782a5a930a577eb20167DRC	if((jName=(*env)->NewStringUTF(env, property))!=NULL  \
690713c1bb542672257c08782a5a930a577eb20167DRC		&& (jValue=(*env)->CallStaticObjectMethod(env, cls, mid, jName))!=NULL)  \
700713c1bb542672257c08782a5a930a577eb20167DRC	{  \
710713c1bb542672257c08782a5a930a577eb20167DRC		if((value=(*env)->GetStringUTFChars(env, jValue, 0))!=NULL)  \
720713c1bb542672257c08782a5a930a577eb20167DRC		{  \
730713c1bb542672257c08782a5a930a577eb20167DRC			setenv(envvar, value, 1);  \
740713c1bb542672257c08782a5a930a577eb20167DRC			(*env)->ReleaseStringUTFChars(env, jValue, value);  \
750713c1bb542672257c08782a5a930a577eb20167DRC		}  \
760713c1bb542672257c08782a5a930a577eb20167DRC	}  \
770713c1bb542672257c08782a5a930a577eb20167DRC}
780713c1bb542672257c08782a5a930a577eb20167DRC
790713c1bb542672257c08782a5a930a577eb20167DRCint ProcessSystemProperties(JNIEnv *env)
800713c1bb542672257c08782a5a930a577eb20167DRC{
810713c1bb542672257c08782a5a930a577eb20167DRC	jclass cls;  jmethodID mid;
820713c1bb542672257c08782a5a930a577eb20167DRC	jstring jName, jValue;
830713c1bb542672257c08782a5a930a577eb20167DRC	const char *value;
840713c1bb542672257c08782a5a930a577eb20167DRC
850713c1bb542672257c08782a5a930a577eb20167DRC	bailif0(cls=(*env)->FindClass(env, "java/lang/System"));
860713c1bb542672257c08782a5a930a577eb20167DRC	bailif0(mid=(*env)->GetStaticMethodID(env, cls, "getProperty",
870713c1bb542672257c08782a5a930a577eb20167DRC		"(Ljava/lang/String;)Ljava/lang/String;"));
880713c1bb542672257c08782a5a930a577eb20167DRC
890713c1bb542672257c08782a5a930a577eb20167DRC	prop2env("turbojpeg.optimize", "TJ_OPTIMIZE");
900713c1bb542672257c08782a5a930a577eb20167DRC	prop2env("turbojpeg.arithmetic", "TJ_ARITHMETIC");
910713c1bb542672257c08782a5a930a577eb20167DRC	prop2env("turbojpeg.restart", "TJ_RESTART");
920713c1bb542672257c08782a5a930a577eb20167DRC	prop2env("turbojpeg.progressive", "TJ_PROGRESSIVE");
930713c1bb542672257c08782a5a930a577eb20167DRC	return 0;
940713c1bb542672257c08782a5a930a577eb20167DRC
950713c1bb542672257c08782a5a930a577eb20167DRC	bailout:
960713c1bb542672257c08782a5a930a577eb20167DRC	return -1;
970713c1bb542672257c08782a5a930a577eb20167DRC}
980713c1bb542672257c08782a5a930a577eb20167DRC
99a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJ::bufSize() */
1003bad53fa04699ce22a7d2ba6763d7a357ef30540DRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize
1019b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	(JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp)
102f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC{
1039b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	jint retval=(jint)tjBufSize(width, height, jpegSubsamp);
10436336fcddc4cc9f74988e3f03c4683c88c8fce45DRC	if(retval==-1) _throw(tjGetErrorStr());
10536336fcddc4cc9f74988e3f03c4683c88c8fce45DRC
10636336fcddc4cc9f74988e3f03c4683c88c8fce45DRC	bailout:
10736336fcddc4cc9f74988e3f03c4683c88c8fce45DRC	return retval;
10836336fcddc4cc9f74988e3f03c4683c88c8fce45DRC}
10936336fcddc4cc9f74988e3f03c4683c88c8fce45DRC
110a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.4.x: TJ::bufSizeYUV() */
111fef9852da3a80bfaf84862462609f97d77ad6db7DRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII
112fef9852da3a80bfaf84862462609f97d77ad6db7DRC	(JNIEnv *env, jclass cls, jint width, jint pad, jint height, jint subsamp)
11336336fcddc4cc9f74988e3f03c4683c88c8fce45DRC{
114fef9852da3a80bfaf84862462609f97d77ad6db7DRC	jint retval=(jint)tjBufSizeYUV2(width, pad, height, subsamp);
11536336fcddc4cc9f74988e3f03c4683c88c8fce45DRC	if(retval==-1) _throw(tjGetErrorStr());
11636336fcddc4cc9f74988e3f03c4683c88c8fce45DRC
11736336fcddc4cc9f74988e3f03c4683c88c8fce45DRC	bailout:
11836336fcddc4cc9f74988e3f03c4683c88c8fce45DRC	return retval;
119f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
120f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
121a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJ::bufSizeYUV() */
122fef9852da3a80bfaf84862462609f97d77ad6db7DRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__III
123fef9852da3a80bfaf84862462609f97d77ad6db7DRC	(JNIEnv *env, jclass cls, jint width, jint height, jint subsamp)
124fef9852da3a80bfaf84862462609f97d77ad6db7DRC{
125fef9852da3a80bfaf84862462609f97d77ad6db7DRC	return Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII(env, cls, width,
126fef9852da3a80bfaf84862462609f97d77ad6db7DRC		4, height, subsamp);
127fef9852da3a80bfaf84862462609f97d77ad6db7DRC}
128fef9852da3a80bfaf84862462609f97d77ad6db7DRC
12940dd3146cde2ba5036fe76a4f09e1125b4592347DRC/* TurboJPEG 1.4.x: TJ::planeSizeYUV() */
13040dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeSizeYUV__IIIII
13140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jclass cls, jint componentID, jint width, jint stride,
13240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint height, jint subsamp)
13340dd3146cde2ba5036fe76a4f09e1125b4592347DRC{
13440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jint retval=(jint)tjPlaneSizeYUV(componentID, width, stride, height,
13540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		subsamp);
13640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(retval==-1) _throw(tjGetErrorStr());
13740dd3146cde2ba5036fe76a4f09e1125b4592347DRC
13840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailout:
13940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	return retval;
14040dd3146cde2ba5036fe76a4f09e1125b4592347DRC}
14140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
14240dd3146cde2ba5036fe76a4f09e1125b4592347DRC/* TurboJPEG 1.4.x: TJ::planeWidth() */
14340dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeWidth__III
14440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jclass cls, jint componentID, jint width, jint subsamp)
14540dd3146cde2ba5036fe76a4f09e1125b4592347DRC{
14640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jint retval=(jint)tjPlaneWidth(componentID, width, subsamp);
14740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(retval==-1) _throw(tjGetErrorStr());
14840dd3146cde2ba5036fe76a4f09e1125b4592347DRC
14940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailout:
15040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	return retval;
15140dd3146cde2ba5036fe76a4f09e1125b4592347DRC}
15240dd3146cde2ba5036fe76a4f09e1125b4592347DRC
15340dd3146cde2ba5036fe76a4f09e1125b4592347DRC/* TurboJPEG 1.4.x: TJ::planeHeight() */
15440dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeHeight__III
15540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jclass cls, jint componentID, jint height, jint subsamp)
15640dd3146cde2ba5036fe76a4f09e1125b4592347DRC{
15740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jint retval=(jint)tjPlaneHeight(componentID, height, subsamp);
15840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(retval==-1) _throw(tjGetErrorStr());
15940dd3146cde2ba5036fe76a4f09e1125b4592347DRC
16040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailout:
16140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	return retval;
16240dd3146cde2ba5036fe76a4f09e1125b4592347DRC}
16340dd3146cde2ba5036fe76a4f09e1125b4592347DRC
164a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJCompressor::init() */
165c5a419970eb91c85844002901210484b29e25fb1DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
166f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	(JNIEnv *env, jobject obj)
167f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC{
168f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	jclass cls;
169f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	jfieldID fid;
170f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	tjhandle handle;
171f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
1721a3dbe6fba2e05092d64615a1a2625b5a37456ecDRC	if((handle=tjInitCompress())==NULL)
173f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC		_throw(tjGetErrorStr());
174f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
175f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailif0(cls=(*env)->GetObjectClass(env, obj));
176f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
17746a0392cf37a58183a7aa3852e51b57777ba002cDRC	(*env)->SetLongField(env, obj, fid, (size_t)handle);
178f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
179f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailout:
180f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	return;
181f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
182f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
1835d87f6ddff832dd6c47e1f0c55fe9099792cff08DRCstatic jint TJCompressor_compress
184927a10db05d6691c200a6372718f0e6bebadd60cDRC	(JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y,
185927a10db05d6691c200a6372718f0e6bebadd60cDRC		jint width, jint pitch, jint height, jint pf, jbyteArray dst,
186927a10db05d6691c200a6372718f0e6bebadd60cDRC		jint jpegSubsamp, jint jpegQual, jint flags)
187f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC{
1889b28defe6ac85dd8a52479cf276606beae24920eDRC	tjhandle handle=0;
189fac3bea8dae8664110951427434d94bcd139d17bDRC	unsigned long jpegSize=0;
190fac3bea8dae8664110951427434d94bcd139d17bDRC	jsize arraySize=0, actualPitch;
1919b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned char *srcBuf=NULL, *jpegBuf=NULL;
192f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
193f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	gethandle();
194f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
19592549de2c2b139070294aec12ec39b7c86a56b52DRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
1966acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC		|| pitch<0)
1974f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw("Invalid argument in compress()");
1989b28defe6ac85dd8a52479cf276606beae24920eDRC	if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
1999b28defe6ac85dd8a52479cf276606beae24920eDRC		_throw("Mismatch between Java and C API");
2004f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
201fac3bea8dae8664110951427434d94bcd139d17bDRC	actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
202927a10db05d6691c200a6372718f0e6bebadd60cDRC	arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
203927a10db05d6691c200a6372718f0e6bebadd60cDRC	if((*env)->GetArrayLength(env, src)*srcElementSize<arraySize)
2046acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC		_throw("Source buffer is not large enough");
2059b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	jpegSize=tjBufSize(width, height, jpegSubsamp);
2069b28defe6ac85dd8a52479cf276606beae24920eDRC	if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
2076acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC		_throw("Destination buffer is not large enough");
2086acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC
2099b28defe6ac85dd8a52479cf276606beae24920eDRC	bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
2109b28defe6ac85dd8a52479cf276606beae24920eDRC	bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
211f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
2120713c1bb542672257c08782a5a930a577eb20167DRC	if(ProcessSystemProperties(env)<0) goto bailout;
2130713c1bb542672257c08782a5a930a577eb20167DRC
214fac3bea8dae8664110951427434d94bcd139d17bDRC	if(tjCompress2(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]], width,
215fac3bea8dae8664110951427434d94bcd139d17bDRC		pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, jpegQual,
216fac3bea8dae8664110951427434d94bcd139d17bDRC		flags|TJFLAG_NOREALLOC)==-1)
217f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC		_throw(tjGetErrorStr());
218f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
219f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailout:
2209b28defe6ac85dd8a52479cf276606beae24920eDRC	if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
2219b28defe6ac85dd8a52479cf276606beae24920eDRC	if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
2229b28defe6ac85dd8a52479cf276606beae24920eDRC	return (jint)jpegSize;
223f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
224f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
225a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.3.x: TJCompressor::compress() byte source */
226927a10db05d6691c200a6372718f0e6bebadd60cDRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII
227927a10db05d6691c200a6372718f0e6bebadd60cDRC	(JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
228927a10db05d6691c200a6372718f0e6bebadd60cDRC		jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
229927a10db05d6691c200a6372718f0e6bebadd60cDRC		jint jpegQual, jint flags)
230927a10db05d6691c200a6372718f0e6bebadd60cDRC{
231927a10db05d6691c200a6372718f0e6bebadd60cDRC	return TJCompressor_compress(env, obj, src, 1, x, y, width, pitch, height,
232927a10db05d6691c200a6372718f0e6bebadd60cDRC		pf, dst, jpegSubsamp, jpegQual, flags);
233927a10db05d6691c200a6372718f0e6bebadd60cDRC}
234927a10db05d6691c200a6372718f0e6bebadd60cDRC
235a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJCompressor::compress() byte source */
236fac3bea8dae8664110951427434d94bcd139d17bDRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
237fac3bea8dae8664110951427434d94bcd139d17bDRC	(JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
2389b28defe6ac85dd8a52479cf276606beae24920eDRC		jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
2394f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		jint flags)
24084a1bcca6fd0f21091a84f04b820b29012c60857DRC{
241927a10db05d6691c200a6372718f0e6bebadd60cDRC	return TJCompressor_compress(env, obj, src, 1, 0, 0, width, pitch, height,
242927a10db05d6691c200a6372718f0e6bebadd60cDRC		pf, dst, jpegSubsamp, jpegQual, flags);
243fac3bea8dae8664110951427434d94bcd139d17bDRC}
244fac3bea8dae8664110951427434d94bcd139d17bDRC
245a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.3.x: TJCompressor::compress() int source */
246fac3bea8dae8664110951427434d94bcd139d17bDRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII
247fac3bea8dae8664110951427434d94bcd139d17bDRC	(JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
248fac3bea8dae8664110951427434d94bcd139d17bDRC		jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
249fac3bea8dae8664110951427434d94bcd139d17bDRC		jint jpegQual, jint flags)
250fac3bea8dae8664110951427434d94bcd139d17bDRC{
251927a10db05d6691c200a6372718f0e6bebadd60cDRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
2524f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw("Invalid argument in compress()");
2539b28defe6ac85dd8a52479cf276606beae24920eDRC	if(tjPixelSize[pf]!=sizeof(jint))
2544f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw("Pixel format must be 32-bit when compressing from an integer buffer.");
2554f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
256927a10db05d6691c200a6372718f0e6bebadd60cDRC	return TJCompressor_compress(env, obj, src, sizeof(jint), x, y, width,
257927a10db05d6691c200a6372718f0e6bebadd60cDRC		stride*sizeof(jint), height, pf, dst, jpegSubsamp, jpegQual, flags);
25884a1bcca6fd0f21091a84f04b820b29012c60857DRC
25984a1bcca6fd0f21091a84f04b820b29012c60857DRC	bailout:
260927a10db05d6691c200a6372718f0e6bebadd60cDRC	return 0;
26184a1bcca6fd0f21091a84f04b820b29012c60857DRC}
26284a1bcca6fd0f21091a84f04b820b29012c60857DRC
263a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJCompressor::compress() int source */
264fac3bea8dae8664110951427434d94bcd139d17bDRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
265927a10db05d6691c200a6372718f0e6bebadd60cDRC	(JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
266fac3bea8dae8664110951427434d94bcd139d17bDRC		jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
267fac3bea8dae8664110951427434d94bcd139d17bDRC		jint flags)
268fac3bea8dae8664110951427434d94bcd139d17bDRC{
269927a10db05d6691c200a6372718f0e6bebadd60cDRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
270927a10db05d6691c200a6372718f0e6bebadd60cDRC		_throw("Invalid argument in compress()");
271927a10db05d6691c200a6372718f0e6bebadd60cDRC	if(tjPixelSize[pf]!=sizeof(jint))
272927a10db05d6691c200a6372718f0e6bebadd60cDRC		_throw("Pixel format must be 32-bit when compressing from an integer buffer.");
273927a10db05d6691c200a6372718f0e6bebadd60cDRC
274927a10db05d6691c200a6372718f0e6bebadd60cDRC	return TJCompressor_compress(env, obj, src, sizeof(jint), 0, 0, width,
275927a10db05d6691c200a6372718f0e6bebadd60cDRC		stride*sizeof(jint), height, pf, dst, jpegSubsamp, jpegQual, flags);
276927a10db05d6691c200a6372718f0e6bebadd60cDRC
277927a10db05d6691c200a6372718f0e6bebadd60cDRC	bailout:
278927a10db05d6691c200a6372718f0e6bebadd60cDRC	return 0;
279fac3bea8dae8664110951427434d94bcd139d17bDRC}
280fac3bea8dae8664110951427434d94bcd139d17bDRC
281a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.4.x: TJCompressor::compressFromYUV() */
28240dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3_3B_3II_3III_3BII
28340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
28440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint width, jintArray jSrcStrides, jint height, jint subsamp,
28540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jbyteArray dst, jint jpegQual, jint flags)
2861e67274bd7f77f6ace653db7b356ab3f24453c88DRC{
2871e67274bd7f77f6ace653db7b356ab3f24453c88DRC	tjhandle handle=0;
2881e67274bd7f77f6ace653db7b356ab3f24453c88DRC	unsigned long jpegSize=0;
28940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jbyteArray jSrcPlanes[3]={NULL, NULL, NULL};
29040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	unsigned char *srcPlanes[3], *jpegBuf=NULL;
29140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int *srcOffsets=NULL, *srcStrides=NULL;
29240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int nc=(subsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3), i;
2931e67274bd7f77f6ace653db7b356ab3f24453c88DRC
2941e67274bd7f77f6ace653db7b356ab3f24453c88DRC	gethandle();
2951e67274bd7f77f6ace653db7b356ab3f24453c88DRC
29640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(subsamp<0 || subsamp>=org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
29740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Invalid argument in compressFromYUV()");
29840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(org_libjpegturbo_turbojpeg_TJ_NUMSAMP!=TJ_NUMSAMP)
29940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Mismatch between Java and C API");
30040dd3146cde2ba5036fe76a4f09e1125b4592347DRC
30140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, srcobjs)<nc)
30240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Planes array is too small for the subsampling type");
30340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, jSrcOffsets)<nc)
30440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Offsets array is too small for the subsampling type");
30540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, jSrcStrides)<nc)
30640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Strides array is too small for the subsampling type");
30740dd3146cde2ba5036fe76a4f09e1125b4592347DRC
3081e67274bd7f77f6ace653db7b356ab3f24453c88DRC	jpegSize=tjBufSize(width, height, subsamp);
3091e67274bd7f77f6ace653db7b356ab3f24453c88DRC	if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
3101e67274bd7f77f6ace653db7b356ab3f24453c88DRC		_throw("Destination buffer is not large enough");
3111e67274bd7f77f6ace653db7b356ab3f24453c88DRC
31240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(srcOffsets=(*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0));
31340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(srcStrides=(*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0));
31440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
31540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
31640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int planeSize=tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp);
31740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int pw=tjPlaneWidth(i, width, subsamp);
31840dd3146cde2ba5036fe76a4f09e1125b4592347DRC
31940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(planeSize<0 || pw<0)
32040dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw(tjGetErrorStr());
32140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
32240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(srcOffsets[i]<0)
32340dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Invalid argument in compressFromYUV()");
32440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(srcStrides[i]<0 && srcOffsets[i]-planeSize+pw<0)
32540dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Negative plane stride would cause memory to be accessed below plane boundary");
32640dd3146cde2ba5036fe76a4f09e1125b4592347DRC
32740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		bailif0(jSrcPlanes[i]=(*env)->GetObjectArrayElement(env, srcobjs, i));
32840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if((*env)->GetArrayLength(env, jSrcPlanes[i])<srcOffsets[i]+planeSize)
32940dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Source plane is not large enough");
33040dd3146cde2ba5036fe76a4f09e1125b4592347DRC
33140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		bailif0(srcPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i],
33240dd3146cde2ba5036fe76a4f09e1125b4592347DRC			0));
33340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		srcPlanes[i]=&srcPlanes[i][srcOffsets[i]];
33440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
3351e67274bd7f77f6ace653db7b356ab3f24453c88DRC	bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
3361e67274bd7f77f6ace653db7b356ab3f24453c88DRC
3370713c1bb542672257c08782a5a930a577eb20167DRC	if(ProcessSystemProperties(env)<0) goto bailout;
3380713c1bb542672257c08782a5a930a577eb20167DRC
33940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(tjCompressFromYUVPlanes(handle, srcPlanes, width, srcStrides, height,
34040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		subsamp, &jpegBuf, &jpegSize, jpegQual, flags|TJFLAG_NOREALLOC)==-1)
3411e67274bd7f77f6ace653db7b356ab3f24453c88DRC		_throw(tjGetErrorStr());
3421e67274bd7f77f6ace653db7b356ab3f24453c88DRC
3431e67274bd7f77f6ace653db7b356ab3f24453c88DRC	bailout:
3441e67274bd7f77f6ace653db7b356ab3f24453c88DRC	if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
34540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
34640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
34740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(srcPlanes[i] && jSrcPlanes[i])
34840dd3146cde2ba5036fe76a4f09e1125b4592347DRC			(*env)->ReleasePrimitiveArrayCritical(env, jSrcPlanes[i], srcPlanes[i],
34940dd3146cde2ba5036fe76a4f09e1125b4592347DRC				0);
35040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
35140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(srcStrides)
35240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		(*env)->ReleasePrimitiveArrayCritical(env, jSrcStrides, srcStrides, 0);
35340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(srcOffsets)
35440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		(*env)->ReleasePrimitiveArrayCritical(env, jSrcOffsets, srcOffsets, 0);
3551e67274bd7f77f6ace653db7b356ab3f24453c88DRC	return (jint)jpegSize;
3561e67274bd7f77f6ace653db7b356ab3f24453c88DRC}
3571e67274bd7f77f6ace653db7b356ab3f24453c88DRC
3585d87f6ddff832dd6c47e1f0c55fe9099792cff08DRCstatic void TJCompressor_encodeYUV
359927a10db05d6691c200a6372718f0e6bebadd60cDRC	(JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y,
36040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint width, jint pitch, jint height, jint pf, jobjectArray dstobjs,
36140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
3624f1580cc0e7c33385e88bca7fe08602b87d29aebDRC{
3639b28defe6ac85dd8a52479cf276606beae24920eDRC	tjhandle handle=0;
36440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jsize arraySize=0, actualPitch;
36540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jbyteArray jDstPlanes[3]={NULL, NULL, NULL};
36640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	unsigned char *srcBuf=NULL, *dstPlanes[3];
36740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int *dstOffsets=NULL, *dstStrides=NULL;
36840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int nc=(subsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3), i;
3694f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
3704f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	gethandle();
3714f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
37292549de2c2b139070294aec12ec39b7c86a56b52DRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
37340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		|| pitch<0 || subsamp<0 || subsamp>=org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
3744f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw("Invalid argument in encodeYUV()");
37540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF
37640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		|| org_libjpegturbo_turbojpeg_TJ_NUMSAMP!=TJ_NUMSAMP)
3779b28defe6ac85dd8a52479cf276606beae24920eDRC		_throw("Mismatch between Java and C API");
3784f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
37940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, dstobjs)<nc)
38040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Planes array is too small for the subsampling type");
38140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, jDstOffsets)<nc)
38240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Offsets array is too small for the subsampling type");
38340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, jDstStrides)<nc)
38440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Strides array is too small for the subsampling type");
38540dd3146cde2ba5036fe76a4f09e1125b4592347DRC
386fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
387927a10db05d6691c200a6372718f0e6bebadd60cDRC	arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
388927a10db05d6691c200a6372718f0e6bebadd60cDRC	if((*env)->GetArrayLength(env, src)*srcElementSize<arraySize)
3896acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC		_throw("Source buffer is not large enough");
3906acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC
39140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(dstOffsets=(*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0));
39240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(dstStrides=(*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0));
39340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
39440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
39540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int planeSize=tjPlaneSizeYUV(i, width, dstStrides[i], height, subsamp);
39640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int pw=tjPlaneWidth(i, width, subsamp);
39740dd3146cde2ba5036fe76a4f09e1125b4592347DRC
39840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(planeSize<0 || pw<0)
39940dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw(tjGetErrorStr());
40040dd3146cde2ba5036fe76a4f09e1125b4592347DRC
40140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(dstOffsets[i]<0)
40240dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Invalid argument in encodeYUV()");
40340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(dstStrides[i]<0 && dstOffsets[i]-planeSize+pw<0)
40440dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Negative plane stride would cause memory to be accessed below plane boundary");
40540dd3146cde2ba5036fe76a4f09e1125b4592347DRC
40640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		bailif0(jDstPlanes[i]=(*env)->GetObjectArrayElement(env, dstobjs, i));
40740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if((*env)->GetArrayLength(env, jDstPlanes[i])<dstOffsets[i]+planeSize)
40840dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Destination plane is not large enough");
40940dd3146cde2ba5036fe76a4f09e1125b4592347DRC
41040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		bailif0(dstPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i],
41140dd3146cde2ba5036fe76a4f09e1125b4592347DRC			0));
41240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes[i]=&dstPlanes[i][dstOffsets[i]];
41340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
4149b28defe6ac85dd8a52479cf276606beae24920eDRC	bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
4154f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
41640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(tjEncodeYUVPlanes(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]],
41740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		width, pitch, height, pf, dstPlanes, dstStrides, subsamp, flags)==-1)
4184f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw(tjGetErrorStr());
4194f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
4204f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	bailout:
4219b28defe6ac85dd8a52479cf276606beae24920eDRC	if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
42240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
42340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
42440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(dstPlanes[i] && jDstPlanes[i])
42540dd3146cde2ba5036fe76a4f09e1125b4592347DRC			(*env)->ReleasePrimitiveArrayCritical(env, jDstPlanes[i], dstPlanes[i],
42640dd3146cde2ba5036fe76a4f09e1125b4592347DRC				0);
42740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
42840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(dstStrides)
42940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		(*env)->ReleasePrimitiveArrayCritical(env, jDstStrides, dstStrides, 0);
43040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(dstOffsets)
43140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		(*env)->ReleasePrimitiveArrayCritical(env, jDstOffsets, dstOffsets, 0);
4324f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	return;
4334f1580cc0e7c33385e88bca7fe08602b87d29aebDRC}
4344f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
435a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.4.x: TJCompressor::encodeYUV() byte source */
43640dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3_3B_3I_3III
437927a10db05d6691c200a6372718f0e6bebadd60cDRC	(JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
43840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint pitch, jint height, jint pf, jobjectArray dstobjs,
43940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
4404f1580cc0e7c33385e88bca7fe08602b87d29aebDRC{
44140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	TJCompressor_encodeYUV(env, obj, src, 1, x, y, width, pitch, height, pf,
44240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstobjs, jDstOffsets, jDstStrides, subsamp, flags);
443fef9852da3a80bfaf84862462609f97d77ad6db7DRC}
444fef9852da3a80bfaf84862462609f97d77ad6db7DRC
445a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.4.x: TJCompressor::encodeYUV() int source */
44640dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3_3B_3I_3III
447fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	(JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
44840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint stride, jint height, jint pf, jobjectArray dstobjs,
44940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
450fef9852da3a80bfaf84862462609f97d77ad6db7DRC{
451927a10db05d6691c200a6372718f0e6bebadd60cDRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
4521d29c5f97bf5538a771c681ffff91c6fa8709d5cDRC		_throw("Invalid argument in encodeYUV()");
4539b28defe6ac85dd8a52479cf276606beae24920eDRC	if(tjPixelSize[pf]!=sizeof(jint))
4544f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw("Pixel format must be 32-bit when encoding from an integer buffer.");
4554f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
45646a0392cf37a58183a7aa3852e51b57777ba002cDRC	TJCompressor_encodeYUV(env, obj, src, sizeof(jint), x, y, width,
45740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		stride*sizeof(jint), height, pf, dstobjs, jDstOffsets, jDstStrides,
45840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		subsamp, flags);
4594f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
4604f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	bailout:
4614f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	return;
4624f1580cc0e7c33385e88bca7fe08602b87d29aebDRC}
4634f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
46440dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT void JNICALL TJCompressor_encodeYUV_12
46540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint width,
46640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint pitch, jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
46740dd3146cde2ba5036fe76a4f09e1125b4592347DRC{
46840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	tjhandle handle=0;
46940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jsize arraySize=0;
47040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	unsigned char *srcBuf=NULL, *dstBuf=NULL;
47140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
47240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	gethandle();
47340dd3146cde2ba5036fe76a4f09e1125b4592347DRC
47440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
47540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		|| pitch<0)
47640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Invalid argument in encodeYUV()");
47740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
47840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Mismatch between Java and C API");
47940dd3146cde2ba5036fe76a4f09e1125b4592347DRC
48040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	arraySize=(pitch==0)? width*tjPixelSize[pf]*height:pitch*height;
48140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, src)*srcElementSize<arraySize)
48240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Source buffer is not large enough");
48340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, dst)
48440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		<(jsize)tjBufSizeYUV(width, height, subsamp))
48540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Destination buffer is not large enough");
48640dd3146cde2ba5036fe76a4f09e1125b4592347DRC
48740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
48840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
48940dd3146cde2ba5036fe76a4f09e1125b4592347DRC
49040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(tjEncodeYUV2(handle, srcBuf, width, pitch, height, pf, dstBuf, subsamp,
49140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		flags)==-1)
49240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw(tjGetErrorStr());
49340dd3146cde2ba5036fe76a4f09e1125b4592347DRC
49440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailout:
49540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
49640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
49740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	return;
49840dd3146cde2ba5036fe76a4f09e1125b4592347DRC}
49940dd3146cde2ba5036fe76a4f09e1125b4592347DRC
50040dd3146cde2ba5036fe76a4f09e1125b4592347DRC/* TurboJPEG 1.2.x: TJCompressor::encodeYUV() byte source */
50140dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
50240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
50340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
50440dd3146cde2ba5036fe76a4f09e1125b4592347DRC{
50540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	TJCompressor_encodeYUV_12(env, obj, src, 1, width, pitch, height, pf, dst,
50640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		subsamp, flags);
50740dd3146cde2ba5036fe76a4f09e1125b4592347DRC}
50840dd3146cde2ba5036fe76a4f09e1125b4592347DRC
509a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJCompressor::encodeYUV() int source */
510fef9852da3a80bfaf84862462609f97d77ad6db7DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
511927a10db05d6691c200a6372718f0e6bebadd60cDRC	(JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
512fef9852da3a80bfaf84862462609f97d77ad6db7DRC		jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
513fef9852da3a80bfaf84862462609f97d77ad6db7DRC{
514927a10db05d6691c200a6372718f0e6bebadd60cDRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
515927a10db05d6691c200a6372718f0e6bebadd60cDRC		_throw("Invalid argument in encodeYUV()");
516927a10db05d6691c200a6372718f0e6bebadd60cDRC	if(tjPixelSize[pf]!=sizeof(jint))
517927a10db05d6691c200a6372718f0e6bebadd60cDRC		_throw("Pixel format must be 32-bit when encoding from an integer buffer.");
518927a10db05d6691c200a6372718f0e6bebadd60cDRC
51940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	TJCompressor_encodeYUV_12(env, obj, src, sizeof(jint), width,
52040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		stride*sizeof(jint), height, pf, dst, subsamp, flags);
521927a10db05d6691c200a6372718f0e6bebadd60cDRC
522927a10db05d6691c200a6372718f0e6bebadd60cDRC	bailout:
523927a10db05d6691c200a6372718f0e6bebadd60cDRC	return;
524fef9852da3a80bfaf84862462609f97d77ad6db7DRC}
525fef9852da3a80bfaf84862462609f97d77ad6db7DRC
526a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJCompressor::destroy() */
527c5a419970eb91c85844002901210484b29e25fb1DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
528f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	(JNIEnv *env, jobject obj)
529f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC{
530f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	tjhandle handle=0;
531f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
532f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	gethandle();
533f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
534f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	if(tjDestroy(handle)==-1) _throw(tjGetErrorStr());
5353bad53fa04699ce22a7d2ba6763d7a357ef30540DRC	(*env)->SetLongField(env, obj, _fid, 0);
536f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
537f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailout:
538f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	return;
539f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
540f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
541a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJDecompressor::init() */
542c5a419970eb91c85844002901210484b29e25fb1DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init
543f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	(JNIEnv *env, jobject obj)
544f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC{
545f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	jclass cls;
546f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	jfieldID fid;
547f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	tjhandle handle;
548f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
5491a3dbe6fba2e05092d64615a1a2625b5a37456ecDRC	if((handle=tjInitDecompress())==NULL) _throw(tjGetErrorStr());
550f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
551f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailif0(cls=(*env)->GetObjectClass(env, obj));
552f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
55346a0392cf37a58183a7aa3852e51b57777ba002cDRC	(*env)->SetLongField(env, obj, fid, (size_t)handle);
554f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
555f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailout:
556f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	return;
557f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
558f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
559a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJDecompressor::getScalingFactors() */
560109a578e89ea8cd2c39d50b012698148dd11dedbDRCJNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors
561109a578e89ea8cd2c39d50b012698148dd11dedbDRC	(JNIEnv *env, jclass cls)
56236336fcddc4cc9f74988e3f03c4683c88c8fce45DRC{
563b7c8c86d6a2fca5733a8e94c8fd662d4d99523e0DRC	jclass sfcls=NULL;  jfieldID fid=0;
564109a578e89ea8cd2c39d50b012698148dd11dedbDRC	tjscalingfactor *sf=NULL;  int n=0, i;
565109a578e89ea8cd2c39d50b012698148dd11dedbDRC	jobject sfobj=NULL;
566109a578e89ea8cd2c39d50b012698148dd11dedbDRC	jobjectArray sfjava=NULL;
567109a578e89ea8cd2c39d50b012698148dd11dedbDRC
568109a578e89ea8cd2c39d50b012698148dd11dedbDRC	if((sf=tjGetScalingFactors(&n))==NULL || n==0)
56936336fcddc4cc9f74988e3f03c4683c88c8fce45DRC		_throw(tjGetErrorStr());
57036336fcddc4cc9f74988e3f03c4683c88c8fce45DRC
571b2f9415a6365b8eb412a5b6159be3cc0f875325fDRC	bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor"));
572109a578e89ea8cd2c39d50b012698148dd11dedbDRC	bailif0(sfjava=(jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0));
57336336fcddc4cc9f74988e3f03c4683c88c8fce45DRC
574109a578e89ea8cd2c39d50b012698148dd11dedbDRC	for(i=0; i<n; i++)
575109a578e89ea8cd2c39d50b012698148dd11dedbDRC	{
576109a578e89ea8cd2c39d50b012698148dd11dedbDRC		bailif0(sfobj=(*env)->AllocObject(env, sfcls));
577109a578e89ea8cd2c39d50b012698148dd11dedbDRC		bailif0(fid=(*env)->GetFieldID(env, sfcls, "num", "I"));
578109a578e89ea8cd2c39d50b012698148dd11dedbDRC		(*env)->SetIntField(env, sfobj, fid, sf[i].num);
579109a578e89ea8cd2c39d50b012698148dd11dedbDRC		bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I"));
580109a578e89ea8cd2c39d50b012698148dd11dedbDRC		(*env)->SetIntField(env, sfobj, fid, sf[i].denom);
581109a578e89ea8cd2c39d50b012698148dd11dedbDRC		(*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
582109a578e89ea8cd2c39d50b012698148dd11dedbDRC	}
58336336fcddc4cc9f74988e3f03c4683c88c8fce45DRC
58436336fcddc4cc9f74988e3f03c4683c88c8fce45DRC	bailout:
585109a578e89ea8cd2c39d50b012698148dd11dedbDRC	return sfjava;
58636336fcddc4cc9f74988e3f03c4683c88c8fce45DRC}
58736336fcddc4cc9f74988e3f03c4683c88c8fce45DRC
588a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJDecompressor::decompressHeader() */
5893bad53fa04699ce22a7d2ba6763d7a357ef30540DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
5909b28defe6ac85dd8a52479cf276606beae24920eDRC	(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize)
591f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC{
592f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	tjhandle handle=0;
5939b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned char *jpegBuf=NULL;
59438cb1ec2a77b7209a260f3cced1e6c6365616c8eDRC	int width=0, height=0, jpegSubsamp=-1, jpegColorspace=-1;
595f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
596f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	gethandle();
597f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
5989b28defe6ac85dd8a52479cf276606beae24920eDRC	if((*env)->GetArrayLength(env, src)<jpegSize)
5996acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC		_throw("Source buffer is not large enough");
6006acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC
6019b28defe6ac85dd8a52479cf276606beae24920eDRC	bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
602f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
6031a45b81fa2edf682ae72251a18fd84eacef9dbbeDRC	if(tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize,
60438cb1ec2a77b7209a260f3cced1e6c6365616c8eDRC		&width, &height, &jpegSubsamp, &jpegColorspace)==-1)
605f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC		_throw(tjGetErrorStr());
6068951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC
6079b28defe6ac85dd8a52479cf276606beae24920eDRC	(*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);  jpegBuf=NULL;
608f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
60926dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
6109b28defe6ac85dd8a52479cf276606beae24920eDRC	(*env)->SetIntField(env, obj, _fid, jpegSubsamp);
61126dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	if((_fid=(*env)->GetFieldID(env, _cls, "jpegColorspace", "I"))==0)
61226dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC		(*env)->ExceptionClear(env);
61326dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	else
61426dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC		(*env)->SetIntField(env, obj, _fid, jpegColorspace);
61526dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
6163bad53fa04699ce22a7d2ba6763d7a357ef30540DRC	(*env)->SetIntField(env, obj, _fid, width);
61726dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
6183bad53fa04699ce22a7d2ba6763d7a357ef30540DRC	(*env)->SetIntField(env, obj, _fid, height);
619f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
620f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailout:
6218951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
6223bad53fa04699ce22a7d2ba6763d7a357ef30540DRC	return;
623f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
624f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
6255d87f6ddff832dd6c47e1f0c55fe9099792cff08DRCstatic void TJDecompressor_decompress
626927a10db05d6691c200a6372718f0e6bebadd60cDRC	(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jarray dst,
627927a10db05d6691c200a6372718f0e6bebadd60cDRC		jint dstElementSize, jint x, jint y, jint width, jint pitch, jint height,
628927a10db05d6691c200a6372718f0e6bebadd60cDRC		jint pf, jint flags)
629f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC{
6309b28defe6ac85dd8a52479cf276606beae24920eDRC	tjhandle handle=0;
631f659f43f937ed3fcd786753569d879989a640154DRC	jsize arraySize=0, actualPitch;
6329b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned char *jpegBuf=NULL, *dstBuf=NULL;
633f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
634f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	gethandle();
635f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
63692549de2c2b139070294aec12ec39b7c86a56b52DRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
6374f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw("Invalid argument in decompress()");
6389b28defe6ac85dd8a52479cf276606beae24920eDRC	if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
6399b28defe6ac85dd8a52479cf276606beae24920eDRC		_throw("Mismatch between Java and C API");
6404f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
6419b28defe6ac85dd8a52479cf276606beae24920eDRC	if((*env)->GetArrayLength(env, src)<jpegSize)
6426acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC		_throw("Source buffer is not large enough");
643f659f43f937ed3fcd786753569d879989a640154DRC	actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
644dc31f0bc410e57fad3380077649b5c033103f2ceDRC	arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
645927a10db05d6691c200a6372718f0e6bebadd60cDRC	if((*env)->GetArrayLength(env, dst)*dstElementSize<arraySize)
6466acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC		_throw("Destination buffer is not large enough");
6476acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC
6489b28defe6ac85dd8a52479cf276606beae24920eDRC	bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
6499b28defe6ac85dd8a52479cf276606beae24920eDRC	bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
650f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
651f659f43f937ed3fcd786753569d879989a640154DRC	if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
652f659f43f937ed3fcd786753569d879989a640154DRC		&dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
653f659f43f937ed3fcd786753569d879989a640154DRC		flags)==-1)
654f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC		_throw(tjGetErrorStr());
655f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
656f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	bailout:
6579b28defe6ac85dd8a52479cf276606beae24920eDRC	if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
6589b28defe6ac85dd8a52479cf276606beae24920eDRC	if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
659f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	return;
660f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
661f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC
662a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.3.x: TJDecompressor::decompress() byte destination */
663927a10db05d6691c200a6372718f0e6bebadd60cDRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
664927a10db05d6691c200a6372718f0e6bebadd60cDRC	(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
665927a10db05d6691c200a6372718f0e6bebadd60cDRC		jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
666927a10db05d6691c200a6372718f0e6bebadd60cDRC{
667927a10db05d6691c200a6372718f0e6bebadd60cDRC	TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, x, y, width,
668927a10db05d6691c200a6372718f0e6bebadd60cDRC		pitch, height, pf, flags);
669927a10db05d6691c200a6372718f0e6bebadd60cDRC}
670927a10db05d6691c200a6372718f0e6bebadd60cDRC
671a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJDecompressor::decompress() byte destination */
672f659f43f937ed3fcd786753569d879989a640154DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
673f659f43f937ed3fcd786753569d879989a640154DRC	(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
6744f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		jint width, jint pitch, jint height, jint pf, jint flags)
67584a1bcca6fd0f21091a84f04b820b29012c60857DRC{
676927a10db05d6691c200a6372718f0e6bebadd60cDRC	TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, 0, 0, width,
677927a10db05d6691c200a6372718f0e6bebadd60cDRC		pitch, height, pf, flags);
678f659f43f937ed3fcd786753569d879989a640154DRC}
679f659f43f937ed3fcd786753569d879989a640154DRC
680a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.3.x: TJDecompressor::decompress() int destination */
681f659f43f937ed3fcd786753569d879989a640154DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
682f659f43f937ed3fcd786753569d879989a640154DRC	(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
683f659f43f937ed3fcd786753569d879989a640154DRC		jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags)
684f659f43f937ed3fcd786753569d879989a640154DRC{
68592549de2c2b139070294aec12ec39b7c86a56b52DRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
6864f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw("Invalid argument in decompress()");
6879b28defe6ac85dd8a52479cf276606beae24920eDRC	if(tjPixelSize[pf]!=sizeof(jint))
6884f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
6894f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
690927a10db05d6691c200a6372718f0e6bebadd60cDRC	TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), x, y,
691927a10db05d6691c200a6372718f0e6bebadd60cDRC		width, stride*sizeof(jint), height, pf, flags);
69284a1bcca6fd0f21091a84f04b820b29012c60857DRC
69384a1bcca6fd0f21091a84f04b820b29012c60857DRC	bailout:
69484a1bcca6fd0f21091a84f04b820b29012c60857DRC	return;
6954f1580cc0e7c33385e88bca7fe08602b87d29aebDRC}
6964f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
697a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJDecompressor::decompress() int destination */
698f659f43f937ed3fcd786753569d879989a640154DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
699f659f43f937ed3fcd786753569d879989a640154DRC	(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
700f659f43f937ed3fcd786753569d879989a640154DRC		jint width, jint stride, jint height, jint pf, jint flags)
701f659f43f937ed3fcd786753569d879989a640154DRC{
702927a10db05d6691c200a6372718f0e6bebadd60cDRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
703927a10db05d6691c200a6372718f0e6bebadd60cDRC		_throw("Invalid argument in decompress()");
704927a10db05d6691c200a6372718f0e6bebadd60cDRC	if(tjPixelSize[pf]!=sizeof(jint))
705927a10db05d6691c200a6372718f0e6bebadd60cDRC		_throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
706927a10db05d6691c200a6372718f0e6bebadd60cDRC
707927a10db05d6691c200a6372718f0e6bebadd60cDRC	TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), 0, 0,
708927a10db05d6691c200a6372718f0e6bebadd60cDRC		width, stride*sizeof(jint), height, pf, flags);
709927a10db05d6691c200a6372718f0e6bebadd60cDRC
710927a10db05d6691c200a6372718f0e6bebadd60cDRC	bailout:
711927a10db05d6691c200a6372718f0e6bebadd60cDRC	return;
7121a45b81fa2edf682ae72251a18fd84eacef9dbbeDRC
713f659f43f937ed3fcd786753569d879989a640154DRC}
714f659f43f937ed3fcd786753569d879989a640154DRC
715a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.4.x: TJDecompressor::decompressToYUV() */
71640dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3_3B_3II_3III
71740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize,
71840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jobjectArray dstobjs, jintArray jDstOffsets, jint desiredWidth,
71940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jintArray jDstStrides, jint desiredHeight, jint flags)
7204f1580cc0e7c33385e88bca7fe08602b87d29aebDRC{
7214f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	tjhandle handle=0;
72240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jbyteArray jDstPlanes[3]={NULL, NULL, NULL};
72340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	unsigned char *jpegBuf=NULL, *dstPlanes[3];
72440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int *dstOffsets=NULL, *dstStrides=NULL;
7256acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC	int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
72640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int nc=0, i, width, height, scaledWidth, scaledHeight, nsf=0;
72740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	tjscalingfactor *sf;
72840dd3146cde2ba5036fe76a4f09e1125b4592347DRC
7294f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
7304f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	gethandle();
73184a1bcca6fd0f21091a84f04b820b29012c60857DRC
7329b28defe6ac85dd8a52479cf276606beae24920eDRC	if((*env)->GetArrayLength(env, src)<jpegSize)
7336acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC		_throw("Source buffer is not large enough");
73426dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
7356acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC	jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
73626dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
7376acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC	jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
73826dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
7396acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC	jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
7406acf52b5f9df20fbe3d46c517ff4325a1b12a896DRC
74140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	nc=(jpegSubsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3);
74240dd3146cde2ba5036fe76a4f09e1125b4592347DRC
74340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	width=desiredWidth;  height=desiredHeight;
74440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(width==0) width=jpegWidth;
74540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(height==0) height=jpegHeight;
74640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	sf=tjGetScalingFactors(&nsf);
74740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(!sf || nsf<1)
748fef9852da3a80bfaf84862462609f97d77ad6db7DRC		_throw(tjGetErrorStr());
74940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nsf; i++)
75040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
75140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		scaledWidth=TJSCALED(jpegWidth, sf[i]);
75240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		scaledHeight=TJSCALED(jpegHeight, sf[i]);
75340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(scaledWidth<=width && scaledHeight<=height)
75440dd3146cde2ba5036fe76a4f09e1125b4592347DRC			break;
75540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
75640dd3146cde2ba5036fe76a4f09e1125b4592347DRC
75740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(dstOffsets=(*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0));
75840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(dstStrides=(*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0));
75940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
76040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
76140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int planeSize=tjPlaneSizeYUV(i, scaledWidth, dstStrides[i], scaledHeight,
76240dd3146cde2ba5036fe76a4f09e1125b4592347DRC			jpegSubsamp);
76340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int pw=tjPlaneWidth(i, scaledWidth, jpegSubsamp);
76440dd3146cde2ba5036fe76a4f09e1125b4592347DRC
76540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(planeSize<0 || pw<0)
76640dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw(tjGetErrorStr());
76740dd3146cde2ba5036fe76a4f09e1125b4592347DRC
76840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(dstOffsets[i]<0)
76940dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Invalid argument in decompressToYUV()");
77040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(dstStrides[i]<0 && dstOffsets[i]-planeSize+pw<0)
77140dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Negative plane stride would cause memory to be accessed below plane boundary");
77240dd3146cde2ba5036fe76a4f09e1125b4592347DRC
77340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		bailif0(jDstPlanes[i]=(*env)->GetObjectArrayElement(env, dstobjs, i));
77440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if((*env)->GetArrayLength(env, jDstPlanes[i])<dstOffsets[i]+planeSize)
77540dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Destination plane is not large enough");
77640dd3146cde2ba5036fe76a4f09e1125b4592347DRC
77740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		bailif0(dstPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i],
77840dd3146cde2ba5036fe76a4f09e1125b4592347DRC			0));
77940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes[i]=&dstPlanes[i][dstOffsets[i]];
78040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
7819b28defe6ac85dd8a52479cf276606beae24920eDRC	bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
7824f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
78340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize,
78440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		dstPlanes, desiredWidth, dstStrides, desiredHeight, flags)==-1)
7854f1580cc0e7c33385e88bca7fe08602b87d29aebDRC		_throw(tjGetErrorStr());
7864f1580cc0e7c33385e88bca7fe08602b87d29aebDRC
7874f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	bailout:
7889b28defe6ac85dd8a52479cf276606beae24920eDRC	if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
78940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
79040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
79140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(dstPlanes[i] && jDstPlanes[i])
79240dd3146cde2ba5036fe76a4f09e1125b4592347DRC			(*env)->ReleasePrimitiveArrayCritical(env, jDstPlanes[i], dstPlanes[i],
79340dd3146cde2ba5036fe76a4f09e1125b4592347DRC				0);
79440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
79540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(dstStrides)
79640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		(*env)->ReleasePrimitiveArrayCritical(env, jDstStrides, dstStrides, 0);
79740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(dstOffsets)
79840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		(*env)->ReleasePrimitiveArrayCritical(env, jDstOffsets, dstOffsets, 0);
7994f1580cc0e7c33385e88bca7fe08602b87d29aebDRC	return;
80084a1bcca6fd0f21091a84f04b820b29012c60857DRC}
80184a1bcca6fd0f21091a84f04b820b29012c60857DRC
802a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJDecompressor::decompressToYUV() */
803fef9852da3a80bfaf84862462609f97d77ad6db7DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI
804fef9852da3a80bfaf84862462609f97d77ad6db7DRC	(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
805fef9852da3a80bfaf84862462609f97d77ad6db7DRC		jint flags)
806fef9852da3a80bfaf84862462609f97d77ad6db7DRC{
80740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	tjhandle handle=0;
80840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	unsigned char *jpegBuf=NULL, *dstBuf=NULL;
80940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
81040dd3146cde2ba5036fe76a4f09e1125b4592347DRC
81140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	gethandle();
81240dd3146cde2ba5036fe76a4f09e1125b4592347DRC
81340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, src)<jpegSize)
81440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Source buffer is not large enough");
81540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
81640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
81740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
81840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
81940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
82040dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
82140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, dst)
82240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		<(jsize)tjBufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp))
82340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Destination buffer is not large enough");
82440dd3146cde2ba5036fe76a4f09e1125b4592347DRC
82540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
82640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
82740dd3146cde2ba5036fe76a4f09e1125b4592347DRC
82840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
82940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		flags)==-1)
83040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw(tjGetErrorStr());
83140dd3146cde2ba5036fe76a4f09e1125b4592347DRC
83240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailout:
83340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
83440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
83540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	return;
836fef9852da3a80bfaf84862462609f97d77ad6db7DRC}
837fef9852da3a80bfaf84862462609f97d77ad6db7DRC
8385d87f6ddff832dd6c47e1f0c55fe9099792cff08DRCstatic void TJDecompressor_decodeYUV
83940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
84040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jintArray jSrcStrides, jint subsamp, jarray dst, jint dstElementSize,
84140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
842fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC{
843fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	tjhandle handle=0;
844fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	jsize arraySize=0, actualPitch;
84540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	jbyteArray jSrcPlanes[3]={NULL, NULL, NULL};
84640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	unsigned char *srcPlanes[3], *dstBuf=NULL;
84740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int *srcOffsets=NULL, *srcStrides=NULL;
84840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	int nc=(subsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3), i;
849fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
850fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	gethandle();
851fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
85240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || subsamp<0
85340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		|| subsamp>=org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
854fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC		_throw("Invalid argument in decodeYUV()");
85540dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF
85640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		|| org_libjpegturbo_turbojpeg_TJ_NUMSAMP!=TJ_NUMSAMP)
857fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC		_throw("Mismatch between Java and C API");
858fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
85940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, srcobjs)<nc)
86040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Planes array is too small for the subsampling type");
86140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, jSrcOffsets)<nc)
86240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Offsets array is too small for the subsampling type");
86340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if((*env)->GetArrayLength(env, jSrcStrides)<nc)
86440dd3146cde2ba5036fe76a4f09e1125b4592347DRC		_throw("Strides array is too small for the subsampling type");
86540dd3146cde2ba5036fe76a4f09e1125b4592347DRC
866fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
867fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
868927a10db05d6691c200a6372718f0e6bebadd60cDRC	if((*env)->GetArrayLength(env, dst)*dstElementSize<arraySize)
869fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC		_throw("Destination buffer is not large enough");
870fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
87140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(srcOffsets=(*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0));
87240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	bailif0(srcStrides=(*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0));
87340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
87440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
87540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int planeSize=tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp);
87640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		int pw=tjPlaneWidth(i, width, subsamp);
87740dd3146cde2ba5036fe76a4f09e1125b4592347DRC
87840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(planeSize<0 || pw<0)
87940dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw(tjGetErrorStr());
88040dd3146cde2ba5036fe76a4f09e1125b4592347DRC
88140dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(srcOffsets[i]<0)
88240dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Invalid argument in decodeYUV()");
88340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(srcStrides[i]<0 && srcOffsets[i]-planeSize+pw<0)
88440dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Negative plane stride would cause memory to be accessed below plane boundary");
88540dd3146cde2ba5036fe76a4f09e1125b4592347DRC
88640dd3146cde2ba5036fe76a4f09e1125b4592347DRC		bailif0(jSrcPlanes[i]=(*env)->GetObjectArrayElement(env, srcobjs, i));
88740dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if((*env)->GetArrayLength(env, jSrcPlanes[i])<srcOffsets[i]+planeSize)
88840dd3146cde2ba5036fe76a4f09e1125b4592347DRC			_throw("Source plane is not large enough");
88940dd3146cde2ba5036fe76a4f09e1125b4592347DRC
89040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		bailif0(srcPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i],
89140dd3146cde2ba5036fe76a4f09e1125b4592347DRC			0));
89240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		srcPlanes[i]=&srcPlanes[i][srcOffsets[i]];
89340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
894fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
895fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
89640dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(tjDecodeYUVPlanes(handle, srcPlanes, srcStrides, subsamp,
897fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC		&dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
898fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC		flags)==-1)
899fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC		_throw(tjGetErrorStr());
900fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
901fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	bailout:
902fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
90340dd3146cde2ba5036fe76a4f09e1125b4592347DRC	for(i=0; i<nc; i++)
90440dd3146cde2ba5036fe76a4f09e1125b4592347DRC	{
90540dd3146cde2ba5036fe76a4f09e1125b4592347DRC		if(srcPlanes[i] && jSrcPlanes[i])
90640dd3146cde2ba5036fe76a4f09e1125b4592347DRC			(*env)->ReleasePrimitiveArrayCritical(env, jSrcPlanes[i], srcPlanes[i],
90740dd3146cde2ba5036fe76a4f09e1125b4592347DRC				0);
90840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	}
90940dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(srcStrides)
91040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		(*env)->ReleasePrimitiveArrayCritical(env, jSrcStrides, srcStrides, 0);
91140dd3146cde2ba5036fe76a4f09e1125b4592347DRC	if(srcOffsets)
91240dd3146cde2ba5036fe76a4f09e1125b4592347DRC		(*env)->ReleasePrimitiveArrayCritical(env, jSrcOffsets, srcOffsets, 0);
913fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	return;
914fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC}
915fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
916a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() byte destination */
91740dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3BIIIIIII
91840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
91940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jintArray jSrcStrides, jint subsamp, jbyteArray dst, jint x, jint y,
92040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint width, jint pitch, jint height, jint pf, jint flags)
921927a10db05d6691c200a6372718f0e6bebadd60cDRC{
92240dd3146cde2ba5036fe76a4f09e1125b4592347DRC	TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides,
92340dd3146cde2ba5036fe76a4f09e1125b4592347DRC		subsamp, dst, 1, x, y, width, pitch, height, pf, flags);
924927a10db05d6691c200a6372718f0e6bebadd60cDRC}
925927a10db05d6691c200a6372718f0e6bebadd60cDRC
926a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() int destination */
92740dd3146cde2ba5036fe76a4f09e1125b4592347DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3IIIIIIII
92840dd3146cde2ba5036fe76a4f09e1125b4592347DRC	(JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
92940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jintArray jSrcStrides, jint subsamp, jintArray dst, jint x, jint y,
93040dd3146cde2ba5036fe76a4f09e1125b4592347DRC		jint width, jint stride, jint height, jint pf, jint flags)
931fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC{
932fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
933fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC		_throw("Invalid argument in decodeYUV()");
934fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	if(tjPixelSize[pf]!=sizeof(jint))
935fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC		_throw("Pixel format must be 32-bit when decoding to an integer buffer.");
936fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
93740dd3146cde2ba5036fe76a4f09e1125b4592347DRC	TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides,
93840dd3146cde2ba5036fe76a4f09e1125b4592347DRC		subsamp, dst, sizeof(jint), x, y, width, stride*sizeof(jint), height, pf,
93940dd3146cde2ba5036fe76a4f09e1125b4592347DRC		flags);
940fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
941fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	bailout:
942fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC	return;
943fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC}
944fc26b6577a2c422899e5cb9f483ee9d3ed37e185DRC
945a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJTransformer::init() */
946e85730157e0b4fb12b0500d1a41b3e370874a74dDRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init
947e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	(JNIEnv *env, jobject obj)
948e85730157e0b4fb12b0500d1a41b3e370874a74dDRC{
949e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	jclass cls;
950e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	jfieldID fid;
951e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	tjhandle handle;
952e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
953e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	if((handle=tjInitTransform())==NULL) _throw(tjGetErrorStr());
954e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
955e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	bailif0(cls=(*env)->GetObjectClass(env, obj));
956e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
95746a0392cf37a58183a7aa3852e51b57777ba002cDRC	(*env)->SetLongField(env, obj, fid, (size_t)handle);
958e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
959e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	bailout:
960e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	return;
961e85730157e0b4fb12b0500d1a41b3e370874a74dDRC}
962e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
963f5467110763f7a44ca8baf1c035eb39a68c913c6DRCtypedef struct _JNICustomFilterParams
964f5467110763f7a44ca8baf1c035eb39a68c913c6DRC{
965f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	JNIEnv *env;
966f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	jobject tobj;
967f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	jobject cfobj;
968f5467110763f7a44ca8baf1c035eb39a68c913c6DRC} JNICustomFilterParams;
969f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
970f5467110763f7a44ca8baf1c035eb39a68c913c6DRCstatic int JNICustomFilter(short *coeffs, tjregion arrayRegion,
971f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	tjregion planeRegion, int componentIndex, int transformIndex,
972f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	tjtransform *transform)
973f5467110763f7a44ca8baf1c035eb39a68c913c6DRC{
974f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	JNICustomFilterParams *params=(JNICustomFilterParams *)transform->data;
975f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	JNIEnv *env=params->env;
976f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	jobject tobj=params->tobj, cfobj=params->cfobj;
977b7c8c86d6a2fca5733a8e94c8fd662d4d99523e0DRC	jobject arrayRegionObj, planeRegionObj, bufobj, borobj;
978f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	jclass cls;  jmethodID mid;  jfieldID fid;
979f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
980f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(bufobj=(*env)->NewDirectByteBuffer(env, coeffs,
981f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		sizeof(short)*arrayRegion.w*arrayRegion.h));
982f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(cls=(*env)->FindClass(env, "java/nio/ByteOrder"));
983b7c8c86d6a2fca5733a8e94c8fd662d4d99523e0DRC	bailif0(mid=(*env)->GetStaticMethodID(env, cls, "nativeOrder",
984f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		"()Ljava/nio/ByteOrder;"));
985f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(borobj=(*env)->CallStaticObjectMethod(env, cls, mid));
986f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(cls=(*env)->GetObjectClass(env, bufobj));
987f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(mid=(*env)->GetMethodID(env, cls, "order",
988f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		"(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"));
989f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->CallObjectMethod(env, bufobj, mid, borobj);
990b7c8c86d6a2fca5733a8e94c8fd662d4d99523e0DRC	bailif0(mid=(*env)->GetMethodID(env, cls, "asShortBuffer",
991f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		"()Ljava/nio/ShortBuffer;"));
992f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(bufobj=(*env)->CallObjectMethod(env, bufobj, mid));
993f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
994f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(cls=(*env)->FindClass(env, "java/awt/Rectangle"));
995f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(arrayRegionObj=(*env)->AllocObject(env, cls));
996f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
997f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
998f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
999f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
1000f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
1001f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
1002f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
1003f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h);
1004f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
1005f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(planeRegionObj=(*env)->AllocObject(env, cls));
1006f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
1007f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
1008f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
1009f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
1010f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
1011f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
1012f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
1013f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h);
1014f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
1015f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(cls=(*env)->GetObjectClass(env, cfobj));
1016f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailif0(mid=(*env)->GetMethodID(env, cls, "customFilter",
1017f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		"(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V"));
1018f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	(*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj,
1019f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		planeRegionObj, componentIndex, transformIndex, tobj);
1020f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
1021f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	return 0;
1022f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
1023f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	bailout:
1024f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	return -1;
1025f5467110763f7a44ca8baf1c035eb39a68c913c6DRC}
1026f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
1027a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJTransformer::transform() */
1028e85730157e0b4fb12b0500d1a41b3e370874a74dDRCJNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
10299b28defe6ac85dd8a52479cf276606beae24920eDRC	(JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
1030e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		jobjectArray dstobjs, jobjectArray tobjs, jint flags)
1031e85730157e0b4fb12b0500d1a41b3e370874a74dDRC{
1032e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	tjhandle handle=0;  int i;
10339b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned char *jpegBuf=NULL, **dstBufs=NULL;  jsize n=0;
10349b28defe6ac85dd8a52479cf276606beae24920eDRC	unsigned long *dstSizes=NULL;  tjtransform *t=NULL;
10359b28defe6ac85dd8a52479cf276606beae24920eDRC	jbyteArray *jdstBufs=NULL;
10369b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	int jpegWidth=0, jpegHeight=0, jpegSubsamp;
10379b28defe6ac85dd8a52479cf276606beae24920eDRC	jintArray jdstSizes=0;  jint *dstSizesi=NULL;
1038f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	JNICustomFilterParams *params=NULL;
1039e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
1040e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	gethandle();
1041e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
10429b28defe6ac85dd8a52479cf276606beae24920eDRC	if((*env)->GetArrayLength(env, jsrcBuf)<jpegSize)
1043e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		_throw("Source buffer is not large enough");
104426dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
1045e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
104626dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
1047e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
104826dd86bd89a05598f7d1b97d0d02b09f83cc8a43DRC	bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
10499b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC	jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
1050e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
1051e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	n=(*env)->GetArrayLength(env, dstobjs);
1052e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	if(n!=(*env)->GetArrayLength(env, tobjs))
1053e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		_throw("Mismatch between size of transforms array and destination buffers array");
1054e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
10559b28defe6ac85dd8a52479cf276606beae24920eDRC	if((dstBufs=(unsigned char **)malloc(sizeof(unsigned char *)*n))==NULL)
1056e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		_throw("Memory allocation failure");
10579b28defe6ac85dd8a52479cf276606beae24920eDRC	if((jdstBufs=(jbyteArray *)malloc(sizeof(jbyteArray)*n))==NULL)
1058e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		_throw("Memory allocation failure");
10599b28defe6ac85dd8a52479cf276606beae24920eDRC	if((dstSizes=(unsigned long *)malloc(sizeof(unsigned long)*n))==NULL)
1060e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		_throw("Memory allocation failure");
1061e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL)
1062e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		_throw("Memory allocation failure");
1063f5467110763f7a44ca8baf1c035eb39a68c913c6DRC	if((params=(JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams)*n))
1064f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		==NULL)
1065f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		_throw("Memory allocation failure");
1066e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	for(i=0; i<n; i++)
1067e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	{
10689b28defe6ac85dd8a52479cf276606beae24920eDRC		dstBufs[i]=NULL;  jdstBufs[i]=NULL;  dstSizes[i]=0;
1069e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		memset(&t[i], 0, sizeof(tjtransform));
1070f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		memset(&params[i], 0, sizeof(JNICustomFilterParams));
1071e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	}
1072e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
1073e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	for(i=0; i<n; i++)
1074e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	{
1075f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		jobject tobj, cfobj;
1076e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
1077e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		bailif0(tobj=(*env)->GetObjectArrayElement(env, tobjs, i));
1078e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		bailif0(_cls=(*env)->GetObjectClass(env, tobj));
1079e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		bailif0(_fid=(*env)->GetFieldID(env, _cls, "op", "I"));
1080e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		t[i].op=(*env)->GetIntField(env, tobj, _fid);
1081e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		bailif0(_fid=(*env)->GetFieldID(env, _cls, "options", "I"));
1082e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		t[i].options=(*env)->GetIntField(env, tobj, _fid);
1083e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		bailif0(_fid=(*env)->GetFieldID(env, _cls, "x", "I"));
1084e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		t[i].r.x=(*env)->GetIntField(env, tobj, _fid);
1085e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		bailif0(_fid=(*env)->GetFieldID(env, _cls, "y", "I"));
1086e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		t[i].r.y=(*env)->GetIntField(env, tobj, _fid);
1087e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		bailif0(_fid=(*env)->GetFieldID(env, _cls, "width", "I"));
1088e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		t[i].r.w=(*env)->GetIntField(env, tobj, _fid);
1089e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		bailif0(_fid=(*env)->GetFieldID(env, _cls, "height", "I"));
1090e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		t[i].r.h=(*env)->GetIntField(env, tobj, _fid);
1091f5467110763f7a44ca8baf1c035eb39a68c913c6DRC
1092f5467110763f7a44ca8baf1c035eb39a68c913c6DRC		bailif0(_fid=(*env)->GetFieldID(env, _cls, "cf",
1093f5467110763f7a44ca8baf1c035eb39a68c913c6DRC			"Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
109406420c42c428c3ad72d245c18c6e2b77f860d66dDRC		cfobj=(*env)->GetObjectField(env, tobj, _fid);
109506420c42c428c3ad72d245c18c6e2b77f860d66dDRC		if(cfobj)
109606420c42c428c3ad72d245c18c6e2b77f860d66dDRC		{
109706420c42c428c3ad72d245c18c6e2b77f860d66dDRC			params[i].env=env;
109806420c42c428c3ad72d245c18c6e2b77f860d66dDRC			params[i].tobj=tobj;
109906420c42c428c3ad72d245c18c6e2b77f860d66dDRC			params[i].cfobj=cfobj;
110006420c42c428c3ad72d245c18c6e2b77f860d66dDRC			t[i].customFilter=JNICustomFilter;
110106420c42c428c3ad72d245c18c6e2b77f860d66dDRC			t[i].data=(void *)&params[i];
110206420c42c428c3ad72d245c18c6e2b77f860d66dDRC		}
1103e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	}
1104e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
1105e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	for(i=0; i<n; i++)
1106e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	{
1107e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		int w=jpegWidth, h=jpegHeight;
1108e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		if(t[i].r.w!=0) w=t[i].r.w;
1109e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		if(t[i].r.h!=0) h=t[i].r.h;
11109b28defe6ac85dd8a52479cf276606beae24920eDRC		bailif0(jdstBufs[i]=(*env)->GetObjectArrayElement(env, dstobjs, i));
1111efe28cec4b29b5a7357d9cd1c30a066486d19b12DRC		if((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i])
1112efe28cec4b29b5a7357d9cd1c30a066486d19b12DRC			<tjBufSize(w, h, jpegSubsamp))
1113e85730157e0b4fb12b0500d1a41b3e370874a74dDRC			_throw("Destination buffer is not large enough");
1114e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	}
11158951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
11168951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	for(i=0; i<n; i++)
11178951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC		bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
1118e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
11199b28defe6ac85dd8a52479cf276606beae24920eDRC	if(tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
11204db92add1bed68f35ae68758889f4c7f0048cdbdDRC		flags|TJFLAG_NOREALLOC)==-1)
1121e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		_throw(tjGetErrorStr());
11228951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC
11238951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	for(i=0; i<n; i++)
11248951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	{
11258951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC		(*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
11268951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC		dstBufs[i]=NULL;
1127e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	}
11288951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	(*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
11298951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	jpegBuf=NULL;
1130e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
11319b28defe6ac85dd8a52479cf276606beae24920eDRC	jdstSizes=(*env)->NewIntArray(env, n);
11329b28defe6ac85dd8a52479cf276606beae24920eDRC	bailif0(dstSizesi=(*env)->GetIntArrayElements(env, jdstSizes, 0));
11339b28defe6ac85dd8a52479cf276606beae24920eDRC	for(i=0; i<n; i++) dstSizesi[i]=(int)dstSizes[i];
1134e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
1135e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	bailout:
11368951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	if(dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0);
11379b28defe6ac85dd8a52479cf276606beae24920eDRC	if(dstBufs)
1138e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	{
1139e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		for(i=0; i<n; i++)
1140e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		{
11419b28defe6ac85dd8a52479cf276606beae24920eDRC			if(dstBufs[i] && jdstBufs && jdstBufs[i])
11429b28defe6ac85dd8a52479cf276606beae24920eDRC				(*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
1143e85730157e0b4fb12b0500d1a41b3e370874a74dDRC		}
11449b28defe6ac85dd8a52479cf276606beae24920eDRC		free(dstBufs);
1145e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	}
11468951cf01fe61d09a3b3a77d704f43cb4f2afb096DRC	if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
11479b28defe6ac85dd8a52479cf276606beae24920eDRC	if(jdstBufs) free(jdstBufs);
11489b28defe6ac85dd8a52479cf276606beae24920eDRC	if(dstSizes) free(dstSizes);
1149e85730157e0b4fb12b0500d1a41b3e370874a74dDRC	if(t) free(t);
11509b28defe6ac85dd8a52479cf276606beae24920eDRC	return jdstSizes;
1151e85730157e0b4fb12b0500d1a41b3e370874a74dDRC}
1152e85730157e0b4fb12b0500d1a41b3e370874a74dDRC
1153a4940d13963300cb015931d944ab7fdd2759b2a2DRC/* TurboJPEG 1.2.x: TJDecompressor::destroy() */
1154c5a419970eb91c85844002901210484b29e25fb1DRCJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
1155f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC	(JNIEnv *env, jobject obj)
1156f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC{
1157c5a419970eb91c85844002901210484b29e25fb1DRC	Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj);
1158f8e0055a6a1f7a99dffcee6ff327c58047426f1dDRC}
1159