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