< prev index next >

src/java.desktop/share/native/liblcms/cmsalpha.c

Print this page

414        /* from HLF*/ { fromHLFto8,  fromHLFto16, fromHLFto16SE, copy16,       fromHLFtoFLT,  fromHLFtoDBL  },
415        /* from FLT*/ { fromFLTto8,  fromFLTto16, fromFLTto16SE, fromFLTtoHLF, copy32,        fromFLTtoDBL  },
416        /* from DBL*/ { fromDBLto8,  fromDBLto16, fromDBLto16SE, fromDBLtoHLF, fromDBLtoFLT,  copy64 }};
417 
418         int in_n  = FormatterPos(in);
419         int out_n = FormatterPos(out);
420 
421         if (in_n < 0 || out_n < 0 || in_n > 5 || out_n > 5) {
422 
423                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width");
424                return NULL;
425         }
426 
427         return FormattersAlpha[in_n][out_n];
428 }
429 
430 
431 
432 // This function computes the distance from each component to the next one in bytes.
433 static
434 void ComputeIncrementsForChunky(cmsUInt32Number Format,
435                                 cmsUInt32Number ComponentStartingOrder[],
436                                 cmsUInt32Number ComponentPointerIncrements[])
437 {
438        cmsUInt32Number channels[cmsMAXCHANNELS];
439        cmsUInt32Number extra = T_EXTRA(Format);
440        cmsUInt32Number nchannels = T_CHANNELS(Format);
441        cmsUInt32Number total_chans = nchannels + extra;
442        cmsUInt32Number i;
443        cmsUInt32Number channelSize = trueBytesSize(Format);
444        cmsUInt32Number pixelSize = channelSize * total_chans;
445 
446        // Sanity check
447        if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
448            return;
449 
450         memset(channels, 0, sizeof(channels));
451 
452        // Separation is independent of starting point and only depends on channel size
453        for (i = 0; i < extra; i++)
454               ComponentPointerIncrements[i] = pixelSize;
455 
456        // Handle do swap
457        for (i = 0; i < total_chans; i++)
458        {
459               if (T_DOSWAP(Format)) {
460                      channels[i] = total_chans - i - 1;
461               }
462               else {
463                      channels[i] = i;
464               }
465        }
466 
467        // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
468        if (T_SWAPFIRST(Format) && total_chans > 1) {
469 
470               cmsUInt32Number tmp = channels[0];
471               for (i = 0; i < total_chans-1; i++)
472                      channels[i] = channels[i + 1];
473 
474               channels[total_chans - 1] = tmp;
475        }
476 
477        // Handle size
478        if (channelSize > 1)
479               for (i = 0; i < total_chans; i++) {
480                      channels[i] *= channelSize;
481               }
482 
483        for (i = 0; i < extra; i++)
484               ComponentStartingOrder[i] = channels[i + nchannels];


485 }
486 
487 
488 
489 //  On planar configurations, the distance is the stride added to any non-negative
490 static
491 void ComputeIncrementsForPlanar(cmsUInt32Number Format,
492                                 cmsUInt32Number BytesPerPlane,
493                                 cmsUInt32Number ComponentStartingOrder[],
494                                 cmsUInt32Number ComponentPointerIncrements[])
495 {
496        cmsUInt32Number channels[cmsMAXCHANNELS];
497        cmsUInt32Number extra = T_EXTRA(Format);
498        cmsUInt32Number nchannels = T_CHANNELS(Format);
499        cmsUInt32Number total_chans = nchannels + extra;
500        cmsUInt32Number i;
501        cmsUInt32Number channelSize = trueBytesSize(Format);
502 
503        // Sanity check
504        if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
505            return;
506 
507        memset(channels, 0, sizeof(channels));
508 
509        // Separation is independent of starting point and only depends on channel size
510        for (i = 0; i < extra; i++)
511               ComponentPointerIncrements[i] = channelSize;
512 
513        // Handle do swap
514        for (i = 0; i < total_chans; i++)
515        {
516               if (T_DOSWAP(Format)) {
517                      channels[i] = total_chans - i - 1;
518               }
519               else {
520                      channels[i] = i;
521               }
522        }
523 
524        // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
525        if (T_SWAPFIRST(Format) && total_chans > 0) {
526 
527               cmsUInt32Number tmp = channels[0];
528               for (i = 0; i < total_chans - 1; i++)
529                      channels[i] = channels[i + 1];
530 
531               channels[total_chans - 1] = tmp;
532        }
533 
534        // Handle size
535        for (i = 0; i < total_chans; i++) {
536               channels[i] *= BytesPerPlane;
537        }
538 
539        for (i = 0; i < extra; i++)
540               ComponentStartingOrder[i] = channels[i + nchannels];


541 }
542 
543 
544 
545 // Dispatcher por chunky and planar RGB
546 static
547 void  ComputeComponentIncrements(cmsUInt32Number Format,
548                                  cmsUInt32Number BytesPerPlane,
549                                  cmsUInt32Number ComponentStartingOrder[],
550                                  cmsUInt32Number ComponentPointerIncrements[])
551 {
552        if (T_PLANAR(Format)) {
553 
554               ComputeIncrementsForPlanar(Format,  BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
555        }
556        else {
557               ComputeIncrementsForChunky(Format,  ComponentStartingOrder, ComponentPointerIncrements);
558        }
559 
560 }
561 
562 
563 
564 // Handles extra channels copying alpha if requested by the flags
565 void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
566                                                void* out,
567                                                cmsUInt32Number PixelsPerLine,
568                                                cmsUInt32Number LineCount,
569                                                const cmsStride* Stride)
570 {
571     cmsUInt32Number i, j, k;
572     cmsUInt32Number nExtra;
573     cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
574     cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
575     cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
576     cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
577 
578     cmsFormatterAlphaFn copyValueFn;
579 
580     // Make sure we need some copy
581     if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
582         return;
583 
584     // Exit early if in-place color-management is occurring - no need to copy extra channels to themselves.
585     if (p->InputFormat == p->OutputFormat && in == out)
586         return;
587 
588     // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
589     nExtra = T_EXTRA(p->InputFormat);
590     if (nExtra != T_EXTRA(p->OutputFormat))
591         return;
592 
593     // Anything to do?
594     if (nExtra == 0)
595         return;
596 
597     // Compute the increments
598     ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
599     ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);


600 
601     // Check for conversions 8, 16, half, float, dbl
602     copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
603     if (copyValueFn == NULL)
604         return;
605 
606     if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly
607 
608         cmsUInt8Number* SourcePtr;
609         cmsUInt8Number* DestPtr;
610 
611         cmsUInt32Number SourceStrideIncrement = 0;
612         cmsUInt32Number DestStrideIncrement = 0;
613 
614         // The loop itself
615         for (i = 0; i < LineCount; i++) {
616 
617             // Prepare pointers for the loop
618             SourcePtr = (cmsUInt8Number*)in + SourceStartingOrder[0] + SourceStrideIncrement;
619             DestPtr = (cmsUInt8Number*)out + DestStartingOrder[0] + DestStrideIncrement;

414        /* from HLF*/ { fromHLFto8,  fromHLFto16, fromHLFto16SE, copy16,       fromHLFtoFLT,  fromHLFtoDBL  },
415        /* from FLT*/ { fromFLTto8,  fromFLTto16, fromFLTto16SE, fromFLTtoHLF, copy32,        fromFLTtoDBL  },
416        /* from DBL*/ { fromDBLto8,  fromDBLto16, fromDBLto16SE, fromDBLtoHLF, fromDBLtoFLT,  copy64 }};
417 
418         int in_n  = FormatterPos(in);
419         int out_n = FormatterPos(out);
420 
421         if (in_n < 0 || out_n < 0 || in_n > 5 || out_n > 5) {
422 
423                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width");
424                return NULL;
425         }
426 
427         return FormattersAlpha[in_n][out_n];
428 }
429 
430 
431 
432 // This function computes the distance from each component to the next one in bytes.
433 static
434 cmsBool ComputeIncrementsForChunky(cmsUInt32Number Format,
435                                 cmsUInt32Number ComponentStartingOrder[],
436                                 cmsUInt32Number ComponentPointerIncrements[])
437 {
438        cmsUInt32Number channels[cmsMAXCHANNELS];
439        cmsUInt32Number extra = T_EXTRA(Format);
440        cmsUInt32Number nchannels = T_CHANNELS(Format);
441        cmsUInt32Number total_chans = nchannels + extra;
442        cmsUInt32Number i;
443        cmsUInt32Number channelSize = trueBytesSize(Format);
444        cmsUInt32Number pixelSize = channelSize * total_chans;
445 
446        // Sanity check
447        if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
448            return FALSE;
449 
450         memset(channels, 0, sizeof(channels));
451 
452        // Separation is independent of starting point and only depends on channel size
453        for (i = 0; i < extra; i++)
454               ComponentPointerIncrements[i] = pixelSize;
455 
456        // Handle do swap
457        for (i = 0; i < total_chans; i++)
458        {
459               if (T_DOSWAP(Format)) {
460                      channels[i] = total_chans - i - 1;
461               }
462               else {
463                      channels[i] = i;
464               }
465        }
466 
467        // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
468        if (T_SWAPFIRST(Format) && total_chans > 1) {
469 
470               cmsUInt32Number tmp = channels[0];
471               for (i = 0; i < total_chans-1; i++)
472                      channels[i] = channels[i + 1];
473 
474               channels[total_chans - 1] = tmp;
475        }
476 
477        // Handle size
478        if (channelSize > 1)
479               for (i = 0; i < total_chans; i++) {
480                      channels[i] *= channelSize;
481               }
482 
483        for (i = 0; i < extra; i++)
484               ComponentStartingOrder[i] = channels[i + nchannels];
485 
486        return TRUE;
487 }
488 
489 
490 
491 //  On planar configurations, the distance is the stride added to any non-negative
492 static
493 cmsBool ComputeIncrementsForPlanar(cmsUInt32Number Format,
494                                 cmsUInt32Number BytesPerPlane,
495                                 cmsUInt32Number ComponentStartingOrder[],
496                                 cmsUInt32Number ComponentPointerIncrements[])
497 {
498        cmsUInt32Number channels[cmsMAXCHANNELS];
499        cmsUInt32Number extra = T_EXTRA(Format);
500        cmsUInt32Number nchannels = T_CHANNELS(Format);
501        cmsUInt32Number total_chans = nchannels + extra;
502        cmsUInt32Number i;
503        cmsUInt32Number channelSize = trueBytesSize(Format);
504 
505        // Sanity check
506        if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
507            return FALSE;
508 
509        memset(channels, 0, sizeof(channels));
510 
511        // Separation is independent of starting point and only depends on channel size
512        for (i = 0; i < extra; i++)
513               ComponentPointerIncrements[i] = channelSize;
514 
515        // Handle do swap
516        for (i = 0; i < total_chans; i++)
517        {
518               if (T_DOSWAP(Format)) {
519                      channels[i] = total_chans - i - 1;
520               }
521               else {
522                      channels[i] = i;
523               }
524        }
525 
526        // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
527        if (T_SWAPFIRST(Format) && total_chans > 0) {
528 
529               cmsUInt32Number tmp = channels[0];
530               for (i = 0; i < total_chans - 1; i++)
531                      channels[i] = channels[i + 1];
532 
533               channels[total_chans - 1] = tmp;
534        }
535 
536        // Handle size
537        for (i = 0; i < total_chans; i++) {
538               channels[i] *= BytesPerPlane;
539        }
540 
541        for (i = 0; i < extra; i++)
542               ComponentStartingOrder[i] = channels[i + nchannels];
543 
544        return TRUE;
545 }
546 
547 
548 
549 // Dispatcher por chunky and planar RGB
550 static
551 cmsBool ComputeComponentIncrements(cmsUInt32Number Format,
552                                  cmsUInt32Number BytesPerPlane,
553                                  cmsUInt32Number ComponentStartingOrder[],
554                                  cmsUInt32Number ComponentPointerIncrements[])
555 {
556        if (T_PLANAR(Format)) {
557 
558               return ComputeIncrementsForPlanar(Format,  BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
559        }
560        else {
561               return ComputeIncrementsForChunky(Format,  ComponentStartingOrder, ComponentPointerIncrements);
562        }
563 
564 }
565 


566 // Handles extra channels copying alpha if requested by the flags
567 void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
568                                                void* out,
569                                                cmsUInt32Number PixelsPerLine,
570                                                cmsUInt32Number LineCount,
571                                                const cmsStride* Stride)
572 {
573     cmsUInt32Number i, j, k;
574     cmsUInt32Number nExtra;
575     cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
576     cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
577     cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
578     cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
579 
580     cmsFormatterAlphaFn copyValueFn;
581 
582     // Make sure we need some copy
583     if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
584         return;
585 
586     // Exit early if in-place color-management is occurring - no need to copy extra channels to themselves.
587     if (p->InputFormat == p->OutputFormat && in == out)
588         return;
589 
590     // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
591     nExtra = T_EXTRA(p->InputFormat);
592     if (nExtra != T_EXTRA(p->OutputFormat))
593         return;
594 
595     // Anything to do?
596     if (nExtra == 0)
597         return;
598 
599     // Compute the increments
600     if (!ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements))
601         return;
602     if (!ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements))
603         return;
604 
605     // Check for conversions 8, 16, half, float, dbl
606     copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
607     if (copyValueFn == NULL)
608         return;
609 
610     if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly
611 
612         cmsUInt8Number* SourcePtr;
613         cmsUInt8Number* DestPtr;
614 
615         cmsUInt32Number SourceStrideIncrement = 0;
616         cmsUInt32Number DestStrideIncrement = 0;
617 
618         // The loop itself
619         for (i = 0; i < LineCount; i++) {
620 
621             // Prepare pointers for the loop
622             SourcePtr = (cmsUInt8Number*)in + SourceStartingOrder[0] + SourceStrideIncrement;
623             DestPtr = (cmsUInt8Number*)out + DestStartingOrder[0] + DestStrideIncrement;
< prev index next >