JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
PixelFormat.java
Go to the documentation of this file.
1/**
2 * Copyright (c) 2014 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.nativewindow.util;
30
31import java.util.Arrays;
32
33import com.jogamp.common.util.Bitfield;
34
35/**
36 * Basic pixel formats
37 * <p>
38 * Notation follows OpenGL notation, i.e.
39 * name consist of all it's component names
40 * followed by their bit size.
41 * </p>
42 * <p>
43 * Order of component names is from lowest-bit to highest-bit.
44 * </p>
45 * <p>
46 * In case component-size is 1 byte (e.g. OpenGL data-type GL_UNSIGNED_BYTE),
47 * component names are ordered from lowest-byte to highest-byte.
48 * Note that OpenGL applies special interpretation if
49 * data-type is e.g. GL_UNSIGNED_8_8_8_8_REV or GL_UNSIGNED_8_8_8_8_REV.
50 * </p>
51 * <p>
52 * PixelFormat can be converted to OpenGL GLPixelAttributes
53 * via
54 * <pre>
55 * GLPixelAttributes glpa = GLPixelAttributes.convert(PixelFormat pixFmt, GLProfile glp);
56 * </pre>
57 * </p>
58 * <p>
59 * See OpenGL Specification 4.3 - February 14, 2013, Core Profile,
60 * Section 8.4.4 Transfer of Pixel Rectangles, p. 161-174.
61 * </ul>
62 *
63 * </p>
64 */
65public enum PixelFormat {
66 /**
67 * Stride is 8 bits, 8 bits per pixel, 1 component of 8 bits.
68 * Compatible with:
69 * <ul>
70 * <li>OpenGL: data-format GL_ALPHA (< GL3), GL_RED (>= GL3), data-type GL_UNSIGNED_BYTE</li>
71 * <li>AWT: <i>none</i></li>
72 * </ul>
73 * </p>
74 */
75 LUMINANCE(new CType[]{ CType.Y }, 1, 8, 8),
76
77 /**
78 * Stride is 16 bits, 16 bits per pixel, 3 {@link PackedComposition#isUniform() discrete} components.
79 * <p>
80 * The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
81 * are interleaved in the order Low to High:
82 * <ol>
83 * <li>R: 0x1F << 0</li>
84 * <li>G: 0x3F << 5</li>
85 * <li>B: 0x1F << 11</li>
86 * </ol>
87 * </p>
88 * <p>
89 * Compatible with:
90 * <ul>
91 * <li>OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_SHORT_5_6_5_REV</li>
92 * <li>AWT: <i>None</i></li>
93 * </ul>
94 * </p>
95 */
96 RGB565(new CType[]{ CType.R, CType.G, CType.B },
97 new int[]{ 0x1F, 0x3F, 0x1F },
98 new int[]{ 0, 5, 5+6 },
99 16 ),
100
101 /**
102 * Stride is 16 bits, 16 bits per pixel, 3 {@link PackedComposition#isUniform() discrete} components.
103 * <p>
104 * The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
105 * are interleaved in the order Low to High:
106 * <ol>
107 * <li>B: 0x1F << 0</li>
108 * <li>G: 0x3F << 5</li>
109 * <li>R: 0x1F << 11</li>
110 * </ol>
111 * </p>
112 * <p>
113 * Compatible with:
114 * <ul>
115 * <li>OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_SHORT_5_6_5</li>
116 * <li>AWT: <i>None</i></li>
117 * </ul>
118 * </p>
119 */
120 BGR565(new CType[]{ CType.B, CType.G, CType.R},
121 new int[]{ 0x1F, 0x3F, 0x1F },
122 new int[]{ 0, 5, 5+6 },
123 16 ),
124
125 /**
126 * Stride is 16 bits, 16 bits per pixel, 4 {@link PackedComposition#isUniform() discrete} components.
127 * <p>
128 * The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
129 * are interleaved in the order Low to High:
130 * <ol>
131 * <li>R: 0x1F << 0</li>
132 * <li>G: 0x1F << 5</li>
133 * <li>B: 0x1F << 10</li>
134 * <li>A: 0x01 << 15</li>
135 * </ol>
136 * </p>
137 * <p>
138 * Compatible with:
139 * <ul>
140 * <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_SHORT_1_5_5_5_REV</li>
141 * <li>AWT: <i>None</i></li>
142 * </ul>
143 * </p>
144 */
145 RGBA5551(new CType[]{ CType.R, CType.G, CType.B, CType.A},
146 new int[]{ 0x1F, 0x1F, 0x1F, 0x01 },
147 new int[]{ 0, 5, 5+5, 5+5+5 },
148 16 ),
149
150 /**
151 * Stride is 16 bits, 16 bits per pixel, 4 {@link PackedComposition#isUniform() discrete} components.
152 * <p>
153 * The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
154 * are interleaved in the order Low to High:
155 * <ol>
156 * <li>A: 0x01 << 0</li>
157 * <li>B: 0x1F << 1</li>
158 * <li>G: 0x1F << 6</li>
159 * <li>R: 0x1F << 11</li>
160 * </ol>
161 * </p>
162 * <p>
163 * Compatible with:
164 * <ul>
165 * <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_SHORT_5_5_5_1</li>
166 * <li>AWT: <i>None</i></li>
167 * </ul>
168 * </p>
169 */
170 ABGR1555(new CType[]{ CType.A, CType.B, CType.G, CType.R },
171 new int[]{ 0x01, 0x1F, 0x1F, 0x1F },
172 new int[]{ 0, 1, 1+5, 1+5+5 },
173 16 ),
174
175 /**
176 * Stride 24 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
177 * <p>
178 * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
179 * are interleaved in the order Low to High:
180 * <ol>
181 * <li>R: 0xFF << 0</li>
182 * <li>G: 0xFF << 8</li>
183 * <li>B: 0xFF << 16</li>
184 * </ol>
185 * </p>
186 * <p>
187 * Compatible with:
188 * <ul>
189 * <li>OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_BYTE</li>
190 * <li>AWT: <i>None</i></li>
191 * </ul>
192 * </p>
193 */
194 RGB888(new CType[]{ CType.R, CType.G, CType.B }, 3, 8, 24),
195
196 /**
197 * Stride is 24 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of of 8 bits.
198 * <p>
199 * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
200 * are interleaved in the order Low to High:
201 * <ol>
202 * <li>B: 0xFF << 0</li>
203 * <li>G: 0xFF << 8</li>
204 * <li>R: 0xFF << 16</li>
205 * </ol>
206 * </p>
207 * <p>
208 * Compatible with:
209 * <ul>
210 * <li>OpenGL: data-format GL_BGR (>= GL2), data-type GL_UNSIGNED_BYTE</li>
211 * <li>AWT: {@link java.awt.image.BufferedImage#TYPE_3BYTE_BGR TYPE_3BYTE_BGR}</li>
212 * </ul>
213 * </p>
214 */
215 BGR888(new CType[]{ CType.B, CType.G, CType.R }, 3, 8, 24),
216
217 /**
218 * Stride is 32 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
219 * <p>
220 * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
221 * are interleaved in the order Low to High:
222 * <ol>
223 * <li>R: 0xFF << 0</li>
224 * <li>G: 0xFF << 8</li>
225 * <li>B: 0xFF << 16</li>
226 * </ol>
227 * </p>
228 * <p>
229 * Compatible with:
230 * <ul>
231 * <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_BYTE, with alpha discarded!</li>
232 * <li>AWT: {@link java.awt.image.BufferedImage#TYPE_INT_BGR TYPE_INT_BGR}</li>
233 * </ul>
234 * </p>
235 */
236 RGBx8888(new CType[]{ CType.R, CType.G, CType.B }, 3, 8, 32),
237
238 /**
239 * Stride is 32 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
240 * <p>
241 * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
242 * are interleaved in the order Low to High:
243 * <ol>
244 * <li>B: 0xFF << 0</li>
245 * <li>G: 0xFF << 8</li>
246 * <li>R: 0xFF << 16</li>
247 * </ol>
248 * </p>
249 * <p>
250 * Compatible with:
251 * <ul>
252 * <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_BYTE - with alpha discarded!</li>
253 * <li>AWT: {@link java.awt.image.BufferedImage#TYPE_INT_RGB TYPE_INT_RGB}</li>
254 * </ul>
255 * </p>
256 */
257 BGRx8888(new CType[]{ CType.B, CType.G, CType.R }, 3, 8, 32),
258
259 /**
260 * Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
261 * <p>
262 * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
263 * are interleaved in the order Low to High:
264 * <ol>
265 * <li>R: 0xFF << 0</li>
266 * <li>G: 0xFF << 8</li>
267 * <li>B: 0xFF << 16</li>
268 * <li>A: 0xFF << 24</li>
269 * </ol>
270 * </p>
271 * <p>
272 * Compatible with:
273 * <ul>
274 * <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_BYTE</li>
275 * <li>AWT: <i>None</i></li>
276 * <li>PointerIcon: OSX (NSBitmapImageRep)</li>
277 * <li>Window Icon: OSX (NSBitmapImageRep)</li>
278 * <li>PNGJ: Scanlines</li>
279 * </ul>
280 * </p>
281 */
282 RGBA8888(new CType[]{ CType.R, CType.G, CType.B, CType.A }, 4, 8, 32),
283
284 /**
285 * Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
286 * <p>
287 * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
288 * are interleaved in the order Low to High:
289 * <ol>
290 * <li>A: 0xFF << 0</li>
291 * <li>B: 0xFF << 8</li>
292 * <li>G: 0xFF << 16</li>
293 * <li>R: 0xFF << 24</li>
294 * </ol>
295 * </p>
296 * <p>
297 * Compatible with:
298 * <ul>
299 * <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_INT_8_8_8_8</li>
300 * <li>AWT: {@link java.awt.image.BufferedImage#TYPE_4BYTE_ABGR TYPE_4BYTE_ABGR}</li>
301 * </ul>
302 * </p>
303 */
304 ABGR8888(new CType[]{ CType.A, CType.B, CType.G, CType.R }, 4, 8, 32),
305
306 /**
307 * Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
308 * <p>
309 * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
310 * are interleaved in the order Low to High:
311 * <ol>
312 * <li>A: 0xFF << 0</li>
313 * <li>R: 0xFF << 8</li>
314 * <li>G: 0xFF << 16</li>
315 * <li>B: 0xFF << 24</li>
316 * </ol>
317 * </p>
318 * <p>
319 * Compatible with:
320 * <ul>
321 * <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_INT_8_8_8_8</li>
322 * <li>AWT: <i>None</i></li>
323 * </ul>
324 * </p>
325 */
326 ARGB8888(new CType[]{ CType.A, CType.R, CType.G, CType.B }, 4, 8, 32),
327
328 /**
329 * Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
330 * <p>
331 * The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
332 * are interleaved in the order Low to High:
333 * <ol>
334 * <li>B: 0xFF << 0</li>
335 * <li>G: 0xFF << 8</li>
336 * <li>R: 0xFF << 16</li>
337 * <li>A: 0xFF << 24</li>
338 * </ol>
339 * </p>
340 * <p>
341 * Compatible with:
342 * <ul>
343 * <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_BYTE</li>
344 * <li>AWT: {@link java.awt.image.BufferedImage#TYPE_INT_ARGB TYPE_INT_ARGB}</li>
345 * <li>PointerIcon: X11 (XCURSOR), Win32, AWT</li>
346 * <li>Window Icon: X11, Win32</li>
347 * </ul>
348 * </p>
349 */
350 BGRA8888(new CType[]{ CType.B, CType.G, CType.R, CType.A }, 4, 8, 32);
351
352 /** Unique {@link Composition Pixel Composition}, i.e. layout of its components. */
353 public final Composition comp;
354
355 /**
356 * @param componentOrder {@link CType Component type} order of all components, see {@link Composition#componentBitMask()}.
357 * @param componentCount number of components
358 * @param bpc bits per component
359 * @param bitStride stride bits to next pixel
360 */
361 private PixelFormat(final CType[] componentOrder, final int componentCount, final int bpc, final int bitStride) {
362 this.comp = new PackedComposition(componentOrder, componentCount, bpc, bitStride);
363 }
364
365 /**
366 * @param componentOrder {@link CType Component type} order of all components, see {@link Composition#componentBitMask()}.
367 * @param componentMask bit-mask of of all components, see {@link Composition##componentBitMask()}.
368 * @param componentBitShift bit-shift of all components, see {@link Composition##componentBitMask()}.
369 * @param bitStride stride bits to next pixel
370 */
371 private PixelFormat(final CType[] componentOrder, final int[] componentMask, final int[] componentBitShift, final int bitStride) {
372 this.comp = new PackedComposition(componentOrder, componentMask, componentBitShift, bitStride);
373 }
374
375 /**
376 * Returns the unique matching {@link PixelFormat} of the given {@link Composition}
377 * or {@code null} if none is available.
378 */
379 public static PixelFormat valueOf(final Composition comp) {
380 final PixelFormat[] all = PixelFormat.values();
381 for(int i=all.length-1; i>=0; i--) {
382 final PixelFormat pf = all[i];
383 if( comp.hashCode() == pf.comp.hashCode() && comp.equals(pf.comp) ) {
384 return pf;
385 }
386 }
387 return null;
388 }
389
390 /** Component types */
391 public static enum CType {
392 /** Red component */
394 /** Green component */
396 /** Blue component */
398 /** Alpha component */
400 /** Luminance component, e.g. grayscale or Y of YUV */
402 /** U component of YUV */
404 /** V component of YUV */
406 }
407
408 /**
409 * Pixel composition, i.e. layout of its components.
410 */
411 public static interface Composition {
412 /** {@value} */
413 public static final int UNDEF = -1;
414
415 /**
416 * Returns {@code true} if all components are of same bit-size, e.g. {@link PixelFormat#RGBA8888 RGBA8888},
417 * otherwise {@code false}, e.g. {@link PixelFormat#RGBA5551 RGBA5551}
418 */
419 boolean isUniform();
420
421 /**
422 * Returns {@code true} if all components are packed, i.e. interleaved, e.g. {@link PixelFormat#RGBA8888 RGBA8888},
423 * otherwise {@code false}.
424 */
425 boolean isInterleaved();
426
427 /** Number of components per pixel, e.g. 3 for {@link PixelFormat#RGBx8888 RGBx8888}. */
429 /** Number of bits per pixel, e.g. 24 bits for {@link PixelFormat#RGBx8888 RGBx8888}. */
431 /**
432 * Bit distance between pixels.
433 * <p>
434 * For packed pixels e.g. 32 bits for {@link PixelFormat#RGBx8888 RGBx8888}.
435 * </p>
436 */
438 /** Number of bytes per pixel, i.e. packed {@link #bitStride()} in bytes, e.g. 4 for {@link PixelFormat#RGBx8888 RGBx8888}. */
440 /**
441 * Returns the {@link CType Component type} order of all components, see {@link #componentBitMask()}.
442 */
444 /**
445 * Returns the index of given {@link CType} within {@link #componentOrder()}, -1 if not exists.
446 */
447 int find(final PixelFormat.CType s);
448 /**
449 * Returns the un-shifted bit-mask of all components.
450 * <p>
451 * Components mask is returned in the order Low-Index to High-Index, e.g.:
452 * <ul>
453 * <li>{@link PixelFormat#RGB565 RGB565}: 0: R 0x1F, 1: G 0x3F, 2: B 0x1F</li>
454 * <li>{@link PixelFormat#RGBA5551 RGBA5551}: 0: R 0x1F, 1: G 0x1F, 2: B 0x1F, 3: A 0x01</li>
455 * <li>{@link PixelFormat#RGBA8888 RGBA8888}: 0: R 0xFF, 1: G 0xFF, 2: B 0xFF, 3: A 0xFF</li>
456 * </ul>
457 * </p>
458 * <p>
459 */
461 /**
462 * Returns the number of bits of all components, see {@link #componentBitMask()}.
463 */
465 /**
466 * Returns the bit-shift of all components, see {@link #componentBitMask()}.
467 */
469
470 /**
471 * Decodes a component from the shifted pixel data with a {@link #bytesPerPixel()} of up to 32bit.
472 * @param shifted complete pixel encoded into on 32bit integer
473 * @param cIdx the desired component index
474 * @return the decoded component value
475 */
476 int decodeSingleI32(final int shifted, final int cIdx);
477 /**
478 * Decodes a component from the shifted pixel data with a {@link #bytesPerPixel()} of up to 64bit.
479 * @param shifted complete pixel encoded into on 64bit integer
480 * @param cIdx the desired component index
481 * @return the decoded component value
482 */
483 int decodeSingleI64(final long shifted, final int cIdx);
484
485 int encodeSingleI32(final int norm, final int cIdx);
486 long encodeSingleI64(final int norm, final int cIdx);
487
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);
490
491 int encodeSingleI8(final byte normalI8, final int cIdx);
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);
494
495 float toFloat(final int i32, final int cIdx, final boolean i32Shifted);
496 int fromFloat(final float f, final int cIdx, final boolean shiftResult);
497
498 int defaultValue(final int cIdx, final boolean shiftResult);
499
500 /**
501 * Returns cached immutable hash value, see {@link Object#hashCode()}.
502 */
503 int hashCode();
504 /**
505 * Returns {@link Object#equals(Object)}
506 */
507 boolean equals(final Object o);
508
509 /**
510 * Returns {@link Object#toString()}.
511 */
512 String toString();
513 }
514
515 /**
516 * Packed pixel composition, see {@link Composition}.
517 * <p>
518 * Components are interleaved, i.e. packed.
519 * </p>
520 */
521 public static class PackedComposition implements Composition {
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;
530
531 public final String toString() {
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));
535 }
536
537 /**
538 * @param componentOrder {@link CType Component type} order of all components, see {@link #componentBitMask()}.
539 * @param componentCount number of components
540 * @param bpc bits per component
541 * @param bitStride stride bits to next pixel
542 */
543 public PackedComposition(final CType[] componentOrder, final int componentCount, final int bpc, final int bitStride) {
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;
553 }
554 this.uniform = true;
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));
559 }
560 this.hashCode = hashCodeImpl();
561 }
562
563 /**
564 * @param componentOrder {@link CType Component type} order of all components, see {@link #componentBitMask()}.
565 * @param componentMask bit-mask of of all components, see {@link #componentBitMask()}.
566 * @param componentBitShift bit-shift of all components, see {@link #componentBitMask()}.
567 * @param bitStride stride bits to next pixel
568 */
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];
574 int bpp = 0;
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);
579 bpp += bitCount;
580 this.compBitCount[i] = bitCount;
581 if( i > 0 && uniform ) {
582 uniform = componentMask[i-1] == cmask;
583 }
584 }
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));
590 }
591 this.hashCode = hashCodeImpl();
592 }
593
594 @Override
595 public final boolean isUniform() { return uniform; }
596 /**
597 * {@inheritDoc}
598 * <p>
599 * Instances of {@link PackedComposition} returns {@code true}.
600 * </p>
601 */
602 @Override
603 public final boolean isInterleaved() { return true; }
604 @Override
605 public final int componentCount() { return compMask.length; }
606 @Override
607 public final int bitsPerPixel() { return bitsPerPixel; }
608 @Override
609 public final int bitStride() { return bitStride; }
610 @Override
611 public final int bytesPerPixel() { return (7+bitStride)/8; }
612 @Override
613 public final CType[] componentOrder() { return compOrder; }
614 @Override
615 public final int find(final PixelFormat.CType s) { return PixelFormatUtil.find(s, compOrder, false /* mapRGB2Y */); }
616 @Override
617 public final int[] componentBitMask() { return compMask; }
618 @Override
619 public final int[] componentBitCount() { return compBitCount; }
620 @Override
621 public final int[] componentBitShift() { return compBitShift; }
622
623 @Override
624 public final int decodeSingleI32(final int shifted, final int cIdx) {
625 return ( shifted >>> compBitShift[cIdx] ) & compMask[cIdx];
626 }
627 @Override
628 public final int decodeSingleI64(final long shifted, final int cIdx) {
629 return ( (int)( 0xffffffffL & ( shifted >>> compBitShift[cIdx] ) ) ) & compMask[cIdx];
630 }
631 @Override
632 public final int encodeSingleI32(final int norm, final int cIdx) {
633 return ( norm & compMask[cIdx] ) << compBitShift[cIdx] ;
634 }
635 @Override
636 public final long encodeSingleI64(final int norm, final int cIdx) {
637 return ( 0xffffffffL & ( norm & compMask[cIdx] ) ) << compBitShift[cIdx] ;
638 }
639 @Override
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] ;
644 }
645 @Override
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] ;
651 }
652 @Override
653 public final int encodeSingleI8(final byte normI8, final int cIdx) {
654 return ( normI8 & compMask[cIdx] ) << compBitShift[cIdx] ;
655 }
656 @Override
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] ;
661 }
662 @Override
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] ;
668 }
669
670 @Override
671 public final float toFloat(final int i32, final int cIdx, final boolean i32Shifted) {
672 if( i32Shifted ) {
673 return ( ( i32 >>> compBitShift[cIdx] ) & compMask[cIdx] ) / (float)( compMask[cIdx] ) ;
674 } else {
675 return ( i32 & compMask[cIdx] ) / (float)( compMask[cIdx] ) ;
676 }
677 }
678 @Override
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;
682 }
683
684 @Override
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;
689 }
690
691 @Override
692 public final int hashCode() { return hashCode; }
693 private final int hashCodeImpl() {
694 // 31 * x == (x << 5) - x
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();
700 }
701 for(int i=compMask.length-1; i>=0; i--) {
702 hash = ((hash << 5) - hash) + compMask[i];
703 }
704 for(int i=compBitShift.length-1; i>=0; i--) {
705 hash = ((hash << 5) - hash) + compBitShift[i];
706 }
707 return hash;
708 }
709
710 @Override
711 public final boolean equals(final Object obj) {
712 if(this == obj) { return true; }
713 if( obj instanceof PackedComposition ) {
714 final PackedComposition other = (PackedComposition) obj;
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);
720 } else {
721 return false;
722 }
723 }
724 }
725
726 private static String toHexString(final int[] bitCount, final int[] mask, final int[] shift) {
727 final StringBuilder sb = new StringBuilder();
728 sb.append("[");
729 final int l = mask.length;
730 for(int i=0; i < l; i++) {
731 if(i > 0) {
732 sb.append(", ");
733 }
734 sb.append(bitCount[i]).append(": ").
735 append("0x").append(Integer.toHexString(mask[i])).append(" << ").append(shift[i]);
736 }
737 return sb.append("]").toString();
738 }
739}
static final int find(final PixelFormat.CType s, final PixelFormat.CType[] pool, final boolean mapRGB2Y)
Packed pixel composition, see Composition.
final int bitsPerPixel()
Number of bits per pixel, e.g.
final int find(final PixelFormat.CType s)
Returns the index of given CType within componentOrder(), -1 if not exists.
final int hashCode()
Returns cached immutable hash value, see Object#hashCode().
final int decodeSingleI64(final long shifted, final int cIdx)
Decodes a component from the shifted pixel data with a bytesPerPixel() of up to 64bit.
final int encode3CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8)
final int[] componentBitCount()
Returns the number of bits of all components, see componentBitMask().
final int encode4CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32, final int c4NormI32)
final int bitStride()
Bit distance between pixels.
final int componentCount()
Number of components per pixel, e.g.
final boolean isUniform()
Returns true if all components are of same bit-size, e.g.
final CType[] componentOrder()
Returns the Component type order of all components, see componentBitMask().
final boolean equals(final Object obj)
Returns Object#equals(Object).
final int encodeSingleI32(final int norm, final int cIdx)
PackedComposition(final CType[] componentOrder, final int componentCount, final int bpc, final int bitStride)
final int encode4CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8, final byte c4NormI8)
final String toString()
Returns Object#toString().
final boolean isInterleaved()
Returns true if all components are packed, i.e.interleaved, e.g. RGBA8888, otherwise false.
final long encodeSingleI64(final int norm, final int cIdx)
final int decodeSingleI32(final int shifted, final int cIdx)
Decodes a component from the shifted pixel data with a bytesPerPixel() of up to 32bit.
final int[] componentBitShift()
Returns the bit-shift of all components, see componentBitMask().
final int bytesPerPixel()
Number of bytes per pixel, i.e.
final int encode3CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32)
final int fromFloat(final float f, final int cIdx, final boolean shiftResult)
PackedComposition(final CType[] componentOrder, final int[] componentMask, final int[] componentBitShift, final int bitStride)
final int[] componentBitMask()
Returns the un-shifted bit-mask of all components.
final int encodeSingleI8(final byte normI8, final int cIdx)
final int defaultValue(final int cIdx, final boolean shiftResult)
final float toFloat(final int i32, final int cIdx, final boolean i32Shifted)
LUMINANCE
Stride is 8 bits, 8 bits per pixel, 1 component of 8 bits.
ABGR8888
Stride is 32 bits, 32 bits per pixel, 4 uniform components of 8 bits.
BGRA8888
Stride is 32 bits, 32 bits per pixel, 4 uniform components of 8 bits.
static PixelFormat valueOf(final Composition comp)
Returns the unique matching PixelFormat of the given Composition or null if none is available.
final Composition comp
Unique Pixel Composition, i.e.
RGBx8888
Stride is 32 bits, 24 bits per pixel, 3 uniform components of 8 bits.
BGR888
Stride is 24 bits, 24 bits per pixel, 3 uniform components of of 8 bits.
BGRx8888
Stride is 32 bits, 24 bits per pixel, 3 uniform components of 8 bits.
RGBA8888
Stride is 32 bits, 32 bits per pixel, 4 uniform components of 8 bits.
ARGB8888
Stride is 32 bits, 32 bits per pixel, 4 uniform components of 8 bits.
RGB888
Stride 24 bits, 24 bits per pixel, 3 uniform components of 8 bits.
int bitStride()
Bit distance between pixels.
CType[] componentOrder()
Returns the Component type order of all components, see componentBitMask().
int[] componentBitShift()
Returns the bit-shift of all components, see componentBitMask().
float toFloat(final int i32, final int cIdx, final boolean i32Shifted)
int componentCount()
Number of components per pixel, e.g.
int fromFloat(final float f, final int cIdx, final boolean shiftResult)
int bytesPerPixel()
Number of bytes per pixel, i.e.
int find(final PixelFormat.CType s)
Returns the index of given CType within componentOrder(), -1 if not exists.
int encode3CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32)
boolean isInterleaved()
Returns true if all components are packed, i.e.
int decodeSingleI32(final int shifted, final int cIdx)
Decodes a component from the shifted pixel data with a bytesPerPixel() of up to 32bit.
int defaultValue(final int cIdx, final boolean shiftResult)
int[] componentBitMask()
Returns the un-shifted bit-mask of all components.
int encode4CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8, final byte c4NormI8)
boolean equals(final Object o)
Returns Object#equals(Object).
boolean isUniform()
Returns true if all components are of same bit-size, e.g.
int hashCode()
Returns cached immutable hash value, see Object#hashCode().
String toString()
Returns Object#toString().
int decodeSingleI64(final long shifted, final int cIdx)
Decodes a component from the shifted pixel data with a bytesPerPixel() of up to 64bit.
int encodeSingleI8(final byte normalI8, final int cIdx)
int encode4CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32, final int c4NormI32)
long encodeSingleI64(final int norm, final int cIdx)
int encode3CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8)
int bitsPerPixel()
Number of bits per pixel, e.g.
int encodeSingleI32(final int norm, final int cIdx)
int[] componentBitCount()
Returns the number of bits of all components, see componentBitMask().