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