Bug Summary

File:jdk/src/java.desktop/share/native/libawt/awt/image/awt_parseImage.c
Warning:line 100, column 10
Although the value stored to 'status' is used in the enclosing expression, the value is never actually read from 'status'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name awt_parseImage.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -D __MEDIALIB_OLD_NAMES -D __USE_J2D_NAMES -D MLIB_NO_LIBSUNMATH -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/awt -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.desktop -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/image -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/image/cvutils -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d/loops -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d/pipe -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.base -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/medialib -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/medialib -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libmlib_image -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/include -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/include -I /home/daniel/Projects/java/jdk/src/java.base/linux/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/include -I /home/daniel/Projects/java/jdk/src/java.base/share/native/include -D _FORTIFY_SOURCE=2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-unused -Wno-sign-compare -Wno-unused-result -Wno-maybe-uninitialized -Wno-format-nonliteral -Wno-parentheses -Wno-unused-value -Wno-unused-function -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility default -stack-protector 1 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/image/awt_parseImage.c
1/*
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include <stdio.h>
27#include <stdlib.h>
28#include "awt_parseImage.h"
29#include "imageInitIDs.h"
30#include "java_awt_Transparency.h"
31#include "java_awt_image_BufferedImage.h"
32#include "sun_awt_image_IntegerComponentRaster.h"
33#include "sun_awt_image_ImagingLib.h"
34#include "java_awt_color_ColorSpace.h"
35#include "awt_Mlib.h"
36#include "safe_alloc.h"
37#include "safe_math.h"
38
39static int setHints(JNIEnv *env, BufImageS_t *imageP);
40
41
42
43/* Parse the buffered image. All of the raster information is returned in the
44 * imagePP structure.
45 *
46 * The handleCustom parameter specifies whether or not the caller
47 * can use custom channels. If it is false and a custom channel
48 * is encountered, the returned value will be 0 and all structures
49 * will be deallocated.
50 *
51 * Return value:
52 * -1: Exception
53 * 0: Can't do it.
54 * 1: Success
55 */
56int awt_parseImage(JNIEnv *env, jobject jimage, BufImageS_t **imagePP,
57 int handleCustom) {
58 BufImageS_t *imageP;
59 int status;
60 jobject jraster;
61 jobject jcmodel;
62
63 /* Make sure the image exists */
64 if (JNU_IsNull(env, jimage)((jimage) == ((void*)0))) {
65 JNU_ThrowNullPointerException(env, "null BufferedImage object");
66 return -1;
67 }
68
69 if ((imageP = (BufImageS_t *) calloc(1, sizeof(BufImageS_t))) == NULL((void*)0)) {
70 JNU_ThrowOutOfMemoryError(env, "Out of memory");
71 return -1;
72 }
73 imageP->jimage = jimage;
74
75 /* Retrieve the raster */
76 if ((jraster = (*env)->GetObjectField(env, jimage,
77 g_BImgRasterID)) == NULL((void*)0)) {
78 free((void *) imageP);
79 JNU_ThrowNullPointerException(env, "null Raster object");
80 return 0;
81 }
82
83 /* Retrieve the image type */
84 imageP->imageType = (*env)->GetIntField(env, jimage, g_BImgTypeID);
85
86 /* Parse the raster */
87 if ((status = awt_parseRaster(env, jraster, &imageP->raster)) <= 0) {
88 free((void *)imageP);
89 return status;
90 }
91
92 /* Retrieve the color model */
93 if ((jcmodel = (*env)->GetObjectField(env, jimage, g_BImgCMID)) == NULL((void*)0)) {
94 free((void *) imageP);
95 JNU_ThrowNullPointerException(env, "null Raster object");
96 return 0;
97 }
98
99 /* Parse the color model */
100 if ((status = awt_parseColorModel(env, jcmodel, imageP->imageType,
Although the value stored to 'status' is used in the enclosing expression, the value is never actually read from 'status'
101 &imageP->cmodel)) <= 0) {
102 awt_freeParsedRaster(&imageP->raster, FALSE(0));
103 free((void *)imageP);
104 return 0;
105 }
106
107 /* Set hints */
108 if ((status = setHints(env, imageP)) <= 0) {
109 awt_freeParsedImage(imageP, TRUE(1));
110 return 0;
111 }
112
113 *imagePP = imageP;
114
115 return status;
116}
117
118/* Verifies whether the channel offsets are sane and correspond to the type of
119 * the raster.
120 *
121 * Return value:
122 * 0: Failure: channel offsets are invalid
123 * 1: Success
124 */
125static int checkChannelOffsets(RasterS_t *rasterP, int dataArrayLength) {
126 int i, lastPixelOffset, lastScanOffset;
127 switch (rasterP->rasterType) {
128 case COMPONENT_RASTER_TYPE1:
129 if (!SAFE_TO_MULT(rasterP->height, rasterP->scanlineStride)(((rasterP->height) > 0) && ((rasterP->scanlineStride
) >= 0) && ((0x7fffffff / (rasterP->height)) >
(rasterP->scanlineStride)))
) {
130 return 0;
131 }
132 if (!SAFE_TO_MULT(rasterP->width, rasterP->pixelStride)(((rasterP->width) > 0) && ((rasterP->pixelStride
) >= 0) && ((0x7fffffff / (rasterP->width)) >
(rasterP->pixelStride)))
) {
133 return 0;
134 }
135
136 lastScanOffset = (rasterP->height - 1) * rasterP->scanlineStride;
137 lastPixelOffset = (rasterP->width - 1) * rasterP->pixelStride;
138
139
140 if (!SAFE_TO_ADD(lastPixelOffset, lastScanOffset)(((lastPixelOffset) >= 0) && ((lastScanOffset) >=
0) && ((0x7fffffff - (lastPixelOffset)) > (lastScanOffset
)))
) {
141 return 0;
142 }
143
144 lastPixelOffset += lastScanOffset;
145
146 for (i = 0; i < rasterP->numDataElements; i++) {
147 int off = rasterP->chanOffsets[i];
148 int size = lastPixelOffset + off;
149
150 if (off < 0 || !SAFE_TO_ADD(lastPixelOffset, off)(((lastPixelOffset) >= 0) && ((off) >= 0) &&
((0x7fffffff - (lastPixelOffset)) > (off)))
) {
151 return 0;
152 }
153
154 if (size < lastPixelOffset || size >= dataArrayLength) {
155 // an overflow, or insufficient buffer capacity
156 return 0;
157 }
158 }
159 return 1;
160 case BANDED_RASTER_TYPE2:
161 // NB:caller does not support the banded rasters yet,
162 // so this branch of the code must be re-defined in
163 // order to provide valid criteria for the data offsets
164 // verification, when/if banded rasters will be supported.
165 // At the moment, we prohibit banded rasters as well.
166 return 0;
167 default:
168 // PACKED_RASTER_TYPE: does not support channel offsets
169 // UNKNOWN_RASTER_TYPE: should not be used, likely indicates an error
170 return 0;
171 }
172}
173
174/* Parse the raster. All of the raster information is returned in the
175 * rasterP structure.
176 *
177 * Return value:
178 * -1: Exception
179 * 0: Can't do it (Custom channel)
180 * 1: Success
181 */
182int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
183 jobject joffs = NULL((void*)0);
184 /* int status;*/
185 jclass singlePixelPackedSampleModelClass = NULL((void*)0);
186 jclass integerComponentRasterClass = NULL((void*)0);
187 jclass byteComponentRasterClass = NULL((void*)0);
188 jclass shortComponentRasterClass = NULL((void*)0);
189 jclass bytePackedRasterClass = NULL((void*)0);
190
191 if (JNU_IsNull(env, jraster)((jraster) == ((void*)0))) {
192 JNU_ThrowNullPointerException(env, "null Raster object");
193 return -1;
194 }
195
196 rasterP->jraster = jraster;
197 rasterP->width = (*env)->GetIntField(env, jraster, g_RasterWidthID);
198 rasterP->height = (*env)->GetIntField(env, jraster, g_RasterHeightID);
199 rasterP->numDataElements = (*env)->GetIntField(env, jraster,
200 g_RasterNumDataElementsID);
201 rasterP->numBands = (*env)->GetIntField(env, jraster,
202 g_RasterNumBandsID);
203
204 rasterP->baseOriginX = (*env)->GetIntField(env, jraster,
205 g_RasterBaseOriginXID);
206 rasterP->baseOriginY = (*env)->GetIntField(env, jraster,
207 g_RasterBaseOriginYID);
208 rasterP->minX = (*env)->GetIntField(env, jraster, g_RasterMinXID);
209 rasterP->minY = (*env)->GetIntField(env, jraster, g_RasterMinYID);
210
211 rasterP->jsampleModel = (*env)->GetObjectField(env, jraster,
212 g_RasterSampleModelID);
213
214 if (JNU_IsNull(env, rasterP->jsampleModel)((rasterP->jsampleModel) == ((void*)0))) {
215 JNU_ThrowNullPointerException(env, "null Raster object");
216 return -1;
217 }
218
219 // make sure that the raster type is initialized
220 rasterP->rasterType = UNKNOWN_RASTER_TYPE0;
221
222 if (rasterP->numBands <= 0 ||
223 rasterP->numBands > MAX_NUMBANDS32)
224 {
225 /*
226 * we can't handle such kind of rasters due to limitations
227 * of SPPSampleModelS_t structure and expand/set methods.
228 */
229 return 0;
230 }
231
232 rasterP->sppsm.isUsed = 0;
233
234 singlePixelPackedSampleModelClass = (*env)->FindClass(env,
235 "java/awt/image/SinglePixelPackedSampleModel");
236 CHECK_NULL_RETURN(singlePixelPackedSampleModelClass, -1)do { if ((singlePixelPackedSampleModelClass) == ((void*)0)) {
return (-1); } } while (0)
;
237 if ((*env)->IsInstanceOf(env, rasterP->jsampleModel,
238 singlePixelPackedSampleModelClass)) {
239 jobject jmask, joffs, jnbits;
240
241 rasterP->sppsm.isUsed = 1;
242
243 rasterP->sppsm.maxBitSize = (*env)->GetIntField(env,
244 rasterP->jsampleModel,
245 g_SPPSMmaxBitID);
246 jmask = (*env)->GetObjectField(env, rasterP->jsampleModel,
247 g_SPPSMmaskArrID);
248 joffs = (*env)->GetObjectField(env, rasterP->jsampleModel,
249 g_SPPSMmaskOffID);
250 jnbits = (*env)->GetObjectField(env, rasterP->jsampleModel,
251 g_SPPSMnBitsID);
252 if (jmask == NULL((void*)0) || joffs == NULL((void*)0) || jnbits == NULL((void*)0) ||
253 rasterP->sppsm.maxBitSize < 0)
254 {
255 JNU_ThrowInternalError(env, "Can't grab SPPSM fields");
256 return -1;
257 }
258 (*env)->GetIntArrayRegion(env, jmask, 0,
259 rasterP->numBands, rasterP->sppsm.maskArray);
260 (*env)->GetIntArrayRegion(env, joffs, 0,
261 rasterP->numBands, rasterP->sppsm.offsets);
262 (*env)->GetIntArrayRegion(env, jnbits, 0,
263 rasterP->numBands, rasterP->sppsm.nBits);
264
265 }
266 rasterP->baseRasterWidth = (*env)->GetIntField(env, rasterP->jsampleModel,
267 g_SMWidthID);
268 rasterP->baseRasterHeight = (*env)->GetIntField(env,
269 rasterP->jsampleModel,
270 g_SMHeightID);
271
272 integerComponentRasterClass = (*env)->FindClass(env, "sun/awt/image/IntegerComponentRaster");
273 CHECK_NULL_RETURN(integerComponentRasterClass, -1)do { if ((integerComponentRasterClass) == ((void*)0)) { return
(-1); } } while (0)
;
274 byteComponentRasterClass = (*env)->FindClass(env, "sun/awt/image/ByteComponentRaster");
275 CHECK_NULL_RETURN(byteComponentRasterClass, -1)do { if ((byteComponentRasterClass) == ((void*)0)) { return (
-1); } } while (0)
;
276 shortComponentRasterClass = (*env)->FindClass(env,"sun/awt/image/ShortComponentRaster");
277 CHECK_NULL_RETURN(shortComponentRasterClass, -1)do { if ((shortComponentRasterClass) == ((void*)0)) { return (
-1); } } while (0)
;
278 bytePackedRasterClass = (*env)->FindClass(env, "sun/awt/image/BytePackedRaster");
279 CHECK_NULL_RETURN(bytePackedRasterClass, -1)do { if ((bytePackedRasterClass) == ((void*)0)) { return (-1)
; } } while (0)
;
280 if ((*env)->IsInstanceOf(env, jraster, integerComponentRasterClass)){
281 rasterP->jdata = (*env)->GetObjectField(env, jraster, g_ICRdataID);
282 rasterP->dataType = INT_DATA_TYPE3;
283 rasterP->dataSize = 4;
284 rasterP->dataIsShared = TRUE(1);
285 rasterP->rasterType = COMPONENT_RASTER_TYPE1;
286 rasterP->type = (*env)->GetIntField(env, jraster, g_ICRtypeID);
287 rasterP->scanlineStride = (*env)->GetIntField(env, jraster, g_ICRscanstrID);
288 rasterP->pixelStride = (*env)->GetIntField(env, jraster, g_ICRpixstrID);
289 joffs = (*env)->GetObjectField(env, jraster, g_ICRdataOffsetsID);
290 }
291 else if ((*env)->IsInstanceOf(env, jraster, byteComponentRasterClass)){
292 rasterP->jdata = (*env)->GetObjectField(env, jraster, g_BCRdataID);
293 rasterP->dataType = BYTE_DATA_TYPE1;
294 rasterP->dataSize = 1;
295 rasterP->dataIsShared = TRUE(1);
296 rasterP->rasterType = COMPONENT_RASTER_TYPE1;
297 rasterP->type = (*env)->GetIntField(env, jraster, g_BCRtypeID);
298 rasterP->scanlineStride = (*env)->GetIntField(env, jraster, g_BCRscanstrID);
299 rasterP->pixelStride = (*env)->GetIntField(env, jraster, g_BCRpixstrID);
300 joffs = (*env)->GetObjectField(env, jraster, g_BCRdataOffsetsID);
301 }
302 else if ((*env)->IsInstanceOf(env, jraster, shortComponentRasterClass)){
303 rasterP->jdata = (*env)->GetObjectField(env, jraster, g_SCRdataID);
304 rasterP->dataType = SHORT_DATA_TYPE2;
305 rasterP->dataSize = 2;
306 rasterP->dataIsShared = TRUE(1);
307 rasterP->rasterType = COMPONENT_RASTER_TYPE1;
308 rasterP->type = (*env)->GetIntField(env, jraster, g_SCRtypeID);
309 rasterP->scanlineStride = (*env)->GetIntField(env, jraster, g_SCRscanstrID);
310 rasterP->pixelStride = (*env)->GetIntField(env, jraster, g_SCRpixstrID);
311 joffs = (*env)->GetObjectField(env, jraster, g_SCRdataOffsetsID);
312 }
313 else if ((*env)->IsInstanceOf(env, jraster, bytePackedRasterClass)){
314 rasterP->rasterType = PACKED_RASTER_TYPE3;
315 rasterP->dataType = BYTE_DATA_TYPE1;
316 rasterP->dataSize = 1;
317 rasterP->scanlineStride = (*env)->GetIntField(env, jraster, g_BPRscanstrID);
318 rasterP->pixelStride = (*env)->GetIntField(env, jraster, g_BPRpixstrID);
319 rasterP->jdata = (*env)->GetObjectField(env, jraster, g_BPRdataID);
320 rasterP->type = (*env)->GetIntField(env, jraster, g_BPRtypeID);
321 rasterP->chanOffsets = NULL((void*)0);
322 if (SAFE_TO_ALLOC_2(rasterP->numDataElements, sizeof(jint))(((rasterP->numDataElements) > 0) && ((sizeof(jint
)) > 0) && ((0x7fffffff / (rasterP->numDataElements
)) > (sizeof(jint))))
) {
323 rasterP->chanOffsets =
324 (jint *)malloc(rasterP->numDataElements * sizeof(jint));
325 }
326 if (rasterP->chanOffsets == NULL((void*)0)) {
327 /* Out of memory */
328 JNU_ThrowOutOfMemoryError(env, "Out of memory");
329 return -1;
330 }
331 rasterP->chanOffsets[0] = (*env)->GetIntField(env, jraster, g_BPRdataBitOffsetID);
332 rasterP->dataType = BYTE_DATA_TYPE1;
333 }
334 else {
335 rasterP->type = sun_awt_image_IntegerComponentRaster_TYPE_CUSTOM0L;
336 rasterP->dataType = UNKNOWN_DATA_TYPE0;
337 rasterP->rasterType = UNKNOWN_RASTER_TYPE0;
338 rasterP->chanOffsets = NULL((void*)0);
339 /* Custom raster */
340 return 0;
341 }
342
343 // do basic validation of the raster structure
344 if (rasterP->width <= 0 || rasterP->height <= 0 ||
345 rasterP->pixelStride <= 0 || rasterP->scanlineStride <= 0)
346 {
347 // invalid raster
348 return -1;
349 }
350
351 // channel (data) offsets
352 switch (rasterP->rasterType) {
353 case COMPONENT_RASTER_TYPE1:
354 case BANDED_RASTER_TYPE2: // note that this routine does not support banded rasters at the moment
355 // get channel (data) offsets
356 rasterP->chanOffsets = NULL((void*)0);
357 if (SAFE_TO_ALLOC_2(rasterP->numDataElements, sizeof(jint))(((rasterP->numDataElements) > 0) && ((sizeof(jint
)) > 0) && ((0x7fffffff / (rasterP->numDataElements
)) > (sizeof(jint))))
) {
358 rasterP->chanOffsets =
359 (jint *)malloc(rasterP->numDataElements * sizeof(jint));
360 }
361 if (rasterP->chanOffsets == NULL((void*)0)) {
362 /* Out of memory */
363 JNU_ThrowOutOfMemoryError(env, "Out of memory");
364 return -1;
365 }
366 (*env)->GetIntArrayRegion(env, joffs, 0, rasterP->numDataElements,
367 rasterP->chanOffsets);
368 if (rasterP->jdata == NULL((void*)0)) {
369 // unable to verify the raster
370 return -1;
371 }
372 // verify whether channel offsets look sane
373 if (!checkChannelOffsets(rasterP, (*env)->GetArrayLength(env, rasterP->jdata))) {
374 return -1;
375 }
376 break;
377 default:
378 ; // PACKED_RASTER_TYPE does not use the channel offsets.
379 }
380
381 /* additional check for sppsm fields validity: make sure that
382 * size of raster samples doesn't exceed the data type capacity.
383 */
384 if (rasterP->dataType > UNKNOWN_DATA_TYPE0 && /* data type has been recognized */
385 rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */
386 rasterP->sppsm.maxBitSize > (rasterP->dataSize * 8))
387 {
388 JNU_ThrowInternalError(env, "Raster samples are too big");
389 return -1;
390 }
391
392#if 0
393 fprintf(stderr,"---------------------\n")__fprintf_chk (stderr, 2 - 1, "---------------------\n");
394 fprintf(stderr,"Width : %d\n",rasterP->width)__fprintf_chk (stderr, 2 - 1, "Width : %d\n",rasterP->width
)
;
395 fprintf(stderr,"Height : %d\n",rasterP->height)__fprintf_chk (stderr, 2 - 1, "Height : %d\n",rasterP->height
)
;
396 fprintf(stderr,"X : %d\n",rasterP->x)__fprintf_chk (stderr, 2 - 1, "X : %d\n",rasterP->x);
397 fprintf(stderr,"Y : %d\n",rasterP->y)__fprintf_chk (stderr, 2 - 1, "Y : %d\n",rasterP->y);
398 fprintf(stderr,"numC : %d\n",rasterP->numDataElements)__fprintf_chk (stderr, 2 - 1, "numC : %d\n",rasterP->numDataElements
)
;
399 fprintf(stderr,"SS : %d\n",rasterP->scanlineStride)__fprintf_chk (stderr, 2 - 1, "SS : %d\n",rasterP->scanlineStride
)
;
400 fprintf(stderr,"PS : %d\n",rasterP->pixelStride)__fprintf_chk (stderr, 2 - 1, "PS : %d\n",rasterP->pixelStride
)
;
401 fprintf(stderr,"CO : %d\n",rasterP->chanOffsets)__fprintf_chk (stderr, 2 - 1, "CO : %d\n",rasterP->chanOffsets
)
;
402 fprintf(stderr,"shared?: %d\n",rasterP->dataIsShared)__fprintf_chk (stderr, 2 - 1, "shared?: %d\n",rasterP->dataIsShared
)
;
403 fprintf(stderr,"RasterT: %d\n",rasterP->rasterType)__fprintf_chk (stderr, 2 - 1, "RasterT: %d\n",rasterP->rasterType
)
;
404 fprintf(stderr,"DataT : %d\n",rasterP->dataType)__fprintf_chk (stderr, 2 - 1, "DataT : %d\n",rasterP->dataType
)
;
405 fprintf(stderr,"---------------------\n")__fprintf_chk (stderr, 2 - 1, "---------------------\n");
406#endif
407
408 return 1;
409}
410
411static int getColorModelType(JNIEnv *env, jobject jcmodel) {
412 jclass colorModelClass;
413
414 colorModelClass = (*env)->FindClass(env,
415 "java/awt/image/IndexColorModel");
416 CHECK_NULL_RETURN(colorModelClass, UNKNOWN_CM_TYPE)do { if ((colorModelClass) == ((void*)0)) { return (0); } } while
(0)
;
417
418 if ((*env)->IsInstanceOf(env, jcmodel, colorModelClass))
419 {
420 return INDEX_CM_TYPE3;
421 }
422
423 colorModelClass = (*env)->FindClass(env,
424 "java/awt/image/PackedColorModel");
425 CHECK_NULL_RETURN(colorModelClass, UNKNOWN_CM_TYPE)do { if ((colorModelClass) == ((void*)0)) { return (0); } } while
(0)
;
426 if ((*env)->IsInstanceOf(env, jcmodel, colorModelClass))
427 {
428 colorModelClass = (*env)->FindClass(env,
429 "java/awt/image/DirectColorModel");
430 CHECK_NULL_RETURN(colorModelClass, UNKNOWN_CM_TYPE)do { if ((colorModelClass) == ((void*)0)) { return (0); } } while
(0)
;
431 if ((*env)->IsInstanceOf(env, jcmodel, colorModelClass)) {
432 return DIRECT_CM_TYPE2;
433 }
434 else {
435 return PACKED_CM_TYPE4;
436 }
437 }
438 colorModelClass = (*env)->FindClass(env,
439 "java/awt/image/ComponentColorModel");
440 CHECK_NULL_RETURN(colorModelClass, UNKNOWN_CM_TYPE)do { if ((colorModelClass) == ((void*)0)) { return (0); } } while
(0)
;
441 if ((*env)->IsInstanceOf(env, jcmodel, colorModelClass))
442 {
443 return COMPONENT_CM_TYPE1;
444 }
445
446 return UNKNOWN_CM_TYPE0;
447}
448
449int awt_parseColorModel (JNIEnv *env, jobject jcmodel, int imageType,
450 ColorModelS_t *cmP) {
451 /*jmethodID jID; */
452 jobject jnBits;
453 jsize nBitsLength;
454
455 int i;
456 static jobject s_jdefCM = NULL((void*)0);
457
458 if (JNU_IsNull(env, jcmodel)((jcmodel) == ((void*)0))) {
459 JNU_ThrowNullPointerException(env, "null ColorModel object");
460 return -1;
461 }
462
463 cmP->jcmodel = jcmodel;
464
465 cmP->jcspace = (*env)->GetObjectField(env, jcmodel, g_CMcspaceID);
466
467 cmP->numComponents = (*env)->GetIntField(env, jcmodel,
468 g_CMnumComponentsID);
469 cmP->supportsAlpha = (*env)->GetBooleanField(env, jcmodel,
470 g_CMsuppAlphaID);
471 cmP->isAlphaPre = (*env)->GetBooleanField(env,jcmodel,
472 g_CMisAlphaPreID);
473 cmP->transparency = (*env)->GetIntField(env, jcmodel,
474 g_CMtransparencyID);
475
476 jnBits = (*env)->GetObjectField(env, jcmodel, g_CMnBitsID);
477 if (jnBits == NULL((void*)0)) {
478 JNU_ThrowNullPointerException(env, "null nBits structure in CModel");
479 return -1;
480 }
481
482 nBitsLength = (*env)->GetArrayLength(env, jnBits);
483 if (nBitsLength != cmP->numComponents) {
484 // invalid number of components?
485 return -1;
486 }
487
488 cmP->nBits = NULL((void*)0);
489 if (SAFE_TO_ALLOC_2(cmP->numComponents, sizeof(jint))(((cmP->numComponents) > 0) && ((sizeof(jint)) >
0) && ((0x7fffffff / (cmP->numComponents)) > (
sizeof(jint))))
) {
490 cmP->nBits = (jint *)malloc(cmP->numComponents * sizeof(jint));
491 }
492
493 if (cmP->nBits == NULL((void*)0)){
494 JNU_ThrowOutOfMemoryError(env, "Out of memory");
495 return -1;
496 }
497 (*env)->GetIntArrayRegion(env, jnBits, 0, cmP->numComponents,
498 cmP->nBits);
499 cmP->maxNbits = 0;
500 for (i=0; i < cmP->numComponents; i++) {
501 if (cmP->maxNbits < cmP->nBits[i]) {
502 cmP->maxNbits = cmP->nBits[i];
503 }
504 }
505
506 cmP->is_sRGB = (*env)->GetBooleanField(env, cmP->jcmodel, g_CMis_sRGBID);
507
508 cmP->csType = (*env)->GetIntField(env, cmP->jcmodel, g_CMcsTypeID);
509
510 cmP->cmType = getColorModelType(env, jcmodel);
511 JNU_CHECK_EXCEPTION_RETURN(env, -1)do { if ((*env)->ExceptionCheck(env)) { return (-1); } } while
(0)
;
512
513 cmP->isDefaultCM = FALSE(0);
514 cmP->isDefaultCompatCM = FALSE(0);
515
516 /* look for standard cases */
517 if (imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB2L) {
518 cmP->isDefaultCM = TRUE(1);
519 cmP->isDefaultCompatCM = TRUE(1);
520 } else if (imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE3L ||
521 imageType == java_awt_image_BufferedImage_TYPE_INT_RGB1L ||
522 imageType == java_awt_image_BufferedImage_TYPE_INT_BGR4L ||
523 imageType == java_awt_image_BufferedImage_TYPE_4BYTE_ABGR6L ||
524 imageType == java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE7L)
525 {
526 cmP->isDefaultCompatCM = TRUE(1);
527 }
528 else {
529 /* Figure out if this is the default CM */
530 if (s_jdefCM == NULL((void*)0)) {
531 jobject defCM;
532 jclass jcm = (*env)->FindClass(env, "java/awt/image/ColorModel");
533 CHECK_NULL_RETURN(jcm, -1)do { if ((jcm) == ((void*)0)) { return (-1); } } while (0);
534 defCM = (*env)->CallStaticObjectMethod(env, jcm,
535 g_CMgetRGBdefaultMID, NULL((void*)0));
536 s_jdefCM = (*env)->NewGlobalRef(env, defCM);
537 if (defCM == NULL((void*)0) || s_jdefCM == NULL((void*)0)) {
538 (*env)->ExceptionClear(env);
539 JNU_ThrowNullPointerException(env, "Unable to find default CM");
540 return -1;
541 }
542 }
543 cmP->isDefaultCM = ((*env)->IsSameObject(env, s_jdefCM, jcmodel));
544 cmP->isDefaultCompatCM = cmP->isDefaultCM;
545 }
546
547 /* check whether image attributes correspond to default cm */
548 if (cmP->isDefaultCompatCM) {
549 if (cmP->csType != java_awt_color_ColorSpace_TYPE_RGB5L ||
550 !cmP->is_sRGB)
551 {
552 return -1;
553 }
554
555 for (i = 0; i < cmP->numComponents; i++) {
556 if (cmP->nBits[i] != 8) {
557 return -1;
558 }
559 }
560 }
561
562 /* Get index color model attributes */
563 if (imageType == java_awt_image_BufferedImage_TYPE_BYTE_INDEXED13L ||
564 cmP->cmType == INDEX_CM_TYPE3)
565 {
566 cmP->transIdx = (*env)->GetIntField(env, jcmodel, g_ICMtransIdxID);
567 cmP->mapSize = (*env)->GetIntField(env, jcmodel, g_ICMmapSizeID);
568 cmP->jrgb = (*env)->GetObjectField(env, jcmodel, g_ICMrgbID);
569 if (cmP->transIdx == -1) {
570 /* Need to find the transparent index */
571 int *rgb = (int *) (*env)->GetPrimitiveArrayCritical(env,
572 cmP->jrgb,
573 NULL((void*)0));
574 if (rgb == NULL((void*)0)) {
575 return -1;
576 }
577 for (i=0; i < cmP->mapSize; i++) {
578 if ((rgb[i]&0xff000000) == 0) {
579 cmP->transIdx = i;
580 break;
581 }
582 }
583 (*env)->ReleasePrimitiveArrayCritical(env, cmP->jrgb, rgb,
584 JNI_ABORT2);
585 if (cmP->transIdx == -1) {
586 /* Now what? No transparent pixel... */
587 cmP->transIdx = 0;
588 }
589 }
590 }
591
592 return 1;
593}
594
595void awt_freeParsedRaster(RasterS_t *rasterP, int freeRasterP) {
596 if (rasterP->chanOffsets) {
597 free((void *) rasterP->chanOffsets);
598 }
599
600 if (freeRasterP) {
601 free((void *) rasterP);
602 }
603}
604
605void awt_freeParsedImage(BufImageS_t *imageP, int freeImageP) {
606 if (imageP->hints.colorOrder) {
607 free ((void *) imageP->hints.colorOrder);
608 }
609
610 if (imageP->cmodel.nBits) {
611 free ((void *) imageP->cmodel.nBits);
612 }
613
614 /* Free the raster */
615 awt_freeParsedRaster(&imageP->raster, FALSE(0));
616
617 if (freeImageP) {
618 free((void *) imageP);
619 }
620}
621
622static void
623awt_getBIColorOrder(int type, int *colorOrder) {
624 switch(type) {
625 case java_awt_image_BufferedImage_TYPE_INT_ARGB2L:
626 case java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE3L:
627#ifdef _LITTLE_ENDIAN1
628 colorOrder[0] = 2;
629 colorOrder[1] = 1;
630 colorOrder[2] = 0;
631 colorOrder[3] = 3;
632#else
633 colorOrder[0] = 1;
634 colorOrder[1] = 2;
635 colorOrder[2] = 3;
636 colorOrder[3] = 0;
637#endif
638 break;
639 case java_awt_image_BufferedImage_TYPE_INT_BGR4L:
640#ifdef _LITTLE_ENDIAN1
641 colorOrder[0] = 0;
642 colorOrder[1] = 1;
643 colorOrder[2] = 2;
644#else
645 colorOrder[0] = 3;
646 colorOrder[1] = 2;
647 colorOrder[2] = 1;
648#endif
649 break;
650 case java_awt_image_BufferedImage_TYPE_INT_RGB1L:
651#ifdef _LITTLE_ENDIAN1
652 colorOrder[0] = 2;
653 colorOrder[1] = 1;
654 colorOrder[2] = 0;
655#else
656 colorOrder[0] = 1;
657 colorOrder[1] = 2;
658 colorOrder[2] = 3;
659#endif
660 break;
661 case java_awt_image_BufferedImage_TYPE_4BYTE_ABGR6L:
662 case java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE7L:
663 colorOrder[0] = 3;
664 colorOrder[1] = 2;
665 colorOrder[2] = 1;
666 colorOrder[3] = 0;
667 break;
668 case java_awt_image_BufferedImage_TYPE_3BYTE_BGR5L:
669 colorOrder[0] = 2;
670 colorOrder[1] = 1;
671 colorOrder[2] = 0;
672 break;
673 case java_awt_image_BufferedImage_TYPE_USHORT_565_RGB8L:
674 case java_awt_image_BufferedImage_TYPE_USHORT_555_RGB9L:
675 colorOrder[0] = 0;
676 colorOrder[1] = 1;
677 colorOrder[2] = 2;
678 break;
679 case java_awt_image_BufferedImage_TYPE_BYTE_GRAY10L:
680 case java_awt_image_BufferedImage_TYPE_USHORT_GRAY11L:
681 case java_awt_image_BufferedImage_TYPE_BYTE_BINARY12L:
682 case java_awt_image_BufferedImage_TYPE_BYTE_INDEXED13L:
683 colorOrder[0] = 0;
684 break;
685 }
686}
687
688static int
689setHints(JNIEnv *env, BufImageS_t *imageP) {
690 HintS_t *hintP = &imageP->hints;
691 RasterS_t *rasterP = &imageP->raster;
692 ColorModelS_t *cmodelP = &imageP->cmodel;
693 int imageType = imageP->imageType;
694
695 // check whether raster and color model are compatible
696 if (cmodelP->numComponents != rasterP->numBands) {
697 if (cmodelP->cmType != INDEX_CM_TYPE3) {
698 return -1;
699 }
700 }
701
702 hintP->numChans = imageP->cmodel.numComponents;
703 hintP->colorOrder = NULL((void*)0);
704 if (SAFE_TO_ALLOC_2(hintP->numChans, sizeof(int))(((hintP->numChans) > 0) && ((sizeof(int)) >
0) && ((0x7fffffff / (hintP->numChans)) > (sizeof
(int))))
) {
705 hintP->colorOrder = (int *)malloc(hintP->numChans * sizeof(int));
706 }
707 if (hintP->colorOrder == NULL((void*)0)) {
708 JNU_ThrowOutOfMemoryError(env, "Out of memory");
709 return -1;
710 }
711 if (imageType != java_awt_image_BufferedImage_TYPE_CUSTOM0L) {
712 awt_getBIColorOrder(imageType, hintP->colorOrder);
713 }
714 if (imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB2L ||
715 imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE3L ||
716 imageType == java_awt_image_BufferedImage_TYPE_INT_RGB1L)
717 {
718 hintP->channelOffset = rasterP->chanOffsets[0];
719 /* These hints are #bytes */
720 hintP->dataOffset = hintP->channelOffset*rasterP->dataSize;
721 hintP->sStride = rasterP->scanlineStride*rasterP->dataSize;
722 hintP->pStride = rasterP->pixelStride*rasterP->dataSize;
723 hintP->packing = BYTE_INTERLEAVED(0x1 | 0x10);
724 } else if (imageType ==java_awt_image_BufferedImage_TYPE_4BYTE_ABGR6L ||
725 imageType==java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE7L||
726 imageType == java_awt_image_BufferedImage_TYPE_3BYTE_BGR5L ||
727 imageType == java_awt_image_BufferedImage_TYPE_INT_BGR4L)
728 {
729 if (imageType == java_awt_image_BufferedImage_TYPE_INT_BGR4L) {
730 hintP->channelOffset = rasterP->chanOffsets[0];
731 }
732 else {
733 hintP->channelOffset = rasterP->chanOffsets[hintP->numChans-1];
734 }
735 hintP->dataOffset = hintP->channelOffset*rasterP->dataSize;
736 hintP->sStride = rasterP->scanlineStride*rasterP->dataSize;
737 hintP->pStride = rasterP->pixelStride*rasterP->dataSize;
738 hintP->packing = BYTE_INTERLEAVED(0x1 | 0x10);
739 } else if (imageType==java_awt_image_BufferedImage_TYPE_USHORT_565_RGB8L ||
740 imageType==java_awt_image_BufferedImage_TYPE_USHORT_555_RGB9L) {
741 hintP->needToExpand = TRUE(1);
742 hintP->expandToNbits = 8;
743 hintP->packing = PACKED_SHORT_INTER(0x4 | 0x10);
744 } else if (cmodelP->cmType == INDEX_CM_TYPE3) {
745 int i;
746 hintP->numChans = 1;
747 hintP->channelOffset = rasterP->chanOffsets[0];
748 hintP->dataOffset = hintP->channelOffset*rasterP->dataSize;
749 hintP->sStride = rasterP->scanlineStride*rasterP->dataSize;
750 hintP->pStride = rasterP->pixelStride*rasterP->dataSize;
751 switch(rasterP->dataType ) {
752 case BYTE_DATA_TYPE1:
753 if (rasterP->rasterType == PACKED_RASTER_TYPE3) {
754 hintP->needToExpand = TRUE(1);
755 hintP->expandToNbits = 8;
756 hintP->packing = BYTE_PACKED_BAND(0x1 | 0x40);
757 }
758 else {
759 hintP->packing = BYTE_SINGLE_BAND(0x1 | 0x30);
760 }
761 break;
762 case SHORT_DATA_TYPE2:
763 hintP->packing = SHORT_SINGLE_BAND(0x2 | 0x30);
764 break;
765 case INT_DATA_TYPE3:
766 default:
767 hintP->packing = UNKNOWN_PACKING0;
768 break;
769 }
770 for (i=0; i < hintP->numChans; i++) {
771 hintP->colorOrder[i] = i;
772 }
773 }
774 else if (cmodelP->cmType == COMPONENT_CM_TYPE1) {
775 /* Figure out if it is interleaved */
776 int bits=1;
777 int i;
778 int low = rasterP->chanOffsets[0];
779 int diff;
780 int banded = 0;
781 for (i=1; i < hintP->numChans; i++) {
782 if (rasterP->chanOffsets[i] < low) {
783 low = rasterP->chanOffsets[i];
784 }
785 }
786 for (i=1; i < hintP->numChans; i++) {
787 diff = rasterP->chanOffsets[i]-low;
788 if (diff < hintP->numChans) {
789 if (bits & (1<<diff)) {
790 /* Overlapping samples */
791 /* Could just copy */
792 return -1;
793 }
794 bits |= (1<<diff);
795 }
796 else if (diff >= rasterP->width) {
797 banded = 1;
798 }
799 /* Ignore the case if bands are overlapping */
800 }
801 hintP->channelOffset = low;
802 hintP->dataOffset = low*rasterP->dataSize;
803 hintP->sStride = rasterP->scanlineStride*rasterP->dataSize;
804 hintP->pStride = rasterP->pixelStride*rasterP->dataSize;
805 switch(rasterP->dataType) {
806 case BYTE_DATA_TYPE1:
807 hintP->packing = BYTE_COMPONENTS0x1;
808 break;
809 case SHORT_DATA_TYPE2:
810 hintP->packing = SHORT_COMPONENTS0x2;
811 break;
812 default:
813 /* Don't handle any other case */
814 return -1;
815 }
816 if (bits == ((1<<hintP->numChans)-1)) {
817 hintP->packing |= INTERLEAVED0x10;
818 for (i=0; i < hintP->numChans; i++) {
819 hintP->colorOrder[rasterP->chanOffsets[i]-low] = i;
820 }
821 }
822 else if (banded == 1) {
823 int bandSize = rasterP->width*rasterP->height;
824 hintP->packing |= BANDED0x20;
825 for (i=0; i < hintP->numChans; i++) {
826 /* REMIND: Not necessarily correct */
827 hintP->colorOrder[(rasterP->chanOffsets[i]-low)%bandSize] = i;
828 }
829 }
830 else {
831 return -1;
832 }
833 }
834 else if (cmodelP->cmType == DIRECT_CM_TYPE2 || cmodelP->cmType == PACKED_CM_TYPE4) {
835 int i;
836
837 /* do some sanity check first: make sure that
838 * - sample model is SinglePixelPackedSampleModel
839 * - number of bands in the raster corresponds to the number
840 * of color components in the color model
841 */
842 if (!rasterP->sppsm.isUsed ||
843 rasterP->numBands != cmodelP->numComponents)
844 {
845 /* given raster is not compatible with the color model,
846 * so the operation has to be aborted.
847 */
848 return -1;
849 }
850
851 if (cmodelP->maxNbits > 8) {
852 hintP->needToExpand = TRUE(1);
853 hintP->expandToNbits = cmodelP->maxNbits;
854 }
855 else {
856 for (i=0; i < rasterP->numBands; i++) {
857 if (!(rasterP->sppsm.offsets[i] % 8)) {
858 hintP->needToExpand = TRUE(1);
859 hintP->expandToNbits = 8;
860 break;
861 }
862 else {
863 hintP->colorOrder[i] = rasterP->sppsm.offsets[i]>>3;
864 }
865 }
866 }
867
868 hintP->channelOffset = rasterP->chanOffsets[0];
869 hintP->dataOffset = hintP->channelOffset*rasterP->dataSize;
870 hintP->sStride = rasterP->scanlineStride*rasterP->dataSize;
871 hintP->pStride = rasterP->pixelStride*rasterP->dataSize;
872 if (hintP->needToExpand) {
873 switch(rasterP->dataType) {
874 case BYTE_DATA_TYPE1:
875 hintP->packing = PACKED_BYTE_INTER(0x5 | 0x10);
876 break;
877 case SHORT_DATA_TYPE2:
878 hintP->packing = PACKED_SHORT_INTER(0x4 | 0x10);
879 break;
880 case INT_DATA_TYPE3:
881 hintP->packing = PACKED_INT_INTER(0x3 | 0x10);
882 break;
883 default:
884 /* Don't know what it is */
885 return -1;
886 }
887 }
888 else {
889 hintP->packing = BYTE_INTERLEAVED(0x1 | 0x10);
890
891 }
892 }
893 else {
894 /* REMIND: Need to handle more cases */
895 return -1;
896 }
897
898 return 1;
899}
900
901#define MAX_TO_GRAB(10240) (10240)
902
903typedef union {
904 void *pv;
905 unsigned char *pb;
906 unsigned short *ps;
907} PixelData_t;
908
909
910int awt_getPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP) {
911 const int w = rasterP->width;
912 const int h = rasterP->height;
913 const int numBands = rasterP->numBands;
914 int y;
915 int i;
916 int maxLines;
917 jobject jsm;
918 int off = 0;
919 jarray jdata = NULL((void*)0);
920 jobject jdatabuffer;
921 int *dataP;
922 int maxSamples;
923 PixelData_t p;
924
925 if (bufferP == NULL((void*)0)) {
926 return -1;
927 }
928
929 if (rasterP->dataType != BYTE_DATA_TYPE1 &&
930 rasterP->dataType != SHORT_DATA_TYPE2)
931 {
932 return -1;
933 }
934
935 p.pv = bufferP;
936
937 if (!SAFE_TO_MULT(w, numBands)(((w) > 0) && ((numBands) >= 0) && ((0x7fffffff
/ (w)) > (numBands)))
) {
938 return -1;
939 }
940 maxSamples = w * numBands;
941
942 maxLines = maxSamples > MAX_TO_GRAB(10240) ? 1 : (MAX_TO_GRAB(10240) / maxSamples);
943 if (maxLines > h) {
944 maxLines = h;
945 }
946
947 if (!SAFE_TO_MULT(maxSamples, maxLines)(((maxSamples) > 0) && ((maxLines) >= 0) &&
((0x7fffffff / (maxSamples)) > (maxLines)))
) {
948 return -1;
949 }
950
951 maxSamples *= maxLines;
952
953 jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID);
954 jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster,
955 g_RasterDataBufferID);
956
957 jdata = (*env)->NewIntArray(env, maxSamples);
958 if (JNU_IsNull(env, jdata)((jdata) == ((void*)0))) {
959 (*env)->ExceptionClear(env);
960 JNU_ThrowOutOfMemoryError(env, "Out of Memory");
961 return -1;
962 }
963
964 for (y = 0; y < h; y += maxLines) {
965 if (y + maxLines > h) {
966 maxLines = h - y;
967 maxSamples = w * numBands * maxLines;
968 }
969
970 (*env)->CallObjectMethod(env, jsm, g_SMGetPixelsMID,
971 0, y, w,
972 maxLines, jdata, jdatabuffer);
973
974 if ((*env)->ExceptionOccurred(env)) {
975 (*env)->DeleteLocalRef(env, jdata);
976 return -1;
977 }
978
979 dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
980 NULL((void*)0));
981 if (dataP == NULL((void*)0)) {
982 (*env)->DeleteLocalRef(env, jdata);
983 return -1;
984 }
985
986 switch (rasterP->dataType) {
987 case BYTE_DATA_TYPE1:
988 for (i = 0; i < maxSamples; i ++) {
989 p.pb[off++] = (unsigned char) dataP[i];
990 }
991 break;
992 case SHORT_DATA_TYPE2:
993 for (i = 0; i < maxSamples; i ++) {
994 p.ps[off++] = (unsigned short) dataP[i];
995 }
996 break;
997 }
998
999 (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
1000 JNI_ABORT2);
1001 }
1002 (*env)->DeleteLocalRef(env, jdata);
1003
1004 return 1;
1005}
1006
1007int awt_setPixels(JNIEnv *env, RasterS_t *rasterP, void *bufferP) {
1008 const int w = rasterP->width;
1009 const int h = rasterP->height;
1010 const int numBands = rasterP->numBands;
1011
1012 int y;
1013 int i;
1014 int maxLines;
1015 jobject jsm;
1016 int off = 0;
1017 jarray jdata = NULL((void*)0);
1018 jobject jdatabuffer;
1019 int *dataP;
1020 int maxSamples;
1021 PixelData_t p;
1022
1023 if (bufferP == NULL((void*)0)) {
1024 return -1;
1025 }
1026
1027 if (rasterP->dataType != BYTE_DATA_TYPE1 &&
1028 rasterP->dataType != SHORT_DATA_TYPE2)
1029 {
1030 return -1;
1031 }
1032
1033 p.pv = bufferP;
1034
1035 if (!SAFE_TO_MULT(w, numBands)(((w) > 0) && ((numBands) >= 0) && ((0x7fffffff
/ (w)) > (numBands)))
) {
1036 return -1;
1037 }
1038 maxSamples = w * numBands;
1039
1040 maxLines = maxSamples > MAX_TO_GRAB(10240) ? 1 : (MAX_TO_GRAB(10240) / maxSamples);
1041 if (maxLines > h) {
1042 maxLines = h;
1043 }
1044
1045 if (!SAFE_TO_MULT(maxSamples, maxLines)(((maxSamples) > 0) && ((maxLines) >= 0) &&
((0x7fffffff / (maxSamples)) > (maxLines)))
) {
1046 return -1;
1047 }
1048
1049 maxSamples *= maxLines;
1050
1051 jsm = (*env)->GetObjectField(env, rasterP->jraster, g_RasterSampleModelID);
1052 jdatabuffer = (*env)->GetObjectField(env, rasterP->jraster,
1053 g_RasterDataBufferID);
1054
1055 jdata = (*env)->NewIntArray(env, maxSamples);
1056 if (JNU_IsNull(env, jdata)((jdata) == ((void*)0))) {
1057 (*env)->ExceptionClear(env);
1058 JNU_ThrowOutOfMemoryError(env, "Out of Memory");
1059 return -1;
1060 }
1061
1062 for (y = 0; y < h; y += maxLines) {
1063 if (y + maxLines > h) {
1064 maxLines = h - y;
1065 maxSamples = w * numBands * maxLines;
1066 }
1067 dataP = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata,
1068 NULL((void*)0));
1069 if (dataP == NULL((void*)0)) {
1070 (*env)->DeleteLocalRef(env, jdata);
1071 return -1;
1072 }
1073
1074 switch (rasterP->dataType) {
1075 case BYTE_DATA_TYPE1:
1076 for (i = 0; i < maxSamples; i ++) {
1077 dataP[i] = p.pb[off++];
1078 }
1079 break;
1080 case SHORT_DATA_TYPE2:
1081 for (i = 0; i < maxSamples; i ++) {
1082 dataP[i] = p.ps[off++];
1083 }
1084 break;
1085 }
1086
1087 (*env)->ReleasePrimitiveArrayCritical(env, jdata, dataP,
1088 JNI_ABORT2);
1089
1090 (*env)->CallVoidMethod(env, jsm, g_SMSetPixelsMID,
1091 0, y, w,
1092 maxLines, jdata, jdatabuffer);
1093
1094 if ((*env)->ExceptionOccurred(env)) {
1095 (*env)->DeleteLocalRef(env, jdata);
1096 return -1;
1097 }
1098 }
1099
1100 (*env)->DeleteLocalRef(env, jdata);
1101
1102 return 1;
1103}