File: | jdk/src/java.desktop/share/native/libawt/awt/medialib/awt_ImagingLib.c |
Warning: | line 3752, column 39 The right operand of '<<' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright (c) 1997, 2016, 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 <string.h> | |||
29 | #include "sun_awt_image_ImagingLib.h" | |||
30 | #include "java_awt_Transparency.h" | |||
31 | #include "java_awt_image_AffineTransformOp.h" | |||
32 | #include "java_awt_image_BufferedImage.h" | |||
33 | #include "java_awt_color_ColorSpace.h" | |||
34 | #include "java_awt_image_ConvolveOp.h" | |||
35 | #include "sun_awt_image_IntegerComponentRaster.h" | |||
36 | #include "awt_ImagingLib.h" | |||
37 | #include "awt_parseImage.h" | |||
38 | #include "imageInitIDs.h" | |||
39 | #include <jni.h> | |||
40 | #include <jni_util.h> | |||
41 | #include <assert.h> | |||
42 | #include "awt_Mlib.h" | |||
43 | #include "gdefs.h" | |||
44 | #include "safe_alloc.h" | |||
45 | #include "safe_math.h" | |||
46 | ||||
47 | /*************************************************************************** | |||
48 | * Definitions * | |||
49 | ***************************************************************************/ | |||
50 | #define jio_fprintffprintf fprintf | |||
51 | ||||
52 | #ifndef TRUE(1) | |||
53 | #define TRUE(1) 1 | |||
54 | #endif /* TRUE */ | |||
55 | ||||
56 | #ifndef FALSE(0) | |||
57 | #define FALSE(0) 0 | |||
58 | #endif /* FALSE */ | |||
59 | ||||
60 | #define TYPE_CUSTOM0L java_awt_image_BufferedImage_TYPE_CUSTOM0L | |||
61 | #define TYPE_INT_RGB1L java_awt_image_BufferedImage_TYPE_INT_RGB1L | |||
62 | #define TYPE_INT_ARGB2L java_awt_image_BufferedImage_TYPE_INT_ARGB2L | |||
63 | #define TYPE_INT_ARGB_PRE3L java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE3L | |||
64 | #define TYPE_INT_BGR4L java_awt_image_BufferedImage_TYPE_INT_BGR4L | |||
65 | #define TYPE_4BYTE_ABGR6L java_awt_image_BufferedImage_TYPE_4BYTE_ABGR6L | |||
66 | #define TYPE_4BYTE_ABGR_PRE7L java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE7L | |||
67 | ||||
68 | /* (alpha*color)>>nbits + alpha>>(nbits-1) */ | |||
69 | #define BLEND(color, alpha, alphaNbits)((((alpha)*(color))>>(alphaNbits)) + ((alpha) >> ( (alphaNbits)-1))) \ | |||
70 | ((((alpha)*(color))>>(alphaNbits)) + ((alpha) >> ((alphaNbits)-1))) | |||
71 | ||||
72 | /* ((color - (alpha>>(nBits-1)))<<nBits)/alpha */ | |||
73 | #define UNBLEND(color, alpha, alphaNbits)((((color)-((alpha)>>((alphaNbits)-1)))<<(alphaNbits ))/(alpha)) \ | |||
74 | ((((color)-((alpha)>>((alphaNbits)-1)))<<(alphaNbits))/(alpha)) | |||
75 | ||||
76 | /* Enumeration of all of the mlib functions used */ | |||
77 | typedef enum { | |||
78 | MLIB_CONVMxN, | |||
79 | MLIB_AFFINE, | |||
80 | MLIB_LOOKUP, | |||
81 | MLIB_CONVKERNCVT | |||
82 | } mlibTypeE_t; | |||
83 | ||||
84 | typedef struct { | |||
85 | int dataType; /* One of BYTE_DATA_TYPE, SHORT_DATA_TYPE, */ | |||
86 | int needToCopy; | |||
87 | int cvtSrcToDefault; /* If TRUE, convert the src to def CM (pre?) */ | |||
88 | int allocDefaultDst; /* If TRUE, alloc def CM dst buffer */ | |||
89 | int cvtToDst; /* If TRUE, convert dst buffer to Dst CM */ | |||
90 | int addAlpha; | |||
91 | } mlibHintS_t; | |||
92 | ||||
93 | /*************************************************************************** | |||
94 | * Static Variables/Structures * | |||
95 | ***************************************************************************/ | |||
96 | ||||
97 | static mlibSysFnS_t sMlibSysFns = { | |||
98 | NULL((void*)0), // placeholder for j2d_mlib_ImageCreate | |||
99 | NULL((void*)0), // placeholder for j2d_mlib_ImageCreateStruct | |||
100 | NULL((void*)0), // placeholder for j2d_mlib_ImageDelete | |||
101 | }; | |||
102 | ||||
103 | static mlibFnS_t sMlibFns[] = { | |||
104 | {NULL((void*)0), "j2d_mlib_ImageConvMxN"}, | |||
105 | {NULL((void*)0), "j2d_mlib_ImageAffine"}, | |||
106 | {NULL((void*)0), "j2d_mlib_ImageLookUp"}, | |||
107 | {NULL((void*)0), "j2d_mlib_ImageConvKernelConvert"}, | |||
108 | {NULL((void*)0), NULL((void*)0)}, | |||
109 | }; | |||
110 | ||||
111 | static int s_timeIt = 0; | |||
112 | static int s_printIt = 0; | |||
113 | static int s_startOff = 0; | |||
114 | static int s_nomlib = 0; | |||
115 | ||||
116 | /*************************************************************************** | |||
117 | * Static Function Prototypes * | |||
118 | ***************************************************************************/ | |||
119 | ||||
120 | static int | |||
121 | allocateArray(JNIEnv *env, BufImageS_t *imageP, | |||
122 | mlib_image **mlibImagePP, void **dataPP, int isSrc, | |||
123 | int cvtToDefault, int addAlpha); | |||
124 | static int | |||
125 | allocateRasterArray(JNIEnv *env, RasterS_t *rasterP, | |||
126 | mlib_image **mlibImagePP, void **dataPP, int isSrc); | |||
127 | ||||
128 | static void | |||
129 | freeArray(JNIEnv *env, BufImageS_t *srcimageP, mlib_image *srcmlibImP, | |||
130 | void *srcdataP, BufImageS_t *dstimageP, mlib_image *dstmlibImP, | |||
131 | void *dstdataP); | |||
132 | static void | |||
133 | freeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP, | |||
134 | void *srcdataP, jobject dstJdata, mlib_image *dstmlibImP, | |||
135 | void *dstdataP); | |||
136 | ||||
137 | static int | |||
138 | storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, | |||
139 | mlib_image *mlibImP); | |||
140 | ||||
141 | static int | |||
142 | storeRasterArray(JNIEnv *env, RasterS_t *srcP, RasterS_t *dstP, | |||
143 | mlib_image *mlibImP); | |||
144 | ||||
145 | static int | |||
146 | storeICMarray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, | |||
147 | mlib_image *mlibImP); | |||
148 | ||||
149 | static int | |||
150 | colorMatch(int r, int g, int b, int a, unsigned char *argb, int numColors); | |||
151 | ||||
152 | static int | |||
153 | setImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, | |||
154 | int expandICM, int useAlpha, | |||
155 | int premultiply, mlibHintS_t *hintP); | |||
156 | ||||
157 | ||||
158 | static int expandICM(JNIEnv *env, BufImageS_t *imageP, unsigned int *mDataP); | |||
159 | static int expandPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
160 | unsigned char *outDataP); | |||
161 | static int expandPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
162 | unsigned char *outDataP); | |||
163 | static int expandPackedICR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
164 | unsigned char *outDataP); | |||
165 | static int expandPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
166 | int component, unsigned char *outDataP, | |||
167 | int forceAlpha); | |||
168 | static int expandPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
169 | int component, unsigned char *outDataP, | |||
170 | int forceAlpha); | |||
171 | static int expandPackedICRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
172 | int component, unsigned char *outDataP, | |||
173 | int forceAlpha); | |||
174 | static int setPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
175 | unsigned char *outDataP); | |||
176 | static int setPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
177 | unsigned char *outDataP); | |||
178 | static int setPackedICR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
179 | unsigned char *outDataP); | |||
180 | static int setPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
181 | int component, unsigned char *outDataP, | |||
182 | int supportsAlpha); | |||
183 | static int setPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
184 | int component, unsigned char *outDataP, | |||
185 | int supportsAlpha); | |||
186 | static int setPackedICRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
187 | int component, unsigned char *outDataP, | |||
188 | int supportsAlpha); | |||
189 | ||||
190 | mlib_start_timer start_timer = NULL((void*)0); | |||
191 | mlib_stop_timer stop_timer = NULL((void*)0); | |||
192 | ||||
193 | /*************************************************************************** | |||
194 | * Debugging Definitions * | |||
195 | ***************************************************************************/ | |||
196 | #ifdef DEBUG1 | |||
197 | ||||
198 | static void | |||
199 | printMedialibError(int status) { | |||
200 | switch(status) { | |||
201 | case MLIB_FAILURE: | |||
202 | jio_fprintf(stderr, "failure\n")__fprintf_chk (stderr, 2 - 1, "failure\n"); | |||
203 | break; | |||
204 | case MLIB_NULLPOINTER: | |||
205 | jio_fprintf(stderr, "null pointer\n")__fprintf_chk (stderr, 2 - 1, "null pointer\n"); | |||
206 | break; | |||
207 | case MLIB_OUTOFRANGE: | |||
208 | jio_fprintf (stderr, "out of range\n")__fprintf_chk (stderr, 2 - 1, "out of range\n"); | |||
209 | break; | |||
210 | default: | |||
211 | jio_fprintf (stderr, "medialib error\n")__fprintf_chk (stderr, 2 - 1, "medialib error\n"); | |||
212 | break; | |||
213 | } | |||
214 | } | |||
215 | #else /* ! DEBUG */ | |||
216 | # define printMedialibError(x) | |||
217 | ||||
218 | #endif /* ! DEBUG */ | |||
219 | ||||
220 | static int | |||
221 | getMlibEdgeHint(jint edgeHint) { | |||
222 | switch (edgeHint) { | |||
223 | case java_awt_image_ConvolveOp_EDGE_NO_OP1L: | |||
224 | return MLIB_EDGE_DST_COPY_SRC; | |||
225 | case java_awt_image_ConvolveOp_EDGE_ZERO_FILL0L: | |||
226 | default: | |||
227 | return MLIB_EDGE_DST_FILL_ZERO; | |||
228 | } | |||
229 | } | |||
230 | ||||
231 | /* | |||
232 | * We have to make sure that awt_setPixels can be safely applied to the given pair of | |||
233 | * raster and mlib image. | |||
234 | * | |||
235 | * In particular, make sure that | |||
236 | * - dimension is the same | |||
237 | * - number of channels in mlib image corresponds to the number of bands in the raster | |||
238 | * - sample size in image and raster are the same. | |||
239 | * | |||
240 | * Returns: | |||
241 | * -1 to indicate failure, | |||
242 | * 1 to indicate success | |||
243 | */ | |||
244 | static int setPixelsFormMlibImage(JNIEnv *env, RasterS_t *rasterP, mlib_image* img) { | |||
245 | if (rasterP->width != img->width || rasterP->height != img->height) { | |||
246 | /* dimension does not match */ | |||
247 | return -1; | |||
248 | } | |||
249 | ||||
250 | if (rasterP->numBands != img->channels) { | |||
251 | /* number of bands does not match */ | |||
252 | return -1; | |||
253 | } | |||
254 | ||||
255 | switch (rasterP->dataType) { | |||
256 | case BYTE_DATA_TYPE1: | |||
257 | if (img->type != MLIB_BYTE) { | |||
258 | return -1; | |||
259 | } | |||
260 | break; | |||
261 | case SHORT_DATA_TYPE2: | |||
262 | if (img->type != MLIB_SHORT && img->type != MLIB_USHORT) { | |||
263 | return -1; | |||
264 | } | |||
265 | break; | |||
266 | default: | |||
267 | /* awt_setPixels does not support such rasters */ | |||
268 | return -1; | |||
269 | } | |||
270 | ||||
271 | return awt_setPixels(env, rasterP, mlib_ImageGetData(img)); | |||
272 | } | |||
273 | ||||
274 | /*************************************************************************** | |||
275 | * External Functions * | |||
276 | ***************************************************************************/ | |||
277 | JNIEXPORT__attribute__((visibility("default"))) jint JNICALL | |||
278 | Java_sun_awt_image_ImagingLib_convolveBI(JNIEnv *env, jobject this, | |||
279 | jobject jsrc, jobject jdst, | |||
280 | jobject jkernel, jint edgeHint) | |||
281 | { | |||
282 | void *sdata, *ddata; | |||
283 | mlib_image *src; | |||
284 | mlib_image *dst; | |||
285 | int i, scale; | |||
286 | mlib_d64 *dkern; | |||
287 | mlib_s32 *kdata; | |||
288 | int klen; | |||
289 | float kmax; | |||
290 | mlib_s32 cmask; | |||
291 | mlib_status status; | |||
292 | int retStatus = 1; | |||
293 | float *kern; | |||
294 | BufImageS_t *srcImageP, *dstImageP; | |||
295 | jobject jdata; | |||
296 | int kwidth; | |||
297 | int kheight; | |||
298 | int w, h; | |||
299 | int x, y; | |||
300 | mlibHintS_t hint; | |||
301 | int nbands; | |||
302 | ||||
303 | /* This function requires a lot of local refs ??? Is 64 enough ??? */ | |||
304 | if ((*env)->EnsureLocalCapacity(env, 64) < 0) | |||
| ||||
305 | return 0; | |||
306 | ||||
307 | if (s_nomlib) return 0; | |||
308 | if (s_timeIt) (*start_timer)(3600); | |||
309 | ||||
310 | kwidth = (*env)->GetIntField(env, jkernel, g_KernelWidthID); | |||
311 | kheight = (*env)->GetIntField(env, jkernel, g_KernelHeightID); | |||
312 | jdata = (*env)->GetObjectField(env, jkernel, g_KernelDataID); | |||
313 | klen = (*env)->GetArrayLength(env, jdata); | |||
314 | kern = (float *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL((void*)0)); | |||
315 | if (kern == NULL((void*)0)) { | |||
316 | /* out of memory exception already thrown */ | |||
317 | return 0; | |||
318 | } | |||
319 | ||||
320 | if ((kwidth&0x1) == 0) { | |||
321 | /* Kernel has even width */ | |||
322 | w = kwidth+1; | |||
323 | } | |||
324 | else { | |||
325 | w = kwidth; | |||
326 | } | |||
327 | if ((kheight&0x1) == 0) { | |||
328 | /* Kernel has even height */ | |||
329 | h = kheight+1; | |||
330 | } | |||
331 | else { | |||
332 | h = kheight; | |||
333 | } | |||
334 | ||||
335 | dkern = NULL((void*)0); | |||
336 | if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_d64))(((w) > 0) && ((h) > 0) && ((sizeof(mlib_d64 )) > 0) && (((0x7fffffff / (w)) / (h)) > (sizeof (mlib_d64))))) { | |||
337 | dkern = (mlib_d64 *)calloc(1, w * h * sizeof(mlib_d64)); | |||
338 | } | |||
339 | if (dkern == NULL((void*)0)) { | |||
340 | (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT2); | |||
341 | return 0; | |||
342 | } | |||
343 | ||||
344 | /* Need to flip and find max value of the kernel. | |||
345 | * Also, save the kernel values as mlib_d64 values. | |||
346 | * The flip is to operate correctly with medialib, | |||
347 | * which doesn't do the mathemetically correct thing, | |||
348 | * i.e. it doesn't rotate the kernel by 180 degrees. | |||
349 | * REMIND: This should perhaps be done at the Java | |||
350 | * level by ConvolveOp. | |||
351 | * REMIND: Should the max test be looking at absolute | |||
352 | * values? | |||
353 | * REMIND: What if klen != kheight * kwidth? | |||
354 | */ | |||
355 | kmax = kern[klen-1]; | |||
356 | i = klen-1; | |||
357 | for (y=0; y
| |||
358 | for (x=0; x < kwidth; x++, i--) { | |||
359 | dkern[y*w+x] = (mlib_d64) kern[i]; | |||
360 | if (kern[i] > kmax) { | |||
361 | kmax = kern[i]; | |||
362 | } | |||
363 | } | |||
364 | } | |||
365 | ||||
366 | (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT2); | |||
367 | ||||
368 | if (kmax > 1<<16) { | |||
369 | /* We can only handle 16 bit max */ | |||
370 | free(dkern); | |||
371 | return 0; | |||
372 | } | |||
373 | ||||
374 | ||||
375 | /* Parse the source image */ | |||
376 | if (awt_parseImage(env, jsrc, &srcImageP, FALSE(0)) <= 0) { | |||
377 | /* Can't handle any custom images */ | |||
378 | free(dkern); | |||
379 | return 0; | |||
380 | } | |||
381 | ||||
382 | /* Parse the destination image */ | |||
383 | if (awt_parseImage(env, jdst, &dstImageP, FALSE(0)) <= 0) { | |||
384 | /* Can't handle any custom images */ | |||
385 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
386 | free(dkern); | |||
387 | return 0; | |||
388 | } | |||
389 | ||||
390 | nbands = setImageHints(env, srcImageP, dstImageP, TRUE(1), TRUE(1), | |||
391 | FALSE(0), &hint); | |||
392 | if (nbands < 1) { | |||
393 | /* Can't handle any custom images */ | |||
394 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
395 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
396 | free(dkern); | |||
397 | return 0; | |||
398 | } | |||
399 | /* Allocate the arrays */ | |||
400 | if (allocateArray(env, srcImageP, &src, &sdata, TRUE(1), | |||
401 | hint.cvtSrcToDefault, hint.addAlpha) < 0) { | |||
402 | /* Must be some problem */ | |||
403 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
404 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
405 | free(dkern); | |||
406 | return 0; | |||
407 | } | |||
408 | if (allocateArray(env, dstImageP, &dst, &ddata, FALSE(0), | |||
409 | hint.cvtToDst, FALSE(0)) < 0) { | |||
410 | /* Must be some problem */ | |||
411 | freeArray(env, srcImageP, src, sdata, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
412 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
413 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
414 | free(dkern); | |||
415 | return 0; | |||
416 | } | |||
417 | ||||
418 | kdata = NULL((void*)0); | |||
419 | if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_s32))(((w) > 0) && ((h) > 0) && ((sizeof(mlib_s32 )) > 0) && (((0x7fffffff / (w)) / (h)) > (sizeof (mlib_s32))))) { | |||
420 | kdata = (mlib_s32 *)malloc(w * h * sizeof(mlib_s32)); | |||
421 | } | |||
422 | if (kdata == NULL((void*)0)) { | |||
423 | freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata); | |||
424 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
425 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
426 | free(dkern); | |||
427 | return 0; | |||
428 | } | |||
429 | ||||
430 | if ((*sMlibFns[MLIB_CONVKERNCVT].fptr)(kdata, &scale, dkern, w, h, | |||
431 | mlib_ImageGetType(src)) != MLIB_SUCCESS) { | |||
432 | freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata); | |||
433 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
434 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
435 | free(dkern); | |||
436 | free(kdata); | |||
437 | return 0; | |||
438 | } | |||
439 | ||||
440 | if (s_printIt) { | |||
441 | fprintf(stderr, "Orig Kernel(len=%d):\n",klen)__fprintf_chk (stderr, 2 - 1, "Orig Kernel(len=%d):\n",klen); | |||
442 | for (y=kheight-1; y >= 0; y--) { | |||
443 | for (x=kwidth-1; x >= 0; x--) { | |||
444 | fprintf(stderr, "%g ", dkern[y*w+x])__fprintf_chk (stderr, 2 - 1, "%g ", dkern[y*w+x]); | |||
445 | } | |||
446 | fprintf(stderr, "\n")__fprintf_chk (stderr, 2 - 1, "\n"); | |||
447 | } | |||
448 | fprintf(stderr, "New Kernel(scale=%d):\n", scale)__fprintf_chk (stderr, 2 - 1, "New Kernel(scale=%d):\n", scale ); | |||
449 | for (y=kheight-1; y >= 0; y--) { | |||
450 | for (x=kwidth-1; x >= 0; x--) { | |||
451 | fprintf(stderr, "%d ", kdata[y*w+x])__fprintf_chk (stderr, 2 - 1, "%d ", kdata[y*w+x]); | |||
452 | } | |||
453 | fprintf(stderr, "\n")__fprintf_chk (stderr, 2 - 1, "\n"); | |||
454 | } | |||
455 | } | |||
456 | ||||
457 | cmask = (1<<src->channels)-1; | |||
458 | status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h, | |||
459 | (w-1)/2, (h-1)/2, scale, cmask, | |||
460 | getMlibEdgeHint(edgeHint)); | |||
461 | ||||
462 | if (status != MLIB_SUCCESS) { | |||
463 | printMedialibError(status); | |||
464 | retStatus = 0; | |||
465 | } | |||
466 | ||||
467 | if (s_printIt) { | |||
468 | unsigned int *dP; | |||
469 | if (s_startOff != 0) { | |||
470 | printf("Starting at %d\n", s_startOff)__printf_chk (2 - 1, "Starting at %d\n", s_startOff); | |||
471 | } | |||
472 | if (sdata == NULL((void*)0)) { | |||
473 | dP = (unsigned int *) mlib_ImageGetData(src); | |||
474 | } | |||
475 | else { | |||
476 | dP = (unsigned int *) sdata; | |||
477 | } | |||
478 | printf("src is\n")__printf_chk (2 - 1, "src is\n"); | |||
479 | for (i=0; i < 20; i++) { | |||
480 | printf("%x ",dP[s_startOff+i])__printf_chk (2 - 1, "%x ",dP[s_startOff+i]); | |||
481 | } | |||
482 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
483 | if (ddata == NULL((void*)0)) { | |||
484 | dP = (unsigned int *)mlib_ImageGetData(dst); | |||
485 | } | |||
486 | else { | |||
487 | dP = (unsigned int *) ddata; | |||
488 | } | |||
489 | printf("dst is \n")__printf_chk (2 - 1, "dst is \n"); | |||
490 | for (i=0; i < 20; i++) { | |||
491 | printf("%x ",dP[s_startOff+i])__printf_chk (2 - 1, "%x ",dP[s_startOff+i]); | |||
492 | } | |||
493 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
494 | } | |||
495 | ||||
496 | /* Means that we couldn't write directly into the destination buffer */ | |||
497 | if (ddata == NULL((void*)0)) { | |||
498 | ||||
499 | /* Need to store it back into the array */ | |||
500 | if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) { | |||
501 | /* Error */ | |||
502 | retStatus = 0; | |||
503 | } | |||
504 | } | |||
505 | ||||
506 | /* Release the pinned memory */ | |||
507 | freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata); | |||
508 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
509 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
510 | free(dkern); | |||
511 | free(kdata); | |||
512 | ||||
513 | if (s_timeIt) (*stop_timer)(3600, 1); | |||
514 | ||||
515 | return retStatus; | |||
516 | } | |||
517 | ||||
518 | JNIEXPORT__attribute__((visibility("default"))) jint JNICALL | |||
519 | Java_sun_awt_image_ImagingLib_convolveRaster(JNIEnv *env, jobject this, | |||
520 | jobject jsrc, jobject jdst, | |||
521 | jobject jkernel, jint edgeHint) | |||
522 | { | |||
523 | mlib_image *src; | |||
524 | mlib_image *dst; | |||
525 | int i, scale; | |||
526 | mlib_d64 *dkern; | |||
527 | mlib_s32 *kdata; | |||
528 | int klen; | |||
529 | float kmax; | |||
530 | int retStatus = 1; | |||
531 | mlib_status status; | |||
532 | mlib_s32 cmask; | |||
533 | void *sdata; | |||
534 | void *ddata; | |||
535 | RasterS_t *srcRasterP; | |||
536 | RasterS_t *dstRasterP; | |||
537 | int kwidth; | |||
538 | int kheight; | |||
539 | int w, h; | |||
540 | int x, y; | |||
541 | jobject jdata; | |||
542 | float *kern; | |||
543 | ||||
544 | /* This function requires a lot of local refs ??? Is 64 enough ??? */ | |||
545 | if ((*env)->EnsureLocalCapacity(env, 64) < 0) | |||
546 | return 0; | |||
547 | ||||
548 | if (s_nomlib) return 0; | |||
549 | if (s_timeIt) (*start_timer)(3600); | |||
550 | ||||
551 | kwidth = (*env)->GetIntField(env, jkernel, g_KernelWidthID); | |||
552 | kheight = (*env)->GetIntField(env, jkernel, g_KernelHeightID); | |||
553 | jdata = (*env)->GetObjectField(env, jkernel, g_KernelDataID); | |||
554 | klen = (*env)->GetArrayLength(env, jdata); | |||
555 | kern = (float *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL((void*)0)); | |||
556 | if (kern == NULL((void*)0)) { | |||
557 | /* out of memory exception already thrown */ | |||
558 | return 0; | |||
559 | } | |||
560 | ||||
561 | if ((kwidth&0x1) == 0) { | |||
562 | /* Kernel has even width */ | |||
563 | w = kwidth+1; | |||
564 | } | |||
565 | else { | |||
566 | w = kwidth; | |||
567 | } | |||
568 | if ((kheight&0x1) == 0) { | |||
569 | /* Kernel has even height */ | |||
570 | h = kheight+1; | |||
571 | } | |||
572 | else { | |||
573 | h = kheight; | |||
574 | } | |||
575 | ||||
576 | dkern = NULL((void*)0); | |||
577 | if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_d64))(((w) > 0) && ((h) > 0) && ((sizeof(mlib_d64 )) > 0) && (((0x7fffffff / (w)) / (h)) > (sizeof (mlib_d64))))) { | |||
578 | dkern = (mlib_d64 *)calloc(1, w * h * sizeof(mlib_d64)); | |||
579 | } | |||
580 | if (dkern == NULL((void*)0)) { | |||
581 | (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT2); | |||
582 | return 0; | |||
583 | } | |||
584 | ||||
585 | /* Need to flip and find max value of the kernel. | |||
586 | * Also, save the kernel values as mlib_d64 values. | |||
587 | * The flip is to operate correctly with medialib, | |||
588 | * which doesn't do the mathemetically correct thing, | |||
589 | * i.e. it doesn't rotate the kernel by 180 degrees. | |||
590 | * REMIND: This should perhaps be done at the Java | |||
591 | * level by ConvolveOp. | |||
592 | * REMIND: Should the max test be looking at absolute | |||
593 | * values? | |||
594 | * REMIND: What if klen != kheight * kwidth? | |||
595 | */ | |||
596 | kmax = kern[klen-1]; | |||
597 | i = klen-1; | |||
598 | for (y=0; y < kheight; y++) { | |||
599 | for (x=0; x < kwidth; x++, i--) { | |||
600 | dkern[y*w+x] = (mlib_d64) kern[i]; | |||
601 | if (kern[i] > kmax) { | |||
602 | kmax = kern[i]; | |||
603 | } | |||
604 | } | |||
605 | } | |||
606 | ||||
607 | (*env)->ReleasePrimitiveArrayCritical(env, jdata, kern, JNI_ABORT2); | |||
608 | ||||
609 | if (kmax > 1<<16) { | |||
610 | /* We can only handle 16 bit max */ | |||
611 | free(dkern); | |||
612 | return 0; | |||
613 | } | |||
614 | ||||
615 | /* Parse the source image */ | |||
616 | if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL((void*)0)) { | |||
617 | JNU_ThrowOutOfMemoryError(env, "Out of memory"); | |||
618 | free(dkern); | |||
619 | return -1; | |||
620 | } | |||
621 | ||||
622 | if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL((void*)0)) { | |||
623 | JNU_ThrowOutOfMemoryError(env, "Out of memory"); | |||
624 | free(srcRasterP); | |||
625 | free(dkern); | |||
626 | return -1; | |||
627 | } | |||
628 | ||||
629 | /* Parse the source raster */ | |||
630 | if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { | |||
631 | /* Can't handle any custom rasters */ | |||
632 | free(srcRasterP); | |||
633 | free(dstRasterP); | |||
634 | free(dkern); | |||
635 | return 0; | |||
636 | } | |||
637 | ||||
638 | /* Parse the destination raster */ | |||
639 | if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { | |||
640 | /* Can't handle any custom images */ | |||
641 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
642 | free(dstRasterP); | |||
643 | free(dkern); | |||
644 | return 0; | |||
645 | } | |||
646 | ||||
647 | /* Allocate the arrays */ | |||
648 | if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE(1)) < 0) { | |||
649 | /* Must be some problem */ | |||
650 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
651 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
652 | free(dkern); | |||
653 | return 0; | |||
654 | } | |||
655 | if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE(0)) < 0) { | |||
656 | /* Must be some problem */ | |||
657 | freeDataArray(env, srcRasterP->jdata, src, sdata, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
658 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
659 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
660 | free(dkern); | |||
661 | return 0; | |||
662 | } | |||
663 | ||||
664 | kdata = NULL((void*)0); | |||
665 | if (SAFE_TO_ALLOC_3(w, h, sizeof(mlib_s32))(((w) > 0) && ((h) > 0) && ((sizeof(mlib_s32 )) > 0) && (((0x7fffffff / (w)) / (h)) > (sizeof (mlib_s32))))) { | |||
666 | kdata = (mlib_s32 *)malloc(w * h * sizeof(mlib_s32)); | |||
667 | } | |||
668 | if (kdata == NULL((void*)0)) { | |||
669 | freeDataArray(env, srcRasterP->jdata, src, sdata, | |||
670 | dstRasterP->jdata, dst, ddata); | |||
671 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
672 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
673 | free(dkern); | |||
674 | return 0; | |||
675 | } | |||
676 | ||||
677 | if ((*sMlibFns[MLIB_CONVKERNCVT].fptr)(kdata, &scale, dkern, w, h, | |||
678 | mlib_ImageGetType(src)) != MLIB_SUCCESS) { | |||
679 | freeDataArray(env, srcRasterP->jdata, src, sdata, | |||
680 | dstRasterP->jdata, dst, ddata); | |||
681 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
682 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
683 | free(dkern); | |||
684 | free(kdata); | |||
685 | return 0; | |||
686 | } | |||
687 | ||||
688 | if (s_printIt) { | |||
689 | fprintf(stderr, "Orig Kernel(len=%d):\n",klen)__fprintf_chk (stderr, 2 - 1, "Orig Kernel(len=%d):\n",klen); | |||
690 | for (y=kheight-1; y >= 0; y--) { | |||
691 | for (x=kwidth-1; x >= 0; x--) { | |||
692 | fprintf(stderr, "%g ", dkern[y*w+x])__fprintf_chk (stderr, 2 - 1, "%g ", dkern[y*w+x]); | |||
693 | } | |||
694 | fprintf(stderr, "\n")__fprintf_chk (stderr, 2 - 1, "\n"); | |||
695 | } | |||
696 | fprintf(stderr, "New Kernel(scale=%d):\n", scale)__fprintf_chk (stderr, 2 - 1, "New Kernel(scale=%d):\n", scale ); | |||
697 | for (y=kheight-1; y >= 0; y--) { | |||
698 | for (x=kwidth-1; x >= 0; x--) { | |||
699 | fprintf(stderr, "%d ", kdata[y*w+x])__fprintf_chk (stderr, 2 - 1, "%d ", kdata[y*w+x]); | |||
700 | } | |||
701 | fprintf(stderr, "\n")__fprintf_chk (stderr, 2 - 1, "\n"); | |||
702 | } | |||
703 | } | |||
704 | ||||
705 | cmask = (1<<src->channels)-1; | |||
706 | status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h, | |||
707 | (w-1)/2, (h-1)/2, scale, cmask, | |||
708 | getMlibEdgeHint(edgeHint)); | |||
709 | ||||
710 | if (status != MLIB_SUCCESS) { | |||
711 | printMedialibError(status); | |||
712 | retStatus = 0; | |||
713 | } | |||
714 | ||||
715 | if (s_printIt) { | |||
716 | unsigned int *dP; | |||
717 | if (s_startOff != 0) { | |||
718 | printf("Starting at %d\n", s_startOff)__printf_chk (2 - 1, "Starting at %d\n", s_startOff); | |||
719 | } | |||
720 | if (sdata == NULL((void*)0)) { | |||
721 | dP = (unsigned int *) mlib_ImageGetData(src); | |||
722 | } | |||
723 | else { | |||
724 | dP = (unsigned int *) sdata; | |||
725 | } | |||
726 | printf("src is\n")__printf_chk (2 - 1, "src is\n"); | |||
727 | for (i=0; i < 20; i++) { | |||
728 | printf("%x ",dP[s_startOff+i])__printf_chk (2 - 1, "%x ",dP[s_startOff+i]); | |||
729 | } | |||
730 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
731 | if (ddata == NULL((void*)0)) { | |||
732 | dP = (unsigned int *)mlib_ImageGetData(dst); | |||
733 | } | |||
734 | else { | |||
735 | dP = (unsigned int *) ddata; | |||
736 | } | |||
737 | printf("dst is\n")__printf_chk (2 - 1, "dst is\n"); | |||
738 | for (i=0; i < 20; i++) { | |||
739 | printf("%x ",dP[s_startOff+i])__printf_chk (2 - 1, "%x ",dP[s_startOff+i]); | |||
740 | } | |||
741 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
742 | } | |||
743 | ||||
744 | /* Means that we couldn't write directly into the destination buffer */ | |||
745 | if (ddata == NULL((void*)0)) { | |||
746 | if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) { | |||
747 | retStatus = setPixelsFormMlibImage(env, dstRasterP, dst); | |||
748 | } | |||
749 | } | |||
750 | ||||
751 | /* Release the pinned memory */ | |||
752 | freeDataArray(env, srcRasterP->jdata, src, sdata, | |||
753 | dstRasterP->jdata, dst, ddata); | |||
754 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
755 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
756 | free(dkern); | |||
757 | free(kdata); | |||
758 | ||||
759 | if (s_timeIt) (*stop_timer)(3600,1); | |||
760 | ||||
761 | return retStatus; | |||
762 | } | |||
763 | ||||
764 | ||||
765 | JNIEXPORT__attribute__((visibility("default"))) jint JNICALL | |||
766 | Java_sun_awt_image_ImagingLib_transformBI(JNIEnv *env, jobject this, | |||
767 | jobject jsrc, | |||
768 | jobject jdst, | |||
769 | jdoubleArray jmatrix, | |||
770 | jint interpType) | |||
771 | { | |||
772 | mlib_image *src; | |||
773 | mlib_image *dst; | |||
774 | int i; | |||
775 | int j = 0; | |||
776 | int retStatus = 1; | |||
777 | mlib_status status; | |||
778 | double *matrix; | |||
779 | mlib_d64 mtx[6]; | |||
780 | void *sdata; | |||
781 | void *ddata; | |||
782 | BufImageS_t *srcImageP; | |||
783 | BufImageS_t *dstImageP; | |||
784 | mlib_filter filter; | |||
785 | mlibHintS_t hint; | |||
786 | unsigned int *dP; | |||
787 | int useIndexed; | |||
788 | int nbands; | |||
789 | ||||
790 | /* This function requires a lot of local refs ??? Is 64 enough ??? */ | |||
791 | if ((*env)->EnsureLocalCapacity(env, 64) < 0) | |||
792 | return 0; | |||
793 | ||||
794 | if (s_nomlib) return 0; | |||
795 | if (s_timeIt) { | |||
796 | (*start_timer)(3600); | |||
797 | } | |||
798 | ||||
799 | switch(interpType) { | |||
800 | case java_awt_image_AffineTransformOp_TYPE_BILINEAR2L: | |||
801 | filter = MLIB_BILINEAR; | |||
802 | break; | |||
803 | case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR1L: | |||
804 | filter = MLIB_NEAREST; | |||
805 | break; | |||
806 | case java_awt_image_AffineTransformOp_TYPE_BICUBIC3L: | |||
807 | filter = MLIB_BICUBIC; | |||
808 | break; | |||
809 | default: | |||
810 | JNU_ThrowInternalError(env, "Unknown interpolation type"); | |||
811 | return -1; | |||
812 | } | |||
813 | ||||
814 | if ((*env)->GetArrayLength(env, jmatrix) < 6) { | |||
815 | /* | |||
816 | * Very unlikely, however we should check for this: | |||
817 | * if given matrix array is too short, we can't handle it | |||
818 | */ | |||
819 | return 0; | |||
820 | } | |||
821 | ||||
822 | matrix = (*env)->GetPrimitiveArrayCritical(env, jmatrix, NULL((void*)0)); | |||
823 | if (matrix == NULL((void*)0)) { | |||
824 | /* out of memory error already thrown */ | |||
825 | return 0; | |||
826 | } | |||
827 | ||||
828 | /* Check for invalid double value in transformation matrix */ | |||
829 | for (j = 0; j < 6; j++) { | |||
830 | ||||
831 | if (!(IS_FINITE(matrix[j])(((matrix[j]) >= -1.7976931348623157E+308) && ((matrix [j]) <= 1.7976931348623157E+308)))) { | |||
832 | (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT2); | |||
833 | return 0; | |||
834 | } | |||
835 | } | |||
836 | ||||
837 | if (s_printIt) { | |||
838 | printf("matrix is %g %g %g %g %g %g\n", matrix[0], matrix[1],__printf_chk (2 - 1, "matrix is %g %g %g %g %g %g\n", matrix[ 0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]) | |||
839 | matrix[2], matrix[3], matrix[4], matrix[5])__printf_chk (2 - 1, "matrix is %g %g %g %g %g %g\n", matrix[ 0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); | |||
840 | } | |||
841 | ||||
842 | mtx[0] = matrix[0]; | |||
843 | mtx[1] = matrix[2]; | |||
844 | mtx[2] = matrix[4]; | |||
845 | mtx[3] = matrix[1]; | |||
846 | mtx[4] = matrix[3]; | |||
847 | mtx[5] = matrix[5]; | |||
848 | ||||
849 | (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT2); | |||
850 | ||||
851 | /* Parse the source image */ | |||
852 | if (awt_parseImage(env, jsrc, &srcImageP, FALSE(0)) <= 0) { | |||
853 | /* Can't handle any custom images */ | |||
854 | return 0; | |||
855 | } | |||
856 | ||||
857 | /* Parse the destination image */ | |||
858 | if (awt_parseImage(env, jdst, &dstImageP, FALSE(0)) <= 0) { | |||
859 | /* Can't handle any custom images */ | |||
860 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
861 | return 0; | |||
862 | } | |||
863 | ||||
864 | /* REMIND!! Can't assume that it is the same LUT!! */ | |||
865 | /* Fix 4213160, 4184283 */ | |||
866 | useIndexed = (srcImageP->cmodel.cmType == INDEX_CM_TYPE3 && | |||
867 | dstImageP->cmodel.cmType == INDEX_CM_TYPE3 && | |||
868 | srcImageP->raster.rasterType == dstImageP->raster.rasterType && | |||
869 | srcImageP->raster.rasterType == COMPONENT_RASTER_TYPE1); | |||
870 | ||||
871 | nbands = setImageHints(env, srcImageP, dstImageP, !useIndexed, TRUE(1), | |||
872 | FALSE(0), &hint); | |||
873 | if (nbands < 1) { | |||
874 | /* Can't handle any custom images */ | |||
875 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
876 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
877 | return 0; | |||
878 | } | |||
879 | ||||
880 | /* Allocate the arrays */ | |||
881 | if (allocateArray(env, srcImageP, &src, &sdata, TRUE(1), | |||
882 | hint.cvtSrcToDefault, hint.addAlpha) < 0) { | |||
883 | /* Must be some problem */ | |||
884 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
885 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
886 | return 0; | |||
887 | } | |||
888 | if (allocateArray(env, dstImageP, &dst, &ddata, FALSE(0), | |||
889 | hint.cvtToDst, FALSE(0)) < 0) { | |||
890 | /* Must be some problem */ | |||
891 | freeArray(env, srcImageP, src, sdata, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
892 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
893 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
894 | return 0; | |||
895 | } | |||
896 | #if 0 | |||
897 | fprintf(stderr,"Src----------------\n")__fprintf_chk (stderr, 2 - 1, "Src----------------\n"); | |||
898 | fprintf(stderr,"Type : %d\n",src->type)__fprintf_chk (stderr, 2 - 1, "Type : %d\n",src->type); | |||
899 | fprintf(stderr,"Channels: %d\n",src->channels)__fprintf_chk (stderr, 2 - 1, "Channels: %d\n",src->channels ); | |||
900 | fprintf(stderr,"Width : %d\n",src->width)__fprintf_chk (stderr, 2 - 1, "Width : %d\n",src->width); | |||
901 | fprintf(stderr,"Height : %d\n",src->height)__fprintf_chk (stderr, 2 - 1, "Height : %d\n",src->height ); | |||
902 | fprintf(stderr,"Stride : %d\n",src->stride)__fprintf_chk (stderr, 2 - 1, "Stride : %d\n",src->stride ); | |||
903 | fprintf(stderr,"Flags : %d\n",src->flags)__fprintf_chk (stderr, 2 - 1, "Flags : %d\n",src->flags); | |||
904 | ||||
905 | fprintf(stderr,"Dst----------------\n")__fprintf_chk (stderr, 2 - 1, "Dst----------------\n"); | |||
906 | fprintf(stderr,"Type : %d\n",dst->type)__fprintf_chk (stderr, 2 - 1, "Type : %d\n",dst->type); | |||
907 | fprintf(stderr,"Channels: %d\n",dst->channels)__fprintf_chk (stderr, 2 - 1, "Channels: %d\n",dst->channels ); | |||
908 | fprintf(stderr,"Width : %d\n",dst->width)__fprintf_chk (stderr, 2 - 1, "Width : %d\n",dst->width); | |||
909 | fprintf(stderr,"Height : %d\n",dst->height)__fprintf_chk (stderr, 2 - 1, "Height : %d\n",dst->height ); | |||
910 | fprintf(stderr,"Stride : %d\n",dst->stride)__fprintf_chk (stderr, 2 - 1, "Stride : %d\n",dst->stride ); | |||
911 | fprintf(stderr,"Flags : %d\n",dst->flags)__fprintf_chk (stderr, 2 - 1, "Flags : %d\n",dst->flags); | |||
912 | #endif | |||
913 | ||||
914 | if (dstImageP->cmodel.cmType == INDEX_CM_TYPE3) { | |||
915 | /* Need to clear the destination to the transparent pixel */ | |||
916 | unsigned char *cP = (unsigned char *)mlib_ImageGetData(dst); | |||
917 | ||||
918 | memset(cP, dstImageP->cmodel.transIdx, | |||
919 | mlib_ImageGetWidth(dst)*mlib_ImageGetHeight(dst)); | |||
920 | } | |||
921 | /* Perform the transformation */ | |||
922 | if ((status = (*sMlibFns[MLIB_AFFINE].fptr)(dst, src, mtx, filter, | |||
923 | MLIB_EDGE_SRC_EXTEND) != MLIB_SUCCESS)) | |||
924 | { | |||
925 | printMedialibError(status); | |||
926 | freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata); | |||
927 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
928 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
929 | ||||
930 | return 0; | |||
931 | } | |||
932 | ||||
933 | if (s_printIt) { | |||
934 | if (sdata == NULL((void*)0)) { | |||
935 | dP = (unsigned int *) mlib_ImageGetData(src); | |||
936 | } | |||
937 | else { | |||
938 | dP = (unsigned int *) sdata; | |||
939 | } | |||
940 | printf("src is\n")__printf_chk (2 - 1, "src is\n"); | |||
941 | for (i=0; i < 20; i++) { | |||
942 | printf("%x ",dP[i])__printf_chk (2 - 1, "%x ",dP[i]); | |||
943 | } | |||
944 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
945 | if (ddata == NULL((void*)0)) { | |||
946 | dP = (unsigned int *)mlib_ImageGetData(dst); | |||
947 | } | |||
948 | else { | |||
949 | dP = (unsigned int *) ddata; | |||
950 | } | |||
951 | printf("dst is\n")__printf_chk (2 - 1, "dst is\n"); | |||
952 | for (i=0; i < 20; i++) { | |||
953 | printf("%x ",dP[i])__printf_chk (2 - 1, "%x ",dP[i]); | |||
954 | } | |||
955 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
956 | } | |||
957 | ||||
958 | /* Means that we couldn't write directly into the destination buffer */ | |||
959 | if (ddata == NULL((void*)0)) { | |||
960 | freeDataArray(env, srcImageP->raster.jdata, src, sdata, | |||
961 | NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
962 | /* Need to store it back into the array */ | |||
963 | if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) { | |||
964 | /* Error */ | |||
965 | retStatus = 0; | |||
966 | } | |||
967 | freeDataArray(env, NULL((void*)0), NULL((void*)0), NULL((void*)0), dstImageP->raster.jdata, | |||
968 | dst, ddata); | |||
969 | } | |||
970 | else { | |||
971 | /* Release the pinned memory */ | |||
972 | freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata); | |||
973 | } | |||
974 | ||||
975 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
976 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
977 | ||||
978 | if (s_timeIt) (*stop_timer)(3600,1); | |||
979 | ||||
980 | return retStatus; | |||
981 | } | |||
982 | ||||
983 | JNIEXPORT__attribute__((visibility("default"))) jint JNICALL | |||
984 | Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this, | |||
985 | jobject jsrc, | |||
986 | jobject jdst, | |||
987 | jdoubleArray jmatrix, | |||
988 | jint interpType) | |||
989 | { | |||
990 | mlib_image *src; | |||
991 | mlib_image *dst; | |||
992 | int i; | |||
993 | int j = 0; | |||
994 | int retStatus = 1; | |||
995 | mlib_status status; | |||
996 | double *matrix; | |||
997 | mlib_d64 mtx[6]; | |||
998 | void *sdata; | |||
999 | void *ddata; | |||
1000 | RasterS_t *srcRasterP; | |||
1001 | RasterS_t *dstRasterP; | |||
1002 | mlib_filter filter; | |||
1003 | unsigned int *dP; | |||
1004 | ||||
1005 | /* This function requires a lot of local refs ??? Is 64 enough ??? */ | |||
1006 | if ((*env)->EnsureLocalCapacity(env, 64) < 0) | |||
1007 | return 0; | |||
1008 | ||||
1009 | if (s_nomlib) return 0; | |||
1010 | if (s_timeIt) { | |||
1011 | (*start_timer)(3600); | |||
1012 | } | |||
1013 | ||||
1014 | switch(interpType) { | |||
1015 | case java_awt_image_AffineTransformOp_TYPE_BILINEAR2L: | |||
1016 | filter = MLIB_BILINEAR; | |||
1017 | break; | |||
1018 | case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR1L: | |||
1019 | filter = MLIB_NEAREST; | |||
1020 | break; | |||
1021 | case java_awt_image_AffineTransformOp_TYPE_BICUBIC3L: | |||
1022 | filter = MLIB_BICUBIC; | |||
1023 | break; | |||
1024 | default: | |||
1025 | JNU_ThrowInternalError(env, "Unknown interpolation type"); | |||
1026 | return -1; | |||
1027 | } | |||
1028 | ||||
1029 | if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL((void*)0)) { | |||
1030 | JNU_ThrowOutOfMemoryError(env, "Out of memory"); | |||
1031 | return -1; | |||
1032 | } | |||
1033 | ||||
1034 | if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL((void*)0)) { | |||
1035 | JNU_ThrowOutOfMemoryError(env, "Out of memory"); | |||
1036 | free(srcRasterP); | |||
1037 | return -1; | |||
1038 | } | |||
1039 | ||||
1040 | if ((*env)->GetArrayLength(env, jmatrix) < 6) { | |||
1041 | /* | |||
1042 | * Very unlikely, however we should check for this: | |||
1043 | * if given matrix array is too short, we can't handle it. | |||
1044 | */ | |||
1045 | free(srcRasterP); | |||
1046 | free(dstRasterP); | |||
1047 | return 0; | |||
1048 | } | |||
1049 | ||||
1050 | matrix = (*env)->GetPrimitiveArrayCritical(env, jmatrix, NULL((void*)0)); | |||
1051 | if (matrix == NULL((void*)0)) { | |||
1052 | /* out of memory error already thrown */ | |||
1053 | free(srcRasterP); | |||
1054 | free(dstRasterP); | |||
1055 | return 0; | |||
1056 | } | |||
1057 | ||||
1058 | /* Check for invalid double value in transformation matrix */ | |||
1059 | for (j = 0; j < 6; j++) { | |||
1060 | ||||
1061 | if (!(IS_FINITE(matrix[j])(((matrix[j]) >= -1.7976931348623157E+308) && ((matrix [j]) <= 1.7976931348623157E+308)))) { | |||
1062 | (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT2); | |||
1063 | free(srcRasterP); | |||
1064 | free(dstRasterP); | |||
1065 | ||||
1066 | return 0; | |||
1067 | } | |||
1068 | } | |||
1069 | ||||
1070 | if (s_printIt) { | |||
1071 | printf("matrix is %g %g %g %g %g %g\n", matrix[0], matrix[1],__printf_chk (2 - 1, "matrix is %g %g %g %g %g %g\n", matrix[ 0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]) | |||
1072 | matrix[2], matrix[3], matrix[4], matrix[5])__printf_chk (2 - 1, "matrix is %g %g %g %g %g %g\n", matrix[ 0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); | |||
1073 | } | |||
1074 | ||||
1075 | mtx[0] = matrix[0]; | |||
1076 | mtx[1] = matrix[2]; | |||
1077 | mtx[2] = matrix[4]; | |||
1078 | mtx[3] = matrix[1]; | |||
1079 | mtx[4] = matrix[3]; | |||
1080 | mtx[5] = matrix[5]; | |||
1081 | ||||
1082 | (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT2); | |||
1083 | ||||
1084 | /* Parse the source raster */ | |||
1085 | if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { | |||
1086 | /* Can't handle any custom rasters */ | |||
1087 | free(srcRasterP); | |||
1088 | free(dstRasterP); | |||
1089 | return 0; | |||
1090 | } | |||
1091 | ||||
1092 | /* Parse the destination raster */ | |||
1093 | if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { | |||
1094 | /* Can't handle any custom images */ | |||
1095 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1096 | free(dstRasterP); | |||
1097 | return 0; | |||
1098 | } | |||
1099 | ||||
1100 | /* Allocate the arrays */ | |||
1101 | if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE(1)) < 0) { | |||
1102 | /* Must be some problem */ | |||
1103 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1104 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1105 | return 0; | |||
1106 | } | |||
1107 | if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE(0)) < 0) { | |||
1108 | /* Must be some problem */ | |||
1109 | freeDataArray(env, srcRasterP->jdata, src, sdata, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
1110 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1111 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1112 | return 0; | |||
1113 | } | |||
1114 | ||||
1115 | #if 0 | |||
1116 | fprintf(stderr,"Src----------------\n")__fprintf_chk (stderr, 2 - 1, "Src----------------\n"); | |||
1117 | fprintf(stderr,"Type : %d\n",src->type)__fprintf_chk (stderr, 2 - 1, "Type : %d\n",src->type); | |||
1118 | fprintf(stderr,"Channels: %d\n",src->channels)__fprintf_chk (stderr, 2 - 1, "Channels: %d\n",src->channels ); | |||
1119 | fprintf(stderr,"Width : %d\n",src->width)__fprintf_chk (stderr, 2 - 1, "Width : %d\n",src->width); | |||
1120 | fprintf(stderr,"Height : %d\n",src->height)__fprintf_chk (stderr, 2 - 1, "Height : %d\n",src->height ); | |||
1121 | fprintf(stderr,"Stride : %d\n",src->stride)__fprintf_chk (stderr, 2 - 1, "Stride : %d\n",src->stride ); | |||
1122 | fprintf(stderr,"Flags : %d\n",src->flags)__fprintf_chk (stderr, 2 - 1, "Flags : %d\n",src->flags); | |||
1123 | ||||
1124 | fprintf(stderr,"Dst----------------\n")__fprintf_chk (stderr, 2 - 1, "Dst----------------\n"); | |||
1125 | fprintf(stderr,"Type : %d\n",dst->type)__fprintf_chk (stderr, 2 - 1, "Type : %d\n",dst->type); | |||
1126 | fprintf(stderr,"Channels: %d\n",dst->channels)__fprintf_chk (stderr, 2 - 1, "Channels: %d\n",dst->channels ); | |||
1127 | fprintf(stderr,"Width : %d\n",dst->width)__fprintf_chk (stderr, 2 - 1, "Width : %d\n",dst->width); | |||
1128 | fprintf(stderr,"Height : %d\n",dst->height)__fprintf_chk (stderr, 2 - 1, "Height : %d\n",dst->height ); | |||
1129 | fprintf(stderr,"Stride : %d\n",dst->stride)__fprintf_chk (stderr, 2 - 1, "Stride : %d\n",dst->stride ); | |||
1130 | fprintf(stderr,"Flags : %d\n",dst->flags)__fprintf_chk (stderr, 2 - 1, "Flags : %d\n",dst->flags); | |||
1131 | #endif | |||
1132 | ||||
1133 | { | |||
1134 | unsigned char *cP = (unsigned char *)mlib_ImageGetData(dst); | |||
1135 | ||||
1136 | memset(cP, 0, mlib_ImageGetWidth(dst)*mlib_ImageGetHeight(dst)); | |||
1137 | } | |||
1138 | ||||
1139 | /* Perform the transformation */ | |||
1140 | if ((status = (*sMlibFns[MLIB_AFFINE].fptr)(dst, src, mtx, filter, | |||
1141 | MLIB_EDGE_SRC_EXTEND) != MLIB_SUCCESS)) | |||
1142 | { | |||
1143 | printMedialibError(status); | |||
1144 | /* REMIND: Free the regions */ | |||
1145 | return 0; | |||
1146 | } | |||
1147 | ||||
1148 | if (s_printIt) { | |||
1149 | if (sdata == NULL((void*)0)) { | |||
1150 | dP = (unsigned int *) mlib_ImageGetData(src); | |||
1151 | } | |||
1152 | else { | |||
1153 | dP = (unsigned int *) sdata; | |||
1154 | } | |||
1155 | printf("src is\n")__printf_chk (2 - 1, "src is\n"); | |||
1156 | for (i=0; i < 20; i++) { | |||
1157 | printf("%x ",dP[i])__printf_chk (2 - 1, "%x ",dP[i]); | |||
1158 | } | |||
1159 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
1160 | if (ddata == NULL((void*)0)) { | |||
1161 | dP = (unsigned int *)mlib_ImageGetData(dst); | |||
1162 | } | |||
1163 | else { | |||
1164 | dP = (unsigned int *) ddata; | |||
1165 | } | |||
1166 | printf("dst is\n")__printf_chk (2 - 1, "dst is\n"); | |||
1167 | for (i=0; i < 20; i++) { | |||
1168 | printf("%x ",dP[i])__printf_chk (2 - 1, "%x ",dP[i]); | |||
1169 | } | |||
1170 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
1171 | } | |||
1172 | ||||
1173 | /* Means that we couldn't write directly into the destination buffer */ | |||
1174 | if (ddata == NULL((void*)0)) { | |||
1175 | /* Need to store it back into the array */ | |||
1176 | if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) { | |||
1177 | (*env)->ExceptionClear(env); // Could not store the array, try another way | |||
1178 | retStatus = setPixelsFormMlibImage(env, dstRasterP, dst); | |||
1179 | } | |||
1180 | } | |||
1181 | ||||
1182 | /* Release the pinned memory */ | |||
1183 | freeDataArray(env, srcRasterP->jdata, src, sdata, | |||
1184 | dstRasterP->jdata, dst, ddata); | |||
1185 | ||||
1186 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1187 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1188 | ||||
1189 | if (s_timeIt) (*stop_timer)(3600,1); | |||
1190 | ||||
1191 | return retStatus; | |||
1192 | } | |||
1193 | ||||
1194 | typedef struct { | |||
1195 | jobject jArray; | |||
1196 | jsize length; | |||
1197 | unsigned char *table; | |||
1198 | } LookupArrayInfo; | |||
1199 | ||||
1200 | #define NLUT8 8 | |||
1201 | ||||
1202 | #ifdef _LITTLE_ENDIAN1 | |||
1203 | #define INDEXES{ 3, 2, 1, 0, 7, 6, 5, 4 } { 3, 2, 1, 0, 7, 6, 5, 4 } | |||
1204 | #else | |||
1205 | #define INDEXES{ 3, 2, 1, 0, 7, 6, 5, 4 } { 0, 1, 2, 3, 4, 5, 6, 7 } | |||
1206 | #endif | |||
1207 | ||||
1208 | static int lookupShortData(mlib_image* src, mlib_image* dst, | |||
1209 | LookupArrayInfo* lookup) | |||
1210 | { | |||
1211 | int x, y; | |||
1212 | unsigned int mask = NLUT8-1; | |||
1213 | ||||
1214 | unsigned short* srcLine = (unsigned short*)src->data; | |||
1215 | unsigned char* dstLine = (unsigned char*)dst->data; | |||
1216 | ||||
1217 | static int indexes[NLUT8] = INDEXES{ 3, 2, 1, 0, 7, 6, 5, 4 }; | |||
1218 | ||||
1219 | if (src->width != dst->width || src->height != dst->height) { | |||
1220 | return 0; | |||
1221 | } | |||
1222 | ||||
1223 | for (y=0; y < src->height; y++) { | |||
1224 | int nloop, nx; | |||
1225 | int npix = src->width; | |||
1226 | ||||
1227 | unsigned short* srcPixel = srcLine; | |||
1228 | unsigned char* dstPixel = dstLine; | |||
1229 | ||||
1230 | #ifdef SIMPLE_LOOKUP_LOOP | |||
1231 | for (x=0; status && x < width; x++) { | |||
1232 | unsigned short s = *srcPixel++; | |||
1233 | if (s >= lookup->length) { | |||
1234 | /* we can not handle source image using | |||
1235 | * byte lookup table. Fall back to processing | |||
1236 | * images in java | |||
1237 | */ | |||
1238 | return 0; | |||
1239 | } | |||
1240 | *dstPixel++ = lookup->table[s]; | |||
1241 | } | |||
1242 | #else | |||
1243 | /* Get to 32 bit-aligned point */ | |||
1244 | while(((uintptr_t)dstPixel & 0x3) != 0 && npix>0) { | |||
1245 | unsigned short s = *srcPixel++; | |||
1246 | if (s >= lookup->length) { | |||
1247 | return 0; | |||
1248 | } | |||
1249 | *dstPixel++ = lookup->table[s]; | |||
1250 | npix--; | |||
1251 | } | |||
1252 | ||||
1253 | /* | |||
1254 | * Do NLUT pixels per loop iteration. | |||
1255 | * Pack into ints and write out 2 at a time. | |||
1256 | */ | |||
1257 | nloop = npix/NLUT8; | |||
1258 | nx = npix%NLUT8; | |||
1259 | ||||
1260 | for(x=nloop; x!=0; x--) { | |||
1261 | int i = 0; | |||
1262 | int* dstP = (int*)dstPixel; | |||
1263 | ||||
1264 | for (i = 0; i < NLUT8; i++) { | |||
1265 | if (srcPixel[i] >= lookup->length) { | |||
1266 | return 0; | |||
1267 | } | |||
1268 | } | |||
1269 | ||||
1270 | dstP[0] = (int) | |||
1271 | ((lookup->table[srcPixel[indexes[0]]] << 24) | | |||
1272 | (lookup->table[srcPixel[indexes[1]]] << 16) | | |||
1273 | (lookup->table[srcPixel[indexes[2]]] << 8) | | |||
1274 | lookup->table[srcPixel[indexes[3]]]); | |||
1275 | dstP[1] = (int) | |||
1276 | ((lookup->table[srcPixel[indexes[4]]] << 24) | | |||
1277 | (lookup->table[srcPixel[indexes[5]]] << 16) | | |||
1278 | (lookup->table[srcPixel[indexes[6]]] << 8) | | |||
1279 | lookup->table[srcPixel[indexes[7]]]); | |||
1280 | ||||
1281 | ||||
1282 | dstPixel += NLUT8; | |||
1283 | srcPixel += NLUT8; | |||
1284 | } | |||
1285 | ||||
1286 | /* | |||
1287 | * Complete any remaining pixels | |||
1288 | */ | |||
1289 | for(x=nx; x!=0; x--) { | |||
1290 | unsigned short s = *srcPixel++; | |||
1291 | if (s >= lookup->length) { | |||
1292 | return 0; | |||
1293 | } | |||
1294 | *dstPixel++ = lookup->table[s]; | |||
1295 | } | |||
1296 | #endif | |||
1297 | ||||
1298 | dstLine += dst->stride; // array of bytes, scan stride in bytes | |||
1299 | srcLine += src->stride / 2; // array of shorts, scan stride in bytes | |||
1300 | } | |||
1301 | return 1; | |||
1302 | } | |||
1303 | ||||
1304 | JNIEXPORT__attribute__((visibility("default"))) jint JNICALL | |||
1305 | Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject thisLib, | |||
1306 | jobject jsrc, jobject jdst, | |||
1307 | jobjectArray jtableArrays) | |||
1308 | { | |||
1309 | mlib_image *src; | |||
1310 | mlib_image *dst; | |||
1311 | void *sdata, *ddata; | |||
1312 | unsigned char **tbl; | |||
1313 | unsigned char lut[256]; | |||
1314 | int retStatus = 1; | |||
1315 | int i; | |||
1316 | mlib_status status; | |||
1317 | int lut_nbands; | |||
1318 | LookupArrayInfo *jtable; | |||
1319 | BufImageS_t *srcImageP, *dstImageP; | |||
1320 | int nbands; | |||
1321 | int ncomponents; | |||
1322 | mlibHintS_t hint; | |||
1323 | ||||
1324 | /* This function requires a lot of local refs ??? Is 64 enough ??? */ | |||
1325 | if ((*env)->EnsureLocalCapacity(env, 64) < 0) | |||
1326 | return 0; | |||
1327 | ||||
1328 | if (s_nomlib) return 0; | |||
1329 | if (s_timeIt) (*start_timer)(3600); | |||
1330 | ||||
1331 | /* Parse the source image */ | |||
1332 | if (awt_parseImage(env, jsrc, &srcImageP, FALSE(0)) <= 0) { | |||
1333 | /* Can't handle any custom images */ | |||
1334 | return 0; | |||
1335 | } | |||
1336 | ||||
1337 | /* Parse the destination image */ | |||
1338 | if (awt_parseImage(env, jdst, &dstImageP, FALSE(0)) <= 0) { | |||
1339 | /* Can't handle any custom images */ | |||
1340 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1341 | return 0; | |||
1342 | } | |||
1343 | ||||
1344 | nbands = setImageHints(env, srcImageP, dstImageP, FALSE(0), TRUE(1), | |||
1345 | FALSE(0), &hint); | |||
1346 | ||||
1347 | if (nbands < 1 || nbands > srcImageP->cmodel.numComponents) { | |||
1348 | /* Can't handle any custom images */ | |||
1349 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1350 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
1351 | return 0; | |||
1352 | } | |||
1353 | ||||
1354 | ncomponents = srcImageP->cmodel.isDefaultCompatCM | |||
1355 | ? 4 | |||
1356 | : srcImageP->cmodel.numComponents; | |||
1357 | ||||
1358 | /* Make sure that color order can be used for | |||
1359 | * re-ordering of lookup arrays. | |||
1360 | */ | |||
1361 | for (i = 0; i < nbands; i++) { | |||
1362 | int idx = srcImageP->hints.colorOrder[i]; | |||
1363 | ||||
1364 | if (idx < 0 || idx >= ncomponents) { | |||
1365 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1366 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
1367 | return 0; | |||
1368 | } | |||
1369 | } | |||
1370 | ||||
1371 | lut_nbands = (*env)->GetArrayLength(env, jtableArrays); | |||
1372 | ||||
1373 | if (lut_nbands > ncomponents) { | |||
1374 | lut_nbands = ncomponents; | |||
1375 | } | |||
1376 | ||||
1377 | tbl = NULL((void*)0); | |||
1378 | if (SAFE_TO_ALLOC_2(ncomponents, sizeof(unsigned char *))(((ncomponents) > 0) && ((sizeof(unsigned char *)) > 0) && ((0x7fffffff / (ncomponents)) > (sizeof (unsigned char *))))) { | |||
1379 | tbl = (unsigned char **) | |||
1380 | calloc(1, ncomponents * sizeof(unsigned char *)); | |||
1381 | } | |||
1382 | ||||
1383 | jtable = NULL((void*)0); | |||
1384 | if (SAFE_TO_ALLOC_2(lut_nbands, sizeof(LookupArrayInfo))(((lut_nbands) > 0) && ((sizeof(LookupArrayInfo)) > 0) && ((0x7fffffff / (lut_nbands)) > (sizeof(LookupArrayInfo ))))) { | |||
1385 | jtable = (LookupArrayInfo *)malloc(lut_nbands * sizeof (LookupArrayInfo)); | |||
1386 | } | |||
1387 | ||||
1388 | if (tbl == NULL((void*)0) || jtable == NULL((void*)0)) { | |||
1389 | if (tbl != NULL((void*)0)) free(tbl); | |||
1390 | if (jtable != NULL((void*)0)) free(jtable); | |||
1391 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1392 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
1393 | JNU_ThrowNullPointerException(env, "NULL LUT"); | |||
1394 | return 0; | |||
1395 | } | |||
1396 | /* Need to grab these pointers before we lock down arrays */ | |||
1397 | for (i=0; i < lut_nbands; i++) { | |||
1398 | jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i); | |||
1399 | ||||
1400 | if (jtable[i].jArray != NULL((void*)0)) { | |||
1401 | jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray); | |||
1402 | jtable[i].table = NULL((void*)0); | |||
1403 | ||||
1404 | if (jtable[i].length < 256) { | |||
1405 | /* we may read outside the table during lookup */ | |||
1406 | jtable[i].jArray = NULL((void*)0); | |||
1407 | jtable[i].length = 0; | |||
1408 | } | |||
1409 | } | |||
1410 | if (jtable[i].jArray == NULL((void*)0)) { | |||
1411 | free(tbl); | |||
1412 | free(jtable); | |||
1413 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1414 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
1415 | return 0; | |||
1416 | } | |||
1417 | } | |||
1418 | ||||
1419 | /* Allocate the arrays */ | |||
1420 | if (allocateArray(env, srcImageP, &src, &sdata, TRUE(1), FALSE(0), FALSE(0)) < 0) { | |||
1421 | /* Must be some problem */ | |||
1422 | free(tbl); | |||
1423 | free(jtable); | |||
1424 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1425 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
1426 | return 0; | |||
1427 | } | |||
1428 | if (allocateArray(env, dstImageP, &dst, &ddata, FALSE(0), FALSE(0), FALSE(0)) < 0) { | |||
1429 | /* Must be some problem */ | |||
1430 | free(tbl); | |||
1431 | free(jtable); | |||
1432 | freeArray(env, srcImageP, src, sdata, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
1433 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1434 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
1435 | return 0; | |||
1436 | } | |||
1437 | ||||
1438 | /* Set up a straight lut so we don't mess around with alpha */ | |||
1439 | /* | |||
1440 | * NB: medialib lookup routine expects lookup array for each | |||
1441 | * component of source image including alpha. | |||
1442 | * If lookup table we got form the java layer does not contain | |||
1443 | * sufficient number of lookup arrays we add references to identity | |||
1444 | * lookup array to make medialib happier. | |||
1445 | */ | |||
1446 | if (lut_nbands < ncomponents) { | |||
1447 | int j; | |||
1448 | /* REMIND: This should be the size of the input lut!! */ | |||
1449 | for (j=0; j < 256; j++) { | |||
1450 | lut[j] = j; | |||
1451 | } | |||
1452 | for (j=0; j < ncomponents; j++) { | |||
1453 | tbl[j] = lut; | |||
1454 | } | |||
1455 | } | |||
1456 | ||||
1457 | for (i=0; i < lut_nbands; i++) { | |||
1458 | jtable[i].table = (unsigned char *) | |||
1459 | (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL((void*)0)); | |||
1460 | if (jtable[i].table == NULL((void*)0)) { | |||
1461 | /* Free what we've got so far. */ | |||
1462 | int j; | |||
1463 | for (j = 0; j < i; j++) { | |||
1464 | (*env)->ReleasePrimitiveArrayCritical(env, | |||
1465 | jtable[j].jArray, | |||
1466 | (jbyte *) jtable[j].table, | |||
1467 | JNI_ABORT2); | |||
1468 | } | |||
1469 | free(tbl); | |||
1470 | free(jtable); | |||
1471 | freeArray(env, srcImageP, src, sdata, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
1472 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1473 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
1474 | return 0; | |||
1475 | } | |||
1476 | tbl[srcImageP->hints.colorOrder[i]] = jtable[i].table; | |||
1477 | } | |||
1478 | ||||
1479 | if (lut_nbands == 1) { | |||
1480 | for (i=1; i < nbands - | |||
1481 | srcImageP->cmodel.supportsAlpha; i++) { | |||
1482 | tbl[srcImageP->hints.colorOrder[i]] = jtable[0].table; | |||
1483 | } | |||
1484 | } | |||
1485 | ||||
1486 | /* Mlib needs 16bit lookuptable and must be signed! */ | |||
1487 | if (src->type == MLIB_SHORT) { | |||
1488 | if (dst->type == MLIB_BYTE) { | |||
1489 | if (nbands > 1) { | |||
1490 | retStatus = 0; | |||
1491 | } | |||
1492 | else { | |||
1493 | retStatus = lookupShortData(src, dst, &jtable[0]); | |||
1494 | } | |||
1495 | } | |||
1496 | /* How about ddata == null? */ | |||
1497 | } | |||
1498 | else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src, | |||
1499 | (void **)tbl) != MLIB_SUCCESS)) { | |||
1500 | printMedialibError(status); | |||
1501 | retStatus = 0; | |||
1502 | } | |||
1503 | ||||
1504 | /* Release the LUT */ | |||
1505 | for (i=0; i < lut_nbands; i++) { | |||
1506 | (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray, | |||
1507 | (jbyte *) jtable[i].table, JNI_ABORT2); | |||
1508 | } | |||
1509 | free ((void *) jtable); | |||
1510 | free ((void *) tbl); | |||
1511 | ||||
1512 | /* | |||
1513 | * Means that we couldn't write directly into | |||
1514 | * the destination buffer | |||
1515 | */ | |||
1516 | if (ddata == NULL((void*)0)) { | |||
1517 | ||||
1518 | /* Need to store it back into the array */ | |||
1519 | if (storeImageArray(env, srcImageP, dstImageP, dst) < 0) { | |||
1520 | /* Error */ | |||
1521 | retStatus = 0; | |||
1522 | } | |||
1523 | } | |||
1524 | ||||
1525 | ||||
1526 | /* Release the pinned memory */ | |||
1527 | freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata); | |||
1528 | ||||
1529 | awt_freeParsedImage(srcImageP, TRUE(1)); | |||
1530 | awt_freeParsedImage(dstImageP, TRUE(1)); | |||
1531 | ||||
1532 | if (s_timeIt) (*stop_timer)(3600, 1); | |||
1533 | ||||
1534 | return retStatus; | |||
1535 | } | |||
1536 | ||||
1537 | JNIEXPORT__attribute__((visibility("default"))) jint JNICALL | |||
1538 | Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env, | |||
1539 | jobject this, | |||
1540 | jobject jsrc, | |||
1541 | jobject jdst, | |||
1542 | jobjectArray jtableArrays) | |||
1543 | { | |||
1544 | RasterS_t* srcRasterP; | |||
1545 | RasterS_t* dstRasterP; | |||
1546 | mlib_image* src; | |||
1547 | mlib_image* dst; | |||
1548 | void* sdata; | |||
1549 | void* ddata; | |||
1550 | LookupArrayInfo jtable[4]; | |||
1551 | unsigned char* mlib_lookupTable[4]; | |||
1552 | int i; | |||
1553 | int retStatus = 1; | |||
1554 | mlib_status status; | |||
1555 | int jlen; | |||
1556 | int lut_nbands; | |||
1557 | int src_nbands; | |||
1558 | int dst_nbands; | |||
1559 | unsigned char ilut[256]; | |||
1560 | ||||
1561 | /* This function requires a lot of local refs ??? Is 64 enough ??? */ | |||
1562 | if ((*env)->EnsureLocalCapacity(env, 64) < 0) | |||
1563 | return 0; | |||
1564 | ||||
1565 | if (s_nomlib) return 0; | |||
1566 | if (s_timeIt) (*start_timer)(3600); | |||
1567 | ||||
1568 | if ((srcRasterP = (RasterS_t*) calloc(1, sizeof(RasterS_t))) == NULL((void*)0)) { | |||
1569 | JNU_ThrowOutOfMemoryError(env, "Out of memory"); | |||
1570 | return -1; | |||
1571 | } | |||
1572 | ||||
1573 | if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL((void*)0)) { | |||
1574 | JNU_ThrowOutOfMemoryError(env, "Out of memory"); | |||
1575 | free(srcRasterP); | |||
1576 | return -1; | |||
1577 | } | |||
1578 | ||||
1579 | /* Parse the source raster - reject custom images */ | |||
1580 | if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { | |||
1581 | free(srcRasterP); | |||
1582 | free(dstRasterP); | |||
1583 | return 0; | |||
1584 | } | |||
1585 | ||||
1586 | /* Parse the destination image - reject custom images */ | |||
1587 | if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { | |||
1588 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1589 | free(dstRasterP); | |||
1590 | return 0; | |||
1591 | } | |||
1592 | ||||
1593 | jlen = (*env)->GetArrayLength(env, jtableArrays); | |||
1594 | ||||
1595 | lut_nbands = jlen; | |||
1596 | src_nbands = srcRasterP->numBands; | |||
1597 | dst_nbands = dstRasterP->numBands; | |||
1598 | ||||
1599 | /* adjust number of lookup bands */ | |||
1600 | if (lut_nbands > src_nbands) { | |||
1601 | lut_nbands = src_nbands; | |||
1602 | } | |||
1603 | ||||
1604 | /* MediaLib can't do more than 4 bands */ | |||
1605 | if (src_nbands <= 0 || src_nbands > 4 || | |||
1606 | dst_nbands <= 0 || dst_nbands > 4 || | |||
1607 | lut_nbands <= 0 || lut_nbands > 4 || | |||
1608 | src_nbands != dst_nbands || | |||
1609 | ((lut_nbands != 1) && (lut_nbands != src_nbands))) | |||
1610 | { | |||
1611 | // we should free parsed rasters here | |||
1612 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1613 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1614 | return 0; | |||
1615 | } | |||
1616 | ||||
1617 | /* Allocate the raster arrays */ | |||
1618 | if (allocateRasterArray(env, srcRasterP, &src, &sdata, TRUE(1)) < 0) { | |||
1619 | /* Must be some problem */ | |||
1620 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1621 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1622 | return 0; | |||
1623 | } | |||
1624 | if (allocateRasterArray(env, dstRasterP, &dst, &ddata, FALSE(0)) < 0) { | |||
1625 | /* Must be some problem */ | |||
1626 | freeDataArray(env, srcRasterP->jdata, src, sdata, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
1627 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1628 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1629 | return 0; | |||
1630 | } | |||
1631 | ||||
1632 | /* | |||
1633 | * Well, until now we have analyzed number of bands in | |||
1634 | * src and dst rasters. | |||
1635 | * However, it is not enough because medialib lookup routine uses | |||
1636 | * number of channels of medialib image. Note that in certain | |||
1637 | * case number of channels may differs form the number of bands. | |||
1638 | * Good example is raster that is used in TYPE_INT_RGB buffered | |||
1639 | * image: it has 3 bands, but their medialib representation has | |||
1640 | * 4 channels. | |||
1641 | * | |||
1642 | * In order to avoid the lookup routine failure, we need: | |||
1643 | * | |||
1644 | * 1. verify that src and dst have same number of channels. | |||
1645 | * 2. provide lookup array for every channel. If we have "extra" | |||
1646 | * channel (like the raster described above) then we need to | |||
1647 | * provide identical lookup array. | |||
1648 | */ | |||
1649 | if (src->channels != dst->channels) { | |||
1650 | freeDataArray(env, srcRasterP->jdata, src, sdata, | |||
1651 | dstRasterP->jdata, dst, ddata); | |||
1652 | ||||
1653 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1654 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1655 | return 0; | |||
1656 | } | |||
1657 | ||||
1658 | if (src_nbands < src->channels) { | |||
1659 | for (i = 0; i < 256; i++) { | |||
1660 | ilut[i] = i; | |||
1661 | } | |||
1662 | } | |||
1663 | ||||
1664 | ||||
1665 | /* Get references to the lookup table arrays */ | |||
1666 | /* Need to grab these pointers before we lock down arrays */ | |||
1667 | for (i=0; i < lut_nbands; i++) { | |||
1668 | jtable[i].jArray = (*env)->GetObjectArrayElement(env, jtableArrays, i); | |||
1669 | jtable[i].table = NULL((void*)0); | |||
1670 | if (jtable[i].jArray != NULL((void*)0)) { | |||
1671 | jtable[i].length = (*env)->GetArrayLength(env, jtable[i].jArray); | |||
1672 | if (jtable[i].length < 256) { | |||
1673 | /* we may read outside the table during lookup */ | |||
1674 | jtable[i].jArray = NULL((void*)0); | |||
1675 | } | |||
1676 | } | |||
1677 | ||||
1678 | if (jtable[i].jArray == NULL((void*)0)) | |||
1679 | { | |||
1680 | freeDataArray(env, srcRasterP->jdata, src, sdata, | |||
1681 | dstRasterP->jdata, dst, ddata); | |||
1682 | ||||
1683 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1684 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1685 | return 0; | |||
1686 | } | |||
1687 | } | |||
1688 | ||||
1689 | for (i=0; i < lut_nbands; i++) { | |||
1690 | jtable[i].table = (unsigned char *) | |||
1691 | (*env)->GetPrimitiveArrayCritical(env, jtable[i].jArray, NULL((void*)0)); | |||
1692 | if (jtable[i].table == NULL((void*)0)) { | |||
1693 | /* Free what we've got so far. */ | |||
1694 | int j; | |||
1695 | for (j = 0; j < i; j++) { | |||
1696 | (*env)->ReleasePrimitiveArrayCritical(env, | |||
1697 | jtable[j].jArray, | |||
1698 | (jbyte *) jtable[j].table, | |||
1699 | JNI_ABORT2); | |||
1700 | } | |||
1701 | freeDataArray(env, srcRasterP->jdata, src, sdata, | |||
1702 | dstRasterP->jdata, dst, ddata); | |||
1703 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1704 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1705 | return 0; | |||
1706 | } | |||
1707 | mlib_lookupTable[i] = jtable[i].table; | |||
1708 | } | |||
1709 | ||||
1710 | /* | |||
1711 | * Medialib routine expects lookup array for each band of raster. | |||
1712 | * Setup the rest of lookup arrays if supplied lookup table | |||
1713 | * contains single lookup array. | |||
1714 | */ | |||
1715 | for (i = lut_nbands; i < src_nbands; i++) { | |||
1716 | mlib_lookupTable[i] = jtable[0].table; | |||
1717 | } | |||
1718 | ||||
1719 | /* | |||
1720 | * Setup lookup array for "extra" channels | |||
1721 | */ | |||
1722 | for ( ; i < src->channels; i++) { | |||
1723 | mlib_lookupTable[i] = ilut; | |||
1724 | } | |||
1725 | ||||
1726 | /* Mlib needs 16bit lookuptable and must be signed! */ | |||
1727 | if (src->type == MLIB_SHORT) { | |||
1728 | if (dst->type == MLIB_BYTE) { | |||
1729 | if (lut_nbands > 1) { | |||
1730 | retStatus = 0; | |||
1731 | } else { | |||
1732 | retStatus = lookupShortData(src, dst, &jtable[0]); | |||
1733 | } | |||
1734 | } | |||
1735 | /* How about ddata == null? */ | |||
1736 | } else if ((status = (*sMlibFns[MLIB_LOOKUP].fptr)(dst, src, | |||
1737 | (void **)mlib_lookupTable) != MLIB_SUCCESS)) { | |||
1738 | printMedialibError(status); | |||
1739 | retStatus = 0; | |||
1740 | } | |||
1741 | ||||
1742 | /* Release the LUT */ | |||
1743 | for (i=0; i < lut_nbands; i++) { | |||
1744 | (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray, | |||
1745 | (jbyte *) jtable[i].table, JNI_ABORT2); | |||
1746 | } | |||
1747 | ||||
1748 | /* | |||
1749 | * Means that we couldn't write directly into | |||
1750 | * the destination buffer | |||
1751 | */ | |||
1752 | if (ddata == NULL((void*)0)) { | |||
1753 | if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) { | |||
1754 | retStatus = setPixelsFormMlibImage(env, dstRasterP, dst); | |||
1755 | } | |||
1756 | } | |||
1757 | ||||
1758 | /* Release the pinned memory */ | |||
1759 | freeDataArray(env, srcRasterP->jdata, src, sdata, | |||
1760 | dstRasterP->jdata, dst, ddata); | |||
1761 | ||||
1762 | awt_freeParsedRaster(srcRasterP, TRUE(1)); | |||
1763 | awt_freeParsedRaster(dstRasterP, TRUE(1)); | |||
1764 | ||||
1765 | if (s_timeIt) (*stop_timer)(3600, 1); | |||
1766 | ||||
1767 | return retStatus; | |||
1768 | } | |||
1769 | ||||
1770 | ||||
1771 | JNIEXPORT__attribute__((visibility("default"))) jboolean JNICALL | |||
1772 | Java_sun_awt_image_ImagingLib_init(JNIEnv *env, jclass thisClass) { | |||
1773 | char *start; | |||
1774 | if (getenv("IMLIB_DEBUG")) { | |||
1775 | start_timer = awt_setMlibStartTimer(); | |||
1776 | stop_timer = awt_setMlibStopTimer(); | |||
1777 | if (start_timer && stop_timer) { | |||
1778 | s_timeIt = 1; | |||
1779 | } | |||
1780 | } | |||
1781 | ||||
1782 | if (getenv("IMLIB_PRINT")) { | |||
1783 | s_printIt = 1; | |||
1784 | } | |||
1785 | if ((start = getenv("IMLIB_START")) != NULL((void*)0)) { | |||
1786 | sscanf(start, "%d", &s_startOff); | |||
1787 | } | |||
1788 | ||||
1789 | if (getenv ("IMLIB_NOMLIB")) { | |||
1790 | s_nomlib = 1; | |||
1791 | return JNI_FALSE0; | |||
1792 | } | |||
1793 | ||||
1794 | /* This function is platform-dependent and is in awt_mlib.c */ | |||
1795 | if (awt_getImagingLib(env, (mlibFnS_t *)&sMlibFns, &sMlibSysFns) != | |||
1796 | MLIB_SUCCESS) | |||
1797 | { | |||
1798 | s_nomlib = 1; | |||
1799 | return JNI_FALSE0; | |||
1800 | } | |||
1801 | return JNI_TRUE1; | |||
1802 | } | |||
1803 | ||||
1804 | /* REMIND: How to specify border? */ | |||
1805 | static void extendEdge(JNIEnv *env, BufImageS_t *imageP, | |||
1806 | int *widthP, int *heightP) { | |||
1807 | RasterS_t *rasterP = &imageP->raster; | |||
1808 | int width; | |||
1809 | int height; | |||
1810 | /* Useful for convolution? */ | |||
1811 | ||||
1812 | jobject jbaseraster = (*env)->GetObjectField(env, rasterP->jraster, | |||
1813 | g_RasterBaseRasterID); | |||
1814 | width = rasterP->width; | |||
1815 | height = rasterP->height; | |||
1816 | #ifdef WORKING | |||
1817 | if (! JNU_IsNull(env, jbaseraster)((jbaseraster) == ((void*)0)) && | |||
1818 | !(*env)->IsSameObject(env, rasterP->jraster, jbaseraster)) { | |||
1819 | int xOff; | |||
1820 | int yOff; | |||
1821 | int baseWidth; | |||
1822 | int baseHeight; | |||
1823 | int baseXoff; | |||
1824 | int baseYoff; | |||
1825 | /* Not the same object so get the width and height */ | |||
1826 | xOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterXOffsetID); | |||
1827 | yOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterYOffsetID); | |||
1828 | baseWidth = (*env)->GetIntField(env, jbaseraster, g_RasterWidthID); | |||
1829 | baseHeight = (*env)->GetIntField(env, jbaseraster, g_RasterHeightID); | |||
1830 | baseXoff = (*env)->GetIntField(env, jbaseraster, g_RasterXOffsetID); | |||
1831 | baseYoff = (*env)->GetIntField(env, jbaseraster, g_RasterYOffsetID); | |||
1832 | ||||
1833 | if (xOff + rasterP->width < baseXoff + baseWidth) { | |||
1834 | /* Can use edge */ | |||
1835 | width++; | |||
1836 | } | |||
1837 | if (yOff + rasterP->height < baseYoff + baseHeight) { | |||
1838 | /* Can use edge */ | |||
1839 | height++; | |||
1840 | } | |||
1841 | ||||
1842 | } | |||
1843 | #endif | |||
1844 | ||||
1845 | } | |||
1846 | ||||
1847 | static int | |||
1848 | setImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, | |||
1849 | int expandICM, int useAlpha, | |||
1850 | int premultiply, mlibHintS_t *hintP) | |||
1851 | { | |||
1852 | ColorModelS_t *srcCMP = &srcP->cmodel; | |||
1853 | ColorModelS_t *dstCMP = &dstP->cmodel; | |||
1854 | int nbands = 0; | |||
1855 | int ncomponents; | |||
1856 | ||||
1857 | hintP->dataType = srcP->raster.dataType; | |||
1858 | hintP->addAlpha = FALSE(0); | |||
1859 | ||||
1860 | /* Are the color spaces the same? */ | |||
1861 | if (srcCMP->csType != dstCMP->csType) { | |||
1862 | /* If the src is GRAY and dst RGB, we can handle it */ | |||
1863 | if (!(srcCMP->csType == java_awt_color_ColorSpace_TYPE_GRAY6L && | |||
1864 | dstCMP->csType == java_awt_color_ColorSpace_TYPE_RGB5L)) { | |||
1865 | /* Nope, need to handle that in java for now */ | |||
1866 | return -1; | |||
1867 | } | |||
1868 | else { | |||
1869 | hintP->cvtSrcToDefault = TRUE(1); | |||
1870 | } | |||
1871 | } | |||
1872 | else { | |||
1873 | if (srcP->hints.needToExpand) { | |||
1874 | hintP->cvtSrcToDefault = TRUE(1); | |||
1875 | } | |||
1876 | else { | |||
1877 | /* Need to initialize this */ | |||
1878 | hintP->cvtSrcToDefault = FALSE(0); | |||
1879 | } | |||
1880 | } | |||
1881 | ||||
1882 | ncomponents = srcCMP->numComponents; | |||
1883 | if ((useAlpha == 0) && srcCMP->supportsAlpha) { | |||
1884 | ncomponents--; /* ?? */ | |||
1885 | /* Not really, more like shrink src to get rid of alpha */ | |||
1886 | hintP->cvtSrcToDefault = TRUE(1); | |||
1887 | } | |||
1888 | ||||
1889 | hintP->dataType = srcP->raster.dataType; | |||
1890 | if (hintP->cvtSrcToDefault == FALSE(0)) { | |||
1891 | if (srcCMP->cmType == INDEX_CM_TYPE3) { | |||
1892 | if (expandICM) { | |||
1893 | nbands = srcCMP->numComponents; | |||
1894 | hintP->cvtSrcToDefault = TRUE(1); | |||
1895 | ||||
1896 | if (dstCMP->isDefaultCompatCM) { | |||
1897 | hintP->allocDefaultDst = FALSE(0); | |||
1898 | hintP->cvtToDst = FALSE(0); | |||
1899 | } | |||
1900 | else if (dstCMP->isDefaultCompatCM) { | |||
1901 | hintP->allocDefaultDst = FALSE(0); | |||
1902 | hintP->cvtToDst = FALSE(0); | |||
1903 | } | |||
1904 | } | |||
1905 | else { | |||
1906 | nbands = 1; | |||
1907 | hintP->cvtSrcToDefault = FALSE(0); | |||
1908 | } | |||
1909 | ||||
1910 | } | |||
1911 | else { | |||
1912 | if (srcP->hints.packing & INTERLEAVED0x10) { | |||
1913 | nbands = srcCMP->numComponents; | |||
1914 | } | |||
1915 | else { | |||
1916 | nbands = 1; | |||
1917 | } | |||
1918 | ||||
1919 | /* Look at the packing */ | |||
1920 | if ((srcP->hints.packing&BYTE_INTERLEAVED(0x1 | 0x10))==BYTE_INTERLEAVED(0x1 | 0x10) || | |||
1921 | (srcP->hints.packing&SHORT_INTERLEAVED(0x2 | 0x10))==SHORT_INTERLEAVED(0x2 | 0x10)|| | |||
1922 | (srcP->hints.packing&BYTE_SINGLE_BAND(0x1 | 0x30)) == BYTE_SINGLE_BAND(0x1 | 0x30)|| | |||
1923 | (srcP->hints.packing&SHORT_SINGLE_BAND(0x2 | 0x30))==SHORT_SINGLE_BAND(0x2 | 0x30)|| | |||
1924 | (srcP->hints.packing&BYTE_BANDED(0x1 | 0x20)) == BYTE_BANDED(0x1 | 0x20) || | |||
1925 | (srcP->hints.packing&SHORT_BANDED(0x2 | 0x20)) == SHORT_BANDED(0x2 | 0x20)) { | |||
1926 | /* Can use src directly */ | |||
1927 | hintP->cvtSrcToDefault = FALSE(0); | |||
1928 | } | |||
1929 | else { | |||
1930 | /* Must be packed or custom */ | |||
1931 | hintP->cvtSrcToDefault = TRUE(1); | |||
1932 | } | |||
1933 | } | |||
1934 | } | |||
1935 | if (hintP->cvtSrcToDefault) { | |||
1936 | /* By definition */ | |||
1937 | nbands = 4; /* What about alpha? */ | |||
1938 | hintP->dataType = BYTE_DATA_TYPE1; | |||
1939 | hintP->needToCopy = TRUE(1); | |||
1940 | ||||
1941 | if (srcP->imageType == dstP->imageType) { | |||
1942 | hintP->cvtToDst = TRUE(1); | |||
1943 | } | |||
1944 | else if (dstP->cmodel.isDefaultCM) { | |||
1945 | /* Not necessarily */ | |||
1946 | hintP->cvtToDst = FALSE(0); | |||
1947 | } | |||
1948 | else { | |||
1949 | hintP->cvtToDst = TRUE(1); | |||
1950 | } | |||
1951 | } | |||
1952 | else { | |||
1953 | int srcImageType = srcP->imageType; | |||
1954 | int dstImageType = dstP->imageType; | |||
1955 | /* Special case where we need to fill in alpha values */ | |||
1956 | if (srcCMP->isDefaultCompatCM && dstCMP->isDefaultCompatCM) { | |||
1957 | int i; | |||
1958 | if (!srcCMP->supportsAlpha &&dstCMP->supportsAlpha) { | |||
1959 | hintP->addAlpha = TRUE(1); | |||
1960 | } | |||
1961 | for (i=0; i < srcCMP->numComponents; i++) { | |||
1962 | if (srcP->hints.colorOrder[i] != dstP->hints.colorOrder[i]){ | |||
1963 | if (!srcCMP->isDefaultCM) { | |||
1964 | hintP->cvtSrcToDefault = TRUE(1); | |||
1965 | srcImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB2L; | |||
1966 | } | |||
1967 | if (!dstCMP->isDefaultCM) { | |||
1968 | hintP->cvtToDst = TRUE(1); | |||
1969 | dstImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB2L; | |||
1970 | } | |||
1971 | ||||
1972 | break; | |||
1973 | } | |||
1974 | } | |||
1975 | } | |||
1976 | else if (srcCMP->cmType != INDEX_CM_TYPE3 && | |||
1977 | !srcCMP->supportsAlpha && dstCMP->supportsAlpha) | |||
1978 | { | |||
1979 | /* We've already handled the index case. This is for the rest of the cases */ | |||
1980 | srcImageType = java_awt_image_BufferedImage_TYPE_INT_ARGB2L; | |||
1981 | hintP->cvtSrcToDefault = TRUE(1); | |||
1982 | } | |||
1983 | ||||
1984 | hintP->allocDefaultDst = FALSE(0); | |||
1985 | if (srcImageType == dstImageType) { | |||
1986 | /* Same image type so use it */ | |||
1987 | hintP->cvtToDst = FALSE(0); | |||
1988 | } | |||
1989 | else if (srcImageType == TYPE_INT_RGB1L && | |||
1990 | (dstImageType == TYPE_INT_ARGB2L || | |||
1991 | dstImageType == TYPE_INT_ARGB_PRE3L)) { | |||
1992 | hintP->cvtToDst = FALSE(0); | |||
1993 | } | |||
1994 | else if (srcImageType == TYPE_INT_BGR4L && | |||
1995 | (dstImageType == TYPE_4BYTE_ABGR6L || | |||
1996 | dstImageType == TYPE_4BYTE_ABGR_PRE7L)) { | |||
1997 | hintP->cvtToDst = FALSE(0); | |||
1998 | } | |||
1999 | else if (srcP->hints.packing == dstP->hints.packing) { | |||
2000 | /* Now what? */ | |||
2001 | ||||
2002 | /* Check color order */ | |||
2003 | ||||
2004 | /* Check if just need to scale the data */ | |||
2005 | ||||
2006 | hintP->cvtToDst = TRUE(1); | |||
2007 | } | |||
2008 | else { | |||
2009 | /* Don't know what it is so convert it */ | |||
2010 | hintP->allocDefaultDst = TRUE(1); | |||
2011 | hintP->cvtToDst = TRUE(1); | |||
2012 | } | |||
2013 | hintP->needToCopy = (ncomponents > nbands); | |||
2014 | } | |||
2015 | ||||
2016 | return nbands; | |||
2017 | } | |||
2018 | ||||
2019 | ||||
2020 | static int | |||
2021 | expandPacked(JNIEnv *env, BufImageS_t *img, ColorModelS_t *cmP, | |||
2022 | RasterS_t *rasterP, int component, unsigned char *bdataP) { | |||
2023 | ||||
2024 | if (rasterP->rasterType == COMPONENT_RASTER_TYPE1) { | |||
2025 | switch (rasterP->dataType) { | |||
2026 | case BYTE_DATA_TYPE1: | |||
2027 | if (expandPackedBCR(env, rasterP, component, bdataP) < 0) { | |||
2028 | /* Must have been an error */ | |||
2029 | return -1; | |||
2030 | } | |||
2031 | break; | |||
2032 | ||||
2033 | case SHORT_DATA_TYPE2: | |||
2034 | if (expandPackedICR(env, rasterP, component, bdataP) < 0) { | |||
2035 | /* Must have been an error */ | |||
2036 | return -1; | |||
2037 | } | |||
2038 | break; | |||
2039 | ||||
2040 | case INT_DATA_TYPE3: | |||
2041 | if (expandPackedICR(env, rasterP, component, bdataP) < 0) { | |||
2042 | /* Must have been an error */ | |||
2043 | return -1; | |||
2044 | } | |||
2045 | break; | |||
2046 | ||||
2047 | default: | |||
2048 | /* REMIND: Return some sort of error */ | |||
2049 | return -1; | |||
2050 | } | |||
2051 | } | |||
2052 | else { | |||
2053 | /* REMIND: Return some sort of error */ | |||
2054 | return -1; | |||
2055 | } | |||
2056 | ||||
2057 | return 0; | |||
2058 | } | |||
2059 | ||||
2060 | #define NUM_LINES10 10 | |||
2061 | ||||
2062 | static int | |||
2063 | cvtCustomToDefault(JNIEnv *env, BufImageS_t *imageP, int component, | |||
2064 | unsigned char *dataP) { | |||
2065 | const RasterS_t *rasterP = &imageP->raster; | |||
2066 | const int w = rasterP->width; | |||
2067 | const int h = rasterP->height; | |||
2068 | ||||
2069 | int y; | |||
2070 | jintArray jpixels = NULL((void*)0); | |||
2071 | jint *pixels; | |||
2072 | unsigned char *dP = dataP; | |||
2073 | int numLines = h > NUM_LINES10 ? NUM_LINES10 : h; | |||
2074 | ||||
2075 | /* it is safe to calculate the scan length, because width has been verified | |||
2076 | * on creation of the mlib image | |||
2077 | */ | |||
2078 | const int scanLength = w * 4; | |||
2079 | ||||
2080 | int nbytes = 0; | |||
2081 | if (!SAFE_TO_MULT(numLines, scanLength)(((numLines) > 0) && ((scanLength) >= 0) && ((0x7fffffff / (numLines)) > (scanLength)))) { | |||
2082 | return -1; | |||
2083 | } | |||
2084 | ||||
2085 | nbytes = numLines * scanLength; | |||
2086 | ||||
2087 | jpixels = (*env)->NewIntArray(env, nbytes); | |||
2088 | if (JNU_IsNull(env, jpixels)((jpixels) == ((void*)0))) { | |||
2089 | (*env)->ExceptionClear(env); | |||
2090 | JNU_ThrowOutOfMemoryError(env, "Out of Memory"); | |||
2091 | return -1; | |||
2092 | } | |||
2093 | ||||
2094 | for (y = 0; y < h; y += numLines) { | |||
2095 | if (y + numLines > h) { | |||
2096 | numLines = h - y; | |||
2097 | nbytes = numLines * scanLength; | |||
2098 | } | |||
2099 | ||||
2100 | (*env)->CallObjectMethod(env, imageP->jimage, | |||
2101 | g_BImgGetRGBMID, 0, y, | |||
2102 | w, numLines, | |||
2103 | jpixels, 0, w); | |||
2104 | if ((*env)->ExceptionOccurred(env)) { | |||
2105 | (*env)->DeleteLocalRef(env, jpixels); | |||
2106 | return -1; | |||
2107 | } | |||
2108 | ||||
2109 | pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL((void*)0)); | |||
2110 | if (pixels == NULL((void*)0)) { | |||
2111 | (*env)->DeleteLocalRef(env, jpixels); | |||
2112 | return -1; | |||
2113 | } | |||
2114 | ||||
2115 | memcpy(dP, pixels, nbytes); | |||
2116 | dP += nbytes; | |||
2117 | ||||
2118 | (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels, | |||
2119 | JNI_ABORT2); | |||
2120 | } | |||
2121 | ||||
2122 | /* Need to release the array */ | |||
2123 | (*env)->DeleteLocalRef(env, jpixels); | |||
2124 | ||||
2125 | return 0; | |||
2126 | } | |||
2127 | ||||
2128 | static int | |||
2129 | cvtDefaultToCustom(JNIEnv *env, BufImageS_t *imageP, int component, | |||
2130 | unsigned char *dataP) { | |||
2131 | const RasterS_t *rasterP = &imageP->raster; | |||
2132 | const int w = rasterP->width; | |||
2133 | const int h = rasterP->height; | |||
2134 | ||||
2135 | int y; | |||
2136 | jintArray jpixels = NULL((void*)0); | |||
2137 | jint *pixels; | |||
2138 | unsigned char *dP = dataP; | |||
2139 | int numLines = h > NUM_LINES10 ? NUM_LINES10 : h; | |||
2140 | ||||
2141 | /* it is safe to calculate the scan length, because width has been verified | |||
2142 | * on creation of the mlib image | |||
2143 | */ | |||
2144 | const int scanLength = w * 4; | |||
2145 | ||||
2146 | int nbytes = 0; | |||
2147 | if (!SAFE_TO_MULT(numLines, scanLength)(((numLines) > 0) && ((scanLength) >= 0) && ((0x7fffffff / (numLines)) > (scanLength)))) { | |||
2148 | return -1; | |||
2149 | } | |||
2150 | ||||
2151 | nbytes = numLines * scanLength; | |||
2152 | ||||
2153 | jpixels = (*env)->NewIntArray(env, nbytes); | |||
2154 | if (JNU_IsNull(env, jpixels)((jpixels) == ((void*)0))) { | |||
2155 | (*env)->ExceptionClear(env); | |||
2156 | JNU_ThrowOutOfMemoryError(env, "Out of Memory"); | |||
2157 | return -1; | |||
2158 | } | |||
2159 | ||||
2160 | for (y = 0; y < h; y += numLines) { | |||
2161 | if (y + numLines > h) { | |||
2162 | numLines = h - y; | |||
2163 | nbytes = numLines * scanLength; | |||
2164 | } | |||
2165 | ||||
2166 | pixels = (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL((void*)0)); | |||
2167 | if (pixels == NULL((void*)0)) { | |||
2168 | (*env)->DeleteLocalRef(env, jpixels); | |||
2169 | return -1; | |||
2170 | } | |||
2171 | ||||
2172 | memcpy(pixels, dP, nbytes); | |||
2173 | dP += nbytes; | |||
2174 | ||||
2175 | (*env)->ReleasePrimitiveArrayCritical(env, jpixels, pixels, 0); | |||
2176 | ||||
2177 | (*env)->CallVoidMethod(env, imageP->jimage, g_BImgSetRGBMID, 0, y, | |||
2178 | w, numLines, jpixels, | |||
2179 | 0, w); | |||
2180 | if ((*env)->ExceptionOccurred(env)) { | |||
2181 | (*env)->DeleteLocalRef(env, jpixels); | |||
2182 | return -1; | |||
2183 | } | |||
2184 | } | |||
2185 | ||||
2186 | /* Need to release the array */ | |||
2187 | (*env)->DeleteLocalRef(env, jpixels); | |||
2188 | ||||
2189 | return 0; | |||
2190 | } | |||
2191 | ||||
2192 | static int | |||
2193 | allocateArray(JNIEnv *env, BufImageS_t *imageP, | |||
2194 | mlib_image **mlibImagePP, void **dataPP, int isSrc, | |||
2195 | int cvtToDefault, int addAlpha) { | |||
2196 | void *dataP; | |||
2197 | unsigned char *cDataP; | |||
2198 | RasterS_t *rasterP = &imageP->raster; | |||
2199 | ColorModelS_t *cmP = &imageP->cmodel; | |||
2200 | int dataType = BYTE_DATA_TYPE1; | |||
2201 | int width; | |||
2202 | int height; | |||
2203 | HintS_t *hintP = &imageP->hints; | |||
2204 | *dataPP = NULL((void*)0); | |||
2205 | ||||
2206 | width = rasterP->width; | |||
2207 | height = rasterP->height; | |||
2208 | ||||
2209 | /* Useful for convolution? */ | |||
2210 | /* This code is zero'ed out so that it cannot be called */ | |||
2211 | ||||
2212 | /* To do this correctly, we need to expand src and dst in the */ | |||
2213 | /* same direction up/down/left/right only if both can be expanded */ | |||
2214 | /* in that direction. Expanding right and down is easy - */ | |||
2215 | /* increment width. Expanding top and left requires bumping */ | |||
2216 | /* around pointers and incrementing the width/height */ | |||
2217 | ||||
2218 | #if 0 | |||
2219 | if (0 && useEdges) { | |||
2220 | baseWidth = rasterP->baseRasterWidth; | |||
2221 | baseHeight = rasterP->baseRasterHeight; | |||
2222 | baseXoff = rasterP->baseOriginX; | |||
2223 | baseYoff = rasterP->baseOriginY; | |||
2224 | ||||
2225 | if (rasterP->minX + rasterP->width < baseXoff + baseWidth) { | |||
2226 | /* Can use edge */ | |||
2227 | width++; | |||
2228 | } | |||
2229 | if (rasterP->minY + rasterP->height < baseYoff + baseHeight) { | |||
2230 | /* Can use edge */ | |||
2231 | height++; | |||
2232 | } | |||
2233 | ||||
2234 | if (rasterP->minX > baseXoff ) { | |||
2235 | /* Can use edge */ | |||
2236 | width++; | |||
2237 | /* NEED TO BUMP POINTER BACK A PIXELSTRIDE */ | |||
2238 | } | |||
2239 | if (rasterP->minY > baseYoff) { | |||
2240 | /* Can use edge */ | |||
2241 | height++; | |||
2242 | /* NEED TO BUMP POINTER BACK A SCANLINE */ | |||
2243 | } | |||
2244 | ||||
2245 | ||||
2246 | } | |||
2247 | #endif | |||
2248 | if (cvtToDefault) { | |||
2249 | int status = 0; | |||
2250 | *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height); | |||
2251 | if (*mlibImagePP == NULL((void*)0)) { | |||
2252 | return -1; | |||
2253 | } | |||
2254 | cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); | |||
2255 | /* Make sure the image is cleared. | |||
2256 | * NB: the image dimension is already verified, so we can | |||
2257 | * safely calculate the length of the buffer. | |||
2258 | */ | |||
2259 | memset(cDataP, 0, width*height*4); | |||
2260 | ||||
2261 | if (!isSrc) { | |||
2262 | return 0; | |||
2263 | } | |||
2264 | ||||
2265 | switch(imageP->cmodel.cmType) { | |||
2266 | case INDEX_CM_TYPE3: | |||
2267 | /* REMIND: Need to rearrange according to dst cm */ | |||
2268 | /* Fix 4213160, 4184283 */ | |||
2269 | if (rasterP->rasterType == COMPONENT_RASTER_TYPE1) { | |||
2270 | return expandICM(env, imageP, (unsigned int *)cDataP); | |||
2271 | } | |||
2272 | else { | |||
2273 | return cvtCustomToDefault(env, imageP, -1, cDataP); | |||
2274 | } | |||
2275 | ||||
2276 | case DIRECT_CM_TYPE2: | |||
2277 | switch(imageP->raster.dataType) { | |||
2278 | case BYTE_DATA_TYPE1: | |||
2279 | return expandPackedBCRdefault(env, rasterP, -1, cDataP, | |||
2280 | !imageP->cmodel.supportsAlpha); | |||
2281 | case SHORT_DATA_TYPE2: | |||
2282 | return expandPackedSCRdefault(env, rasterP, -1, cDataP, | |||
2283 | !imageP->cmodel.supportsAlpha); | |||
2284 | case INT_DATA_TYPE3: | |||
2285 | return expandPackedICRdefault(env, rasterP, -1, cDataP, | |||
2286 | !imageP->cmodel.supportsAlpha); | |||
2287 | } | |||
2288 | } /* switch(imageP->cmodel.cmType) */ | |||
2289 | ||||
2290 | return cvtCustomToDefault(env, imageP, -1, cDataP); | |||
2291 | } | |||
2292 | ||||
2293 | /* Interleaved with shared data */ | |||
2294 | dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata, | |||
2295 | NULL((void*)0)); | |||
2296 | if (dataP == NULL((void*)0)) { | |||
2297 | return -1; | |||
2298 | } | |||
2299 | ||||
2300 | /* Means we need to fill in alpha */ | |||
2301 | if (!cvtToDefault && addAlpha) { | |||
2302 | *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height); | |||
2303 | if (*mlibImagePP != NULL((void*)0)) { | |||
2304 | unsigned int *dstP = (unsigned int *) | |||
2305 | mlib_ImageGetData(*mlibImagePP); | |||
2306 | int dstride = (*mlibImagePP)->stride>>2; | |||
2307 | int sstride = hintP->sStride>>2; | |||
2308 | unsigned int *srcP = (unsigned int *) | |||
2309 | ((unsigned char *)dataP + hintP->dataOffset); | |||
2310 | unsigned int *dP, *sP; | |||
2311 | int x, y; | |||
2312 | for (y=0; y < height; y++, srcP += sstride, dstP += dstride){ | |||
2313 | sP = srcP; | |||
2314 | dP = dstP; | |||
2315 | for (x=0; x < width; x++) { | |||
2316 | dP[x] = sP[x] | 0xff000000; | |||
2317 | } | |||
2318 | } | |||
2319 | } | |||
2320 | (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP, | |||
2321 | JNI_ABORT2); | |||
2322 | return 0; | |||
2323 | } | |||
2324 | else if ((hintP->packing & BYTE_INTERLEAVED(0x1 | 0x10)) == BYTE_INTERLEAVED(0x1 | 0x10)) { | |||
2325 | int nChans = (cmP->isDefaultCompatCM ? 4 : hintP->numChans); | |||
2326 | /* Easy case. It is or is similar to the default CM so use | |||
2327 | * the array. Must be byte data. | |||
2328 | */ | |||
2329 | /* Create the medialib image */ | |||
2330 | *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, | |||
2331 | nChans, | |||
2332 | width, | |||
2333 | height, | |||
2334 | hintP->sStride, | |||
2335 | (unsigned char *)dataP | |||
2336 | + hintP->dataOffset); | |||
2337 | } | |||
2338 | else if ((hintP->packing & SHORT_INTERLEAVED(0x2 | 0x10)) == SHORT_INTERLEAVED(0x2 | 0x10)) { | |||
2339 | *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_SHORT, | |||
2340 | hintP->numChans, | |||
2341 | width, | |||
2342 | height, | |||
2343 | imageP->raster.scanlineStride*2, | |||
2344 | (unsigned short *)dataP | |||
2345 | + hintP->channelOffset); | |||
2346 | } | |||
2347 | else { | |||
2348 | /* Release the data array */ | |||
2349 | (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP, | |||
2350 | JNI_ABORT2); | |||
2351 | return -1; | |||
2352 | } | |||
2353 | ||||
2354 | *dataPP = dataP; | |||
2355 | return 0; | |||
2356 | } | |||
2357 | ||||
2358 | static int | |||
2359 | allocateRasterArray(JNIEnv *env, RasterS_t *rasterP, | |||
2360 | mlib_image **mlibImagePP, void **dataPP, int isSrc) { | |||
2361 | void *dataP; | |||
2362 | unsigned char *cDataP; | |||
2363 | int dataType = BYTE_DATA_TYPE1; | |||
2364 | int width; | |||
2365 | int height; | |||
2366 | int dataSize; | |||
2367 | int offset; | |||
2368 | ||||
2369 | *dataPP = NULL((void*)0); | |||
2370 | ||||
2371 | width = rasterP->width; | |||
2372 | height = rasterP->height; | |||
2373 | ||||
2374 | if (rasterP->numBands <= 0 || rasterP->numBands > 4) { | |||
2375 | /* REMIND: Fix this */ | |||
2376 | return -1; | |||
2377 | } | |||
2378 | ||||
2379 | /* Useful for convolution? */ | |||
2380 | /* This code is zero'ed out so that it cannot be called */ | |||
2381 | ||||
2382 | /* To do this correctly, we need to expand src and dst in the */ | |||
2383 | /* same direction up/down/left/right only if both can be expanded */ | |||
2384 | /* in that direction. Expanding right and down is easy - */ | |||
2385 | /* increment width. Expanding top and left requires bumping */ | |||
2386 | /* around pointers and incrementing the width/height */ | |||
2387 | ||||
2388 | #if 0 | |||
2389 | if (0 && useEdges) { | |||
2390 | baseWidth = rasterP->baseRasterWidth; | |||
2391 | baseHeight = rasterP->baseRasterHeight; | |||
2392 | baseXoff = rasterP->baseOriginX; | |||
2393 | baseYoff = rasterP->baseOriginY; | |||
2394 | ||||
2395 | if (rasterP->minX + rasterP->width < baseXoff + baseWidth) { | |||
2396 | /* Can use edge */ | |||
2397 | width++; | |||
2398 | } | |||
2399 | if (rasterP->minY + rasterP->height < baseYoff + baseHeight) { | |||
2400 | /* Can use edge */ | |||
2401 | height++; | |||
2402 | } | |||
2403 | ||||
2404 | if (rasterP->minX > baseXoff ) { | |||
2405 | /* Can use edge */ | |||
2406 | width++; | |||
2407 | /* NEED TO BUMP POINTER BACK A PIXELSTRIDE */ | |||
2408 | } | |||
2409 | if (rasterP->minY > baseYoff) { | |||
2410 | /* Can use edge */ | |||
2411 | height++; | |||
2412 | /* NEED TO BUMP POINTER BACK A SCANLINE */ | |||
2413 | } | |||
2414 | ||||
2415 | ||||
2416 | } | |||
2417 | #endif | |||
2418 | switch (rasterP->type) { | |||
2419 | case sun_awt_image_IntegerComponentRaster_TYPE_INT_8BIT_SAMPLES10L: | |||
2420 | if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 4)(((rasterP->chanOffsets[0]) > 0) && ((4) > 0 ) && ((0x7fffffff / (rasterP->chanOffsets[0])) > (4)))) && | |||
2421 | SAFE_TO_ALLOC_2(width, 4)(((width) > 0) && ((4) > 0) && ((0x7fffffff / (width)) > (4))) && | |||
2422 | SAFE_TO_ALLOC_3(rasterP->scanlineStride, height, 4)(((rasterP->scanlineStride) > 0) && ((height) > 0) && ((4) > 0) && (((0x7fffffff / (rasterP ->scanlineStride)) / (height)) > (4))))) | |||
2423 | { | |||
2424 | return -1; | |||
2425 | } | |||
2426 | offset = 4 * rasterP->chanOffsets[0]; | |||
2427 | dataSize = 4 * (*env)->GetArrayLength(env, rasterP->jdata); | |||
2428 | ||||
2429 | if (offset < 0 || offset >= dataSize || | |||
2430 | width > rasterP->scanlineStride || | |||
2431 | ((width + (height - 1) * rasterP->scanlineStride) * 4) > dataSize - offset) | |||
2432 | { | |||
2433 | // raster data buffer is too short | |||
2434 | return -1; | |||
2435 | } | |||
2436 | dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata, | |||
2437 | NULL((void*)0)); | |||
2438 | if (dataP == NULL((void*)0)) { | |||
2439 | return -1; | |||
2440 | } | |||
2441 | *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, 4, | |||
2442 | width, height, | |||
2443 | rasterP->scanlineStride*4, | |||
2444 | (unsigned char *)dataP + offset); | |||
2445 | *dataPP = dataP; | |||
2446 | return 0; | |||
2447 | case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_SAMPLES1L: | |||
2448 | if (!(SAFE_TO_ALLOC_2(width, rasterP->numBands)(((width) > 0) && ((rasterP->numBands) > 0) && ((0x7fffffff / (width)) > (rasterP->numBands))) && | |||
2449 | SAFE_TO_ALLOC_2(rasterP->scanlineStride, height)(((rasterP->scanlineStride) > 0) && ((height) > 0) && ((0x7fffffff / (rasterP->scanlineStride)) > (height))))) | |||
2450 | { | |||
2451 | return -1; | |||
2452 | } | |||
2453 | offset = rasterP->chanOffsets[0]; | |||
2454 | dataSize = (*env)->GetArrayLength(env, rasterP->jdata); | |||
2455 | ||||
2456 | if (offset < 0 || offset >= dataSize || | |||
2457 | width * rasterP->numBands > rasterP->scanlineStride || | |||
2458 | ((width * rasterP->numBands) + | |||
2459 | (height - 1) * rasterP->scanlineStride) > dataSize - offset) | |||
2460 | { | |||
2461 | // raster data buffer is too short | |||
2462 | return -1; | |||
2463 | } | |||
2464 | dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata, | |||
2465 | NULL((void*)0)); | |||
2466 | if (dataP == NULL((void*)0)) { | |||
2467 | return -1; | |||
2468 | } | |||
2469 | *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_BYTE, rasterP->numBands, | |||
2470 | width, height, | |||
2471 | rasterP->scanlineStride, | |||
2472 | (unsigned char *)dataP + offset); | |||
2473 | *dataPP = dataP; | |||
2474 | return 0; | |||
2475 | case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_SAMPLES2L: | |||
2476 | if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 2)(((rasterP->chanOffsets[0]) > 0) && ((2) > 0 ) && ((0x7fffffff / (rasterP->chanOffsets[0])) > (2)))) && | |||
2477 | SAFE_TO_ALLOC_3(width, rasterP->numBands, 2)(((width) > 0) && ((rasterP->numBands) > 0) && ((2) > 0) && (((0x7fffffff / (width)) / (rasterP-> numBands)) > (2))) && | |||
2478 | SAFE_TO_ALLOC_3(rasterP->scanlineStride, height, 2)(((rasterP->scanlineStride) > 0) && ((height) > 0) && ((2) > 0) && (((0x7fffffff / (rasterP ->scanlineStride)) / (height)) > (2))))) | |||
2479 | { | |||
2480 | return -1; | |||
2481 | } | |||
2482 | offset = rasterP->chanOffsets[0] * 2; | |||
2483 | dataSize = 2 * (*env)->GetArrayLength(env, rasterP->jdata); | |||
2484 | ||||
2485 | if (offset < 0 || offset >= dataSize || | |||
2486 | width * rasterP->numBands > rasterP->scanlineStride || | |||
2487 | (((width * rasterP->numBands) + | |||
2488 | (height - 1) * rasterP->scanlineStride)) * 2 > dataSize - offset) | |||
2489 | { | |||
2490 | // raster data buffer is too short | |||
2491 | return -1; | |||
2492 | } | |||
2493 | dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, rasterP->jdata, | |||
2494 | NULL((void*)0)); | |||
2495 | if (dataP == NULL((void*)0)) { | |||
2496 | return -1; | |||
2497 | } | |||
2498 | *mlibImagePP = (*sMlibSysFns.createStructFP)(MLIB_SHORT, | |||
2499 | rasterP->numBands, | |||
2500 | width, height, | |||
2501 | rasterP->scanlineStride*2, | |||
2502 | (unsigned char *)dataP + offset); | |||
2503 | *dataPP = dataP; | |||
2504 | return 0; | |||
2505 | ||||
2506 | case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES7L: | |||
2507 | *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands, | |||
2508 | width, height); | |||
2509 | if (*mlibImagePP == NULL((void*)0)) { | |||
2510 | return -1; | |||
2511 | } | |||
2512 | if (!isSrc) return 0; | |||
2513 | cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); | |||
2514 | return expandPackedBCR(env, rasterP, -1, cDataP); | |||
2515 | ||||
2516 | case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_PACKED_SAMPLES8L: | |||
2517 | if (rasterP->sppsm.maxBitSize <= 8) { | |||
2518 | *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands, | |||
2519 | width, height); | |||
2520 | if (*mlibImagePP == NULL((void*)0)) { | |||
2521 | return -1; | |||
2522 | } | |||
2523 | if (!isSrc) return 0; | |||
2524 | cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); | |||
2525 | return expandPackedSCR(env, rasterP, -1, cDataP); | |||
2526 | } | |||
2527 | break; | |||
2528 | case sun_awt_image_IntegerComponentRaster_TYPE_INT_PACKED_SAMPLES9L: | |||
2529 | if (rasterP->sppsm.maxBitSize <= 8) { | |||
2530 | *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands, | |||
2531 | width, height); | |||
2532 | if (*mlibImagePP == NULL((void*)0)) { | |||
2533 | return -1; | |||
2534 | } | |||
2535 | if (!isSrc) return 0; | |||
2536 | cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP); | |||
2537 | return expandPackedICR(env, rasterP, -1, cDataP); | |||
2538 | } | |||
2539 | break; | |||
2540 | } | |||
2541 | ||||
2542 | /* Just expand it right now */ | |||
2543 | switch (rasterP->dataType) { | |||
2544 | case BYTE_DATA_TYPE1: | |||
2545 | if ((*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands, | |||
2546 | width, height)) == NULL((void*)0)) { | |||
2547 | return -1; | |||
2548 | } | |||
2549 | if (isSrc) { | |||
2550 | if (awt_getPixels(env, rasterP, mlib_ImageGetData(*mlibImagePP)) < 0) { | |||
2551 | (*sMlibSysFns.deleteImageFP)(*mlibImagePP); | |||
2552 | return -1; | |||
2553 | } | |||
2554 | } | |||
2555 | break; | |||
2556 | ||||
2557 | case SHORT_DATA_TYPE2: | |||
2558 | if ((*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_SHORT, | |||
2559 | rasterP->numBands, | |||
2560 | width, height)) == NULL((void*)0)) { | |||
2561 | return -1; | |||
2562 | } | |||
2563 | if (isSrc) { | |||
2564 | if (awt_getPixels(env, rasterP, mlib_ImageGetData(*mlibImagePP)) < 0) { | |||
2565 | (*sMlibSysFns.deleteImageFP)(*mlibImagePP); | |||
2566 | return -1; | |||
2567 | } | |||
2568 | } | |||
2569 | break; | |||
2570 | ||||
2571 | default: | |||
2572 | return -1; | |||
2573 | } | |||
2574 | return 0; | |||
2575 | } | |||
2576 | ||||
2577 | static void | |||
2578 | freeArray(JNIEnv *env, BufImageS_t *srcimageP, mlib_image *srcmlibImP, | |||
2579 | void *srcdataP, BufImageS_t *dstimageP, mlib_image *dstmlibImP, | |||
2580 | void *dstdataP) { | |||
2581 | jobject srcJdata = (srcimageP != NULL((void*)0) ? srcimageP->raster.jdata : NULL((void*)0)); | |||
2582 | jobject dstJdata = (dstimageP != NULL((void*)0) ? dstimageP->raster.jdata : NULL((void*)0)); | |||
2583 | freeDataArray(env, srcJdata, srcmlibImP, srcdataP, | |||
2584 | dstJdata, dstmlibImP, dstdataP); | |||
2585 | } | |||
2586 | static void | |||
2587 | freeDataArray(JNIEnv *env, jobject srcJdata, mlib_image *srcmlibImP, | |||
2588 | void *srcdataP, jobject dstJdata, mlib_image *dstmlibImP, | |||
2589 | void *dstdataP) | |||
2590 | { | |||
2591 | /* Free the medialib image */ | |||
2592 | if (srcmlibImP) { | |||
2593 | (*sMlibSysFns.deleteImageFP)(srcmlibImP); | |||
2594 | } | |||
2595 | ||||
2596 | /* Release the array */ | |||
2597 | if (srcdataP) { | |||
2598 | (*env)->ReleasePrimitiveArrayCritical(env, srcJdata, | |||
2599 | srcdataP, JNI_ABORT2); | |||
2600 | } | |||
2601 | ||||
2602 | /* Free the medialib image */ | |||
2603 | if (dstmlibImP) { | |||
2604 | (*sMlibSysFns.deleteImageFP)(dstmlibImP); | |||
2605 | } | |||
2606 | ||||
2607 | /* Release the array */ | |||
2608 | if (dstdataP) { | |||
2609 | (*env)->ReleasePrimitiveArrayCritical(env, dstJdata, | |||
2610 | dstdataP, 0); | |||
2611 | } | |||
2612 | } | |||
2613 | ||||
2614 | #define ERR_BAD_IMAGE_LAYOUT(-2) (-2) | |||
2615 | ||||
2616 | #define CHECK_DST_ARRAY(start_offset, elements_per_scan, elements_per_pixel)do { int offset = (start_offset); int lastScanOffset; if (!(( ((elements_per_scan)) > 0) && (((rasterP->height - 1)) >= 0) && ((0x7fffffff / ((elements_per_scan ))) > ((rasterP->height - 1))))) { return (-2); } lastScanOffset = (elements_per_scan) * (rasterP->height - 1); if (!(((offset ) >= 0) && ((lastScanOffset) >= 0) && ( (0x7fffffff - (offset)) > (lastScanOffset)))) { return (-2 ); } lastScanOffset += offset; if (!((((elements_per_pixel)) > 0) && ((rasterP->width) >= 0) && ((0x7fffffff / ((elements_per_pixel))) > (rasterP->width)))) { return (-2); } offset = (elements_per_pixel) * rasterP->width; if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { return ( -2); } lastScanOffset += offset; if (dataArrayLength < lastScanOffset ) { return (-2); } } while(0); \ | |||
2617 | do { \ | |||
2618 | int offset = (start_offset); \ | |||
2619 | int lastScanOffset; \ | |||
2620 | \ | |||
2621 | if (!SAFE_TO_MULT((elements_per_scan), \((((elements_per_scan)) > 0) && (((rasterP->height - 1)) >= 0) && ((0x7fffffff / ((elements_per_scan ))) > ((rasterP->height - 1)))) | |||
2622 | (rasterP->height - 1))((((elements_per_scan)) > 0) && (((rasterP->height - 1)) >= 0) && ((0x7fffffff / ((elements_per_scan ))) > ((rasterP->height - 1))))) \ | |||
2623 | { \ | |||
2624 | return ERR_BAD_IMAGE_LAYOUT(-2); \ | |||
2625 | } \ | |||
2626 | lastScanOffset = (elements_per_scan) * (rasterP->height - 1); \ | |||
2627 | \ | |||
2628 | if (!SAFE_TO_ADD(offset, lastScanOffset)(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { \ | |||
2629 | return ERR_BAD_IMAGE_LAYOUT(-2); \ | |||
2630 | } \ | |||
2631 | lastScanOffset += offset; \ | |||
2632 | \ | |||
2633 | if (!SAFE_TO_MULT((elements_per_pixel), rasterP->width)((((elements_per_pixel)) > 0) && ((rasterP->width ) >= 0) && ((0x7fffffff / ((elements_per_pixel))) > (rasterP->width)))) { \ | |||
2634 | return ERR_BAD_IMAGE_LAYOUT(-2); \ | |||
2635 | } \ | |||
2636 | offset = (elements_per_pixel) * rasterP->width; \ | |||
2637 | \ | |||
2638 | if (!SAFE_TO_ADD(offset, lastScanOffset)(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { \ | |||
2639 | return ERR_BAD_IMAGE_LAYOUT(-2); \ | |||
2640 | } \ | |||
2641 | lastScanOffset += offset; \ | |||
2642 | \ | |||
2643 | if (dataArrayLength < lastScanOffset) { \ | |||
2644 | return ERR_BAD_IMAGE_LAYOUT(-2); \ | |||
2645 | } \ | |||
2646 | } while(0); \ | |||
2647 | ||||
2648 | static int | |||
2649 | storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, | |||
2650 | mlib_image *mlibImP) { | |||
2651 | int mStride; | |||
2652 | unsigned char *cmDataP, *dataP, *cDataP; | |||
2653 | HintS_t *hintP = &dstP->hints; | |||
2654 | RasterS_t *rasterP = &dstP->raster; | |||
2655 | jsize dataArrayLength = (*env)->GetArrayLength(env, rasterP->jdata); | |||
2656 | int y; | |||
2657 | ||||
2658 | /* REMIND: Store mlib data type? */ | |||
2659 | ||||
2660 | /* Check if it is an IndexColorModel */ | |||
2661 | if (dstP->cmodel.cmType == INDEX_CM_TYPE3) { | |||
2662 | if (dstP->raster.rasterType == COMPONENT_RASTER_TYPE1) { | |||
2663 | return storeICMarray(env, srcP, dstP, mlibImP); | |||
2664 | } | |||
2665 | else { | |||
2666 | /* Packed or some other custom raster */ | |||
2667 | cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP); | |||
2668 | return cvtDefaultToCustom(env, dstP, -1, cmDataP); | |||
2669 | } | |||
2670 | } | |||
2671 | ||||
2672 | if (hintP->packing == BYTE_INTERLEAVED(0x1 | 0x10)) { | |||
2673 | /* Write it back to the destination */ | |||
2674 | if (rasterP->dataType != BYTE_DATA_TYPE1) { | |||
2675 | /* We are working with a raster which was marked | |||
2676 | as a byte interleaved due to performance reasons. | |||
2677 | So, we have to convert the length of the data | |||
2678 | array to bytes as well. | |||
2679 | */ | |||
2680 | if (!SAFE_TO_MULT(rasterP->dataSize, dataArrayLength)(((rasterP->dataSize) > 0) && ((dataArrayLength ) >= 0) && ((0x7fffffff / (rasterP->dataSize)) > (dataArrayLength)))) { | |||
2681 | return ERR_BAD_IMAGE_LAYOUT(-2); | |||
2682 | } | |||
2683 | dataArrayLength *= rasterP->dataSize; | |||
2684 | } | |||
2685 | ||||
2686 | CHECK_DST_ARRAY(hintP->dataOffset, hintP->sStride, hintP->numChans)do { int offset = (hintP->dataOffset); int lastScanOffset; if (!((((hintP->sStride)) > 0) && (((rasterP-> height - 1)) >= 0) && ((0x7fffffff / ((hintP->sStride ))) > ((rasterP->height - 1))))) { return (-2); } lastScanOffset = (hintP->sStride) * (rasterP->height - 1); if (!(((offset ) >= 0) && ((lastScanOffset) >= 0) && ( (0x7fffffff - (offset)) > (lastScanOffset)))) { return (-2 ); } lastScanOffset += offset; if (!((((hintP->numChans)) > 0) && ((rasterP->width) >= 0) && ((0x7fffffff / ((hintP->numChans))) > (rasterP->width)))) { return (-2); } offset = (hintP->numChans) * rasterP->width; if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { return ( -2); } lastScanOffset += offset; if (dataArrayLength < lastScanOffset ) { return (-2); } } while(0);; | |||
2687 | cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP); | |||
2688 | mStride = mlib_ImageGetStride(mlibImP); | |||
2689 | dataP = (unsigned char *)(*env)->GetPrimitiveArrayCritical(env, | |||
2690 | rasterP->jdata, NULL((void*)0)); | |||
2691 | if (dataP == NULL((void*)0)) return 0; | |||
2692 | cDataP = dataP + hintP->dataOffset; | |||
2693 | for (y=0; y < rasterP->height; | |||
2694 | y++, cmDataP += mStride, cDataP += hintP->sStride) | |||
2695 | { | |||
2696 | memcpy(cDataP, cmDataP, rasterP->width*hintP->numChans); | |||
2697 | } | |||
2698 | (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP, | |||
2699 | JNI_ABORT2); | |||
2700 | } | |||
2701 | else if (dstP->cmodel.cmType == DIRECT_CM_TYPE2) { | |||
2702 | /* Just need to move bits */ | |||
2703 | if (mlibImP->type == MLIB_BYTE) { | |||
2704 | if (dstP->hints.packing == PACKED_BYTE_INTER(0x5 | 0x10)) { | |||
2705 | return setPackedBCRdefault(env, rasterP, -1, | |||
2706 | (unsigned char *) mlibImP->data, | |||
2707 | dstP->cmodel.supportsAlpha); | |||
2708 | } else if (dstP->hints.packing == PACKED_SHORT_INTER(0x4 | 0x10)) { | |||
2709 | return setPackedSCRdefault(env, rasterP, -1, | |||
2710 | (unsigned char *) mlibImP->data, | |||
2711 | dstP->cmodel.supportsAlpha); | |||
2712 | } else if (dstP->hints.packing == PACKED_INT_INTER(0x3 | 0x10)) { | |||
2713 | return setPackedICRdefault(env, rasterP, -1, | |||
2714 | (unsigned char *) mlibImP->data, | |||
2715 | dstP->cmodel.supportsAlpha); | |||
2716 | } | |||
2717 | } | |||
2718 | else if (mlibImP->type == MLIB_SHORT) { | |||
2719 | return setPixelsFormMlibImage(env, rasterP, mlibImP); | |||
2720 | } | |||
2721 | } | |||
2722 | else { | |||
2723 | return cvtDefaultToCustom(env, dstP, -1, | |||
2724 | (unsigned char *)mlibImP->data); | |||
2725 | } | |||
2726 | ||||
2727 | return 0; | |||
2728 | } | |||
2729 | ||||
2730 | static int | |||
2731 | storeRasterArray(JNIEnv *env, RasterS_t *srcP, RasterS_t *dstP, | |||
2732 | mlib_image *mlibImP) { | |||
2733 | unsigned char *cDataP; | |||
2734 | ||||
2735 | switch(dstP->type) { | |||
2736 | case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES7L: | |||
2737 | cDataP = (unsigned char *) mlib_ImageGetData(mlibImP); | |||
2738 | return setPackedBCR(env, dstP, -1, cDataP); | |||
2739 | ||||
2740 | case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_PACKED_SAMPLES8L: | |||
2741 | if (dstP->sppsm.maxBitSize <= 8) { | |||
2742 | cDataP = (unsigned char *) mlib_ImageGetData(mlibImP); | |||
2743 | return setPackedSCR(env, dstP, -1, cDataP); | |||
2744 | } | |||
2745 | break; | |||
2746 | case sun_awt_image_IntegerComponentRaster_TYPE_INT_PACKED_SAMPLES9L: | |||
2747 | if (dstP->sppsm.maxBitSize <= 8) { | |||
2748 | cDataP = (unsigned char *) mlib_ImageGetData(mlibImP); | |||
2749 | return setPackedICR(env, dstP, -1, cDataP); | |||
2750 | } | |||
2751 | } | |||
2752 | ||||
2753 | return -1; | |||
2754 | } | |||
2755 | ||||
2756 | ||||
2757 | static int | |||
2758 | storeICMarray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, | |||
2759 | mlib_image *mlibImP) | |||
2760 | { | |||
2761 | int *argb; | |||
2762 | int x, y; | |||
2763 | unsigned char *dataP, *cDataP, *cP; | |||
2764 | unsigned char *sP; | |||
2765 | int aIdx, rIdx, gIdx, bIdx; | |||
2766 | ColorModelS_t *cmodelP = &dstP->cmodel; | |||
2767 | RasterS_t *rasterP = &dstP->raster; | |||
2768 | ||||
2769 | /* REMIND: Only works for RGB */ | |||
2770 | if (cmodelP->csType != java_awt_color_ColorSpace_TYPE_RGB5L) { | |||
2771 | JNU_ThrowInternalError(env, "Writing to non-RGB images not implemented yet"); | |||
2772 | return -1; | |||
2773 | } | |||
2774 | ||||
2775 | if (srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB2L || | |||
2776 | srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE3L || | |||
2777 | srcP->imageType == java_awt_image_BufferedImage_TYPE_INT_RGB1L) | |||
2778 | { | |||
2779 | aIdx = 0; | |||
2780 | rIdx = 1; | |||
2781 | gIdx = 2; | |||
2782 | bIdx = 3; | |||
2783 | } | |||
2784 | else if (srcP->imageType ==java_awt_image_BufferedImage_TYPE_4BYTE_ABGR6L|| | |||
2785 | srcP->imageType == java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE7L) | |||
2786 | { | |||
2787 | aIdx = 0; | |||
2788 | rIdx = 3; | |||
2789 | gIdx = 2; | |||
2790 | bIdx = 1; | |||
2791 | } | |||
2792 | else if (srcP->imageType == java_awt_image_BufferedImage_TYPE_3BYTE_BGR5L){ | |||
2793 | rIdx = 2; | |||
2794 | gIdx = 1; | |||
2795 | bIdx = 0; | |||
2796 | aIdx = 0; /* Ignored */ | |||
2797 | } | |||
2798 | else if (srcP->cmodel.cmType == INDEX_CM_TYPE3) { | |||
2799 | rIdx = 0; | |||
2800 | gIdx = 1; | |||
2801 | bIdx = 2; | |||
2802 | aIdx = 3; /* Use supportsAlpha to see if it is really there */ | |||
2803 | } | |||
2804 | else { | |||
2805 | return -1; | |||
2806 | } | |||
2807 | ||||
2808 | /* Lock down the destination raster */ | |||
2809 | dataP = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, | |||
2810 | rasterP->jdata, NULL((void*)0)); | |||
2811 | if (dataP == NULL((void*)0)) { | |||
2812 | return -1; | |||
2813 | } | |||
2814 | argb = (*env)->GetPrimitiveArrayCritical(env, cmodelP->jrgb, NULL((void*)0)); | |||
2815 | if (argb == NULL((void*)0)) { | |||
2816 | (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP, | |||
2817 | JNI_ABORT2); | |||
2818 | return -1; | |||
2819 | } | |||
2820 | ||||
2821 | cDataP = dataP + dstP->hints.dataOffset; | |||
2822 | sP = (unsigned char *) mlib_ImageGetData(mlibImP); | |||
2823 | ||||
2824 | for (y=0; y < rasterP->height; y++, cDataP += rasterP->scanlineStride) { | |||
2825 | cP = cDataP; | |||
2826 | for (x=0; x < rasterP->width; x++, cP += rasterP->pixelStride) { | |||
2827 | *cP = colorMatch(sP[rIdx], sP[gIdx], sP[bIdx], sP[aIdx], | |||
2828 | (unsigned char *)argb, cmodelP->mapSize); | |||
2829 | sP += cmodelP->numComponents; | |||
2830 | } | |||
2831 | } | |||
2832 | ||||
2833 | (*env)->ReleasePrimitiveArrayCritical(env, cmodelP->jrgb, argb, JNI_ABORT2); | |||
2834 | (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP, | |||
2835 | JNI_ABORT2); | |||
2836 | return -1; | |||
2837 | } | |||
2838 | ||||
2839 | static int expandICM(JNIEnv *env, BufImageS_t *imageP, unsigned int *mDataP) | |||
2840 | { | |||
2841 | ColorModelS_t *cmP = &imageP->cmodel; | |||
2842 | RasterS_t *rasterP = &imageP->raster; | |||
2843 | HintS_t *hintP = &imageP->hints; | |||
2844 | int *rgb; | |||
2845 | int status = 0; | |||
2846 | unsigned char *dataP, *cP; | |||
2847 | unsigned int *mP; | |||
2848 | int width = rasterP->width; | |||
2849 | int height = rasterP->height; | |||
2850 | int x, y; | |||
2851 | ||||
2852 | /* Need to grab the lookup tables. Right now only bytes */ | |||
2853 | rgb = (int *) (*env)->GetPrimitiveArrayCritical(env, cmP->jrgb, NULL((void*)0)); | |||
2854 | CHECK_NULL_RETURN(rgb, -1)do { if ((rgb) == ((void*)0)) { return (-1); } } while (0); | |||
2855 | ||||
2856 | /* Interleaved with shared data */ | |||
2857 | dataP = (void *) (*env)->GetPrimitiveArrayCritical(env, | |||
2858 | rasterP->jdata, NULL((void*)0)); | |||
2859 | if (dataP == NULL((void*)0)) { | |||
2860 | /* Release the lookup tables */ | |||
2861 | (*env)->ReleasePrimitiveArrayCritical(env, cmP->jrgb, rgb, JNI_ABORT2); | |||
2862 | return -1; | |||
2863 | } | |||
2864 | ||||
2865 | if (rasterP->dataType == BYTE_DATA_TYPE1) { | |||
2866 | unsigned char *cDataP = ((unsigned char *)dataP) + hintP->dataOffset; | |||
2867 | ||||
2868 | for (y=0; y < height; y++) { | |||
2869 | mP = mDataP; | |||
2870 | cP = cDataP; | |||
2871 | for (x=0; x < width; x++, cP += rasterP->pixelStride) { | |||
2872 | *mP++ = rgb[*cP]; | |||
2873 | } | |||
2874 | mDataP += width; | |||
2875 | cDataP += rasterP->scanlineStride; | |||
2876 | } | |||
2877 | } | |||
2878 | else if (rasterP->dataType == SHORT_DATA_TYPE2) { | |||
2879 | unsigned short *sDataP, *sP; | |||
2880 | sDataP = ((unsigned short *)dataP) + hintP->channelOffset; | |||
2881 | ||||
2882 | for (y=0; y < height; y++) { | |||
2883 | mP = mDataP; | |||
2884 | sP = sDataP; | |||
2885 | for (x=0; x < width; x++, sP+=rasterP->pixelStride) { | |||
2886 | *mP++ = rgb[*sP]; | |||
2887 | } | |||
2888 | mDataP += width; | |||
2889 | sDataP += rasterP->scanlineStride; | |||
2890 | } | |||
2891 | } | |||
2892 | else { | |||
2893 | /* Unknown type */ | |||
2894 | status = -1; | |||
2895 | } | |||
2896 | /* Release the lookup table data */ | |||
2897 | (*env)->ReleasePrimitiveArrayCritical(env, imageP->cmodel.jrgb, | |||
2898 | rgb, JNI_ABORT2); | |||
2899 | /* Release the data array */ | |||
2900 | (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, | |||
2901 | dataP, JNI_ABORT2); | |||
2902 | return status; | |||
2903 | } | |||
2904 | /* This routine is expecting a ByteComponentRaster with a PackedColorModel */ | |||
2905 | static int expandPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
2906 | unsigned char *outDataP) | |||
2907 | { | |||
2908 | int x, y, c; | |||
2909 | unsigned char *outP = outDataP; | |||
2910 | unsigned char *lineInP, *inP; | |||
2911 | jarray jInDataP; | |||
2912 | jint *inDataP; | |||
2913 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
2914 | ||||
2915 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
2916 | return -1; | |||
2917 | } | |||
2918 | ||||
2919 | /* Grab data ptr, strides, offsets from raster */ | |||
2920 | jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID); | |||
2921 | inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0); | |||
2922 | if (inDataP == NULL((void*)0)) { | |||
2923 | return -1; | |||
2924 | } | |||
2925 | lineInP = (unsigned char *)inDataP + rasterP->chanOffsets[0]; | |||
2926 | ||||
2927 | if (component < 0) { | |||
2928 | for (c=0; c < rasterP->numBands; c++) { | |||
2929 | roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
2930 | if (roff[c] < 0) { | |||
2931 | loff[c] = -roff[c]; | |||
2932 | roff[c] = 0; | |||
2933 | } | |||
2934 | else loff[c] = 0; | |||
2935 | } | |||
2936 | /* Convert the all bands */ | |||
2937 | if (rasterP->numBands < 4) { | |||
2938 | /* Need to put in alpha */ | |||
2939 | for (y=0; y < rasterP->height; y++) { | |||
2940 | inP = lineInP; | |||
2941 | for (x=0; x < rasterP->width; x++) { | |||
2942 | for (c=0; c < rasterP->numBands; c++) { | |||
2943 | *outP++ = (unsigned char) | |||
2944 | (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
2945 | <<loff[c]); | |||
2946 | } | |||
2947 | inP++; | |||
2948 | } | |||
2949 | lineInP += rasterP->scanlineStride; | |||
2950 | } | |||
2951 | } | |||
2952 | else { | |||
2953 | for (y=0; y < rasterP->height; y++) { | |||
2954 | inP = lineInP; | |||
2955 | for (x=0; x < rasterP->width; x++) { | |||
2956 | for (c=0; c < rasterP->numBands; c++) { | |||
2957 | *outP++ = (unsigned char) | |||
2958 | (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
2959 | <<loff[c]); | |||
2960 | } | |||
2961 | inP++; | |||
2962 | } | |||
2963 | lineInP += rasterP->scanlineStride; | |||
2964 | } | |||
2965 | } | |||
2966 | } | |||
2967 | else { | |||
2968 | c = component; | |||
2969 | roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
2970 | if (roff[0] < 0) { | |||
2971 | loff[0] = -roff[0]; | |||
2972 | roff[0] = 0; | |||
2973 | } | |||
2974 | else loff[c] = 0; | |||
2975 | for (y=0; y < rasterP->height; y++) { | |||
2976 | inP = lineInP; | |||
2977 | for (x=0; x < rasterP->width; x++) { | |||
2978 | *outP++ = (unsigned char) | |||
2979 | ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]; | |||
2980 | inP++; | |||
2981 | } | |||
2982 | lineInP += rasterP->scanlineStride; | |||
2983 | } | |||
2984 | } | |||
2985 | ||||
2986 | (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT2); | |||
2987 | ||||
2988 | return 0; | |||
2989 | } | |||
2990 | ||||
2991 | /* This routine is expecting a ByteComponentRaster with a PackedColorModel */ | |||
2992 | static int expandPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
2993 | int component, unsigned char *outDataP, | |||
2994 | int forceAlpha) | |||
2995 | { | |||
2996 | int x, y, c; | |||
2997 | unsigned char *outP = outDataP; | |||
2998 | unsigned char *lineInP, *inP; | |||
2999 | jarray jInDataP; | |||
3000 | jint *inDataP; | |||
3001 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3002 | int numBands = rasterP->numBands - (forceAlpha ? 0 : 1); | |||
3003 | int a = numBands; | |||
3004 | ||||
3005 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3006 | return -1; | |||
3007 | } | |||
3008 | ||||
3009 | /* Grab data ptr, strides, offsets from raster */ | |||
3010 | jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID); | |||
3011 | inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0); | |||
3012 | if (inDataP == NULL((void*)0)) { | |||
3013 | return -1; | |||
3014 | } | |||
3015 | lineInP = (unsigned char *)inDataP + rasterP->chanOffsets[0]; | |||
3016 | ||||
3017 | if (component < 0) { | |||
3018 | for (c=0; c < rasterP->numBands; c++) { | |||
3019 | roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3020 | if (roff[c] < 0) { | |||
3021 | loff[c] = -roff[c]; | |||
3022 | roff[c] = 0; | |||
3023 | } | |||
3024 | else loff[c] = 0; | |||
3025 | } | |||
3026 | ||||
3027 | /* Need to put in alpha */ | |||
3028 | if (forceAlpha) { | |||
3029 | for (y=0; y < rasterP->height; y++) { | |||
3030 | inP = lineInP; | |||
3031 | for (x=0; x < rasterP->width; x++) { | |||
3032 | *outP++ = 0xff; | |||
3033 | for (c=0; c < numBands; c++) { | |||
3034 | *outP++ = (unsigned char) | |||
3035 | (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3036 | <<loff[c]); | |||
3037 | } | |||
3038 | inP++; | |||
3039 | } | |||
3040 | lineInP += rasterP->scanlineStride; | |||
3041 | } | |||
3042 | } | |||
3043 | else { | |||
3044 | for (y=0; y < rasterP->height; y++) { | |||
3045 | inP = lineInP; | |||
3046 | for (x=0; x < rasterP->width; x++) { | |||
3047 | *outP++ = (unsigned char) | |||
3048 | (((*inP&rasterP->sppsm.maskArray[a]) >> roff[a]) | |||
3049 | <<loff[a]); | |||
3050 | for (c=0; c < numBands; c++) { | |||
3051 | *outP++ = (unsigned char) | |||
3052 | (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3053 | <<loff[c]); | |||
3054 | } | |||
3055 | inP++; | |||
3056 | } | |||
3057 | lineInP += rasterP->scanlineStride; | |||
3058 | } | |||
3059 | } | |||
3060 | } | |||
3061 | else { | |||
3062 | c = component; | |||
3063 | roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3064 | if (roff[0] < 0) { | |||
3065 | loff[0] = -roff[0]; | |||
3066 | roff[0] = 0; | |||
3067 | } | |||
3068 | else loff[c] = 0; | |||
3069 | for (y=0; y < rasterP->height; y++) { | |||
3070 | inP = lineInP; | |||
3071 | for (x=0; x < rasterP->width; x++) { | |||
3072 | *outP++ = (unsigned char) | |||
3073 | ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]; | |||
3074 | inP++; | |||
3075 | } | |||
3076 | lineInP += rasterP->scanlineStride; | |||
3077 | } | |||
3078 | } | |||
3079 | ||||
3080 | (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT2); | |||
3081 | ||||
3082 | return 0; | |||
3083 | } | |||
3084 | ||||
3085 | /* This routine is expecting a ShortComponentRaster with a PackedColorModel */ | |||
3086 | static int expandPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
3087 | unsigned char *outDataP) | |||
3088 | { | |||
3089 | int x, y, c; | |||
3090 | unsigned char *outP = outDataP; | |||
3091 | unsigned short *lineInP, *inP; | |||
3092 | jarray jInDataP; | |||
3093 | jint *inDataP; | |||
3094 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3095 | ||||
3096 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3097 | return -1; | |||
3098 | } | |||
3099 | ||||
3100 | /* Grab data ptr, strides, offsets from raster */ | |||
3101 | jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID); | |||
3102 | inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0); | |||
3103 | if (inDataP == NULL((void*)0)) { | |||
3104 | return -1; | |||
3105 | } | |||
3106 | lineInP = (unsigned short *)inDataP + rasterP->chanOffsets[0]; | |||
3107 | ||||
3108 | if (component < 0) { | |||
3109 | for (c=0; c < rasterP->numBands; c++) { | |||
3110 | roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3111 | if (roff[c] < 0) { | |||
3112 | loff[c] = -roff[c]; | |||
3113 | roff[c] = 0; | |||
3114 | } | |||
3115 | else loff[c] = 0; | |||
3116 | } | |||
3117 | /* Convert the all bands */ | |||
3118 | if (rasterP->numBands < 4) { | |||
3119 | /* Need to put in alpha */ | |||
3120 | for (y=0; y < rasterP->height; y++) { | |||
3121 | inP = lineInP; | |||
3122 | for (x=0; x < rasterP->width; x++) { | |||
3123 | for (c=0; c < rasterP->numBands; c++) { | |||
3124 | /* | |||
3125 | *Not correct. Might need to unpremult, | |||
3126 | * shift, etc | |||
3127 | */ | |||
3128 | *outP++ = (unsigned char) | |||
3129 | (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3130 | <<loff[c]); | |||
3131 | } | |||
3132 | inP++; | |||
3133 | } | |||
3134 | lineInP += rasterP->scanlineStride; | |||
3135 | } | |||
3136 | } else { | |||
3137 | for (y=0; y < rasterP->height; y++) { | |||
3138 | inP = lineInP; | |||
3139 | for (x=0; x < rasterP->width; x++) { | |||
3140 | for (c=0; c < rasterP->numBands; c++) { | |||
3141 | /* | |||
3142 | *Not correct. Might need to unpremult, | |||
3143 | * shift, etc | |||
3144 | */ | |||
3145 | *outP++ = (unsigned char) | |||
3146 | (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3147 | <<loff[c]); | |||
3148 | } | |||
3149 | inP++; | |||
3150 | } | |||
3151 | lineInP += rasterP->scanlineStride; | |||
3152 | } | |||
3153 | } | |||
3154 | } | |||
3155 | else { | |||
3156 | c = component; | |||
3157 | roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3158 | if (roff[0] < 0) { | |||
3159 | loff[0] = -roff[0]; | |||
3160 | roff[0] = 0; | |||
3161 | } | |||
3162 | else loff[c] = 0; | |||
3163 | for (y=0; y < rasterP->height; y++) { | |||
3164 | inP = lineInP; | |||
3165 | for (x=0; x < rasterP->width; x++) { | |||
3166 | *outP++ = (unsigned char) | |||
3167 | ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]; | |||
3168 | inP++; | |||
3169 | } | |||
3170 | lineInP += rasterP->scanlineStride; | |||
3171 | } | |||
3172 | } | |||
3173 | ||||
3174 | (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT2); | |||
3175 | ||||
3176 | return 0; | |||
3177 | } | |||
3178 | ||||
3179 | /* This routine is expecting a ShortComponentRaster with a PackedColorModel */ | |||
3180 | static int expandPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
3181 | int component, unsigned char *outDataP, | |||
3182 | int forceAlpha) | |||
3183 | { | |||
3184 | int x, y, c; | |||
3185 | unsigned char *outP = outDataP; | |||
3186 | unsigned short *lineInP, *inP; | |||
3187 | jarray jInDataP; | |||
3188 | jint *inDataP; | |||
3189 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3190 | int numBands = rasterP->numBands - (forceAlpha ? 0 : 1); | |||
3191 | int a = numBands; | |||
3192 | ||||
3193 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3194 | return -1; | |||
3195 | } | |||
3196 | ||||
3197 | /* Grab data ptr, strides, offsets from raster */ | |||
3198 | jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID); | |||
3199 | inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0); | |||
3200 | if (inDataP == NULL((void*)0)) { | |||
3201 | return -1; | |||
3202 | } | |||
3203 | lineInP = (unsigned short *)inDataP + rasterP->chanOffsets[0]; | |||
3204 | ||||
3205 | if (component < 0) { | |||
3206 | for (c=0; c < rasterP->numBands; c++) { | |||
3207 | roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3208 | if (roff[c] < 0) { | |||
3209 | loff[c] = -roff[c]; | |||
3210 | roff[c] = 0; | |||
3211 | } | |||
3212 | else loff[c] = 0; | |||
3213 | } | |||
3214 | ||||
3215 | /* Need to put in alpha */ | |||
3216 | if (forceAlpha) { | |||
3217 | for (y=0; y < rasterP->height; y++) { | |||
3218 | inP = lineInP; | |||
3219 | for (x=0; x < rasterP->width; x++) { | |||
3220 | *outP++ = 0xff; | |||
3221 | for (c=0; c < numBands; c++) { | |||
3222 | /* | |||
3223 | * Not correct. Might need to unpremult, | |||
3224 | * shift, etc | |||
3225 | */ | |||
3226 | *outP++ = (unsigned char) | |||
3227 | (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3228 | <<loff[c]); | |||
3229 | } | |||
3230 | inP++; | |||
3231 | } | |||
3232 | lineInP += rasterP->scanlineStride; | |||
3233 | } | |||
3234 | } | |||
3235 | else { | |||
3236 | for (y=0; y < rasterP->height; y++) { | |||
3237 | inP = lineInP; | |||
3238 | for (x=0; x < rasterP->width; x++) { | |||
3239 | *outP++ = (unsigned char) | |||
3240 | (((*inP&rasterP->sppsm.maskArray[a]) >> roff[a]) | |||
3241 | <<loff[a]); | |||
3242 | for (c=0; c < numBands; c++) { | |||
3243 | /* | |||
3244 | * Not correct. Might need to | |||
3245 | * unpremult, shift, etc | |||
3246 | */ | |||
3247 | *outP++ = (unsigned char) | |||
3248 | (((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3249 | <<loff[c]); | |||
3250 | } | |||
3251 | inP++; | |||
3252 | } | |||
3253 | lineInP += rasterP->scanlineStride; | |||
3254 | } | |||
3255 | } | |||
3256 | } | |||
3257 | else { | |||
3258 | c = component; | |||
3259 | roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3260 | if (roff[0] < 0) { | |||
3261 | loff[0] = -roff[0]; | |||
3262 | roff[0] = 0; | |||
3263 | } | |||
3264 | else loff[c] = 0; | |||
3265 | for (y=0; y < rasterP->height; y++) { | |||
3266 | inP = lineInP; | |||
3267 | for (x=0; x < rasterP->width; x++) { | |||
3268 | *outP++ = (unsigned char) | |||
3269 | ((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]; | |||
3270 | inP++; | |||
3271 | } | |||
3272 | lineInP += rasterP->scanlineStride; | |||
3273 | } | |||
3274 | } | |||
3275 | ||||
3276 | (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT2); | |||
3277 | ||||
3278 | return 0; | |||
3279 | ||||
3280 | } | |||
3281 | ||||
3282 | /* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/ | |||
3283 | static int expandPackedICR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
3284 | unsigned char *outDataP) | |||
3285 | { | |||
3286 | int x, y, c; | |||
3287 | unsigned char *outP = outDataP; | |||
3288 | unsigned int *lineInP, *inP; | |||
3289 | jarray jInDataP; | |||
3290 | jint *inDataP; | |||
3291 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3292 | ||||
3293 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3294 | return -1; | |||
3295 | } | |||
3296 | ||||
3297 | /* Grab data ptr, strides, offsets from raster */ | |||
3298 | jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID); | |||
3299 | inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0); | |||
3300 | if (inDataP == NULL((void*)0)) { | |||
3301 | return -1; | |||
3302 | } | |||
3303 | lineInP = (unsigned int *)inDataP + rasterP->chanOffsets[0]; | |||
3304 | ||||
3305 | if (component < 0) { | |||
3306 | for (c=0; c < rasterP->numBands; c++) { | |||
3307 | roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3308 | if (roff[c] < 0) { | |||
3309 | loff[c] = -roff[c]; | |||
3310 | roff[c] = 0; | |||
3311 | } | |||
3312 | else loff[c] = 0; | |||
3313 | } | |||
3314 | /* Convert the all bands */ | |||
3315 | if (rasterP->numBands < 4) { | |||
3316 | for (y=0; y < rasterP->height; y++) { | |||
3317 | inP = lineInP; | |||
3318 | for (x=0; x < rasterP->width; x++) { | |||
3319 | for (c=0; c < rasterP->numBands; c++) { | |||
3320 | /* | |||
3321 | * Not correct. Might need to unpremult, | |||
3322 | * shift, etc | |||
3323 | */ | |||
3324 | *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3325 | <<loff[c]); | |||
3326 | } | |||
3327 | inP++; | |||
3328 | } | |||
3329 | lineInP += rasterP->scanlineStride; | |||
3330 | } | |||
3331 | } | |||
3332 | else { | |||
3333 | for (y=0; y < rasterP->height; y++) { | |||
3334 | inP = lineInP; | |||
3335 | for (x=0; x < rasterP->width; x++) { | |||
3336 | for (c=0; c < rasterP->numBands; c++) { | |||
3337 | /* | |||
3338 | * Not correct. Might need to | |||
3339 | * unpremult, shift, etc | |||
3340 | */ | |||
3341 | *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3342 | <<loff[c]); | |||
3343 | } | |||
3344 | inP++; | |||
3345 | } | |||
3346 | lineInP += rasterP->scanlineStride; | |||
3347 | } | |||
3348 | } | |||
3349 | } | |||
3350 | else { | |||
3351 | c = component; | |||
3352 | roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3353 | if (roff[0] < 0) { | |||
3354 | loff[0] = -roff[0]; | |||
3355 | roff[0] = 0; | |||
3356 | } | |||
3357 | else loff[c] = 0; | |||
3358 | for (y=0; y < rasterP->height; y++) { | |||
3359 | inP = lineInP; | |||
3360 | for (x=0; x < rasterP->width; x++) { | |||
3361 | *outP++ = (unsigned char)(((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]); | |||
3362 | inP++; | |||
3363 | } | |||
3364 | lineInP += rasterP->scanlineStride; | |||
3365 | } | |||
3366 | } | |||
3367 | ||||
3368 | (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT2); | |||
3369 | ||||
3370 | return 0; | |||
3371 | } | |||
3372 | ||||
3373 | /* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/ | |||
3374 | static int expandPackedICRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
3375 | int component, unsigned char *outDataP, | |||
3376 | int forceAlpha) | |||
3377 | { | |||
3378 | int x, y, c; | |||
3379 | unsigned char *outP = outDataP; | |||
3380 | unsigned int *lineInP, *inP; | |||
3381 | jarray jInDataP; | |||
3382 | jint *inDataP; | |||
3383 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3384 | int numBands = rasterP->numBands - (forceAlpha ? 0 : 1); | |||
3385 | int a = numBands; | |||
3386 | ||||
3387 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3388 | return -1; | |||
3389 | } | |||
3390 | ||||
3391 | /* Grab data ptr, strides, offsets from raster */ | |||
3392 | jInDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID); | |||
3393 | inDataP = (*env)->GetPrimitiveArrayCritical(env, jInDataP, 0); | |||
3394 | if (inDataP == NULL((void*)0)) { | |||
3395 | return -1; | |||
3396 | } | |||
3397 | lineInP = (unsigned int *)inDataP + rasterP->chanOffsets[0]; | |||
3398 | ||||
3399 | if (component < 0) { | |||
3400 | for (c=0; c < rasterP->numBands; c++) { | |||
3401 | roff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3402 | if (roff[c] < 0) { | |||
3403 | loff[c] = -roff[c]; | |||
3404 | roff[c] = 0; | |||
3405 | } | |||
3406 | else loff[c] = 0; | |||
3407 | } | |||
3408 | ||||
3409 | /* Need to put in alpha */ | |||
3410 | if (forceAlpha) { | |||
3411 | for (y=0; y < rasterP->height; y++) { | |||
3412 | inP = lineInP; | |||
3413 | for (x=0; x < rasterP->width; x++) { | |||
3414 | *outP++ = 0xff; | |||
3415 | for (c=0; c < numBands; c++) { | |||
3416 | /* | |||
3417 | * Not correct. Might need to unpremult, | |||
3418 | * shift, etc | |||
3419 | */ | |||
3420 | *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3421 | <<loff[c]); | |||
3422 | } | |||
3423 | inP++; | |||
3424 | } | |||
3425 | lineInP += rasterP->scanlineStride; | |||
3426 | } | |||
3427 | } | |||
3428 | else { | |||
3429 | for (y=0; y < rasterP->height; y++) { | |||
3430 | inP = lineInP; | |||
3431 | for (x=0; x < rasterP->width; x++) { | |||
3432 | *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[a]) >> roff[a]) | |||
3433 | <<loff[a]); | |||
3434 | for (c=0; c < numBands; c++) { | |||
3435 | /* | |||
3436 | * Not correct. Might need to | |||
3437 | * unpremult, shift, etc | |||
3438 | */ | |||
3439 | *outP++ = (unsigned char)(((*inP&rasterP->sppsm.maskArray[c]) >> roff[c]) | |||
3440 | <<loff[c]); | |||
3441 | } | |||
3442 | inP++; | |||
3443 | } | |||
3444 | lineInP += rasterP->scanlineStride; | |||
3445 | } | |||
3446 | } | |||
3447 | } | |||
3448 | else { | |||
3449 | c = component; | |||
3450 | roff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3451 | if (roff[0] < 0) { | |||
3452 | loff[0] = -roff[0]; | |||
3453 | roff[0] = 0; | |||
3454 | } | |||
3455 | else loff[c] = 0; | |||
3456 | for (y=0; y < rasterP->height; y++) { | |||
3457 | inP = lineInP; | |||
3458 | for (x=0; x < rasterP->width; x++) { | |||
3459 | *outP++ = (unsigned char)(((*inP & rasterP->sppsm.maskArray[c])>>roff[0])<<loff[0]); | |||
3460 | inP++; | |||
3461 | } | |||
3462 | lineInP += rasterP->scanlineStride; | |||
3463 | } | |||
3464 | } | |||
3465 | ||||
3466 | (*env)->ReleasePrimitiveArrayCritical(env, jInDataP, inDataP, JNI_ABORT2); | |||
3467 | ||||
3468 | return 0; | |||
3469 | } | |||
3470 | ||||
3471 | /* This routine is expecting a ByteComponentRaster with a PackedColorModel */ | |||
3472 | static int setPackedBCR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
3473 | unsigned char *inDataP) | |||
3474 | { | |||
3475 | int x, y, c; | |||
3476 | unsigned char *inP = inDataP; | |||
3477 | unsigned char *lineOutP, *outP; | |||
3478 | jarray jOutDataP; | |||
3479 | jsize dataArrayLength; | |||
3480 | unsigned char *outDataP; | |||
3481 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3482 | ||||
3483 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3484 | return -1; | |||
3485 | } | |||
3486 | ||||
3487 | /* Grab data ptr, strides, offsets from raster */ | |||
3488 | jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID); | |||
3489 | if (JNU_IsNull(env, jOutDataP)((jOutDataP) == ((void*)0))) { | |||
3490 | return -1; | |||
3491 | } | |||
3492 | ||||
3493 | dataArrayLength = (*env)->GetArrayLength(env, jOutDataP); | |||
3494 | CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1)do { int offset = (rasterP->chanOffsets[0]); int lastScanOffset ; if (!((((rasterP->scanlineStride)) > 0) && (( (rasterP->height - 1)) >= 0) && ((0x7fffffff / ( (rasterP->scanlineStride))) > ((rasterP->height - 1) )))) { return (-2); } lastScanOffset = (rasterP->scanlineStride ) * (rasterP->height - 1); if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset )) > (lastScanOffset)))) { return (-2); } lastScanOffset += offset; if (!((((1)) > 0) && ((rasterP->width) >= 0) && ((0x7fffffff / ((1))) > (rasterP-> width)))) { return (-2); } offset = (1) * rasterP->width; if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { return ( -2); } lastScanOffset += offset; if (dataArrayLength < lastScanOffset ) { return (-2); } } while(0);; | |||
3495 | ||||
3496 | outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0); | |||
3497 | if (outDataP == NULL((void*)0)) { | |||
3498 | return -1; | |||
3499 | } | |||
3500 | lineOutP = outDataP + rasterP->chanOffsets[0]; | |||
3501 | ||||
3502 | if (component < 0) { | |||
3503 | for (c=0; c < rasterP->numBands; c++) { | |||
3504 | loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3505 | if (loff[c] < 0) { | |||
3506 | roff[c] = -loff[c]; | |||
3507 | loff[c] = 0; | |||
3508 | } | |||
3509 | else roff[c] = 0; | |||
3510 | } | |||
3511 | /* Convert the all bands */ | |||
3512 | for (y=0; y < rasterP->height; y++) { | |||
3513 | outP = lineOutP; | |||
3514 | *outP = 0; | |||
3515 | for (x=0; x < rasterP->width; x++) { | |||
3516 | for (c=0; c < rasterP->numBands; c++, inP++) { | |||
3517 | *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c]; | |||
3518 | } | |||
3519 | outP++; | |||
3520 | } | |||
3521 | lineOutP += rasterP->scanlineStride; | |||
3522 | } | |||
3523 | } | |||
3524 | else { | |||
3525 | c = component; | |||
3526 | loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3527 | if (loff[0] < 0) { | |||
3528 | roff[0] = -loff[0]; | |||
3529 | loff[0] = 0; | |||
3530 | } | |||
3531 | else roff[c] = 0; | |||
3532 | for (y=0; y < rasterP->height; y++) { | |||
3533 | outP = lineOutP; | |||
3534 | for (x=0; x < rasterP->width; x++, inP++) { | |||
3535 | *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c]; | |||
3536 | outP++; | |||
3537 | } | |||
3538 | lineOutP += rasterP->scanlineStride; | |||
3539 | } | |||
3540 | } | |||
3541 | ||||
3542 | (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT2); | |||
3543 | ||||
3544 | return 0; | |||
3545 | } | |||
3546 | ||||
3547 | /* This routine is expecting a ShortComponentRaster with a PackedColorModel */ | |||
3548 | static int setPackedSCR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
3549 | unsigned char *inDataP) | |||
3550 | { | |||
3551 | int x, y, c; | |||
3552 | unsigned char *inP = inDataP; | |||
3553 | unsigned short *lineOutP, *outP; | |||
3554 | jarray jOutDataP; | |||
3555 | jsize dataArrayLength; | |||
3556 | unsigned short *outDataP; | |||
3557 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3558 | ||||
3559 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3560 | return -1; | |||
3561 | } | |||
3562 | ||||
3563 | /* Grab data ptr, strides, offsets from raster */ | |||
3564 | jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID); | |||
3565 | if (JNU_IsNull(env, jOutDataP)((jOutDataP) == ((void*)0))) { | |||
3566 | return -1; | |||
3567 | } | |||
3568 | ||||
3569 | dataArrayLength = (*env)->GetArrayLength(env, jOutDataP); | |||
3570 | CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1)do { int offset = (rasterP->chanOffsets[0]); int lastScanOffset ; if (!((((rasterP->scanlineStride)) > 0) && (( (rasterP->height - 1)) >= 0) && ((0x7fffffff / ( (rasterP->scanlineStride))) > ((rasterP->height - 1) )))) { return (-2); } lastScanOffset = (rasterP->scanlineStride ) * (rasterP->height - 1); if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset )) > (lastScanOffset)))) { return (-2); } lastScanOffset += offset; if (!((((1)) > 0) && ((rasterP->width) >= 0) && ((0x7fffffff / ((1))) > (rasterP-> width)))) { return (-2); } offset = (1) * rasterP->width; if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { return ( -2); } lastScanOffset += offset; if (dataArrayLength < lastScanOffset ) { return (-2); } } while(0);; | |||
3571 | ||||
3572 | outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0); | |||
3573 | if (outDataP == NULL((void*)0)) { | |||
3574 | return -1; | |||
3575 | } | |||
3576 | lineOutP = outDataP + rasterP->chanOffsets[0]; | |||
3577 | ||||
3578 | if (component < 0) { | |||
3579 | for (c=0; c < rasterP->numBands; c++) { | |||
3580 | loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3581 | if (loff[c] < 0) { | |||
3582 | roff[c] = -loff[c]; | |||
3583 | loff[c] = 0; | |||
3584 | } | |||
3585 | else roff[c] = 0; | |||
3586 | } | |||
3587 | /* Convert the all bands */ | |||
3588 | for (y=0; y < rasterP->height; y++) { | |||
3589 | outP = lineOutP; | |||
3590 | for (x=0; x < rasterP->width; x++) { | |||
3591 | for (c=0; c < rasterP->numBands; c++, inP++) { | |||
3592 | /* Not correct. Might need to unpremult, shift, etc */ | |||
3593 | *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c]; | |||
3594 | } | |||
3595 | outP++; | |||
3596 | } | |||
3597 | lineOutP += rasterP->scanlineStride; | |||
3598 | } | |||
3599 | } | |||
3600 | else { | |||
3601 | c = component; | |||
3602 | loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3603 | if (loff[0] < 0) { | |||
3604 | roff[0] = -loff[0]; | |||
3605 | loff[0] = 0; | |||
3606 | } | |||
3607 | else roff[c] = 0; | |||
3608 | for (y=0; y < rasterP->height; y++) { | |||
3609 | outP = lineOutP; | |||
3610 | for (x=0; x < rasterP->width; x++, inP++) { | |||
3611 | *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c]; | |||
3612 | outP++; | |||
3613 | } | |||
3614 | lineOutP += rasterP->scanlineStride; | |||
3615 | } | |||
3616 | } | |||
3617 | ||||
3618 | (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT2); | |||
3619 | ||||
3620 | return 0; | |||
3621 | } | |||
3622 | ||||
3623 | /* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/ | |||
3624 | static int setPackedICR(JNIEnv *env, RasterS_t *rasterP, int component, | |||
3625 | unsigned char *inDataP) | |||
3626 | { | |||
3627 | int x, y, c; | |||
3628 | unsigned char *inP = inDataP; | |||
3629 | unsigned int *lineOutP, *outP; | |||
3630 | jarray jOutDataP; | |||
3631 | jsize dataArrayLength; | |||
3632 | unsigned int *outDataP; | |||
3633 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3634 | ||||
3635 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3636 | return -1; | |||
3637 | } | |||
3638 | ||||
3639 | /* Grab data ptr, strides, offsets from raster */ | |||
3640 | jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID); | |||
3641 | if (JNU_IsNull(env, jOutDataP)((jOutDataP) == ((void*)0))) { | |||
3642 | return -1; | |||
3643 | } | |||
3644 | ||||
3645 | dataArrayLength = (*env)->GetArrayLength(env, jOutDataP); | |||
3646 | CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1)do { int offset = (rasterP->chanOffsets[0]); int lastScanOffset ; if (!((((rasterP->scanlineStride)) > 0) && (( (rasterP->height - 1)) >= 0) && ((0x7fffffff / ( (rasterP->scanlineStride))) > ((rasterP->height - 1) )))) { return (-2); } lastScanOffset = (rasterP->scanlineStride ) * (rasterP->height - 1); if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset )) > (lastScanOffset)))) { return (-2); } lastScanOffset += offset; if (!((((1)) > 0) && ((rasterP->width) >= 0) && ((0x7fffffff / ((1))) > (rasterP-> width)))) { return (-2); } offset = (1) * rasterP->width; if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { return ( -2); } lastScanOffset += offset; if (dataArrayLength < lastScanOffset ) { return (-2); } } while(0);; | |||
3647 | ||||
3648 | outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0); | |||
3649 | if (outDataP == NULL((void*)0)) { | |||
3650 | return -1; | |||
3651 | } | |||
3652 | lineOutP = outDataP + rasterP->chanOffsets[0]; | |||
3653 | ||||
3654 | if (component < 0) { | |||
3655 | for (c=0; c < rasterP->numBands; c++) { | |||
3656 | loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3657 | if (loff[c] < 0) { | |||
3658 | roff[c] = -loff[c]; | |||
3659 | loff[c] = 0; | |||
3660 | } | |||
3661 | else roff[c] = 0; | |||
3662 | } | |||
3663 | /* Convert the all bands */ | |||
3664 | for (y=0; y < rasterP->height; y++) { | |||
3665 | outP = lineOutP; | |||
3666 | for (x=0; x < rasterP->width; x++) { | |||
3667 | for (c=0; c < rasterP->numBands; c++, inP++) { | |||
3668 | /* Not correct. Might need to unpremult, shift, etc */ | |||
3669 | *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c]; | |||
3670 | } | |||
3671 | outP++; | |||
3672 | } | |||
3673 | lineOutP += rasterP->scanlineStride; | |||
3674 | } | |||
3675 | } | |||
3676 | else { | |||
3677 | c = component; | |||
3678 | loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3679 | if (loff[0] < 0) { | |||
3680 | roff[0] = -loff[0]; | |||
3681 | loff[0] = 0; | |||
3682 | } | |||
3683 | else roff[c] = 0; | |||
3684 | ||||
3685 | for (y=0; y < rasterP->height; y++) { | |||
3686 | outP = lineOutP; | |||
3687 | for (x=0; x < rasterP->width; x++, inP++) { | |||
3688 | *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c]; | |||
3689 | outP++; | |||
3690 | } | |||
3691 | lineOutP += rasterP->scanlineStride; | |||
3692 | } | |||
3693 | } | |||
3694 | ||||
3695 | (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT2); | |||
3696 | ||||
3697 | return 0; | |||
3698 | } | |||
3699 | ||||
3700 | /* This routine is expecting a ByteComponentRaster with a PackedColorModel */ | |||
3701 | static int setPackedBCRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
3702 | int component, unsigned char *inDataP, | |||
3703 | int supportsAlpha) | |||
3704 | { | |||
3705 | int x, y, c; | |||
3706 | unsigned char *inP = inDataP; | |||
3707 | unsigned char *lineOutP, *outP; | |||
3708 | jarray jOutDataP; | |||
3709 | jsize dataArrayLength; | |||
3710 | unsigned char *outDataP; | |||
3711 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3712 | int a = rasterP->numBands - 1; | |||
3713 | ||||
3714 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3715 | return -1; | |||
3716 | } | |||
3717 | ||||
3718 | /* Grab data ptr, strides, offsets from raster */ | |||
3719 | jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID); | |||
3720 | if (JNU_IsNull(env, jOutDataP)((jOutDataP) == ((void*)0))) { | |||
3721 | return -1; | |||
3722 | } | |||
3723 | ||||
3724 | dataArrayLength = (*env)->GetArrayLength(env, jOutDataP); | |||
3725 | CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1)do { int offset = (rasterP->chanOffsets[0]); int lastScanOffset ; if (!((((rasterP->scanlineStride)) > 0) && (( (rasterP->height - 1)) >= 0) && ((0x7fffffff / ( (rasterP->scanlineStride))) > ((rasterP->height - 1) )))) { return (-2); } lastScanOffset = (rasterP->scanlineStride ) * (rasterP->height - 1); if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset )) > (lastScanOffset)))) { return (-2); } lastScanOffset += offset; if (!((((1)) > 0) && ((rasterP->width) >= 0) && ((0x7fffffff / ((1))) > (rasterP-> width)))) { return (-2); } offset = (1) * rasterP->width; if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { return ( -2); } lastScanOffset += offset; if (dataArrayLength < lastScanOffset ) { return (-2); } } while(0);; | |||
3726 | ||||
3727 | outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0); | |||
3728 | if (outDataP == NULL((void*)0)) { | |||
3729 | return -1; | |||
3730 | } | |||
3731 | lineOutP = outDataP + rasterP->chanOffsets[0]; | |||
3732 | ||||
3733 | if (component
| |||
3734 | for (c=0; c < rasterP->numBands; c++) { | |||
3735 | loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3736 | if (loff[c] < 0) { | |||
3737 | roff[c] = -loff[c]; | |||
3738 | loff[c] = 0; | |||
3739 | } | |||
3740 | else roff[c] = 0; | |||
3741 | } | |||
3742 | /* Convert the all bands */ | |||
3743 | if (supportsAlpha) { | |||
3744 | for (y=0; y < rasterP->height; y++) { | |||
3745 | outP = lineOutP; | |||
3746 | *outP = 0; | |||
3747 | for (x=0; x < rasterP->width; x++) { | |||
3748 | *outP |= (*inP<<loff[a]>>roff[a])& | |||
3749 | rasterP->sppsm.maskArray[a]; | |||
3750 | inP++; | |||
3751 | for (c=0; c < rasterP->numBands-1; c++, inP++) { | |||
3752 | *outP |= (*inP<<loff[c]>>roff[c])& | |||
| ||||
3753 | rasterP->sppsm.maskArray[c]; | |||
3754 | } | |||
3755 | outP++; | |||
3756 | } | |||
3757 | lineOutP += rasterP->scanlineStride; | |||
3758 | } | |||
3759 | } | |||
3760 | else { | |||
3761 | for (y=0; y < rasterP->height; y++) { | |||
3762 | outP = lineOutP; | |||
3763 | *outP = 0; | |||
3764 | for (x=0; x < rasterP->width; x++) { | |||
3765 | inP++; | |||
3766 | for (c=0; c < rasterP->numBands; c++, inP++) { | |||
3767 | *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c]; | |||
3768 | } | |||
3769 | outP++; | |||
3770 | } | |||
3771 | lineOutP += rasterP->scanlineStride; | |||
3772 | } | |||
3773 | } | |||
3774 | } | |||
3775 | else { | |||
3776 | c = component; | |||
3777 | loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3778 | if (loff[0] < 0) { | |||
3779 | roff[0] = -loff[0]; | |||
3780 | loff[0] = 0; | |||
3781 | } | |||
3782 | else roff[c] = 0; | |||
3783 | for (y=0; y < rasterP->height; y++) { | |||
3784 | outP = lineOutP; | |||
3785 | for (x=0; x < rasterP->width; x++, inP++) { | |||
3786 | *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c]; | |||
3787 | outP++; | |||
3788 | } | |||
3789 | lineOutP += rasterP->scanlineStride; | |||
3790 | } | |||
3791 | } | |||
3792 | ||||
3793 | (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT2); | |||
3794 | ||||
3795 | return 0; | |||
3796 | } | |||
3797 | ||||
3798 | /* This routine is expecting a ShortComponentRaster with a PackedColorModel */ | |||
3799 | static int setPackedSCRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
3800 | int component, unsigned char *inDataP, | |||
3801 | int supportsAlpha) | |||
3802 | { | |||
3803 | int x, y, c; | |||
3804 | unsigned char *inP = inDataP; | |||
3805 | unsigned short *lineOutP, *outP; | |||
3806 | jarray jOutDataP; | |||
3807 | jsize dataArrayLength; | |||
3808 | unsigned short *outDataP; | |||
3809 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3810 | int a = rasterP->numBands - 1; | |||
3811 | ||||
3812 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3813 | return -1; | |||
3814 | } | |||
3815 | ||||
3816 | /* Grab data ptr, strides, offsets from raster */ | |||
3817 | jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID); | |||
3818 | if (JNU_IsNull(env, jOutDataP)((jOutDataP) == ((void*)0))) { | |||
3819 | return -1; | |||
3820 | } | |||
3821 | dataArrayLength = (*env)->GetArrayLength(env, jOutDataP); | |||
3822 | CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1)do { int offset = (rasterP->chanOffsets[0]); int lastScanOffset ; if (!((((rasterP->scanlineStride)) > 0) && (( (rasterP->height - 1)) >= 0) && ((0x7fffffff / ( (rasterP->scanlineStride))) > ((rasterP->height - 1) )))) { return (-2); } lastScanOffset = (rasterP->scanlineStride ) * (rasterP->height - 1); if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset )) > (lastScanOffset)))) { return (-2); } lastScanOffset += offset; if (!((((1)) > 0) && ((rasterP->width) >= 0) && ((0x7fffffff / ((1))) > (rasterP-> width)))) { return (-2); } offset = (1) * rasterP->width; if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { return ( -2); } lastScanOffset += offset; if (dataArrayLength < lastScanOffset ) { return (-2); } } while(0);; | |||
3823 | ||||
3824 | outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0); | |||
3825 | if (outDataP == NULL((void*)0)) { | |||
3826 | return -1; | |||
3827 | } | |||
3828 | lineOutP = outDataP + rasterP->chanOffsets[0]; | |||
3829 | ||||
3830 | if (component < 0) { | |||
3831 | for (c=0; c < rasterP->numBands; c++) { | |||
3832 | loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3833 | if (loff[c] < 0) { | |||
3834 | roff[c] = -loff[c]; | |||
3835 | loff[c] = 0; | |||
3836 | } | |||
3837 | else roff[c] = 0; | |||
3838 | } | |||
3839 | /* Convert the all bands */ | |||
3840 | if (supportsAlpha) { | |||
3841 | for (y=0; y < rasterP->height; y++) { | |||
3842 | outP = lineOutP; | |||
3843 | for (x=0; x < rasterP->width; x++) { | |||
3844 | *outP |= (*inP<<loff[a]>>roff[a])& | |||
3845 | rasterP->sppsm.maskArray[a]; | |||
3846 | inP++; | |||
3847 | for (c=0; c < rasterP->numBands-1; c++, inP++) { | |||
3848 | /* Not correct. Might need to unpremult, shift, etc */ | |||
3849 | *outP |= (*inP<<loff[c]>>roff[c])& | |||
3850 | rasterP->sppsm.maskArray[c]; | |||
3851 | } | |||
3852 | outP++; | |||
3853 | } | |||
3854 | lineOutP += rasterP->scanlineStride; | |||
3855 | } | |||
3856 | } | |||
3857 | else { | |||
3858 | for (y=0; y < rasterP->height; y++) { | |||
3859 | outP = lineOutP; | |||
3860 | for (x=0; x < rasterP->width; x++) { | |||
3861 | inP++; | |||
3862 | for (c=0; c < rasterP->numBands; c++, inP++) { | |||
3863 | /* Not correct. Might need to unpremult, shift, etc */ | |||
3864 | *outP |= (*inP<<loff[c]>>roff[c])&rasterP->sppsm.maskArray[c]; | |||
3865 | } | |||
3866 | outP++; | |||
3867 | } | |||
3868 | lineOutP += rasterP->scanlineStride; | |||
3869 | } | |||
3870 | } | |||
3871 | } | |||
3872 | else { | |||
3873 | c = component; | |||
3874 | loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3875 | if (loff[0] < 0) { | |||
3876 | roff[0] = -loff[0]; | |||
3877 | loff[0] = 0; | |||
3878 | } | |||
3879 | else roff[c] = 0; | |||
3880 | for (y=0; y < rasterP->height; y++) { | |||
3881 | outP = lineOutP; | |||
3882 | for (x=0; x < rasterP->width; x++, inP++) { | |||
3883 | *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c]; | |||
3884 | outP++; | |||
3885 | } | |||
3886 | lineOutP += rasterP->scanlineStride; | |||
3887 | } | |||
3888 | } | |||
3889 | ||||
3890 | (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT2); | |||
3891 | ||||
3892 | return 0; | |||
3893 | } | |||
3894 | ||||
3895 | /* This routine is expecting a IntegerComponentRaster with a PackedColorModel*/ | |||
3896 | static int setPackedICRdefault(JNIEnv *env, RasterS_t *rasterP, | |||
3897 | int component, unsigned char *inDataP, | |||
3898 | int supportsAlpha) | |||
3899 | { | |||
3900 | int x, y, c; | |||
3901 | unsigned char *inP = inDataP; | |||
3902 | unsigned int *lineOutP, *outP; | |||
3903 | jarray jOutDataP; | |||
3904 | jsize dataArrayLength; | |||
3905 | unsigned int *outDataP; | |||
3906 | int loff[MAX_NUMBANDS32], roff[MAX_NUMBANDS32]; | |||
3907 | int a = rasterP->numBands - 1; | |||
3908 | ||||
3909 | if (rasterP->numBands > MAX_NUMBANDS32) { | |||
3910 | return -1; | |||
3911 | } | |||
3912 | ||||
3913 | /* Grab data ptr, strides, offsets from raster */ | |||
3914 | jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID); | |||
3915 | if (JNU_IsNull(env, jOutDataP)((jOutDataP) == ((void*)0))) { | |||
3916 | return -1; | |||
3917 | } | |||
3918 | ||||
3919 | dataArrayLength = (*env)->GetArrayLength(env, jOutDataP); | |||
3920 | CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1)do { int offset = (rasterP->chanOffsets[0]); int lastScanOffset ; if (!((((rasterP->scanlineStride)) > 0) && (( (rasterP->height - 1)) >= 0) && ((0x7fffffff / ( (rasterP->scanlineStride))) > ((rasterP->height - 1) )))) { return (-2); } lastScanOffset = (rasterP->scanlineStride ) * (rasterP->height - 1); if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset )) > (lastScanOffset)))) { return (-2); } lastScanOffset += offset; if (!((((1)) > 0) && ((rasterP->width) >= 0) && ((0x7fffffff / ((1))) > (rasterP-> width)))) { return (-2); } offset = (1) * rasterP->width; if (!(((offset) >= 0) && ((lastScanOffset) >= 0) && ((0x7fffffff - (offset)) > (lastScanOffset)))) { return ( -2); } lastScanOffset += offset; if (dataArrayLength < lastScanOffset ) { return (-2); } } while(0);; | |||
3921 | ||||
3922 | outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0); | |||
3923 | if (outDataP == NULL((void*)0)) { | |||
3924 | return -1; | |||
3925 | } | |||
3926 | lineOutP = outDataP + rasterP->chanOffsets[0]; | |||
3927 | ||||
3928 | if (component < 0) { | |||
3929 | for (c=0; c < rasterP->numBands; c++) { | |||
3930 | loff[c] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3931 | if (loff[c] < 0) { | |||
3932 | roff[c] = -loff[c]; | |||
3933 | loff[c] = 0; | |||
3934 | } | |||
3935 | else roff[c] = 0; | |||
3936 | } | |||
3937 | /* Convert the all bands */ | |||
3938 | if (supportsAlpha) { | |||
3939 | for (y=0; y < rasterP->height; y++) { | |||
3940 | outP = lineOutP; | |||
3941 | for (x=0; x < rasterP->width; x++) { | |||
3942 | *outP |= (*inP<<loff[a]>>roff[a])& | |||
3943 | rasterP->sppsm.maskArray[a]; | |||
3944 | inP++; | |||
3945 | for (c=0; c < rasterP->numBands-1; c++, inP++) { | |||
3946 | /* Not correct. Might need to unpremult, shift, etc */ | |||
3947 | *outP |= (*inP<<loff[c]>>roff[c])& | |||
3948 | rasterP->sppsm.maskArray[c]; | |||
3949 | } | |||
3950 | outP++; | |||
3951 | } | |||
3952 | lineOutP += rasterP->scanlineStride; | |||
3953 | } | |||
3954 | } | |||
3955 | else { | |||
3956 | for (y=0; y < rasterP->height; y++) { | |||
3957 | outP = lineOutP; | |||
3958 | for (x=0; x < rasterP->width; x++) { | |||
3959 | inP++; | |||
3960 | for (c=0; c < rasterP->numBands; c++, inP++) { | |||
3961 | /* Not correct. Might need to unpremult, shift, etc */ | |||
3962 | *outP |= (*inP<<loff[c]>>roff[c])& | |||
3963 | rasterP->sppsm.maskArray[c]; | |||
3964 | } | |||
3965 | outP++; | |||
3966 | } | |||
3967 | lineOutP += rasterP->scanlineStride; | |||
3968 | } | |||
3969 | } | |||
3970 | } | |||
3971 | else { | |||
3972 | c = component; | |||
3973 | loff[0] = rasterP->sppsm.offsets[c] + (rasterP->sppsm.nBits[c]-8); | |||
3974 | if (loff[0] < 0) { | |||
3975 | roff[0] = -loff[0]; | |||
3976 | loff[0] = 0; | |||
3977 | } | |||
3978 | else roff[c] = 0; | |||
3979 | ||||
3980 | for (y=0; y < rasterP->height; y++) { | |||
3981 | outP = lineOutP; | |||
3982 | for (x=0; x < rasterP->width; x++, inP++) { | |||
3983 | *outP |= (*inP<<loff[0]>>roff[0])&rasterP->sppsm.maskArray[c]; | |||
3984 | outP++; | |||
3985 | } | |||
3986 | lineOutP += rasterP->scanlineStride; | |||
3987 | } | |||
3988 | } | |||
3989 | ||||
3990 | (*env)->ReleasePrimitiveArrayCritical(env, jOutDataP, outDataP, JNI_ABORT2); | |||
3991 | ||||
3992 | return 0; | |||
3993 | } | |||
3994 | ||||
3995 | /* This is temporary code. Should go away when there is better color | |||
3996 | * conversion code available. | |||
3997 | * REMIND: Ignoring alpha | |||
3998 | */ | |||
3999 | /* returns the absolute value x */ | |||
4000 | #define ABS(x)((x) < 0 ? -(x) : (x)) ((x) < 0 ? -(x) : (x)) | |||
4001 | #define CLIP(val,min,max)((val < min) ? min : ((val > max) ? max : val)) ((val < min) ? min : ((val > max) ? max : val)) | |||
4002 | ||||
4003 | static int | |||
4004 | colorMatch(int r, int g, int b, int a, unsigned char *argb, int numColors) { | |||
4005 | int besti = 0; | |||
4006 | int mindist, i, t, d; | |||
4007 | unsigned char red, green, blue; | |||
4008 | ||||
4009 | r = CLIP(r, 0, 255)((r < 0) ? 0 : ((r > 255) ? 255 : r)); | |||
4010 | g = CLIP(g, 0, 255)((g < 0) ? 0 : ((g > 255) ? 255 : g)); | |||
4011 | b = CLIP(b, 0, 255)((b < 0) ? 0 : ((b > 255) ? 255 : b)); | |||
4012 | ||||
4013 | /* look for pure gray match */ | |||
4014 | if ((r == g) && (g == b)) { | |||
4015 | mindist = 256; | |||
4016 | for (i = 0 ; i < numColors ; i++, argb+=4) { | |||
4017 | red = argb[1]; | |||
4018 | green = argb[2]; | |||
4019 | blue = argb[3]; | |||
4020 | if (! ((red == green) && (green == blue)) ) { | |||
4021 | continue; | |||
4022 | } | |||
4023 | d = ABS(red - r)((red - r) < 0 ? -(red - r) : (red - r)); | |||
4024 | if (d == 0) | |||
4025 | return i; | |||
4026 | if (d < mindist) { | |||
4027 | besti = i; | |||
4028 | mindist = d; | |||
4029 | } | |||
4030 | } | |||
4031 | return besti; | |||
4032 | } | |||
4033 | ||||
4034 | /* look for non-pure gray match */ | |||
4035 | mindist = 256 * 256 * 256; | |||
4036 | for (i = 0 ; i < numColors ; i++, argb+=4) { | |||
4037 | red = argb[1]; | |||
4038 | green = argb[2]; | |||
4039 | blue = argb[3]; | |||
4040 | t = red - r; | |||
4041 | d = t * t; | |||
4042 | if (d >= mindist) { | |||
4043 | continue; | |||
4044 | } | |||
4045 | t = green - g; | |||
4046 | d += t * t; | |||
4047 | if (d >= mindist) { | |||
4048 | continue; | |||
4049 | } | |||
4050 | t = blue - b; | |||
4051 | d += t * t; | |||
4052 | if (d >= mindist) { | |||
4053 | continue; | |||
4054 | } | |||
4055 | if (d == 0) | |||
4056 | return i; | |||
4057 | if (d < mindist) { | |||
4058 | besti = i; | |||
4059 | mindist = d; | |||
4060 | } | |||
4061 | } | |||
4062 | ||||
4063 | return besti; | |||
4064 | } |