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