DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 1 | /* |
DRC | 6399d0a | 2019-04-23 14:10:04 -0500 | [diff] [blame] | 2 | * Copyright (C)2011-2019 D. R. Commander. All Rights Reserved. |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions are met: |
| 6 | * |
| 7 | * - Redistributions of source code must retain the above copyright notice, |
| 8 | * this list of conditions and the following disclaimer. |
| 9 | * - Redistributions in binary form must reproduce the above copyright notice, |
| 10 | * this list of conditions and the following disclaimer in the documentation |
| 11 | * and/or other materials provided with the distribution. |
| 12 | * - Neither the name of the libjpeg-turbo Project nor the names of its |
| 13 | * contributors may be used to endorse or promote products derived from this |
| 14 | * software without specific prior written permission. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", |
| 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE |
| 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 26 | * POSSIBILITY OF SUCH DAMAGE. |
| 27 | */ |
| 28 | |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 29 | #include <stdlib.h> |
| 30 | #include <string.h> |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 31 | #include "turbojpeg.h" |
DRC | bc2e66c | 2012-10-02 06:47:37 +0000 | [diff] [blame] | 32 | #ifdef WIN32 |
| 33 | #include "tjutil.h" |
| 34 | #endif |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 35 | #include <jni.h> |
DRC | c5a4199 | 2011-02-08 06:54:36 +0000 | [diff] [blame] | 36 | #include "java/org_libjpegturbo_turbojpeg_TJCompressor.h" |
| 37 | #include "java/org_libjpegturbo_turbojpeg_TJDecompressor.h" |
DRC | 6399d0a | 2019-04-23 14:10:04 -0500 | [diff] [blame] | 38 | #include "java/org_libjpegturbo_turbojpeg_TJTransformer.h" |
DRC | c5a4199 | 2011-02-08 06:54:36 +0000 | [diff] [blame] | 39 | #include "java/org_libjpegturbo_turbojpeg_TJ.h" |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 40 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 41 | #define BAILIF0(f) { \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 42 | if (!(f) || (*env)->ExceptionCheck(env)) { \ |
| 43 | goto bailout; \ |
| 44 | } \ |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 45 | } |
| 46 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 47 | #define THROW(msg, exceptionClass) { \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 48 | jclass _exccls = (*env)->FindClass(env, exceptionClass); \ |
| 49 | \ |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 50 | BAILIF0(_exccls); \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 51 | (*env)->ThrowNew(env, _exccls, msg); \ |
| 52 | goto bailout; \ |
| 53 | } |
| 54 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 55 | #define THROW_TJ() { \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 56 | jclass _exccls; \ |
| 57 | jmethodID _excid; \ |
| 58 | jobject _excobj; \ |
| 59 | jstring _errstr; \ |
| 60 | \ |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 61 | BAILIF0(_errstr = (*env)->NewStringUTF(env, tjGetErrorStr2(handle))); \ |
| 62 | BAILIF0(_exccls = (*env)->FindClass(env, \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 63 | "org/libjpegturbo/turbojpeg/TJException")); \ |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 64 | BAILIF0(_excid = (*env)->GetMethodID(env, _exccls, "<init>", \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 65 | "(Ljava/lang/String;I)V")); \ |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 66 | BAILIF0(_excobj = (*env)->NewObject(env, _exccls, _excid, _errstr, \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 67 | tjGetErrorCode(handle))); \ |
| 68 | (*env)->Throw(env, _excobj); \ |
| 69 | goto bailout; \ |
DRC | d4092f6 | 2017-06-27 10:54:21 -0500 | [diff] [blame] | 70 | } |
DRC | b3817da | 2015-07-14 20:42:52 +0000 | [diff] [blame] | 71 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 72 | #define THROW_ARG(msg) THROW(msg, "java/lang/IllegalArgumentException") |
DRC | b3817da | 2015-07-14 20:42:52 +0000 | [diff] [blame] | 73 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 74 | #define THROW_MEM() \ |
| 75 | THROW("Memory allocation failure", "java/lang/OutOfMemoryError"); |
DRC | b3817da | 2015-07-14 20:42:52 +0000 | [diff] [blame] | 76 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 77 | #define GET_HANDLE() \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 78 | jclass _cls = (*env)->GetObjectClass(env, obj); \ |
| 79 | jfieldID _fid; \ |
| 80 | \ |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 81 | BAILIF0(_cls); \ |
| 82 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "handle", "J")); \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 83 | handle = (tjhandle)(size_t)(*env)->GetLongField(env, obj, _fid); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 84 | |
DRC | bdb36e1 | 2014-08-22 15:39:32 +0000 | [diff] [blame] | 85 | #ifdef _WIN32 |
DRC | 293263c | 2018-03-17 15:14:35 -0500 | [diff] [blame] | 86 | #define setenv(envvar, value, dummy) _putenv_s(envvar, value) |
DRC | bdb36e1 | 2014-08-22 15:39:32 +0000 | [diff] [blame] | 87 | #endif |
| 88 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 89 | #define PROP2ENV(property, envvar) { \ |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 90 | if ((jName = (*env)->NewStringUTF(env, property)) != NULL && \ |
| 91 | (jValue = (*env)->CallStaticObjectMethod(env, cls, mid, \ |
| 92 | jName)) != NULL) { \ |
| 93 | if ((value = (*env)->GetStringUTFChars(env, jValue, 0)) != NULL) { \ |
| 94 | setenv(envvar, value, 1); \ |
| 95 | (*env)->ReleaseStringUTFChars(env, jValue, value); \ |
| 96 | } \ |
| 97 | } \ |
DRC | 0713c1b | 2014-08-22 13:43:33 +0000 | [diff] [blame] | 98 | } |
| 99 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 100 | #define SAFE_RELEASE(javaArray, cArray) { \ |
| 101 | if (javaArray && cArray) \ |
| 102 | (*env)->ReleasePrimitiveArrayCritical(env, javaArray, (void *)cArray, 0); \ |
| 103 | cArray = NULL; \ |
| 104 | } |
| 105 | |
DRC | 6399d0a | 2019-04-23 14:10:04 -0500 | [diff] [blame] | 106 | static int ProcessSystemProperties(JNIEnv *env) |
DRC | 0713c1b | 2014-08-22 13:43:33 +0000 | [diff] [blame] | 107 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 108 | jclass cls; |
| 109 | jmethodID mid; |
| 110 | jstring jName, jValue; |
| 111 | const char *value; |
DRC | 0713c1b | 2014-08-22 13:43:33 +0000 | [diff] [blame] | 112 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 113 | BAILIF0(cls = (*env)->FindClass(env, "java/lang/System")); |
| 114 | BAILIF0(mid = (*env)->GetStaticMethodID(env, cls, "getProperty", |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 115 | "(Ljava/lang/String;)Ljava/lang/String;")); |
DRC | 0713c1b | 2014-08-22 13:43:33 +0000 | [diff] [blame] | 116 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 117 | PROP2ENV("turbojpeg.optimize", "TJ_OPTIMIZE"); |
| 118 | PROP2ENV("turbojpeg.arithmetic", "TJ_ARITHMETIC"); |
| 119 | PROP2ENV("turbojpeg.restart", "TJ_RESTART"); |
| 120 | PROP2ENV("turbojpeg.progressive", "TJ_PROGRESSIVE"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 121 | return 0; |
DRC | 0713c1b | 2014-08-22 13:43:33 +0000 | [diff] [blame] | 122 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 123 | bailout: |
| 124 | return -1; |
DRC | 0713c1b | 2014-08-22 13:43:33 +0000 | [diff] [blame] | 125 | } |
| 126 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 127 | /* TurboJPEG 1.2.x: TJ::bufSize() */ |
DRC | 3bad53f | 2011-02-23 02:20:49 +0000 | [diff] [blame] | 128 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 129 | (JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp) |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 130 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 131 | jint retval = (jint)tjBufSize(width, height, jpegSubsamp); |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 132 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 133 | if (retval == -1) THROW_ARG(tjGetErrorStr()); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 134 | |
| 135 | bailout: |
| 136 | return retval; |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 137 | } |
| 138 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 139 | /* TurboJPEG 1.4.x: TJ::bufSizeYUV() */ |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 140 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 141 | (JNIEnv *env, jclass cls, jint width, jint pad, jint height, jint subsamp) |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 142 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 143 | jint retval = (jint)tjBufSizeYUV2(width, pad, height, subsamp); |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 144 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 145 | if (retval == -1) THROW_ARG(tjGetErrorStr()); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 146 | |
| 147 | bailout: |
| 148 | return retval; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 149 | } |
| 150 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 151 | /* TurboJPEG 1.2.x: TJ::bufSizeYUV() */ |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 152 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__III |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 153 | (JNIEnv *env, jclass cls, jint width, jint height, jint subsamp) |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 154 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 155 | return Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII(env, cls, width, |
| 156 | 4, height, |
| 157 | subsamp); |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 158 | } |
| 159 | |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 160 | /* TurboJPEG 1.4.x: TJ::planeSizeYUV() */ |
| 161 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeSizeYUV__IIIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 162 | (JNIEnv *env, jclass cls, jint componentID, jint width, jint stride, |
| 163 | jint height, jint subsamp) |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 164 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 165 | jint retval = (jint)tjPlaneSizeYUV(componentID, width, stride, height, |
| 166 | subsamp); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 167 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 168 | if (retval == -1) THROW_ARG(tjGetErrorStr()); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 169 | |
| 170 | bailout: |
| 171 | return retval; |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 172 | } |
| 173 | |
| 174 | /* TurboJPEG 1.4.x: TJ::planeWidth() */ |
| 175 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeWidth__III |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 176 | (JNIEnv *env, jclass cls, jint componentID, jint width, jint subsamp) |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 177 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 178 | jint retval = (jint)tjPlaneWidth(componentID, width, subsamp); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 179 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 180 | if (retval == -1) THROW_ARG(tjGetErrorStr()); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 181 | |
| 182 | bailout: |
| 183 | return retval; |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | /* TurboJPEG 1.4.x: TJ::planeHeight() */ |
| 187 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeHeight__III |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 188 | (JNIEnv *env, jclass cls, jint componentID, jint height, jint subsamp) |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 189 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 190 | jint retval = (jint)tjPlaneHeight(componentID, height, subsamp); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 191 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 192 | if (retval == -1) THROW_ARG(tjGetErrorStr()); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 193 | |
| 194 | bailout: |
| 195 | return retval; |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 196 | } |
| 197 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 198 | /* TurboJPEG 1.2.x: TJCompressor::init() */ |
DRC | c5a4199 | 2011-02-08 06:54:36 +0000 | [diff] [blame] | 199 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 200 | (JNIEnv *env, jobject obj) |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 201 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 202 | jclass cls; |
| 203 | jfieldID fid; |
| 204 | tjhandle handle; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 205 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 206 | if ((handle = tjInitCompress()) == NULL) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 207 | THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 208 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 209 | BAILIF0(cls = (*env)->GetObjectClass(env, obj)); |
| 210 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 211 | (*env)->SetLongField(env, obj, fid, (size_t)handle); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 212 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 213 | bailout: |
| 214 | return; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 215 | } |
| 216 | |
DRC | 5d87f6d | 2014-08-15 16:40:56 +0000 | [diff] [blame] | 217 | static jint TJCompressor_compress |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 218 | (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y, |
| 219 | jint width, jint pitch, jint height, jint pf, jbyteArray dst, |
| 220 | jint jpegSubsamp, jint jpegQual, jint flags) |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 221 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 222 | tjhandle handle = 0; |
| 223 | unsigned long jpegSize = 0; |
| 224 | jsize arraySize = 0, actualPitch; |
| 225 | unsigned char *srcBuf = NULL, *jpegBuf = NULL; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 226 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 227 | GET_HANDLE(); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 228 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 229 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || |
| 230 | height < 1 || pitch < 0) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 231 | THROW_ARG("Invalid argument in compress()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 232 | if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 233 | THROW_ARG("Mismatch between Java and C API"); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 234 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 235 | actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; |
| 236 | arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; |
| 237 | if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 238 | THROW_ARG("Source buffer is not large enough"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 239 | jpegSize = tjBufSize(width, height, jpegSubsamp); |
| 240 | if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 241 | THROW_ARG("Destination buffer is not large enough"); |
DRC | 6acf52b | 2011-03-02 01:09:20 +0000 | [diff] [blame] | 242 | |
DRC | 5ea77d8 | 2018-10-26 08:55:22 -0500 | [diff] [blame] | 243 | if (ProcessSystemProperties(env) < 0) goto bailout; |
| 244 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 245 | BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); |
| 246 | BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 247 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 248 | if (tjCompress2(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]], |
| 249 | width, pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 250 | jpegQual, flags | TJFLAG_NOREALLOC) == -1) { |
| 251 | SAFE_RELEASE(dst, jpegBuf); |
| 252 | SAFE_RELEASE(src, srcBuf); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 253 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 254 | } |
DRC | fac3bea | 2012-09-24 02:27:55 +0000 | [diff] [blame] | 255 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 256 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 257 | SAFE_RELEASE(dst, jpegBuf); |
| 258 | SAFE_RELEASE(src, srcBuf); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 259 | return (jint)jpegSize; |
DRC | fac3bea | 2012-09-24 02:27:55 +0000 | [diff] [blame] | 260 | } |
| 261 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 262 | /* TurboJPEG 1.3.x: TJCompressor::compress() byte source */ |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 263 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 264 | (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width, |
| 265 | jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp, |
| 266 | jint jpegQual, jint flags) |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 267 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 268 | return TJCompressor_compress(env, obj, src, 1, x, y, width, pitch, height, |
| 269 | pf, dst, jpegSubsamp, jpegQual, flags); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 270 | } |
| 271 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 272 | /* TurboJPEG 1.2.x: TJCompressor::compress() byte source */ |
DRC | fac3bea | 2012-09-24 02:27:55 +0000 | [diff] [blame] | 273 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 274 | (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch, |
| 275 | jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual, |
| 276 | jint flags) |
DRC | fac3bea | 2012-09-24 02:27:55 +0000 | [diff] [blame] | 277 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 278 | return TJCompressor_compress(env, obj, src, 1, 0, 0, width, pitch, height, |
| 279 | pf, dst, jpegSubsamp, jpegQual, flags); |
DRC | fac3bea | 2012-09-24 02:27:55 +0000 | [diff] [blame] | 280 | } |
| 281 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 282 | /* TurboJPEG 1.3.x: TJCompressor::compress() int source */ |
DRC | fac3bea | 2012-09-24 02:27:55 +0000 | [diff] [blame] | 283 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 284 | (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width, |
| 285 | jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp, |
| 286 | jint jpegQual, jint flags) |
DRC | fac3bea | 2012-09-24 02:27:55 +0000 | [diff] [blame] | 287 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 288 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 289 | THROW_ARG("Invalid argument in compress()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 290 | if (tjPixelSize[pf] != sizeof(jint)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 291 | THROW_ARG("Pixel format must be 32-bit when compressing from an integer buffer."); |
DRC | fac3bea | 2012-09-24 02:27:55 +0000 | [diff] [blame] | 292 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 293 | return TJCompressor_compress(env, obj, src, sizeof(jint), x, y, width, |
| 294 | stride * sizeof(jint), height, pf, dst, |
| 295 | jpegSubsamp, jpegQual, flags); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 296 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 297 | bailout: |
| 298 | return 0; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 299 | } |
| 300 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 301 | /* TurboJPEG 1.2.x: TJCompressor::compress() int source */ |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 302 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 303 | (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride, |
| 304 | jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual, |
| 305 | jint flags) |
DRC | 84a1bcc | 2011-02-23 12:09:56 +0000 | [diff] [blame] | 306 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 307 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 308 | THROW_ARG("Invalid argument in compress()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 309 | if (tjPixelSize[pf] != sizeof(jint)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 310 | THROW_ARG("Pixel format must be 32-bit when compressing from an integer buffer."); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 311 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 312 | return TJCompressor_compress(env, obj, src, sizeof(jint), 0, 0, width, |
| 313 | stride * sizeof(jint), height, pf, dst, |
| 314 | jpegSubsamp, jpegQual, flags); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 315 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 316 | bailout: |
| 317 | return 0; |
DRC | 84a1bcc | 2011-02-23 12:09:56 +0000 | [diff] [blame] | 318 | } |
| 319 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 320 | /* TurboJPEG 1.4.x: TJCompressor::compressFromYUV() */ |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 321 | JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3_3B_3II_3III_3BII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 322 | (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, |
| 323 | jint width, jintArray jSrcStrides, jint height, jint subsamp, |
| 324 | jbyteArray dst, jint jpegQual, jint flags) |
DRC | 1e67274 | 2013-10-31 05:04:51 +0000 | [diff] [blame] | 325 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 326 | tjhandle handle = 0; |
| 327 | unsigned long jpegSize = 0; |
| 328 | jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL }; |
| 329 | const unsigned char *srcPlanes[3]; |
| 330 | unsigned char *jpegBuf = NULL; |
| 331 | int *srcOffsets = NULL, *srcStrides = NULL; |
| 332 | int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; |
DRC | 1e67274 | 2013-10-31 05:04:51 +0000 | [diff] [blame] | 333 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 334 | GET_HANDLE(); |
DRC | 1e67274 | 2013-10-31 05:04:51 +0000 | [diff] [blame] | 335 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 336 | if (subsamp < 0 || subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 337 | THROW_ARG("Invalid argument in compressFromYUV()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 338 | if (org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 339 | THROW_ARG("Mismatch between Java and C API"); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 340 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 341 | if ((*env)->GetArrayLength(env, srcobjs) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 342 | THROW_ARG("Planes array is too small for the subsampling type"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 343 | if ((*env)->GetArrayLength(env, jSrcOffsets) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 344 | THROW_ARG("Offsets array is too small for the subsampling type"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 345 | if ((*env)->GetArrayLength(env, jSrcStrides) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 346 | THROW_ARG("Strides array is too small for the subsampling type"); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 347 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 348 | jpegSize = tjBufSize(width, height, subsamp); |
| 349 | if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 350 | THROW_ARG("Destination buffer is not large enough"); |
DRC | 1e67274 | 2013-10-31 05:04:51 +0000 | [diff] [blame] | 351 | |
DRC | 5ea77d8 | 2018-10-26 08:55:22 -0500 | [diff] [blame] | 352 | if (ProcessSystemProperties(env) < 0) goto bailout; |
| 353 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 354 | #define RELEASE_ARRAYS_COMPRESSFROMYUV() { \ |
| 355 | SAFE_RELEASE(dst, jpegBuf); \ |
| 356 | for (i = 0; i < nc; i++) \ |
| 357 | SAFE_RELEASE(jSrcPlanes[i], srcPlanes[i]); \ |
| 358 | SAFE_RELEASE(jSrcStrides, srcStrides); \ |
| 359 | SAFE_RELEASE(jSrcOffsets, srcOffsets); \ |
| 360 | } |
| 361 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 362 | BAILIF0(srcOffsets = (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); |
| 363 | BAILIF0(srcStrides = (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 364 | for (i = 0; i < nc; i++) { |
| 365 | int planeSize = tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp); |
| 366 | int pw = tjPlaneWidth(i, width, subsamp); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 367 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 368 | if (planeSize < 0 || pw < 0) { |
| 369 | RELEASE_ARRAYS_COMPRESSFROMYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 370 | THROW_ARG(tjGetErrorStr()); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 371 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 372 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 373 | if (srcOffsets[i] < 0) { |
| 374 | RELEASE_ARRAYS_COMPRESSFROMYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 375 | THROW_ARG("Invalid argument in compressFromYUV()"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 376 | } |
| 377 | if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) { |
| 378 | RELEASE_ARRAYS_COMPRESSFROMYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 379 | THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 380 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 381 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 382 | BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 383 | if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < |
| 384 | srcOffsets[i] + planeSize) { |
| 385 | RELEASE_ARRAYS_COMPRESSFROMYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 386 | THROW_ARG("Source plane is not large enough"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 387 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 388 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 389 | BAILIF0(srcPlanes[i] = |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 390 | (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); |
| 391 | srcPlanes[i] = &srcPlanes[i][srcOffsets[i]]; |
| 392 | } |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 393 | BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); |
DRC | 1e67274 | 2013-10-31 05:04:51 +0000 | [diff] [blame] | 394 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 395 | if (tjCompressFromYUVPlanes(handle, srcPlanes, width, srcStrides, height, |
| 396 | subsamp, &jpegBuf, &jpegSize, jpegQual, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 397 | flags | TJFLAG_NOREALLOC) == -1) { |
| 398 | RELEASE_ARRAYS_COMPRESSFROMYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 399 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 400 | } |
DRC | 1e67274 | 2013-10-31 05:04:51 +0000 | [diff] [blame] | 401 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 402 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 403 | RELEASE_ARRAYS_COMPRESSFROMYUV(); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 404 | return (jint)jpegSize; |
DRC | 1e67274 | 2013-10-31 05:04:51 +0000 | [diff] [blame] | 405 | } |
| 406 | |
DRC | 5d87f6d | 2014-08-15 16:40:56 +0000 | [diff] [blame] | 407 | static void TJCompressor_encodeYUV |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 408 | (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y, |
| 409 | jint width, jint pitch, jint height, jint pf, jobjectArray dstobjs, |
| 410 | jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags) |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 411 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 412 | tjhandle handle = 0; |
| 413 | jsize arraySize = 0, actualPitch; |
| 414 | jbyteArray jDstPlanes[3] = { NULL, NULL, NULL }; |
| 415 | unsigned char *srcBuf = NULL, *dstPlanes[3]; |
| 416 | int *dstOffsets = NULL, *dstStrides = NULL; |
| 417 | int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 418 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 419 | GET_HANDLE(); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 420 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 421 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || |
| 422 | height < 1 || pitch < 0 || subsamp < 0 || |
| 423 | subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 424 | THROW_ARG("Invalid argument in encodeYUV()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 425 | if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF || |
| 426 | org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 427 | THROW_ARG("Mismatch between Java and C API"); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 428 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 429 | if ((*env)->GetArrayLength(env, dstobjs) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 430 | THROW_ARG("Planes array is too small for the subsampling type"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 431 | if ((*env)->GetArrayLength(env, jDstOffsets) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 432 | THROW_ARG("Offsets array is too small for the subsampling type"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 433 | if ((*env)->GetArrayLength(env, jDstStrides) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 434 | THROW_ARG("Strides array is too small for the subsampling type"); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 435 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 436 | actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; |
| 437 | arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; |
| 438 | if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 439 | THROW_ARG("Source buffer is not large enough"); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 440 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 441 | #define RELEASE_ARRAYS_ENCODEYUV() { \ |
| 442 | SAFE_RELEASE(src, srcBuf); \ |
| 443 | for (i = 0; i < nc; i++) \ |
| 444 | SAFE_RELEASE(jDstPlanes[i], dstPlanes[i]); \ |
| 445 | SAFE_RELEASE(jDstStrides, dstStrides); \ |
| 446 | SAFE_RELEASE(jDstOffsets, dstOffsets); \ |
| 447 | } |
| 448 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 449 | BAILIF0(dstOffsets = (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); |
| 450 | BAILIF0(dstStrides = (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 451 | for (i = 0; i < nc; i++) { |
| 452 | int planeSize = tjPlaneSizeYUV(i, width, dstStrides[i], height, subsamp); |
| 453 | int pw = tjPlaneWidth(i, width, subsamp); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 454 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 455 | if (planeSize < 0 || pw < 0) { |
| 456 | RELEASE_ARRAYS_ENCODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 457 | THROW_ARG(tjGetErrorStr()); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 458 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 459 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 460 | if (dstOffsets[i] < 0) { |
| 461 | RELEASE_ARRAYS_ENCODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 462 | THROW_ARG("Invalid argument in encodeYUV()"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 463 | } |
| 464 | if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) { |
| 465 | RELEASE_ARRAYS_ENCODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 466 | THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 467 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 468 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 469 | BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 470 | if ((*env)->GetArrayLength(env, jDstPlanes[i]) < |
| 471 | dstOffsets[i] + planeSize) { |
| 472 | RELEASE_ARRAYS_ENCODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 473 | THROW_ARG("Destination plane is not large enough"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 474 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 475 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 476 | BAILIF0(dstPlanes[i] = |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 477 | (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); |
| 478 | dstPlanes[i] = &dstPlanes[i][dstOffsets[i]]; |
| 479 | } |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 480 | BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 481 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 482 | if (tjEncodeYUVPlanes(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]], |
| 483 | width, pitch, height, pf, dstPlanes, dstStrides, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 484 | subsamp, flags) == -1) { |
| 485 | RELEASE_ARRAYS_ENCODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 486 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 487 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 488 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 489 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 490 | RELEASE_ARRAYS_ENCODEYUV(); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 491 | } |
| 492 | |
| 493 | /* TurboJPEG 1.4.x: TJCompressor::encodeYUV() byte source */ |
| 494 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3_3B_3I_3III |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 495 | (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width, |
| 496 | jint pitch, jint height, jint pf, jobjectArray dstobjs, |
| 497 | jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags) |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 498 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 499 | TJCompressor_encodeYUV(env, obj, src, 1, x, y, width, pitch, height, pf, |
| 500 | dstobjs, jDstOffsets, jDstStrides, subsamp, flags); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 501 | } |
| 502 | |
| 503 | /* TurboJPEG 1.4.x: TJCompressor::encodeYUV() int source */ |
| 504 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3_3B_3I_3III |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 505 | (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width, |
| 506 | jint stride, jint height, jint pf, jobjectArray dstobjs, |
| 507 | jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags) |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 508 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 509 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 510 | THROW_ARG("Invalid argument in encodeYUV()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 511 | if (tjPixelSize[pf] != sizeof(jint)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 512 | THROW_ARG("Pixel format must be 32-bit when encoding from an integer buffer."); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 513 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 514 | TJCompressor_encodeYUV(env, obj, src, sizeof(jint), x, y, width, |
| 515 | stride * sizeof(jint), height, pf, dstobjs, |
| 516 | jDstOffsets, jDstStrides, subsamp, flags); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 517 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 518 | bailout: |
| 519 | return; |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 520 | } |
| 521 | |
DRC | 6399d0a | 2019-04-23 14:10:04 -0500 | [diff] [blame] | 522 | static void JNICALL TJCompressor_encodeYUV_12 |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 523 | (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint width, |
| 524 | jint pitch, jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 525 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 526 | tjhandle handle = 0; |
| 527 | jsize arraySize = 0; |
| 528 | unsigned char *srcBuf = NULL, *dstBuf = NULL; |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 529 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 530 | GET_HANDLE(); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 531 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 532 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || |
| 533 | height < 1 || pitch < 0) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 534 | THROW_ARG("Invalid argument in encodeYUV()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 535 | if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 536 | THROW_ARG("Mismatch between Java and C API"); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 537 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 538 | arraySize = (pitch == 0) ? width * tjPixelSize[pf] * height : pitch * height; |
| 539 | if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 540 | THROW_ARG("Source buffer is not large enough"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 541 | if ((*env)->GetArrayLength(env, dst) < |
| 542 | (jsize)tjBufSizeYUV(width, height, subsamp)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 543 | THROW_ARG("Destination buffer is not large enough"); |
DRC | 6acf52b | 2011-03-02 01:09:20 +0000 | [diff] [blame] | 544 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 545 | BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); |
| 546 | BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 547 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 548 | if (tjEncodeYUV2(handle, srcBuf, width, pitch, height, pf, dstBuf, subsamp, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 549 | flags) == -1) { |
| 550 | SAFE_RELEASE(dst, dstBuf); |
| 551 | SAFE_RELEASE(src, srcBuf); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 552 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 553 | } |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 554 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 555 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 556 | SAFE_RELEASE(dst, dstBuf); |
| 557 | SAFE_RELEASE(src, srcBuf); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 558 | } |
| 559 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 560 | /* TurboJPEG 1.2.x: TJCompressor::encodeYUV() byte source */ |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 561 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 562 | (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch, |
| 563 | jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 564 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 565 | TJCompressor_encodeYUV_12(env, obj, src, 1, width, pitch, height, pf, dst, |
| 566 | subsamp, flags); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 567 | } |
| 568 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 569 | /* TurboJPEG 1.2.x: TJCompressor::encodeYUV() int source */ |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 570 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 571 | (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride, |
| 572 | jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 573 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 574 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 575 | THROW_ARG("Invalid argument in encodeYUV()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 576 | if (tjPixelSize[pf] != sizeof(jint)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 577 | THROW_ARG("Pixel format must be 32-bit when encoding from an integer buffer."); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 578 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 579 | TJCompressor_encodeYUV_12(env, obj, src, sizeof(jint), width, |
| 580 | stride * sizeof(jint), height, pf, dst, subsamp, |
| 581 | flags); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 582 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 583 | bailout: |
| 584 | return; |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 585 | } |
| 586 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 587 | /* TurboJPEG 1.2.x: TJCompressor::destroy() */ |
DRC | c5a4199 | 2011-02-08 06:54:36 +0000 | [diff] [blame] | 588 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 589 | (JNIEnv *env, jobject obj) |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 590 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 591 | tjhandle handle = 0; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 592 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 593 | GET_HANDLE(); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 594 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 595 | if (tjDestroy(handle) == -1) THROW_TJ(); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 596 | (*env)->SetLongField(env, obj, _fid, 0); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 597 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 598 | bailout: |
| 599 | return; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 600 | } |
| 601 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 602 | /* TurboJPEG 1.2.x: TJDecompressor::init() */ |
DRC | c5a4199 | 2011-02-08 06:54:36 +0000 | [diff] [blame] | 603 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 604 | (JNIEnv *env, jobject obj) |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 605 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 606 | jclass cls; |
| 607 | jfieldID fid; |
| 608 | tjhandle handle; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 609 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 610 | if ((handle = tjInitDecompress()) == NULL) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 611 | THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 612 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 613 | BAILIF0(cls = (*env)->GetObjectClass(env, obj)); |
| 614 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 615 | (*env)->SetLongField(env, obj, fid, (size_t)handle); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 616 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 617 | bailout: |
| 618 | return; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 619 | } |
| 620 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 621 | /* TurboJPEG 1.2.x: TJDecompressor::getScalingFactors() */ |
DRC | 109a578 | 2011-03-01 09:53:07 +0000 | [diff] [blame] | 622 | JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 623 | (JNIEnv *env, jclass cls) |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 624 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 625 | jclass sfcls = NULL; |
| 626 | jfieldID fid = 0; |
| 627 | tjscalingfactor *sf = NULL; |
| 628 | int n = 0, i; |
| 629 | jobject sfobj = NULL; |
| 630 | jobjectArray sfjava = NULL; |
DRC | 109a578 | 2011-03-01 09:53:07 +0000 | [diff] [blame] | 631 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 632 | if ((sf = tjGetScalingFactors(&n)) == NULL || n == 0) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 633 | THROW_ARG(tjGetErrorStr()); |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 634 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 635 | BAILIF0(sfcls = (*env)->FindClass(env, |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 636 | "org/libjpegturbo/turbojpeg/TJScalingFactor")); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 637 | BAILIF0(sfjava = (jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0)); |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 638 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 639 | for (i = 0; i < n; i++) { |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 640 | BAILIF0(sfobj = (*env)->AllocObject(env, sfcls)); |
| 641 | BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "num", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 642 | (*env)->SetIntField(env, sfobj, fid, sf[i].num); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 643 | BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "denom", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 644 | (*env)->SetIntField(env, sfobj, fid, sf[i].denom); |
| 645 | (*env)->SetObjectArrayElement(env, sfjava, i, sfobj); |
| 646 | } |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 647 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 648 | bailout: |
| 649 | return sfjava; |
DRC | 36336fc | 2011-02-22 10:27:31 +0000 | [diff] [blame] | 650 | } |
| 651 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 652 | /* TurboJPEG 1.2.x: TJDecompressor::decompressHeader() */ |
DRC | 3bad53f | 2011-02-23 02:20:49 +0000 | [diff] [blame] | 653 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 654 | (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize) |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 655 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 656 | tjhandle handle = 0; |
| 657 | unsigned char *jpegBuf = NULL; |
| 658 | int width = 0, height = 0, jpegSubsamp = -1, jpegColorspace = -1; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 659 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 660 | GET_HANDLE(); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 661 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 662 | if ((*env)->GetArrayLength(env, src) < jpegSize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 663 | THROW_ARG("Source buffer is not large enough"); |
DRC | 6acf52b | 2011-03-02 01:09:20 +0000 | [diff] [blame] | 664 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 665 | BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 666 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 667 | if (tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize, &width, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 668 | &height, &jpegSubsamp, &jpegColorspace) == -1) { |
| 669 | SAFE_RELEASE(src, jpegBuf); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 670 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 671 | } |
DRC | 8951cf0 | 2014-08-14 16:54:04 +0000 | [diff] [blame] | 672 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 673 | SAFE_RELEASE(src, jpegBuf); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 674 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 675 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 676 | (*env)->SetIntField(env, obj, _fid, jpegSubsamp); |
| 677 | if ((_fid = (*env)->GetFieldID(env, _cls, "jpegColorspace", "I")) == 0) |
| 678 | (*env)->ExceptionClear(env); |
| 679 | else |
| 680 | (*env)->SetIntField(env, obj, _fid, jpegColorspace); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 681 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 682 | (*env)->SetIntField(env, obj, _fid, width); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 683 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 684 | (*env)->SetIntField(env, obj, _fid, height); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 685 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 686 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 687 | SAFE_RELEASE(src, jpegBuf); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 688 | } |
| 689 | |
DRC | 5d87f6d | 2014-08-15 16:40:56 +0000 | [diff] [blame] | 690 | static void TJDecompressor_decompress |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 691 | (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jarray dst, |
| 692 | jint dstElementSize, jint x, jint y, jint width, jint pitch, jint height, |
| 693 | jint pf, jint flags) |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 694 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 695 | tjhandle handle = 0; |
| 696 | jsize arraySize = 0, actualPitch; |
| 697 | unsigned char *jpegBuf = NULL, *dstBuf = NULL; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 698 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 699 | GET_HANDLE(); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 700 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 701 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 702 | THROW_ARG("Invalid argument in decompress()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 703 | if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 704 | THROW_ARG("Mismatch between Java and C API"); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 705 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 706 | if ((*env)->GetArrayLength(env, src) < jpegSize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 707 | THROW_ARG("Source buffer is not large enough"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 708 | actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; |
| 709 | arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; |
| 710 | if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 711 | THROW_ARG("Destination buffer is not large enough"); |
DRC | 6acf52b | 2011-03-02 01:09:20 +0000 | [diff] [blame] | 712 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 713 | BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); |
| 714 | BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 715 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 716 | if (tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, |
| 717 | &dstBuf[y * actualPitch + x * tjPixelSize[pf]], width, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 718 | pitch, height, pf, flags) == -1) { |
| 719 | SAFE_RELEASE(dst, dstBuf); |
| 720 | SAFE_RELEASE(src, jpegBuf); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 721 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 722 | } |
DRC | f659f43 | 2012-06-06 08:41:06 +0000 | [diff] [blame] | 723 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 724 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 725 | SAFE_RELEASE(dst, dstBuf); |
| 726 | SAFE_RELEASE(src, jpegBuf); |
DRC | f659f43 | 2012-06-06 08:41:06 +0000 | [diff] [blame] | 727 | } |
| 728 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 729 | /* TurboJPEG 1.3.x: TJDecompressor::decompress() byte destination */ |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 730 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 731 | (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, |
| 732 | jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags) |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 733 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 734 | TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, x, y, width, |
| 735 | pitch, height, pf, flags); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 736 | } |
| 737 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 738 | /* TurboJPEG 1.2.x: TJDecompressor::decompress() byte destination */ |
DRC | f659f43 | 2012-06-06 08:41:06 +0000 | [diff] [blame] | 739 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 740 | (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, |
| 741 | jint width, jint pitch, jint height, jint pf, jint flags) |
DRC | f659f43 | 2012-06-06 08:41:06 +0000 | [diff] [blame] | 742 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 743 | TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, 0, 0, width, |
| 744 | pitch, height, pf, flags); |
DRC | f659f43 | 2012-06-06 08:41:06 +0000 | [diff] [blame] | 745 | } |
| 746 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 747 | /* TurboJPEG 1.3.x: TJDecompressor::decompress() int destination */ |
DRC | f659f43 | 2012-06-06 08:41:06 +0000 | [diff] [blame] | 748 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 749 | (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst, |
| 750 | jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags) |
DRC | f659f43 | 2012-06-06 08:41:06 +0000 | [diff] [blame] | 751 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 752 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 753 | THROW_ARG("Invalid argument in decompress()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 754 | if (tjPixelSize[pf] != sizeof(jint)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 755 | THROW_ARG("Pixel format must be 32-bit when decompressing to an integer buffer."); |
DRC | f659f43 | 2012-06-06 08:41:06 +0000 | [diff] [blame] | 756 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 757 | TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), x, y, |
| 758 | width, stride * sizeof(jint), height, pf, flags); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 759 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 760 | bailout: |
| 761 | return; |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 762 | } |
| 763 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 764 | /* TurboJPEG 1.2.x: TJDecompressor::decompress() int destination */ |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 765 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 766 | (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst, |
| 767 | jint width, jint stride, jint height, jint pf, jint flags) |
DRC | 84a1bcc | 2011-02-23 12:09:56 +0000 | [diff] [blame] | 768 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 769 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 770 | THROW_ARG("Invalid argument in decompress()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 771 | if (tjPixelSize[pf] != sizeof(jint)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 772 | THROW_ARG("Pixel format must be 32-bit when decompressing to an integer buffer."); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 773 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 774 | TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), 0, 0, |
| 775 | width, stride * sizeof(jint), height, pf, flags); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 776 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 777 | bailout: |
| 778 | return; |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 779 | } |
DRC | 84a1bcc | 2011-02-23 12:09:56 +0000 | [diff] [blame] | 780 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 781 | /* TurboJPEG 1.4.x: TJDecompressor::decompressToYUV() */ |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 782 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3_3B_3II_3III |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 783 | (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, |
| 784 | jobjectArray dstobjs, jintArray jDstOffsets, jint desiredWidth, |
| 785 | jintArray jDstStrides, jint desiredHeight, jint flags) |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 786 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 787 | tjhandle handle = 0; |
| 788 | jbyteArray jDstPlanes[3] = { NULL, NULL, NULL }; |
| 789 | unsigned char *jpegBuf = NULL, *dstPlanes[3]; |
| 790 | int *dstOffsets = NULL, *dstStrides = NULL; |
| 791 | int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0; |
| 792 | int nc = 0, i, width, height, scaledWidth, scaledHeight, nsf = 0; |
| 793 | tjscalingfactor *sf; |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 794 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 795 | GET_HANDLE(); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 796 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 797 | if ((*env)->GetArrayLength(env, src) < jpegSize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 798 | THROW_ARG("Source buffer is not large enough"); |
| 799 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 800 | jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 801 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 802 | jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 803 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 804 | jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 805 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 806 | nc = (jpegSubsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3); |
DRC | 6acf52b | 2011-03-02 01:09:20 +0000 | [diff] [blame] | 807 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 808 | width = desiredWidth; |
| 809 | height = desiredHeight; |
| 810 | if (width == 0) width = jpegWidth; |
| 811 | if (height == 0) height = jpegHeight; |
| 812 | sf = tjGetScalingFactors(&nsf); |
| 813 | if (!sf || nsf < 1) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 814 | THROW_ARG(tjGetErrorStr()); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 815 | for (i = 0; i < nsf; i++) { |
| 816 | scaledWidth = TJSCALED(jpegWidth, sf[i]); |
| 817 | scaledHeight = TJSCALED(jpegHeight, sf[i]); |
| 818 | if (scaledWidth <= width && scaledHeight <= height) |
| 819 | break; |
| 820 | } |
| 821 | if (i >= nsf) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 822 | THROW_ARG("Could not scale down to desired image dimensions"); |
DRC | 4f1580c | 2011-02-25 06:11:03 +0000 | [diff] [blame] | 823 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 824 | #define RELEASE_ARRAYS_DECOMPRESSTOYUV() { \ |
| 825 | SAFE_RELEASE(src, jpegBuf); \ |
| 826 | for (i = 0; i < nc; i++) \ |
| 827 | SAFE_RELEASE(jDstPlanes[i], dstPlanes[i]); \ |
| 828 | SAFE_RELEASE(jDstStrides, dstStrides); \ |
| 829 | SAFE_RELEASE(jDstOffsets, dstOffsets); \ |
| 830 | } |
| 831 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 832 | BAILIF0(dstOffsets = (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); |
| 833 | BAILIF0(dstStrides = (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 834 | for (i = 0; i < nc; i++) { |
| 835 | int planeSize = tjPlaneSizeYUV(i, scaledWidth, dstStrides[i], scaledHeight, |
| 836 | jpegSubsamp); |
| 837 | int pw = tjPlaneWidth(i, scaledWidth, jpegSubsamp); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 838 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 839 | if (planeSize < 0 || pw < 0) { |
| 840 | RELEASE_ARRAYS_DECOMPRESSTOYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 841 | THROW_ARG(tjGetErrorStr()); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 842 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 843 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 844 | if (dstOffsets[i] < 0) { |
| 845 | RELEASE_ARRAYS_DECOMPRESSTOYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 846 | THROW_ARG("Invalid argument in decompressToYUV()"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 847 | } |
| 848 | if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) { |
| 849 | RELEASE_ARRAYS_DECOMPRESSTOYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 850 | THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 851 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 852 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 853 | BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 854 | if ((*env)->GetArrayLength(env, jDstPlanes[i]) < |
| 855 | dstOffsets[i] + planeSize) { |
| 856 | RELEASE_ARRAYS_DECOMPRESSTOYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 857 | THROW_ARG("Destination plane is not large enough"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 858 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 859 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 860 | BAILIF0(dstPlanes[i] = |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 861 | (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); |
| 862 | dstPlanes[i] = &dstPlanes[i][dstOffsets[i]]; |
| 863 | } |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 864 | BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 865 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 866 | if (tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize, |
| 867 | dstPlanes, desiredWidth, dstStrides, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 868 | desiredHeight, flags) == -1) { |
| 869 | RELEASE_ARRAYS_DECOMPRESSTOYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 870 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 871 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 872 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 873 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 874 | RELEASE_ARRAYS_DECOMPRESSTOYUV(); |
DRC | 84a1bcc | 2011-02-23 12:09:56 +0000 | [diff] [blame] | 875 | } |
| 876 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 877 | /* TurboJPEG 1.2.x: TJDecompressor::decompressToYUV() */ |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 878 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 879 | (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, |
| 880 | jint flags) |
DRC | fef9852 | 2013-04-28 01:32:52 +0000 | [diff] [blame] | 881 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 882 | tjhandle handle = 0; |
| 883 | unsigned char *jpegBuf = NULL, *dstBuf = NULL; |
| 884 | int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0; |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 885 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 886 | GET_HANDLE(); |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 887 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 888 | if ((*env)->GetArrayLength(env, src) < jpegSize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 889 | THROW_ARG("Source buffer is not large enough"); |
| 890 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 891 | jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 892 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 893 | jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 894 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 895 | jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); |
| 896 | if ((*env)->GetArrayLength(env, dst) < |
| 897 | (jsize)tjBufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 898 | THROW_ARG("Destination buffer is not large enough"); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 899 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 900 | BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); |
| 901 | BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 902 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 903 | if (tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 904 | flags) == -1) { |
| 905 | SAFE_RELEASE(dst, dstBuf); |
| 906 | SAFE_RELEASE(src, jpegBuf); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 907 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 908 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 909 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 910 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 911 | SAFE_RELEASE(dst, dstBuf); |
| 912 | SAFE_RELEASE(src, jpegBuf); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 913 | } |
| 914 | |
| 915 | static void TJDecompressor_decodeYUV |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 916 | (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, |
| 917 | jintArray jSrcStrides, jint subsamp, jarray dst, jint dstElementSize, |
| 918 | jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags) |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 919 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 920 | tjhandle handle = 0; |
| 921 | jsize arraySize = 0, actualPitch; |
| 922 | jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL }; |
| 923 | const unsigned char *srcPlanes[3]; |
| 924 | unsigned char *dstBuf = NULL; |
| 925 | int *srcOffsets = NULL, *srcStrides = NULL; |
| 926 | int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 927 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 928 | GET_HANDLE(); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 929 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 930 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || subsamp < 0 || |
| 931 | subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 932 | THROW_ARG("Invalid argument in decodeYUV()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 933 | if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF || |
| 934 | org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 935 | THROW_ARG("Mismatch between Java and C API"); |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 936 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 937 | if ((*env)->GetArrayLength(env, srcobjs) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 938 | THROW_ARG("Planes array is too small for the subsampling type"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 939 | if ((*env)->GetArrayLength(env, jSrcOffsets) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 940 | THROW_ARG("Offsets array is too small for the subsampling type"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 941 | if ((*env)->GetArrayLength(env, jSrcStrides) < nc) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 942 | THROW_ARG("Strides array is too small for the subsampling type"); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 943 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 944 | actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; |
| 945 | arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; |
| 946 | if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 947 | THROW_ARG("Destination buffer is not large enough"); |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 948 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 949 | #define RELEASE_ARRAYS_DECODEYUV() { \ |
| 950 | SAFE_RELEASE(dst, dstBuf); \ |
| 951 | for (i = 0; i < nc; i++) \ |
| 952 | SAFE_RELEASE(jSrcPlanes[i], srcPlanes[i]); \ |
| 953 | SAFE_RELEASE(jSrcStrides, srcStrides); \ |
| 954 | SAFE_RELEASE(jSrcOffsets, srcOffsets); \ |
| 955 | } |
| 956 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 957 | BAILIF0(srcOffsets = (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); |
| 958 | BAILIF0(srcStrides = (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 959 | for (i = 0; i < nc; i++) { |
| 960 | int planeSize = tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp); |
| 961 | int pw = tjPlaneWidth(i, width, subsamp); |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 962 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 963 | if (planeSize < 0 || pw < 0) { |
| 964 | RELEASE_ARRAYS_DECODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 965 | THROW_ARG(tjGetErrorStr()); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 966 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 967 | |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 968 | if (srcOffsets[i] < 0) { |
| 969 | RELEASE_ARRAYS_DECODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 970 | THROW_ARG("Invalid argument in decodeYUV()"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 971 | } |
| 972 | if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) { |
| 973 | RELEASE_ARRAYS_DECODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 974 | THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 975 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 976 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 977 | BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 978 | if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < |
| 979 | srcOffsets[i] + planeSize) { |
| 980 | RELEASE_ARRAYS_DECODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 981 | THROW_ARG("Source plane is not large enough"); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 982 | } |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 983 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 984 | BAILIF0(srcPlanes[i] = |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 985 | (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); |
| 986 | srcPlanes[i] = &srcPlanes[i][srcOffsets[i]]; |
| 987 | } |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 988 | BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 989 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 990 | if (tjDecodeYUVPlanes(handle, srcPlanes, srcStrides, subsamp, |
| 991 | &dstBuf[y * actualPitch + x * tjPixelSize[pf]], width, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 992 | pitch, height, pf, flags) == -1) { |
| 993 | RELEASE_ARRAYS_DECODEYUV(); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 994 | THROW_TJ(); |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 995 | } |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 996 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 997 | bailout: |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 998 | RELEASE_ARRAYS_DECODEYUV(); |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 999 | } |
| 1000 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 1001 | /* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() byte destination */ |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 1002 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3BIIIIIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1003 | (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, |
| 1004 | jintArray jSrcStrides, jint subsamp, jbyteArray dst, jint x, jint y, |
| 1005 | jint width, jint pitch, jint height, jint pf, jint flags) |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 1006 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1007 | TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides, |
| 1008 | subsamp, dst, 1, x, y, width, pitch, height, pf, |
| 1009 | flags); |
DRC | 927a10d | 2014-08-15 13:18:58 +0000 | [diff] [blame] | 1010 | } |
| 1011 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 1012 | /* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() int destination */ |
DRC | 40dd314 | 2014-08-17 12:23:49 +0000 | [diff] [blame] | 1013 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3IIIIIIII |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1014 | (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, |
| 1015 | jintArray jSrcStrides, jint subsamp, jintArray dst, jint x, jint y, |
| 1016 | jint width, jint stride, jint height, jint pf, jint flags) |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 1017 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1018 | if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1019 | THROW_ARG("Invalid argument in decodeYUV()"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1020 | if (tjPixelSize[pf] != sizeof(jint)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1021 | THROW_ARG("Pixel format must be 32-bit when decoding to an integer buffer."); |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 1022 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1023 | TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides, |
| 1024 | subsamp, dst, sizeof(jint), x, y, width, |
| 1025 | stride * sizeof(jint), height, pf, flags); |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 1026 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1027 | bailout: |
| 1028 | return; |
DRC | fc26b65 | 2014-03-16 22:56:26 +0000 | [diff] [blame] | 1029 | } |
| 1030 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 1031 | /* TurboJPEG 1.2.x: TJTransformer::init() */ |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1032 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1033 | (JNIEnv *env, jobject obj) |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1034 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1035 | jclass cls; |
| 1036 | jfieldID fid; |
| 1037 | tjhandle handle; |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1038 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1039 | if ((handle = tjInitTransform()) == NULL) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1040 | THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1041 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1042 | BAILIF0(cls = (*env)->GetObjectClass(env, obj)); |
| 1043 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1044 | (*env)->SetLongField(env, obj, fid, (size_t)handle); |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1045 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1046 | bailout: |
| 1047 | return; |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1048 | } |
| 1049 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1050 | typedef struct _JNICustomFilterParams { |
| 1051 | JNIEnv *env; |
| 1052 | jobject tobj; |
| 1053 | jobject cfobj; |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1054 | } JNICustomFilterParams; |
| 1055 | |
| 1056 | static int JNICustomFilter(short *coeffs, tjregion arrayRegion, |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1057 | tjregion planeRegion, int componentIndex, |
| 1058 | int transformIndex, tjtransform *transform) |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1059 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1060 | JNICustomFilterParams *params = (JNICustomFilterParams *)transform->data; |
| 1061 | JNIEnv *env = params->env; |
| 1062 | jobject tobj = params->tobj, cfobj = params->cfobj; |
| 1063 | jobject arrayRegionObj, planeRegionObj, bufobj, borobj; |
| 1064 | jclass cls; |
| 1065 | jmethodID mid; |
| 1066 | jfieldID fid; |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1067 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1068 | BAILIF0(bufobj = (*env)->NewDirectByteBuffer(env, coeffs, |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1069 | sizeof(short) * arrayRegion.w * arrayRegion.h)); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1070 | BAILIF0(cls = (*env)->FindClass(env, "java/nio/ByteOrder")); |
| 1071 | BAILIF0(mid = (*env)->GetStaticMethodID(env, cls, "nativeOrder", |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1072 | "()Ljava/nio/ByteOrder;")); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1073 | BAILIF0(borobj = (*env)->CallStaticObjectMethod(env, cls, mid)); |
| 1074 | BAILIF0(cls = (*env)->GetObjectClass(env, bufobj)); |
| 1075 | BAILIF0(mid = (*env)->GetMethodID(env, cls, "order", |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1076 | "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;")); |
| 1077 | (*env)->CallObjectMethod(env, bufobj, mid, borobj); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1078 | BAILIF0(mid = (*env)->GetMethodID(env, cls, "asShortBuffer", |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1079 | "()Ljava/nio/ShortBuffer;")); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1080 | BAILIF0(bufobj = (*env)->CallObjectMethod(env, bufobj, mid)); |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1081 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1082 | BAILIF0(cls = (*env)->FindClass(env, "java/awt/Rectangle")); |
| 1083 | BAILIF0(arrayRegionObj = (*env)->AllocObject(env, cls)); |
| 1084 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "x", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1085 | (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1086 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1087 | (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1088 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1089 | (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1090 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "height", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1091 | (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h); |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1092 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1093 | BAILIF0(planeRegionObj = (*env)->AllocObject(env, cls)); |
| 1094 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "x", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1095 | (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1096 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1097 | (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1098 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1099 | (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1100 | BAILIF0(fid = (*env)->GetFieldID(env, cls, "height", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1101 | (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h); |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1102 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1103 | BAILIF0(cls = (*env)->GetObjectClass(env, cfobj)); |
| 1104 | BAILIF0(mid = (*env)->GetMethodID(env, cls, "customFilter", |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1105 | "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V")); |
| 1106 | (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj, |
| 1107 | planeRegionObj, componentIndex, transformIndex, tobj); |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1108 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1109 | return 0; |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1110 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1111 | bailout: |
| 1112 | return -1; |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1113 | } |
| 1114 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 1115 | /* TurboJPEG 1.2.x: TJTransformer::transform() */ |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1116 | JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1117 | (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize, |
| 1118 | jobjectArray dstobjs, jobjectArray tobjs, jint flags) |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1119 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1120 | tjhandle handle = 0; |
| 1121 | unsigned char *jpegBuf = NULL, **dstBufs = NULL; |
| 1122 | jsize n = 0; |
| 1123 | unsigned long *dstSizes = NULL; |
| 1124 | tjtransform *t = NULL; |
| 1125 | jbyteArray *jdstBufs = NULL; |
| 1126 | int i, jpegWidth = 0, jpegHeight = 0, jpegSubsamp; |
| 1127 | jintArray jdstSizes = 0; |
| 1128 | jint *dstSizesi = NULL; |
| 1129 | JNICustomFilterParams *params = NULL; |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1130 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1131 | GET_HANDLE(); |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1132 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1133 | if ((*env)->GetArrayLength(env, jsrcBuf) < jpegSize) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1134 | THROW_ARG("Source buffer is not large enough"); |
| 1135 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1136 | jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1137 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1138 | jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1139 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1140 | jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1141 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1142 | n = (*env)->GetArrayLength(env, dstobjs); |
| 1143 | if (n != (*env)->GetArrayLength(env, tobjs)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1144 | THROW_ARG("Mismatch between size of transforms array and destination buffers array"); |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1145 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1146 | if ((dstBufs = |
| 1147 | (unsigned char **)malloc(sizeof(unsigned char *) * n)) == NULL) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1148 | THROW_MEM(); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1149 | if ((jdstBufs = (jbyteArray *)malloc(sizeof(jbyteArray) * n)) == NULL) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1150 | THROW_MEM(); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1151 | if ((dstSizes = (unsigned long *)malloc(sizeof(unsigned long) * n)) == NULL) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1152 | THROW_MEM(); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1153 | if ((t = (tjtransform *)malloc(sizeof(tjtransform) * n)) == NULL) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1154 | THROW_MEM(); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1155 | if ((params = (JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams) * |
| 1156 | n)) == NULL) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1157 | THROW_MEM(); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1158 | for (i = 0; i < n; i++) { |
| 1159 | dstBufs[i] = NULL; jdstBufs[i] = NULL; dstSizes[i] = 0; |
| 1160 | memset(&t[i], 0, sizeof(tjtransform)); |
| 1161 | memset(¶ms[i], 0, sizeof(JNICustomFilterParams)); |
| 1162 | } |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1163 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1164 | for (i = 0; i < n; i++) { |
| 1165 | jobject tobj, cfobj; |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1166 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1167 | BAILIF0(tobj = (*env)->GetObjectArrayElement(env, tobjs, i)); |
| 1168 | BAILIF0(_cls = (*env)->GetObjectClass(env, tobj)); |
| 1169 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "op", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1170 | t[i].op = (*env)->GetIntField(env, tobj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1171 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "options", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1172 | t[i].options = (*env)->GetIntField(env, tobj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1173 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "x", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1174 | t[i].r.x = (*env)->GetIntField(env, tobj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1175 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "y", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1176 | t[i].r.y = (*env)->GetIntField(env, tobj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1177 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "width", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1178 | t[i].r.w = (*env)->GetIntField(env, tobj, _fid); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1179 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "height", "I")); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1180 | t[i].r.h = (*env)->GetIntField(env, tobj, _fid); |
DRC | f546711 | 2011-09-20 05:02:19 +0000 | [diff] [blame] | 1181 | |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1182 | BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "cf", |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1183 | "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;")); |
| 1184 | cfobj = (*env)->GetObjectField(env, tobj, _fid); |
| 1185 | if (cfobj) { |
| 1186 | params[i].env = env; |
| 1187 | params[i].tobj = tobj; |
| 1188 | params[i].cfobj = cfobj; |
| 1189 | t[i].customFilter = JNICustomFilter; |
| 1190 | t[i].data = (void *)¶ms[i]; |
| 1191 | } |
| 1192 | } |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1193 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1194 | for (i = 0; i < n; i++) { |
| 1195 | int w = jpegWidth, h = jpegHeight; |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1196 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1197 | if (t[i].r.w != 0) w = t[i].r.w; |
| 1198 | if (t[i].r.h != 0) h = t[i].r.h; |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1199 | BAILIF0(jdstBufs[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1200 | if ((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i]) < |
| 1201 | tjBufSize(w, h, jpegSubsamp)) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1202 | THROW_ARG("Destination buffer is not large enough"); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1203 | } |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1204 | BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0)); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1205 | for (i = 0; i < n; i++) |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1206 | BAILIF0(dstBufs[i] = |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1207 | (*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0)); |
DRC | 8951cf0 | 2014-08-14 16:54:04 +0000 | [diff] [blame] | 1208 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1209 | if (tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t, |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 1210 | flags | TJFLAG_NOREALLOC) == -1) { |
| 1211 | for (i = 0; i < n; i++) |
| 1212 | SAFE_RELEASE(jdstBufs[i], dstBufs[i]); |
| 1213 | SAFE_RELEASE(jsrcBuf, jpegBuf); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1214 | THROW_TJ(); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1215 | } |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 1216 | |
| 1217 | for (i = 0; i < n; i++) |
| 1218 | SAFE_RELEASE(jdstBufs[i], dstBufs[i]); |
| 1219 | SAFE_RELEASE(jsrcBuf, jpegBuf); |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1220 | |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1221 | jdstSizes = (*env)->NewIntArray(env, n); |
DRC | bce58f4 | 2019-04-12 07:49:35 -0500 | [diff] [blame] | 1222 | BAILIF0(dstSizesi = (*env)->GetIntArrayElements(env, jdstSizes, 0)); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1223 | for (i = 0; i < n; i++) dstSizesi[i] = (int)dstSizes[i]; |
| 1224 | |
| 1225 | bailout: |
| 1226 | if (dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0); |
| 1227 | if (dstBufs) { |
| 1228 | for (i = 0; i < n; i++) { |
| 1229 | if (dstBufs[i] && jdstBufs && jdstBufs[i]) |
| 1230 | (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0); |
| 1231 | } |
| 1232 | free(dstBufs); |
| 1233 | } |
DRC | 3301175 | 2019-04-12 08:47:28 -0500 | [diff] [blame] | 1234 | SAFE_RELEASE(jsrcBuf, jpegBuf); |
Jake Weinstein | 8683f0e | 2020-08-21 18:48:40 +0200 | [diff] [blame] | 1235 | free(jdstBufs); |
| 1236 | free(dstSizes); |
| 1237 | free(t); |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1238 | return jdstSizes; |
DRC | e857301 | 2011-03-04 10:13:59 +0000 | [diff] [blame] | 1239 | } |
| 1240 | |
DRC | a4940d1 | 2014-08-15 16:07:15 +0000 | [diff] [blame] | 1241 | /* TurboJPEG 1.2.x: TJDecompressor::destroy() */ |
DRC | c5a4199 | 2011-02-08 06:54:36 +0000 | [diff] [blame] | 1242 | JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1243 | (JNIEnv *env, jobject obj) |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 1244 | { |
DRC | 19c791c | 2018-03-08 10:55:20 -0600 | [diff] [blame] | 1245 | Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj); |
DRC | f8e0055 | 2011-02-04 11:06:36 +0000 | [diff] [blame] | 1246 | } |