JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
JPEGImage.java
Go to the documentation of this file.
1/**
2 * Copyright 2013 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 */
28package com.jogamp.opengl.util.texture.spi;
29
30import java.io.IOException;
31import java.io.InputStream;
32import java.nio.ByteBuffer;
33
34import com.jogamp.opengl.GL;
35
36import jogamp.opengl.Debug;
37import jogamp.opengl.util.jpeg.JPEGDecoder;
38
39import com.jogamp.common.nio.Buffers;
40import com.jogamp.opengl.util.texture.TextureData.ColorSpace;
41
42public class JPEGImage {
43 private static final boolean DEBUG = Debug.debug("JPEGImage");
44
45
46 /**
47 * Reads a JPEG image from the specified InputStream, using the given color space for storage.
48 *
49 * @param in
50 * @param cs Storage color space, either {@link ColorSpace#RGB} or {@link ColorSpace#YCbCr}. {@link ColorSpace#YCCK} and {@link ColorSpace#CMYK} will throw an exception!
51 * @return
52 * @throws IOException
53 */
54 public static JPEGImage read(final InputStream in, final ColorSpace cs) throws IOException {
55 return new JPEGImage(in, cs);
56 }
57
58 /** Reads a JPEG image from the specified InputStream, using the {@link ColorSpace#RGB}. */
59 public static JPEGImage read(final InputStream in) throws IOException {
60 return new JPEGImage(in, ColorSpace.RGB);
61 }
62
63 private static class JPEGColorSink implements JPEGDecoder.ColorSink {
64 int width=0, height=0;
65 int sourceComponents=0;
66 ColorSpace sourceCS = ColorSpace.YCbCr;
67 int storageComponents;
68 final ColorSpace storageCS;
69 ByteBuffer data = null;
70
71 JPEGColorSink(final ColorSpace storageCM) {
72 this.storageCS = storageCM;
73 switch(storageCS) {
74 case RGB:
75 case YCbCr:
76 storageComponents = 3;
77 break;
78 default:
79 throw new IllegalArgumentException("Unsupported storage color-space: "+storageCS);
80 }
81 }
82
83 @Override
84 public final ColorSpace allocate(final int width, final int height, final ColorSpace sourceCM, final int sourceComponents) throws RuntimeException {
85 this.width = width;
86 this.height = height;
87 this.sourceComponents = sourceComponents;
88 this.sourceCS = sourceCM;
89 this.data = Buffers.newDirectByteBuffer(width * height * storageComponents);
90 return storageCS;
91 }
92
93 @Override
94 public final void storeRGB(final int x, final int y, final byte r, final byte g, final byte b) {
95 int i = ( ( height - y - 1 ) * width + x ) * storageComponents;
96 data.put(i++, r);
97 data.put(i++, g);
98 data.put(i++, b);
99 // data.put(i++, (byte)0xff);
100 }
101
102 @Override
103 public final void store2(final int x, final int y, final byte c1, final byte c2) {
104 throw new RuntimeException("not supported yet");
105 }
106
107 @Override
108 public final void storeYCbCr(final int x, final int y, final byte Y, final byte Cb, final byte Cr) {
109 int i = ( ( height - y - 1 ) * width + x ) * storageComponents;
110 data.put(i++, Y);
111 data.put(i++, Cb);
112 data.put(i++, Cr);
113 }
114
115 @Override
116 public String toString() {
117 return "JPEGPixels["+width+"x"+height+", sourceComp "+sourceComponents+", sourceCS "+sourceCS+", storageCS "+storageCS+", storageComp "+storageComponents+"]";
118 }
119 };
120
121 private JPEGImage(final InputStream in, final ColorSpace cs) throws IOException {
122 pixelStorage = new JPEGColorSink(cs);
123 final JPEGDecoder decoder = new JPEGDecoder();
124 decoder.parse(in);
125 pixelWidth = decoder.getWidth();
126 pixelHeight = decoder.getHeight();
127 decoder.getPixel(pixelStorage, pixelWidth, pixelHeight);
128 data = pixelStorage.data;
129 final boolean hasAlpha = false;
130
131 bytesPerPixel = 3;
132 glFormat = GL.GL_RGB;
133 reversedChannels = false; // RGB[A]
134 if(DEBUG) {
135 System.err.println("JPEGImage: alpha "+hasAlpha+", bytesPerPixel "+bytesPerPixel+
136 ", pixels "+pixelWidth+"x"+pixelHeight+", glFormat 0x"+Integer.toHexString(glFormat));
137 System.err.println("JPEGImage: "+decoder);
138 System.err.println("JPEGImage: "+pixelStorage);
139 }
140 decoder.clear(null);
141 }
142 private final JPEGColorSink pixelStorage;
143 private final int pixelWidth, pixelHeight, glFormat, bytesPerPixel;
144 private final boolean reversedChannels;
145 private final ByteBuffer data;
146
147 /** Returns the color space of the pixel data */
148 public ColorSpace getColorSpace() { return pixelStorage.storageCS; }
149
150 /** Returns the number of components of the pixel data */
151 public int getComponentCount() { return pixelStorage.storageComponents; }
152
153 /** Returns the width of the image. */
154 public int getWidth() { return pixelWidth; }
155
156 /** Returns the height of the image. */
157 public int getHeight() { return pixelHeight; }
158
159 /** Returns true if data has the channels reversed to BGR or BGRA, otherwise RGB or RGBA is expected. */
160 public boolean getHasReversedChannels() { return reversedChannels; }
161
162 /** Returns the OpenGL format for this texture; e.g. GL.GL_LUMINANCE, GL.GL_RGB or GL.GL_RGBA. */
163 public int getGLFormat() { return glFormat; }
164
165 /** Returns the OpenGL data type: GL.GL_UNSIGNED_BYTE. */
166 public int getGLType() { return GL.GL_UNSIGNED_BYTE; }
167
168 /** Returns the bytes per pixel */
169 public int getBytesPerPixel() { return bytesPerPixel; }
170
171 /** Returns the raw data for this texture in the correct
172 (bottom-to-top) order for calls to glTexImage2D. */
173 public ByteBuffer getData() { return data; }
174
175 @Override
176 public String toString() { return "JPEGImage["+pixelWidth+"x"+pixelHeight+", bytesPerPixel "+bytesPerPixel+", reversedChannels "+reversedChannels+", "+pixelStorage+", "+data+"]"; }
177}
int getComponentCount()
Returns the number of components of the pixel data.
Definition: JPEGImage.java:151
ByteBuffer getData()
Returns the raw data for this texture in the correct (bottom-to-top) order for calls to glTexImage2D.
Definition: JPEGImage.java:173
int getBytesPerPixel()
Returns the bytes per pixel.
Definition: JPEGImage.java:169
ColorSpace getColorSpace()
Returns the color space of the pixel data.
Definition: JPEGImage.java:148
int getGLFormat()
Returns the OpenGL format for this texture; e.g.
Definition: JPEGImage.java:163
int getWidth()
Returns the width of the image.
Definition: JPEGImage.java:154
int getHeight()
Returns the height of the image.
Definition: JPEGImage.java:157
int getGLType()
Returns the OpenGL data type: GL.GL_UNSIGNED_BYTE.
Definition: JPEGImage.java:166
static JPEGImage read(final InputStream in, final ColorSpace cs)
Reads a JPEG image from the specified InputStream, using the given color space for storage.
Definition: JPEGImage.java:54
boolean getHasReversedChannels()
Returns true if data has the channels reversed to BGR or BGRA, otherwise RGB or RGBA is expected.
Definition: JPEGImage.java:160
static JPEGImage read(final InputStream in)
Reads a JPEG image from the specified InputStream, using the ColorSpace#RGB.
Definition: JPEGImage.java:59
static final int GL_UNSIGNED_BYTE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_UNSIGNED_BYTE" with e...
Definition: GL.java:284