100 jobject jobj;
101 jlong j;
102 } storeID_t, *storeID_p;
103
104 typedef union {
105 cmsTagSignature cms;
106 jint j;
107 } TagSignature_t, *TagSignature_p;
108
109 static jfieldID Trans_profileIDs_fID;
110 static jfieldID Trans_renderType_fID;
111 static jfieldID Trans_ID_fID;
112 static jfieldID IL_isIntPacked_fID;
113 static jfieldID IL_dataType_fID;
114 static jfieldID IL_pixelType_fID;
115 static jfieldID IL_dataArray_fID;
116 static jfieldID IL_offset_fID;
117 static jfieldID IL_nextRowOffset_fID;
118 static jfieldID IL_width_fID;
119 static jfieldID IL_height_fID;
120 static jfieldID PF_ID_fID;
121
122 JavaVM *javaVM;
123
124 void errorHandler(cmsContext ContextID, cmsUInt32Number errorCode,
125 const char *errorText) {
126 JNIEnv *env;
127 char errMsg[ERR_MSG_SIZE];
128
129 int count = snprintf(errMsg, ERR_MSG_SIZE,
130 "LCMS error %d: %s", errorCode, errorText);
131 if (count < 0 || count >= ERR_MSG_SIZE) {
132 count = ERR_MSG_SIZE - 1;
133 }
134 errMsg[count] = 0;
135
136 (*javaVM)->AttachCurrentThread(javaVM, (void**)&env, NULL);
137 JNU_ThrowByName(env, "java/awt/color/CMMException", errMsg);
138 }
139
220 J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
221 "sTrans.xf == NULL");
222 JNU_ThrowByName(env, "java/awt/color/CMMException",
223 "Cannot get color transform");
224 } else {
225 Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j);
226 }
227
228 if (iccArray != &_iccArray[0]) {
229 free(iccArray);
230 }
231 return sTrans.j;
232 }
233
234
235 /*
236 * Class: sun_java2d_cmm_lcms_LCMS
237 * Method: loadProfile
238 * Signature: ([B)J
239 */
240 JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfile
241 (JNIEnv *env, jobject obj, jbyteArray data)
242 {
243 jbyte* dataArray;
244 jint dataSize;
245 storeID_t sProf;
246
247 if (JNU_IsNull(env, data)) {
248 JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
249 return 0L;
250 }
251
252 dataArray = (*env)->GetByteArrayElements (env, data, 0);
253 dataSize = (*env)->GetArrayLength (env, data);
254
255 if (dataArray == NULL) {
256 JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
257 return 0L;
258 }
259
260 sProf.pf = cmsOpenProfileFromMem((const void *)dataArray,
267 } else {
268 /* Sanity check: try to save the profile in order
269 * to force basic validation.
270 */
271 cmsUInt32Number pfSize = 0;
272 if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) ||
273 pfSize < sizeof(cmsICCHeader))
274 {
275 JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
276 }
277 }
278
279 return sProf.j;
280 }
281
282 /*
283 * Class: sun_java2d_cmm_lcms_LCMS
284 * Method: freeProfile
285 * Signature: (J)V
286 */
287 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfile
288 (JNIEnv *env, jobject obj, jlong id)
289 {
290 storeID_t sProf;
291
292 sProf.j = id;
293 if (cmsCloseProfile(sProf.pf) == 0) {
294 J2dRlsTraceLn1(J2D_TRACE_ERROR, "LCMS_freeProfile: cmsCloseProfile(%d)"
295 "== 0", id);
296 JNU_ThrowByName(env, "java/awt/color/CMMException",
297 "Cannot close profile");
298 }
299
300 }
301
302 /*
303 * Class: sun_java2d_cmm_lcms_LCMS
304 * Method: getProfileSize
305 * Signature: (J)I
306 */
307 JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize
352 }
353
354 dataArray = (*env)->GetByteArrayElements (env, data, 0);
355
356 status = cmsSaveProfileToMem(sProf.pf, dataArray, &pfSize);
357
358 (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
359
360 if (!status) {
361 JNU_ThrowByName(env, "java/awt/color/CMMException",
362 "Can not access specified profile.");
363 return;
364 }
365 }
366
367 /* Get profile header info */
368 static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
369 static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
370 static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
371
372 /*
373 * Class: sun_java2d_cmm_lcms_LCMS
374 * Method: getTagSize
375 * Signature: (JI)I
376 */
377 JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagSize
378 (JNIEnv *env, jobject obj, jlong id, jint tagSig)
379 {
380 storeID_t sProf;
381 TagSignature_t sig;
382 jint result = -1;
383
384 sProf.j = id;
385 sig.j = tagSig;
386
387 if (tagSig == SigHead) {
388 result = sizeof(cmsICCHeader);
389 } else {
390 if (cmsIsTag(sProf.pf, sig.cms)) {
391 result = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
392 } else {
393 JNU_ThrowByName(env, "java/awt/color/CMMException",
394 "ICC profile tag not found");
395 }
396 }
397
398 return result;
399 }
400
401 /*
402 * Class: sun_java2d_cmm_lcms_LCMS
403 * Method: getTagData
404 * Signature: (JI[B)V
405 */
406 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData
407 (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
408 {
409 storeID_t sProf;
410 TagSignature_t sig;
411 cmsInt32Number tagSize;
412
413 jbyte* dataArray;
414 jint bufSize;
415
416 sProf.j = id;
417 sig.j = tagSig;
418
419 if (tagSig == SigHead) {
420 cmsBool status;
421
422 bufSize =(*env)->GetArrayLength(env, data);
423
424 if (bufSize < sizeof(cmsICCHeader)) {
425 JNU_ThrowByName(env, "java/awt/color/CMMException",
426 "Insufficient buffer capacity");
427 return;
428 }
429
430 dataArray = (*env)->GetByteArrayElements (env, data, 0);
431
432 if (dataArray == NULL) {
433 JNU_ThrowByName(env, "java/awt/color/CMMException",
434 "Unable to get buffer");
435 return;
436 }
437
438 status = _getHeaderInfo(sProf.pf, dataArray, bufSize);
439
440 (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
441
442 if (!status) {
443 JNU_ThrowByName(env, "java/awt/color/CMMException",
444 "ICC Profile header not found");
445 }
446
447 return;
448 }
449
450 if (cmsIsTag(sProf.pf, sig.cms)) {
451 tagSize = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
452 } else {
453 JNU_ThrowByName(env, "java/awt/color/CMMException",
454 "ICC profile tag not found");
455 return;
456 }
457
458 // verify data buffer capacity
459 bufSize = (*env)->GetArrayLength(env, data);
460
461 if (tagSize < 0 || 0 > bufSize || tagSize > bufSize) {
462 JNU_ThrowByName(env, "java/awt/color/CMMException",
463 "Insufficient buffer capacity.");
464 return;
465 }
466
467 dataArray = (*env)->GetByteArrayElements (env, data, 0);
468
469 if (dataArray == NULL) {
470 JNU_ThrowByName(env, "java/awt/color/CMMException",
471 "Unable to get buffer");
472 return;
473 }
474
475 bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize);
476
477 (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
478
479 if (bufSize != tagSize) {
480 JNU_ThrowByName(env, "java/awt/color/CMMException",
481 "Can not get tag data.");
482 }
483 return;
484 }
485
486 /*
487 * Class: sun_java2d_cmm_lcms_LCMS
488 * Method: setTagData
489 * Signature: (JI[B)V
490 */
491 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagData
492 (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
493 {
494 storeID_t sProf;
495 TagSignature_t sig;
496 cmsBool status;
497 jbyte* dataArray;
498 int tagSize;
499
500 sProf.j = id;
501 sig.j = tagSig;
502
503 if (JNU_IsNull(env, data)) {
504 JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
505 return;
506 }
507
508 tagSize =(*env)->GetArrayLength(env, data);
509
510 dataArray = (*env)->GetByteArrayElements(env, data, 0);
511
569 }
570 }
571
572 /*
573 * Class: sun_java2d_cmm_lcms_LCMS
574 * Method: colorConvert
575 * Signature: (Lsun/java2d/cmm/lcms/LCMSTransform;Lsun/java2d/cmm/lcms/LCMSImageLayout;Lsun/java2d/cmm/lcms/LCMSImageLayout;)V
576 */
577 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
578 (JNIEnv *env, jclass obj, jobject trans, jobject src, jobject dst)
579 {
580 storeID_t sTrans;
581 int srcDType, dstDType;
582 int srcOffset, srcNextRowOffset, dstOffset, dstNextRowOffset;
583 int width, height, i;
584 void* inputBuffer;
585 void* outputBuffer;
586 char* inputRow;
587 char* outputRow;
588 jobject srcData, dstData;
589
590 srcOffset = (*env)->GetIntField (env, src, IL_offset_fID);
591 srcNextRowOffset = (*env)->GetIntField (env, src, IL_nextRowOffset_fID);
592 dstOffset = (*env)->GetIntField (env, dst, IL_offset_fID);
593 dstNextRowOffset = (*env)->GetIntField (env, dst, IL_nextRowOffset_fID);
594 width = (*env)->GetIntField (env, src, IL_width_fID);
595 height = (*env)->GetIntField (env, src, IL_height_fID);
596
597 sTrans.j = (*env)->GetLongField (env, trans, Trans_ID_fID);
598
599 if (sTrans.xf == NULL) {
600 J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_colorConvert: transform == NULL");
601 JNU_ThrowByName(env, "java/awt/color/CMMException",
602 "Cannot get color transform");
603 return;
604 }
605
606
607 inputBuffer = getILData (env, src, &srcDType, &srcData);
608
609 if (inputBuffer == NULL) {
610 J2dRlsTraceLn(J2D_TRACE_ERROR, "");
611 JNU_ThrowByName(env, "java/awt/color/CMMException",
612 "Cannot get input data");
613 return;
614 }
615
616 outputBuffer = getILData (env, dst, &dstDType, &dstData);
617
618 if (outputBuffer == NULL) {
619 releaseILData(env, inputBuffer, srcDType, srcData);
620 JNU_ThrowByName(env, "java/awt/color/CMMException",
621 "Cannot get output data");
622 return;
623 }
624
625 inputRow = (char*)inputBuffer + srcOffset;
626 outputRow = (char*)outputBuffer + dstOffset;
627
628 for (i = 0; i < height; i++) {
629 cmsDoTransform(sTrans.xf, inputRow, outputRow, width);
630 inputRow += srcNextRowOffset;
631 outputRow += dstNextRowOffset;
632 }
633
634 releaseILData(env, inputBuffer, srcDType, srcData);
635 releaseILData(env, outputBuffer, dstDType, dstData);
636 }
637
638 /*
639 * Class: sun_java2d_cmm_lcms_LCMS
640 * Method: getProfileID
641 * Signature: (Ljava/awt/color/ICC_Profile;)J
642 */
643 JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
644 (JNIEnv *env, jclass cls, jobject pf)
645 {
646 return (*env)->GetLongField (env, pf, PF_ID_fID);
647 }
648
649 /*
650 * Class: sun_java2d_cmm_lcms_LCMS
651 * Method: initLCMS
652 * Signature: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;)V
653 */
654 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
655 (JNIEnv *env, jclass cls, jclass Trans, jclass IL, jclass Pf)
656 {
657 /* TODO: move initialization of the IDs to the static blocks of
658 * corresponding classes to avoid problems with invalidating ids by class
659 * unloading
660 */
661 Trans_profileIDs_fID = (*env)->GetFieldID (env, Trans, "profileIDs", "[J");
662 Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
663 Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J");
664
665 IL_isIntPacked_fID = (*env)->GetFieldID (env, IL, "isIntPacked", "Z");
666 IL_dataType_fID = (*env)->GetFieldID (env, IL, "dataType", "I");
667 IL_pixelType_fID = (*env)->GetFieldID (env, IL, "pixelType", "I");
668 IL_dataArray_fID = (*env)->GetFieldID(env, IL, "dataArray",
669 "Ljava/lang/Object;");
670 IL_width_fID = (*env)->GetFieldID (env, IL, "width", "I");
671 IL_height_fID = (*env)->GetFieldID (env, IL, "height", "I");
672 IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
673 IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
674
675 PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
676 }
677
678 static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
679 {
680 cmsUInt32Number pfSize = 0;
681 cmsUInt8Number* pfBuffer = NULL;
682 cmsBool status = FALSE;
683
684 if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
685 pfSize < sizeof(cmsICCHeader) ||
686 bufferSize < sizeof(cmsICCHeader))
687 {
688 return FALSE;
689 }
690
691 pfBuffer = malloc(pfSize);
692 if (pfBuffer == NULL) {
|
100 jobject jobj;
101 jlong j;
102 } storeID_t, *storeID_p;
103
104 typedef union {
105 cmsTagSignature cms;
106 jint j;
107 } TagSignature_t, *TagSignature_p;
108
109 static jfieldID Trans_profileIDs_fID;
110 static jfieldID Trans_renderType_fID;
111 static jfieldID Trans_ID_fID;
112 static jfieldID IL_isIntPacked_fID;
113 static jfieldID IL_dataType_fID;
114 static jfieldID IL_pixelType_fID;
115 static jfieldID IL_dataArray_fID;
116 static jfieldID IL_offset_fID;
117 static jfieldID IL_nextRowOffset_fID;
118 static jfieldID IL_width_fID;
119 static jfieldID IL_height_fID;
120 static jfieldID IL_imageAtOnce_fID;
121 static jfieldID PF_ID_fID;
122
123 JavaVM *javaVM;
124
125 void errorHandler(cmsContext ContextID, cmsUInt32Number errorCode,
126 const char *errorText) {
127 JNIEnv *env;
128 char errMsg[ERR_MSG_SIZE];
129
130 int count = snprintf(errMsg, ERR_MSG_SIZE,
131 "LCMS error %d: %s", errorCode, errorText);
132 if (count < 0 || count >= ERR_MSG_SIZE) {
133 count = ERR_MSG_SIZE - 1;
134 }
135 errMsg[count] = 0;
136
137 (*javaVM)->AttachCurrentThread(javaVM, (void**)&env, NULL);
138 JNU_ThrowByName(env, "java/awt/color/CMMException", errMsg);
139 }
140
221 J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
222 "sTrans.xf == NULL");
223 JNU_ThrowByName(env, "java/awt/color/CMMException",
224 "Cannot get color transform");
225 } else {
226 Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j);
227 }
228
229 if (iccArray != &_iccArray[0]) {
230 free(iccArray);
231 }
232 return sTrans.j;
233 }
234
235
236 /*
237 * Class: sun_java2d_cmm_lcms_LCMS
238 * Method: loadProfile
239 * Signature: ([B)J
240 */
241 JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
242 (JNIEnv *env, jobject obj, jbyteArray data)
243 {
244 jbyte* dataArray;
245 jint dataSize;
246 storeID_t sProf;
247
248 if (JNU_IsNull(env, data)) {
249 JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
250 return 0L;
251 }
252
253 dataArray = (*env)->GetByteArrayElements (env, data, 0);
254 dataSize = (*env)->GetArrayLength (env, data);
255
256 if (dataArray == NULL) {
257 JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
258 return 0L;
259 }
260
261 sProf.pf = cmsOpenProfileFromMem((const void *)dataArray,
268 } else {
269 /* Sanity check: try to save the profile in order
270 * to force basic validation.
271 */
272 cmsUInt32Number pfSize = 0;
273 if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) ||
274 pfSize < sizeof(cmsICCHeader))
275 {
276 JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
277 }
278 }
279
280 return sProf.j;
281 }
282
283 /*
284 * Class: sun_java2d_cmm_lcms_LCMS
285 * Method: freeProfile
286 * Signature: (J)V
287 */
288 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative
289 (JNIEnv *env, jobject obj, jlong id)
290 {
291 storeID_t sProf;
292
293 sProf.j = id;
294 if (cmsCloseProfile(sProf.pf) == 0) {
295 J2dRlsTraceLn1(J2D_TRACE_ERROR, "LCMS_freeProfile: cmsCloseProfile(%d)"
296 "== 0", id);
297 JNU_ThrowByName(env, "java/awt/color/CMMException",
298 "Cannot close profile");
299 }
300
301 }
302
303 /*
304 * Class: sun_java2d_cmm_lcms_LCMS
305 * Method: getProfileSize
306 * Signature: (J)I
307 */
308 JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize
353 }
354
355 dataArray = (*env)->GetByteArrayElements (env, data, 0);
356
357 status = cmsSaveProfileToMem(sProf.pf, dataArray, &pfSize);
358
359 (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
360
361 if (!status) {
362 JNU_ThrowByName(env, "java/awt/color/CMMException",
363 "Can not access specified profile.");
364 return;
365 }
366 }
367
368 /* Get profile header info */
369 static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
370 static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
371 static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
372
373
374 /*
375 * Class: sun_java2d_cmm_lcms_LCMS
376 * Method: getTagData
377 * Signature: (JI[B)V
378 */
379 JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
380 (JNIEnv *env, jobject obj, jlong id, jint tagSig)
381 {
382 storeID_t sProf;
383 TagSignature_t sig;
384 cmsInt32Number tagSize;
385
386 jbyte* dataArray = NULL;
387 jbyteArray data = NULL;
388
389 jint bufSize;
390
391 sProf.j = id;
392 sig.j = tagSig;
393
394 if (tagSig == SigHead) {
395 cmsBool status;
396
397 // allocate java array
398 bufSize = sizeof(cmsICCHeader);
399 data = (*env)->NewByteArray(env, bufSize);
400
401 if (data == NULL) {
402 JNU_ThrowByName(env, "java/awt/color/CMMException",
403 "Unable to allocate buffer");
404 return NULL;
405 }
406
407 dataArray = (*env)->GetByteArrayElements (env, data, 0);
408
409 if (dataArray == NULL) {
410 JNU_ThrowByName(env, "java/awt/color/CMMException",
411 "Unable to get buffer");
412 return NULL;
413 }
414
415 status = _getHeaderInfo(sProf.pf, dataArray, bufSize);
416
417 (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
418
419 if (!status) {
420 JNU_ThrowByName(env, "java/awt/color/CMMException",
421 "ICC Profile header not found");
422 return NULL;
423 }
424
425 return data;
426 }
427
428 if (cmsIsTag(sProf.pf, sig.cms)) {
429 tagSize = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
430 } else {
431 JNU_ThrowByName(env, "java/awt/color/CMMException",
432 "ICC profile tag not found");
433 return NULL;
434 }
435
436 // allocate java array
437 data = (*env)->NewByteArray(env, tagSize);
438 if (data == NULL) {
439 JNU_ThrowByName(env, "java/awt/color/CMMException",
440 "Unable to allocate buffer");
441 return NULL;
442 }
443
444 dataArray = (*env)->GetByteArrayElements (env, data, 0);
445
446 if (dataArray == NULL) {
447 JNU_ThrowByName(env, "java/awt/color/CMMException",
448 "Unable to get buffer");
449 return NULL;
450 }
451
452 bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize);
453
454 (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
455
456 if (bufSize != tagSize) {
457 JNU_ThrowByName(env, "java/awt/color/CMMException",
458 "Can not get tag data.");
459 return NULL;
460 }
461 return data;
462 }
463
464 /*
465 * Class: sun_java2d_cmm_lcms_LCMS
466 * Method: setTagData
467 * Signature: (JI[B)V
468 */
469 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
470 (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
471 {
472 storeID_t sProf;
473 TagSignature_t sig;
474 cmsBool status;
475 jbyte* dataArray;
476 int tagSize;
477
478 sProf.j = id;
479 sig.j = tagSig;
480
481 if (JNU_IsNull(env, data)) {
482 JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
483 return;
484 }
485
486 tagSize =(*env)->GetArrayLength(env, data);
487
488 dataArray = (*env)->GetByteArrayElements(env, data, 0);
489
547 }
548 }
549
550 /*
551 * Class: sun_java2d_cmm_lcms_LCMS
552 * Method: colorConvert
553 * Signature: (Lsun/java2d/cmm/lcms/LCMSTransform;Lsun/java2d/cmm/lcms/LCMSImageLayout;Lsun/java2d/cmm/lcms/LCMSImageLayout;)V
554 */
555 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
556 (JNIEnv *env, jclass obj, jobject trans, jobject src, jobject dst)
557 {
558 storeID_t sTrans;
559 int srcDType, dstDType;
560 int srcOffset, srcNextRowOffset, dstOffset, dstNextRowOffset;
561 int width, height, i;
562 void* inputBuffer;
563 void* outputBuffer;
564 char* inputRow;
565 char* outputRow;
566 jobject srcData, dstData;
567 jboolean srcAtOnce = JNI_FALSE, dstAtOnce = JNI_FALSE;
568
569 srcOffset = (*env)->GetIntField (env, src, IL_offset_fID);
570 srcNextRowOffset = (*env)->GetIntField (env, src, IL_nextRowOffset_fID);
571 dstOffset = (*env)->GetIntField (env, dst, IL_offset_fID);
572 dstNextRowOffset = (*env)->GetIntField (env, dst, IL_nextRowOffset_fID);
573 width = (*env)->GetIntField (env, src, IL_width_fID);
574 height = (*env)->GetIntField (env, src, IL_height_fID);
575
576 srcAtOnce = (*env)->GetBooleanField(env, src, IL_imageAtOnce_fID);
577 dstAtOnce = (*env)->GetBooleanField(env, dst, IL_imageAtOnce_fID);
578
579 sTrans.j = (*env)->GetLongField (env, trans, Trans_ID_fID);
580
581 if (sTrans.xf == NULL) {
582 J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_colorConvert: transform == NULL");
583 JNU_ThrowByName(env, "java/awt/color/CMMException",
584 "Cannot get color transform");
585 return;
586 }
587
588
589 inputBuffer = getILData (env, src, &srcDType, &srcData);
590
591 if (inputBuffer == NULL) {
592 J2dRlsTraceLn(J2D_TRACE_ERROR, "");
593 JNU_ThrowByName(env, "java/awt/color/CMMException",
594 "Cannot get input data");
595 return;
596 }
597
598 outputBuffer = getILData (env, dst, &dstDType, &dstData);
599
600 if (outputBuffer == NULL) {
601 releaseILData(env, inputBuffer, srcDType, srcData);
602 JNU_ThrowByName(env, "java/awt/color/CMMException",
603 "Cannot get output data");
604 return;
605 }
606
607 inputRow = (char*)inputBuffer + srcOffset;
608 outputRow = (char*)outputBuffer + dstOffset;
609
610 if (srcAtOnce && dstAtOnce) {
611 cmsDoTransform(sTrans.xf, inputRow, outputRow, width * height);
612 } else {
613 for (i = 0; i < height; i++) {
614 cmsDoTransform(sTrans.xf, inputRow, outputRow, width);
615 inputRow += srcNextRowOffset;
616 outputRow += dstNextRowOffset;
617 }
618 }
619
620 releaseILData(env, inputBuffer, srcDType, srcData);
621 releaseILData(env, outputBuffer, dstDType, dstData);
622 }
623
624 /*
625 * Class: sun_java2d_cmm_lcms_LCMS
626 * Method: getProfileID
627 * Signature: (Ljava/awt/color/ICC_Profile;)J
628 */
629 JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
630 (JNIEnv *env, jclass cls, jobject pf)
631 {
632 return (*env)->GetLongField (env, pf, PF_ID_fID);
633 }
634
635 /*
636 * Class: sun_java2d_cmm_lcms_LCMS
637 * Method: initLCMS
638 * Signature: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;)V
639 */
640 JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
641 (JNIEnv *env, jclass cls, jclass Trans, jclass IL, jclass Pf)
642 {
643 /* TODO: move initialization of the IDs to the static blocks of
644 * corresponding classes to avoid problems with invalidating ids by class
645 * unloading
646 */
647 Trans_profileIDs_fID = (*env)->GetFieldID (env, Trans, "profileIDs", "[J");
648 Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
649 Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J");
650
651 IL_isIntPacked_fID = (*env)->GetFieldID (env, IL, "isIntPacked", "Z");
652 IL_dataType_fID = (*env)->GetFieldID (env, IL, "dataType", "I");
653 IL_pixelType_fID = (*env)->GetFieldID (env, IL, "pixelType", "I");
654 IL_dataArray_fID = (*env)->GetFieldID(env, IL, "dataArray",
655 "Ljava/lang/Object;");
656 IL_width_fID = (*env)->GetFieldID (env, IL, "width", "I");
657 IL_height_fID = (*env)->GetFieldID (env, IL, "height", "I");
658 IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
659 IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
660 IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
661
662 PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
663 }
664
665 static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
666 {
667 cmsUInt32Number pfSize = 0;
668 cmsUInt8Number* pfBuffer = NULL;
669 cmsBool status = FALSE;
670
671 if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
672 pfSize < sizeof(cmsICCHeader) ||
673 bufferSize < sizeof(cmsICCHeader))
674 {
675 return FALSE;
676 }
677
678 pfBuffer = malloc(pfSize);
679 if (pfBuffer == NULL) {
|