29package com.jogamp.nativewindow.util;
31import java.util.Arrays;
33import com.jogamp.common.util.Bitfield;
96 RGB565(
new CType[]{ CType.R, CType.G, CType.B },
97 new int[]{ 0x1F, 0x3F, 0x1F },
98 new int[]{ 0, 5, 5+6 },
121 new int[]{ 0x1F, 0x3F, 0x1F },
122 new int[]{ 0, 5, 5+6 },
146 new int[]{ 0x1F, 0x1F, 0x1F, 0x01 },
147 new int[]{ 0, 5, 5+5, 5+5+5 },
171 new int[]{ 0x01, 0x1F, 0x1F, 0x1F },
172 new int[]{ 0, 1, 1+5, 1+5+5 },
361 private PixelFormat(
final CType[] componentOrder,
final int componentCount,
final int bpc,
final int bitStride) {
362 this.comp =
new PackedComposition(componentOrder, componentCount, bpc, bitStride);
371 private PixelFormat(
final CType[] componentOrder,
final int[] componentMask,
final int[] componentBitShift,
final int bitStride) {
372 this.comp =
new PackedComposition(componentOrder, componentMask, componentBitShift, bitStride);
381 for(
int i=all.length-1; i>=0; i--) {
413 public static final int UNDEF = -1;
488 int encode3CompI32(
final int c1NormI32,
final int c2NormI32,
final int c3NormI32);
489 int encode4CompI32(
final int c1NormI32,
final int c2NormI32,
final int c3NormI32,
final int c4NormI32);
492 int encode3CompI8(
final byte c1NormI8,
final byte c2NormI8,
final byte c3NormI8);
493 int encode4CompI8(
final byte c1NormI8,
final byte c2NormI8,
final byte c3NormI8,
final byte c4NormI8);
495 float toFloat(
final int i32,
final int cIdx,
final boolean i32Shifted);
496 int fromFloat(
final float f,
final int cIdx,
final boolean shiftResult);
522 private final CType[] compOrder;
523 private final int[] compMask;
524 private final int[] compBitCount;
525 private final int[] compBitShift;
526 private final int bitsPerPixel;
527 private final int bitStride;
528 private final boolean uniform;
529 private final int hashCode;
532 return String.format(
"PackedComp[order %s, stride %d, bpp %d, uni %b, comp %d: %s]",
533 Arrays.toString(compOrder), bitStride, bitsPerPixel, uniform,
534 compMask.length, toHexString(compBitCount, compMask, compBitShift));
544 this.compOrder = componentOrder;
545 this.compMask =
new int[componentCount];
546 this.compBitShift =
new int[componentCount];
547 this.compBitCount =
new int[componentCount];
548 final int compMask = ( 1 << bpc ) - 1;
549 for(
int i=0; i<componentCount; i++) {
550 this.compMask[i] = compMask;
551 this.compBitShift[i] = bpc * i;
552 this.compBitCount[i] = bpc;
555 this.bitsPerPixel = bpc * componentCount;
556 this.bitStride = bitStride;
557 if( this.bitStride < this.bitsPerPixel ) {
558 throw new IllegalArgumentException(String.format(
"bit-stride %d < bitsPerPixel %d",
this.bitStride,
this.bitsPerPixel));
560 this.hashCode = hashCodeImpl();
569 public PackedComposition(
final CType[] componentOrder,
final int[] componentMask,
final int[] componentBitShift,
final int bitStride) {
570 this.compOrder = componentOrder;
571 this.compMask = componentMask;
572 this.compBitShift = componentBitShift;
573 this.compBitCount =
new int[componentMask.length];
575 boolean uniform =
true;
576 for(
int i = componentMask.length-1; i>=0; i--) {
577 final int cmask = componentMask[i];
578 final int bitCount = Bitfield.Util.bitCount(cmask);
580 this.compBitCount[i] = bitCount;
581 if( i > 0 && uniform ) {
582 uniform = componentMask[i-1] == cmask;
585 this.uniform = uniform;
586 this.bitsPerPixel = bpp;
587 this.bitStride = bitStride;
588 if( this.bitStride < this.bitsPerPixel ) {
589 throw new IllegalArgumentException(String.format(
"bit-stride %d < bitsPerPixel %d",
this.bitStride,
this.bitsPerPixel));
591 this.hashCode = hashCodeImpl();
625 return ( shifted >>> compBitShift[cIdx] ) & compMask[cIdx];
629 return ( (
int)( 0xffffffffL & ( shifted >>> compBitShift[cIdx] ) ) ) & compMask[cIdx];
633 return ( norm & compMask[cIdx] ) << compBitShift[cIdx] ;
637 return ( 0xffffffffL & ( norm & compMask[cIdx] ) ) << compBitShift[cIdx] ;
640 public final int encode3CompI32(
final int c1NormI32,
final int c2NormI32,
final int c3NormI32) {
641 return ( c1NormI32 & compMask[0] ) << compBitShift[0] |
642 ( c2NormI32 & compMask[1] ) << compBitShift[1] |
643 ( c3NormI32 & compMask[2] ) << compBitShift[2] ;
646 public final int encode4CompI32(
final int c1NormI32,
final int c2NormI32,
final int c3NormI32,
final int c4NormI32) {
647 return ( c1NormI32 & compMask[0] ) << compBitShift[0] |
648 ( c2NormI32 & compMask[1] ) << compBitShift[1] |
649 ( c3NormI32 & compMask[2] ) << compBitShift[2] |
650 ( c4NormI32 & compMask[3] ) << compBitShift[3] ;
654 return ( normI8 & compMask[cIdx] ) << compBitShift[cIdx] ;
657 public final int encode3CompI8(
final byte c1NormI8,
final byte c2NormI8,
final byte c3NormI8) {
658 return ( c1NormI8 & compMask[0] ) << compBitShift[0] |
659 ( c2NormI8 & compMask[1] ) << compBitShift[1] |
660 ( c3NormI8 & compMask[2] ) << compBitShift[2] ;
663 public final int encode4CompI8(
final byte c1NormI8,
final byte c2NormI8,
final byte c3NormI8,
final byte c4NormI8) {
664 return ( c1NormI8 & compMask[0] ) << compBitShift[0] |
665 ( c2NormI8 & compMask[1] ) << compBitShift[1] |
666 ( c3NormI8 & compMask[2] ) << compBitShift[2] |
667 ( c4NormI8 & compMask[3] ) << compBitShift[3] ;
671 public final float toFloat(
final int i32,
final int cIdx,
final boolean i32Shifted) {
673 return ( ( i32 >>> compBitShift[cIdx] ) & compMask[cIdx] ) / (float)( compMask[cIdx] ) ;
675 return ( i32 & compMask[cIdx] ) / (float)( compMask[cIdx] ) ;
679 public final int fromFloat(
final float f,
final int cIdx,
final boolean shiftResult) {
680 final int v = (int)(f * compMask[cIdx] + 0.5f);
681 return shiftResult ? v << compBitShift[cIdx] : v;
685 public final int defaultValue(
final int cIdx,
final boolean shiftResult) {
686 final int v = ( CType.A == compOrder[cIdx] || CType.Y == compOrder[cIdx] )
687 ? compMask[cIdx] : 0;
688 return shiftResult ? v << compBitShift[cIdx] : v;
693 private final int hashCodeImpl() {
695 int hash = 31 + bitStride;
696 hash = ((hash << 5) - hash) + bitsPerPixel;
697 hash = ((hash << 5) - hash) + compMask.length;
698 for(
int i=compOrder.length-1; i>=0; i--) {
699 hash = ((hash << 5) - hash) + compOrder[i].ordinal();
701 for(
int i=compMask.length-1; i>=0; i--) {
702 hash = ((hash << 5) - hash) + compMask[i];
704 for(
int i=compBitShift.length-1; i>=0; i--) {
705 hash = ((hash << 5) - hash) + compBitShift[i];
711 public final boolean equals(
final Object obj) {
712 if(
this == obj) {
return true; }
715 return bitStride == other.bitStride &&
716 bitsPerPixel == other.bitsPerPixel &&
717 Arrays.
equals(compOrder, other.compOrder) &&
718 Arrays.equals(compMask, other.compMask) &&
719 Arrays.equals(compBitShift, other.compBitShift);
726 private static String toHexString(
final int[] bitCount,
final int[] mask,
final int[] shift) {
727 final StringBuilder sb =
new StringBuilder();
729 final int l = mask.length;
730 for(
int i=0; i < l; i++) {
734 sb.append(bitCount[i]).append(
": ").
735 append(
"0x").append(Integer.toHexString(mask[i])).append(
" << ").append(shift[i]);
737 return sb.append(
"]").toString();