28package com.jogamp.nativewindow.util;
30import java.io.IOException;
31import java.nio.ByteBuffer;
32import java.util.Arrays;
34import com.jogamp.common.nio.Buffers;
35import com.jogamp.common.util.Bitstream;
44 private static boolean DEBUG =
false;
62 final boolean hasSrcRGB;
65 final int sCompCount = src.componentCount();
66 final int dCompCount = dst.componentCount();
70 dst2src =
new int[dCompCount];
71 for(
int dIdx=0; dIdx<dCompCount; dIdx++) {
74 src2dst =
new int[sCompCount];
75 for(
int sIdx=0; sIdx<sCompCount; sIdx++) {
83 hasSrcRGB = 0 <= srcRGBA[0] && 0 <= srcRGBA[1] && 0 <= srcRGBA[2];
90 while( i >= 0 && pool[i] != s) { i--; }
112 public static int getShiftedI32(
final int bytesPerPixel,
final byte[] data,
final int offset) {
113 if( bytesPerPixel <= 4 ) {
115 for(
int i=0; i<bytesPerPixel; i++) {
116 shiftedI32 |= ( 0xff & data[offset+i] ) << 8*i;
120 throw new UnsupportedOperationException(bytesPerPixel+
" bytesPerPixel too big, i.e. > 4");
131 public static long getShiftedI64(
final int bytesPerPixel,
final byte[] data,
final int offset) {
132 if( bytesPerPixel <= 8 ) {
134 for(
int i=0; i<bytesPerPixel; i++) {
135 shiftedI64 |= ( 0xff & data[offset+i] ) << 8*i;
139 throw new UnsupportedOperationException(bytesPerPixel+
" bytesPerPixel too big, i.e. > 8");
151 public static int getShiftedI32(
final int bytesPerPixel,
final ByteBuffer data,
final boolean retainDataPos) {
152 if( bytesPerPixel <= 4 ) {
154 if( retainDataPos ) {
155 final int offset = data.position();
156 for(
int i=0; i<bytesPerPixel; i++) {
157 shiftedI32 |= ( 0xff & data.get(offset+i) ) << 8*i;
160 for(
int i=0; i<bytesPerPixel; i++) {
161 shiftedI32 |= ( 0xff & data.get() ) << 8*i;
166 throw new UnsupportedOperationException(bytesPerPixel+
" bytesPerPixel too big, i.e. > 4");
178 public static long getShiftedI64(
final int bytesPerPixel,
final ByteBuffer data,
final boolean retainDataPos) {
179 if( bytesPerPixel <= 8 ) {
181 if( retainDataPos ) {
182 final int offset = data.position();
183 for(
int i=0; i<bytesPerPixel; i++) {
184 shiftedI64 |= ( 0xff & data.get(offset+i) ) << 8*i;
187 for(
int i=0; i<bytesPerPixel; i++) {
188 shiftedI64 |= ( 0xff & data.get() ) << 8*i;
193 throw new UnsupportedOperationException(bytesPerPixel+
" bytesPerPixel too big, i.e. > 8");
231 final byte l = ( byte) ( ( ( ( 0xff & r ) + ( 0xff & g ) + ( 0xff & b ) ) / 3 ) * a );
232 return ( 0xff ) << 24 | ( 0xff & l ) << 16 | ( 0xff & l ) << 8 | ( 0xff & l );
235 return ( 0xff ) << 24 | ( 0xff & b ) << 16 | ( 0xff & g ) << 8 | ( 0xff & r );
237 return ( 0xff ) << 24 | ( 0xff & r ) << 16 | ( 0xff & g ) << 8 | ( 0xff & b );
239 return ( 0xff & a ) << 24 | ( 0xff & b ) << 16 | ( 0xff & g ) << 8 | ( 0xff & r );
241 return ( 0xff & r ) << 24 | ( 0xff & g ) << 16 | ( 0xff & b ) << 8 | ( 0xff & a );
243 return ( 0xff & b ) << 24 | ( 0xff & g ) << 16 | ( 0xff & r ) << 8 | ( 0xff & a );
245 return ( 0xff & a ) << 24 | ( 0xff & r ) << 16 | ( 0xff & g ) << 8 | ( 0xff & b );
247 throw new InternalError(
"Unhandled format "+dst_fmt);
252 final byte r, g, b, a;
255 r = src.get(srcOff++);
261 r = src.get(srcOff++);
262 g = src.get(srcOff++);
263 b = src.get(srcOff++);
267 b = src.get(srcOff++);
268 g = src.get(srcOff++);
269 r = src.get(srcOff++);
273 r = src.get(srcOff++);
274 g = src.get(srcOff++);
275 b = src.get(srcOff++);
276 a = src.get(srcOff++);
279 a = src.get(srcOff++);
280 b = src.get(srcOff++);
281 g = src.get(srcOff++);
282 r = src.get(srcOff++);
285 a = src.get(srcOff++);
286 r = src.get(srcOff++);
287 g = src.get(srcOff++);
288 b = src.get(srcOff++);
291 b = src.get(srcOff++);
292 g = src.get(srcOff++);
293 r = src.get(srcOff++);
294 a = src.get(srcOff++);
297 throw new InternalError(
"Unhandled format "+src_fmt);
303 final byte r, g, b, a;
306 r = (byte) ( src_pixel );
312 r = (byte) ( src_pixel );
313 g = (byte) ( src_pixel >>> 8 );
314 b = (byte) ( src_pixel >>> 16 );
318 b = (byte) ( src_pixel );
319 g = (byte) ( src_pixel >>> 8 );
320 r = (byte) ( src_pixel >>> 16 );
324 r = (byte) ( src_pixel );
325 g = (byte) ( src_pixel >>> 8 );
326 b = (byte) ( src_pixel >>> 16 );
327 a = (byte) ( src_pixel >>> 24 );
330 a = (byte) ( src_pixel );
331 b = (byte) ( src_pixel >>> 8 );
332 g = (byte) ( src_pixel >>> 16 );
333 r = (byte) ( src_pixel >>> 24 );
336 a = (byte) ( src_pixel );
337 r = (byte) ( src_pixel >>> 8 );
338 g = (byte) ( src_pixel >>> 16 );
339 b = (byte) ( src_pixel >>> 24 );
342 b = (byte) ( src_pixel );
343 g = (byte) ( src_pixel >>> 8 );
344 r = (byte) ( src_pixel >>> 16 );
345 a = (byte) ( src_pixel >>> 24 );
348 throw new InternalError(
"Unhandled format "+src_fmt);
354 final PixelFormat destFmt,
final int ddestStride,
final boolean isGLOriented,
355 final boolean destIsDirect) {
359 final int destStride;
360 if( 0 != ddestStride ) {
361 destStride = ddestStride;
363 destStride = bpp * width;
365 final int capacity = destStride*height;
366 final ByteBuffer destBB = destIsDirect ? Buffers.newDirectByteBuffer(capacity) : ByteBuffer.allocate(capacity).order(src.
getPixels().order());
367 convert(src, destBB, destFmt, isGLOriented, destStride);
385 final ByteBuffer dst_bb,
final PixelFormat dst_fmt,
final boolean dst_glOriented,
final int dst_lineStride)
386 throws IllegalStateException
388 convert(src.getSize().getWidth(), src.getSize().getHeight(),
389 src.getPixels(), src.getPixelformat(), src.isGLOriented(), src.getStride(),
390 dst_bb, dst_fmt, dst_glOriented, dst_lineStride);
415 public static void convert(
final int width,
final int height,
416 final ByteBuffer src_bb,
final PixelFormat src_fmt,
final boolean src_glOriented,
int src_lineStride,
417 final ByteBuffer dst_bb,
final PixelFormat dst_fmt,
final boolean dst_glOriented,
int dst_lineStride
418 )
throws IllegalStateException, IllegalArgumentException {
419 final PixelFormat.Composition src_comp = src_fmt.comp;
420 final PixelFormat.Composition dst_comp = dst_fmt.comp;
421 final int src_bpp = src_comp.bytesPerPixel();
422 final int dst_bpp = dst_comp.bytesPerPixel();
424 if( 0 != src_lineStride ) {
425 if( src_lineStride < src_bpp * width ) {
426 throw new IllegalArgumentException(String.format(
"Invalid %s stride %d, must be greater than bytesPerPixel %d * width %d",
427 "source", src_lineStride, src_bpp, width));
430 src_lineStride = src_bpp * width;
432 if( 0 != dst_lineStride ) {
433 if( dst_lineStride < dst_bpp * width ) {
434 throw new IllegalArgumentException(String.format(
"Invalid %s stride %d, must be greater than bytesPerPixel %d * width %d",
435 "destination", dst_lineStride, dst_bpp, width));
438 dst_lineStride = dst_bpp * width;
442 final int dst_comp_bitStride = dst_comp.bitStride();
443 final boolean vert_flip = src_glOriented != dst_glOriented;
444 final boolean fast_copy = src_comp.equals(dst_comp) && 0 == dst_comp_bitStride%8;
446 System.err.println(
"XXX: size "+width+
"x"+height+
", fast_copy "+fast_copy);
447 System.err.println(
"XXX: SRC fmt "+src_fmt+
", "+src_comp+
", stride "+src_lineStride+
", isGLOrient "+src_glOriented);
448 System.err.println(
"XXX: DST fmt "+dst_fmt+
", "+dst_comp+
", stride "+dst_lineStride+
", isGLOrient "+dst_glOriented);
453 for(
int y=0; y<height; y++) {
454 int src_off = vert_flip ? ( height - 1 - y ) * src_lineStride : y * src_lineStride;
455 int dst_off = dst_lineStride*y;
456 for(
int x=0; x<width; x++) {
457 dst_bb.put(dst_off+0, src_bb.get(src_off+0));
459 dst_bb.put(dst_off+1, src_bb.get(src_off+1));
461 dst_bb.put(dst_off+2, src_bb.get(src_off+2));
463 dst_bb.put(dst_off+3, src_bb.get(src_off+3));
475 final Bitstream.ByteBufferStream srcBBS =
new Bitstream.ByteBufferStream(src_bb);
476 final Bitstream<ByteBuffer> srcBitStream =
new Bitstream<ByteBuffer>(srcBBS,
false );
477 srcBitStream.setThrowIOExceptionOnEOF(
true);
479 final Bitstream.ByteBufferStream dstBBS =
new Bitstream.ByteBufferStream(dst_bb);
480 final Bitstream<ByteBuffer> dstBitStream =
new Bitstream<ByteBuffer>(dstBBS,
true );
481 dstBitStream.setThrowIOExceptionOnEOF(
true);
484 System.err.println(
"XXX: cmap.dst2src "+Arrays.toString(cmap.dst2src));
485 System.err.println(
"XXX: cmap.src2dst "+Arrays.toString(cmap.src2dst));
486 System.err.println(
"XXX: cmap.srcRGBA "+Arrays.toString(cmap.srcRGBA));
487 System.err.println(
"XXX: srcBitStream "+srcBitStream);
488 System.err.println(
"XXX: dstBitStream "+dstBitStream);
491 for(
int y=0; y<height; y++) {
492 final int src_off = vert_flip ? ( height - 1 - y ) * src_lineStride * 8 : y * src_lineStride * 8;
494 srcBitStream.position(src_off);
495 for(
int x=0; x<width; x++) {
496 convert(cmap, dst_comp, dstBitStream, src_comp, srcBitStream);
499 dstBitStream.skip(( dst_lineStride * 8 ) - ( dst_comp_bitStride * width ));
501 }
catch(
final IOException ioe) {
502 throw new RuntimeException(ioe);
505 System.err.println(
"XXX: srcBitStream "+srcBitStream);
506 System.err.println(
"XXX: dstBitStream "+dstBitStream);
513 final Bitstream<ByteBuffer> dstBitStream,
515 final Bitstream<ByteBuffer> srcBitStream)
throws IllegalStateException, IOException {
516 final int sCompCount = srcComp.componentCount();
517 final int dCompCount = dstComp.componentCount();
518 final int[] sc =
new int[sCompCount];
519 final int[] dcDef =
new int[dCompCount];
520 final int[] srcCompBitCount = srcComp.componentBitCount();
521 final int[] srcCompBitMask = srcComp.componentBitMask();
522 final int[] dstCompBitCount = dstComp.componentBitCount();
525 for(
int sIdx=0; sIdx<sCompCount; sIdx++) {
526 sc[sIdx] = srcBitStream.readBits31(srcCompBitCount[sIdx]) & srcCompBitMask[sIdx];
528 srcBitStream.skip(srcComp.bitStride() - srcComp.bitsPerPixel());
531 for(
int i=0; i<dCompCount; i++) {
532 dcDef[i] = dstComp.defaultValue(i,
false);
535 if( 1 == dCompCount &&
541 final int r = sc[cmap.srcRGBA[0]];
542 final int g = sc[cmap.srcRGBA[1]];
543 final int b = sc[cmap.srcRGBA[2]];
544 final float rF = srcComp.toFloat(r, cmap.srcRGBA[0],
false);
545 final float gF = srcComp.toFloat(g, cmap.srcRGBA[1],
false);
546 final float bF = srcComp.toFloat(b, cmap.srcRGBA[2],
false);
556 final float lF = ( rF + gF + bF ) * aF / 3f;
557 final int v = dstComp.fromFloat(lF, 0,
false);
559 dstBitStream.writeBits31(dstCompBitCount[0], v);
560 dstBitStream.skip(dstComp.bitStride() - dstComp.bitsPerPixel());
562 if( srcBitStream.position() <= 8*4 ) {
563 System.err.printf(
"convert: rgb[a] -> Y: rgb 0x%02X 0x%02X 0x%02X 0x%02X -> %f %f %f %f"+
564 " -> %f -> dstC 0 0x%08X (%d bits: %s)%n",
567 lF, v, dstCompBitCount[0], Bitstream.toBinString(
true, v, dstCompBitCount[0])
574 for(
int dIdx=0; dIdx<dCompCount; dIdx++) {
576 if( 0 <= ( sIdx = cmap.dst2src[dIdx] ) ) {
577 final float f = srcComp.toFloat(sc[sIdx], sIdx,
false);
578 final int v = dstComp.fromFloat(f, dIdx,
false);
579 dstBitStream.writeBits31(dstCompBitCount[dIdx], v);
581 if( srcBitStream.position() <= 8*4 ) {
582 System.err.printf(
"convert: srcC %d: 0x%08X -> %f -> dstC %d 0x%08X (%d bits: %s)%n",
583 sIdx, sc[sIdx], f, dIdx, v, dstCompBitCount[dIdx], Bitstream.toBinString(
true, v, dstCompBitCount[dIdx]));
587 dstBitStream.writeBits31(dstCompBitCount[dIdx], dcDef[dIdx]);
589 if( srcBitStream.position() <= 8*4 ) {
590 System.err.printf(
"convert: srcC %d: undef -> dstC %d 0x%08X (%d bits: %s)%n",
591 sIdx, dIdx, dcDef[dIdx], dstCompBitCount[dIdx], Bitstream.toBinString(
true, dcDef[dIdx], dstCompBitCount[dIdx]));
596 dstBitStream.skip(dstComp.bitStride() - dstComp.bitsPerPixel());
Generic PixelRectangle implementation.
Pixel Rectangle identified by it's hashCode().
DimensionImmutable getSize()
Returns the size, i.e.
ByteBuffer getPixels()
Returns the pixels.