diff options
author | Sven Gothel <[email protected]> | 2015-08-19 05:55:09 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-08-19 05:55:09 +0200 |
commit | c4ed57f617117e3e38319f1a44a0d066f1a332b3 (patch) | |
tree | b4fcf17f9c1f8d51c7afdab28ec477ccbc51b220 /src | |
parent | 3e8ef0ae4305fede0f1ddac2fee476c76c5a25a3 (diff) |
Bug 1042: ImageIOUtil -> ImageType + ImageType.Util ; Fix implementation and test.
- ImageIOUtil -> ImageType + ImageType.Util
- ImageType.Util.getFileSuffix(..):
- Fix byte type conversion, i.e. 'b == (byte)0x89',
cast is required to avoid byte -> int conversion.
Note: signed byte -128 - +128
- Parse in O(1), i.e. lexicographical parsing
- FIXME: We seem to have at least three type collisions, validate!
- ImageType:
- Complete T_* w/ API doc -> FIXME/TODO missing type references!
- ImageType instancing via InputStream or manual type definition.
- TextureData
- Contains optional source ImageType
- TextureProvider:
- Deprecate newTextureData(..) variants other than InputStream
simplifying TextureIO.
- TextureProvider.SupportsImageTypes:
- Added interface, allowing mapping ImageType -> provider
- Tested standalone ImageType (TestImageTypeNEWT) and
via TextureIO (TestTextureIONEWT) utilizing list of all
test data (ImageTstFiles), i.e. PNG, JPG, TGA and DDS.
Diffstat (limited to 'src')
11 files changed, 2121 insertions, 1505 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java deleted file mode 100644 index 2ce555749..000000000 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageIOUtil.java +++ /dev/null @@ -1,1336 +0,0 @@ -/** - * Copyright 2014 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package com.jogamp.opengl.util.texture; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Utilities for image input and output - * - */ -public class ImageIOUtil { - /** - * Constant which can be used as a file suffix to indicate a JPEG stream. - * <ul> - * <li>{@code http://www.faqs.org/faqs/jpeg-faq/part1/}</li> - * <li>{@code http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=54989}</li> - * </ul> - */ - public static final String T_JPG = "jpg"; - - /** - * Constant which can be used as a file suffix to indicate a PNG stream. - * <ul> - * <li>{@code http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html#R.PNG-file-signature}</li> - * </ul> - */ - public static final String T_PNG = "png"; - - /** - * Constant which can be used as a file suffix to indicate an Apple Icon Image stream. - * <p> - * {@code 'i' 'c' 'n' 's' ascii code} - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_ICNS = "icns"; - - /** - * Constant which can be used as a file suffix to indicate a GIF stream. - * <p> - * {@code GIF87A or GIF89A ascii code} - * </p> - * <ul> - * <li>{@code http://www.w3.org/Graphics/GIF/spec-gif87a.txt http://www.w3.org/Graphics/GIF/spec-gif89a.txt}</li> - * </ul> - */ - public static final String T_GIF = "gif"; - - /** - * Constant which can be used as a file suffix to indicate a GIF stream. - * <p> - * {@code BM ascii code} - * </p> - * <ul> - * <li>{@code http://www.fileformat.info/format/bmp/spec/e27073c25463436f8a64fa789c886d9c/view.htm}</li> - * </ul> - */ - public static final String T_BMP = "bmp"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_DCX = "dcx"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_PCX = "pcx"; - - /** - * Constant which can be used as a file suffix to indicate a PAM stream, NetPbm magic 6 - binary RGB. - * <ul> - * <li>{@code http://netpbm.sourceforge.net/doc/ppm.html}</li> - * </ul> - */ - public static final String T_PPM = "ppm"; - - /** - * Constant which can be used as a file suffix to indicate a Adobe PhotoShop stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_PSD = "psd"; - - /** - * Constant which can be used as a file suffix to indicate a TIFF stream. - * <p> - * Intentionally detects only the little endian tiff images ("II" in the spec). - * </p> - * <ul> - * <li>{@code http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf}</li> - * </ul> - */ - public static final String T_TIFF = "tiff"; - - /** - * Constant which can be used as a file suffix to indicate an SGI RGB stream. - * <p> - * "474 saved as a short" 474 = 0x01DA - * </p> - * <ul> - * <li>{@code http://paulbourke.net/dataformats/sgirgb/sgiversion.html}</li> - * </ul> - */ - public static final String T_SGI_RGB = "rgb"; - - /** - * Constant which can be used as a file suffix to indicate a DirectDraw Surface stream. - * <p> - * 'D' 'D' 'S' ' ' ascii code - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_DDS = "dds"; - - /** - * Constant which can be used as a file suffix to indicate a PAM stream, NetPbm magic 7 - binary RGB and RGBA. - * <ul> - * <li>{@code http://netpbm.sourceforge.net/doc/pam.html}</li> - * </ul> - */ - public static final String T_PAM = "pam"; - - /** - * Constant which can be used as a file suffix to indicate a PGM stream, NetPbm magic 5 - binary grayscale. - * <ul> - * <li>{@code http://netpbm.sourceforge.net/doc/pgm.html}</li> - * </ul> - */ - public static final String T_PGM = "pgm"; - - /** - * Constant which can be used as a file suffix to indicate a PGM stream, NetPbm magic 4 - binary monochrome. - * <ul> - * <li>{@code http://netpbm.sourceforge.net/doc/pbm.html}</li> - * </ul> - */ - public static final String T_PBM = "pbm"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_3D2 = "3d2"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_3DMF = "3dmf"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_92I = "92i"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_AMFF = "amff"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_ART = "art"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_CALS = "cals"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_CAM = "cam"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_CBD = "cbd"; - - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_CE2 = "ce2"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_CIN = "cin"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_COB = "cob"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_CPT = "cpt"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_CVG = "cvg"; - - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_DEM = "dem"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_DIB = "dib"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_DPX = "dpx"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_DRW = "drw"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_DWG = "dwg"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_ECW = "ecw"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_EMF = "emf"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_FPX = "fpx"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_FTS = "fts"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_GRO = "gro"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_HDR = "hdr"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_HRU = "hru"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_IMG = "img"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_INFINI_D = "infini-d"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_IWC = "iwc"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_J6I = "j6i"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_JIF = "jif"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_JP2 = "jp2"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_KDC = "kdc"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_L64 = "l64"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_LBM = "lbm"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_LDF = "ldf"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_LWF = "lwf"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_MBM = "mbm"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_MGL = "mgl"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_MIF = "mif"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_MNG = "mng"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_MPW = "mpw"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_MSP = "msp"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_N64 = "n64"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_NCR = "ncr"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_NFF = "nff"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_NGG = "ngg"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_NLM = "nlm"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_NOL = "nol"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_PAL = "pal"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_PAX = "pax"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_PCD = "pcd"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_PCL = "pcl"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_PIX = "pix"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_POL = "pol"; - - /** - * Constant which can be used as a file suffix to indicate a {@code Paint Shop Pro} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_PSP = "psp"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_QFX = "qfx"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_QTM = "qtm"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_RAD = "rad"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_RAS = "ras"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_RIX = "rix"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_SID = "sid"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_SLD = "sld"; - - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_SOD = "sod"; - - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_WIC = "wic"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_WLM = "wlm"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_WMF = "wmf"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_WPG = "wpg"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_WRL = "wrl"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_XBM = "xbm"; - - /** - * Constant which can be used as a file suffix to indicate a {@code TBD} stream. - * <p> - * TODO - * </p> - * <ul> - * <li>{@code TODO}</li> - * </ul> - */ - public static final String T_XPM = "xpm"; - - // JAU - - /** - * Constant which can be used as a file suffix to indicate an SGI RGB stream. - * <ul> - * <li>{@code }</li> - * </ul> - */ - public static final String T_SGI = "sgi"; - - /** - * Constant which can be used as a file suffix to indicate a Targa stream. - * <ul> - * <li>{@code }</li> - * </ul> - */ - public static final String T_TGA = "tga"; - - /** - * Determines the file suffix (i.e the image format) of the given InputStream. The given - * InputStream must return true from markSupported() and support a minimum of 32 bytes - * of read-ahead. - * - * @param stream stream to check - * @return the file suffix if any, otherwise <code>null</code> - * @throws java.io.IOException if an I/O exception occurred - */ - public static String getFileSuffix(InputStream stream) throws IOException { - if (stream == null) { - throw new IOException("Stream was null"); - } - if (!(stream instanceof BufferedInputStream)) { - stream = new BufferedInputStream(stream); - } - if (!stream.markSupported()) { - throw new IOException("Can not get non-destructively the image format"); - } - if (stream.available() < 32) { - throw new IOException("Not enough bytes to read in order to get the image format"); - } - try { - stream.mark(32); - final byte[] b = new byte[32]; - stream.read(b); - return getFileSuffix(b); - } finally { - stream.reset(); - } - - } - - /** - * Determines the file suffix (i.e the image format) of the given bytes from the header - * of a file. - * - * @param stream stream to check - * @return the file suffix if any, otherwise <code>null</code> - * @throws java.io.IOException if an I/O exception occurred - */ - public static String getFileSuffix(final byte[] b) { - if ( (b[0] == 0xff && b[1] == 0xd8 /* && b[2] == 0xff */) || - (b[0] == 0x4A && b[1] == 0x46 && b[2] == 0x49 && b[3] == 0x46)/* JFIF */ || - (b[0] == 0x45 && b[1] == 0x78 && b[2] == 0x69 && b[3] == 0x66)/* EXIF */) { - return T_JPG; - } - if (b[0] == 0x89 && b[1] == 0x50 && b[2] == 0x4E && b[3] == 0x47 && /* 'P' 'N' 'G', ascii code */ - b[4] == 0x0D && b[5] == 0x0A && b[6] == 0x1A && b[7] == 0x0A) { - return T_PNG; - } - if (b[0] == 0x69 && b[1] == 0x63 && b[2] == 0x6E && b[3] == 0x73) { - return T_ICNS; - } - if (b[0] == 0x47 && b[1] == 0x49 && b[2] == 0x46 && b[3] == 0x38 && (b[4] == 0x37 || b[4] == 0x39) && - b[5] == 0x61) { - return T_GIF; - } - if (b[0] == 0x42 && b[1] == 0x4d) { - return T_BMP; - } - if (b[0] == 0x3A && b[1] == 0xDE && b[2] == 0x68 && b[3] == 0xB1) { - return T_DCX; - } - if (b[0] == 0x0A && b[1] == 0x05 && b[2] == 0x01 && b[3] == 0x08) { - return T_PCX; - } - if (b[0] == 0x50 && (b[1] == 0x33 /* plain */|| b[1] == 0x36)) { - return T_PPM; - } - if (b[0] == 0x38 && b[1] == 0x42 && b[2] == 0x50 && b[3] == 0x53 && b[4] == 0x00 && b[5] == 0x01 && - b[6] == 0x00 && b[7] == 0x00 && b[8] == 0x00 && b[9] == 0x00) { - // Adobe PhotoShop - return T_PSD; - } - if (b[0] == 0x49 && b[1] == 0x49 && b[2] == 0x2A && b[3] == 0x00) { - return T_TIFF; - } - if (b[0] == 0x01 && b[1] == 0xDA /* && b[2] == 0x01 && b[3] == 0x01 && b[4] == 0x00 && b[5] == 0x03 */) { - return T_SGI_RGB; - } - if (b[0] == 0x44 && b[1] == 0x44 && b[2] == 0x53 && b[3] == 0x20) { - return T_DDS; - } - if (b[0] == 0x50 && b[1] == 0x37) { - return T_PAM; - } - if (b[0] == 0x50 && (b[1] == 0x32 /* plain */|| b[1] == 0x35)) { - return T_PGM; - } - if (b[0] == 0x50 && (b[1] == 0x31 /* plain */|| b[1] == 0x34)) { - return T_PBM; - } - if (b[0] == 0x3D && b[1] == 0x02) { - return T_3D2; - } - if (b[0] == 0x33 && b[1] == 0x44 && b[2] == 0x4D && b[3] == 0x46) { - return T_3DMF; - } - if (b[0] == 0x2A && b[1] == 0x2A && b[2] == 0x54 && b[3] == 0x49 && b[4] == 0x39 && b[5] == 0x32 && - b[6] == 0x2A && b[7] == 0x2A && b[8] == 0x01 && b[9] == 0x00 && b[10] == 0x58 && - b[11] == 0x6E && b[12] == 0x56 && b[13] == 0x69) { - return T_92I; - } - if (b[0] == 0x41 && b[1] == 0x4D && b[2] == 0x46 && b[3] == 0x46) { - return T_AMFF; - } - if (b[0] == 0x4A && b[1] == 0x47 && (b[2] == 0x03 || b[2] == 0x04) && b[3] == 0x0E && b[4] == 0x00 && - b[5] == 0x00 && b[6] == 0x00) { - return T_ART; - } - if (b[0] == 0x73 && b[1] == 0x72 && b[2] == 0x63 && b[3] == 0x64 && b[4] == 0x6F && b[5] == 0x63 && - b[6] == 0x69 && b[7] == 0x64 && b[8] == 0x3A) { - return T_CALS; - } - if (b[0] == 0x07 && b[1] == 0x20 && b[2] == 0x4D && b[3] == 0x4D) { - return T_CAM; - } - if (b[0] == 0x20 && b[1] == 0x77 && b[2] == 0x00 && b[3] == 0x02) { - return T_CBD; - } - if (b[0] == 0x45 && b[1] == 0x59 && b[2] == 0x45 && b[3] == 0x53) { - return T_CE2; - } - if (b[0] == 0x80 && b[1] == 0x2A && b[2] == 0x5F && b[3] == 0xD7 && b[4] == 0x00 && b[5] == 0x00 && - b[6] == 0x08 && b[7] == 0x00 && b[8] == 0x00 && b[9] == 0x00 && b[10] == 0x04 && - b[11] == 0x00 && b[12] == 0x00 && b[13] == 0x00) { - return T_CIN; - } - if (b[0] == 0x43 && b[1] == 0x61 && b[2] == 0x6C && b[3] == 0x69 && b[4] == 0x67 && b[5] == 0x61 && - b[6] == 0x72 && b[7] == 0x69) { - return T_COB; - } - if (b[0] == 0x43 && b[1] == 0x50 && b[2] == 0x54 && b[3] == 0x46 && b[4] == 0x49 && b[5] == 0x4C && - b[6] == 0x45) { - return T_CPT; - } - if (b[0] == 0x43 && b[1] == 0x41 && b[2] == 0x4C && b[3] == 0x41 && b[4] == 0x4D && b[5] == 0x55 && - b[6] == 0x53 && b[7] == 0x43 && b[8] == 0x56 && b[9] == 0x47) { - return T_CVG; - } - if (b[0] == 0x56 && b[1] == 0x69 && b[2] == 0x73 && b[3] == 0x74 && b[4] == 0x61 && b[5] == 0x20 && - b[6] == 0x44 && b[7] == 0x45 && b[8] == 0x4D && b[9] == 0x20 && b[10] == 0x46 && - b[11] == 0x69 && b[12] == 0x6C && b[13] == 0x65) { - return T_DEM; - } - if (b[0] == 0x42 && b[1] == 0x4D && b[2] == 0x36) { - return T_DIB; - } - if (b[0] == 0x53 && b[1] == 0x44 && b[2] == 0x50 && b[3] == 0x58) { - return T_DPX; - } - if (b[0] == 0x01 && b[1] == 0xFF && b[2] == 0x02 && b[3] == 0x04 && b[4] == 0x03 && b[5] == 0x02) { - return T_DRW; - } - if (b[0] == 0x41 && b[1] == 0x43 && b[2] == 0x31 && b[3] == 0x30) { - return T_DWG; - } - if (b[0] == 0x65 && b[1] == 0x02 && b[2] == 0x01 && b[3] == 0x02) { - return T_ECW; - } - if (b[0] == 0x01 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x00 && b[4] == 0x58 && b[5] == 0x00 && - b[6] == 0x00 && b[7] == 0x00) { - return T_EMF; - } - if (b[0] == 0xD0 && b[1] == 0xCF && b[2] == 0x11 && b[3] == 0xE0 && b[4] == 0xA1 && b[5] == 0xB1 && - b[6] == 0x1A && b[7] == 0xE1 && b[8] == 0x00) { - return T_FPX; - } - if (b[0] == 0x53 && b[1] == 0x49 && b[2] == 0x4D && b[3] == 0x50 && b[4] == 0x4C && b[5] == 0x45 && - b[6] == 0x20 && b[7] == 0x20 && b[8] == 0x3D) { - return T_FTS; - } - if (b[0] == 0x48 && b[1] == 0x50 && b[2] == 0x48 && b[3] == 0x50 && b[4] == 0x34 && b[5] == 0x38 && - b[6] == 0x2D && b[7] == 0x45 && b[8] == 0x1E && b[9] == 0x2B) { - return T_GRO; - } - if (b[0] == 0x6E && b[1] == 0x63 && b[2] == 0x6F && b[3] == 0x6C && b[4] == 0x73) { - return T_HDR; - } - if (b[0] == 0x35 && b[1] == 0x4B && b[2] == 0x50 && b[3] == 0x35 && b[4] == 0x31 && b[5] == 0x5D && - b[6] == 0x2A && b[7] == 0x67 && b[8] == 0x72 && b[9] == 0x72 && b[10] == 0x80 && - b[11] == 0x83 && b[12] == 0x85 && b[13] == 0x63) { - return T_HRU; - } - if (b[0] == 0xEB && b[1] == 0x3C && b[2] == 0x90 && b[3] == 0x2A) { - return T_IMG; - } - if (b[0] == 0x65 && b[1] == 0x6C && b[2] == 0x6D && b[3] == 0x6F) { - return T_INFINI_D; - } - if (b[0] == 0x49 && b[1] == 0x57 && b[2] == 0x43 && b[3] == 0x01) { - return T_IWC; - } - if (b[0] == 0x80 && b[1] == 0x3E && b[2] == 0x44 && b[3] == 0x53 && b[4] == 0x43 && b[5] == 0x49 && - b[6] == 0x4D) { - return T_J6I; - } - if (b[0] == 0x4A && b[1] == 0x49 && b[2] == 0x46 && b[3] == 0x39 && b[4] == 0x39 && b[5] == 0x61) { - return T_JIF; - } - if (b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x0C && b[4] == 0x6A && b[5] == 0x50 && - b[6] == 0x20 && b[7] == 0x20 && b[8] == 0x0D && b[9] == 0x0A && b[10] == 0x87 && - b[11] == 0x0A) { - return T_JP2; - } - if (b[0] == 0x4D && b[1] == 0x4D && b[2] == 0x00 && b[3] == 0x2A) { - return T_KDC; - } - if (b[0] == 0x36 && b[1] == 0x34 && b[2] == 0x4C && b[3] == 0x41 && b[4] == 0x4E && b[5] == 0x20 && - b[6] == 0x49 && b[7] == 0x44 && b[8] == 0x42 && b[9] == 0x4C && b[10] == 0x4F && - b[11] == 0x43 && b[12] == 0x4B) { - return T_L64; - } - if (b[0] == 0x46 && b[1] == 0x4F && b[2] == 0x52 && b[3] == 0x4D) { - return T_LBM; - } - if (b[0] == 0x49 && b[1] == 0x49 && b[2] == 0x2A && b[3] == 0x00 && b[4] == 0x08 && b[5] == 0x00 && - b[6] == 0x00 && b[7] == 0x00 && b[8] == 0x0E && b[9] == 0x00 && b[10] == 0x00 && - b[11] == 0x01 && b[12] == 0x04 && b[13] == 0x00) { - return T_LDF; - } - if (b[0] == 0x57 && b[1] == 0x56 && b[2] == 0x02 && b[3] == 0x00 && b[4] == 0x47 && b[5] == 0x45 && - b[6] == 0x00 && b[7] == 0x0E) { - return T_LWF; - } - if (b[0] == 0x37 && b[1] == 0x00 && b[2] == 0x00 && b[3] == 0x10 && b[4] == 0x42 && b[5] == 0x00 && - b[6] == 0x00 && b[7] == 0x10 && b[8] == 0x00 && b[9] == 0x00 && b[10] == 0x00 && - b[11] == 0x00 && b[12] == 0x39 && b[13] == 0x64) { - return T_MBM; - } - if (b[0] == 0x4D && b[1] == 0x47 && b[2] == 0x4C) { - return T_MGL; - } - if (b[0] == 0x7B && b[1] == 0x0A && b[2] == 0x20 && b[3] == 0x20 && b[4] == 0x43 && b[5] == 0x72 && - b[6] == 0x65 && b[7] == 0x61 && b[8] == 0x74 && b[9] == 0x65 && b[10] == 0x64) { - return T_MIF; - } - if (b[0] == 0x8A && b[1] == 0x4D && b[2] == 0x4E && b[3] == 0x47 && b[4] == 0x0D && b[5] == 0x0A && - b[6] == 0x1A && b[7] == 0x0A) { - return T_MNG; - } - if (b[0] == 0x4D && b[1] == 0x50 && b[2] == 0x46) { - return T_MPW; - } - if (b[0] == 0x44 && b[1] == 0x61 && b[2] == 0x6E && b[3] == 0x4D) { - return T_MSP; - } - if (b[0] == 0x43 && b[1] == 0x36 && b[2] == 0x34) { - return T_N64; - } - if (b[0] == 0x6E && b[1] == 0x6E && b[2] == 0x0A && b[3] == 0x00 && b[4] == 0x5E && b[5] == 0x00) { - return T_NCR; - } - if (b[0] == 0x6E && b[1] == 0x66 && b[2] == 0x66) { - return T_NFF; - } - if (b[0] == 0x4E && b[1] == 0x47 && b[2] == 0x47 && b[3] == 0x00 && b[4] == 0x01 && b[5] == 0x00) { - return T_NGG; - } - if (b[0] == 0x4E && b[1] == 0x4C && b[2] == 0x4D && b[3] == 0x20 && b[4] == 0x01 && b[5] == 0x02 && - b[6] == 0x00) { - return T_NLM; - } - if (b[0] == 0x4E && b[1] == 0x4F && b[2] == 0x4C && b[3] == 0x00 && b[4] == 0x01 && b[5] == 0x00 && - b[6] == 0x06 && b[7] == 0x01 && b[8] == 0x03 && b[9] == 0x00) { - return T_NOL; - } - if (b[0] == 0x41 && b[1] == 0x48) { - return T_PAL; - } - if (b[0] == 0x50 && b[1] == 0x41 && b[2] == 0x58) { - return T_PAX; - } - if (b[0] == 0x63 && b[1] == 0x52 && b[2] == 0x01 && b[3] == 0x01 && b[4] == 0x38 && b[5] == 0x09 && - b[6] == 0x3D && b[7] == 0x00) { - return T_PCD; - } - if (b[0] == 0x1B && b[1] == 0x45 && b[2] == 0x1B && b[3] == 0x26 && b[4] == 0x6C && b[5] == 0x30 && - b[6] == 0x4F && b[7] == 0x1B && b[8] == 0x26 && b[9] == 0x6C && b[10] == 0x30 && - b[11] == 0x45 && b[12] == 0x1B && b[13] == 0x26) { - return T_PCL; - } - if (b[0] == 0x50 && b[1] == 0x49 && b[2] == 0x58 && b[3] == 0x20) { - return T_PIX; - } - if (b[0] == 0x50 && b[1] == 0x4F && b[2] == 0x4C && b[3] == 0x20 && b[4] == 0x46 && b[5] == 0x6F && - b[6] == 0x72 && b[7] == 0x6D && b[8] == 0x61 && b[9] == 0x74) { - return T_POL; - } - if (b[0] == 0x7E && b[1] == 0x42 && b[2] == 0x4B && b[3] == 0x00) { - return T_PSP; - } - if (b[0] == 0x50 && b[1] == 0x61 && b[2] == 0x69 && b[3] == 0x6E && b[4] == 0x74 && b[5] == 0x20 && - b[6] == 0x53 && b[7] == 0x68 && b[8] == 0x6F && b[9] == 0x70 && b[10] == 0x20 && - b[11] == 0x50 && b[12] == 0x72 && b[13] == 0x6F && b[14] == 0x20 && b[15] == 0x49 && - b[16] == 0x6D && b[17] == 0x61 && b[18] == 0x67 && b[19] == 0x65 && b[20] == 0x20 && - b[21] == 0x46 && b[22] == 0x69 && b[23] == 0x6C && b[24] == 0x65) { - return T_PSP; - } - if (b[0] == 0x51 && b[1] == 0x4C && b[2] == 0x49 && b[3] == 0x49 && b[4] == 0x46 && b[5] == 0x41 && - b[6] == 0x58) { - return T_QFX; - } - if (b[0] == 0x6D && b[1] == 0x6F && b[2] == 0x6F && b[3] == 0x76) { - return T_QTM; - } - if (b[0] == 0x46 && b[1] == 0x4F && b[2] == 0x52 && b[3] == 0x4D && b[4] == 0x41 && b[5] == 0x54 && - b[6] == 0x3D) { - return T_RAD; - } - if (b[0] == 0x59 && b[1] == 0xA6 && b[2] == 0x6A && b[3] == 0x95) { - return T_RAS; - } - if (b[0] == 0x52 && b[1] == 0x49 && b[2] == 0x58 && b[3] == 0x33) { - return T_RIX; - } - if (b[0] == 0x23 && b[1] == 0x20 && b[2] == 0x24 && b[3] == 0x49 && b[4] == 0x64 && b[5] == 0x3A && - b[6] == 0x20) { - return T_SID; - } - if (b[0] == 0x41 && b[1] == 0x75 && b[2] == 0x74 && b[3] == 0x6F && b[4] == 0x43 && b[5] == 0x41 && - b[6] == 0x44 && b[7] == 0x20 && b[8] == 0x53 && b[9] == 0x6C && b[10] == 0x69 && - b[11] == 0x64 && b[12] == 0x65) { - return T_SLD; - } - if (b[0] == 0x53 && b[1] == 0x74 && b[2] == 0x6F && b[3] == 0x72 && b[4] == 0x6D && b[5] == 0x33 && - b[6] == 0x44) { - return T_SOD; - } - if (b[0] == 0xFA && b[1] == 0xDE && b[2] == 0xBA && b[3] == 0xBE && b[4] == 0x01 && b[5] == 0x01) { - return T_WIC; - } - if (b[0] == 0xD3 && b[1] == 0x23 && b[2] == 0x00 && b[3] == 0x00 && b[4] == 0x03 && b[5] == 0x00 && - b[6] == 0x00 && b[7] == 0x00) { - return T_WLM; - } - if (b[0] == 0xD7 && b[1] == 0xCD && b[2] == 0xC6 && b[3] == 0x9A) { - return T_WMF; - } - if (b[0] == 0xFF && b[1] == 0x57 && b[2] == 0x50 && b[3] == 0x43 && b[4] == 0x10) { - return T_WPG; - } - if (b[0] == 0x23 && b[1] == 0x56 && b[2] == 0x52 && b[3] == 0x4D && b[4] == 0x4C && b[5] == 0x20 && - b[6] == 0x56 && b[7] == 0x32 && b[8] == 0x2E && b[9] == 0x30) { - return T_WRL; - } - if (b[0] == 0x23 && b[1] == 0x64 && b[2] == 0x65 && b[3] == 0x66 && b[4] == 0x69 && b[5] == 0x6E && - b[6] == 0x65) { - return T_XBM; - } - if (b[0] == 0x2F && b[1] == 0x2A && b[2] == 0x20 && b[3] == 0x58 && b[4] == 0x50 && b[5] == 0x4D && - b[6] == 0x20 && b[7] == 0x2A && b[8] == 0x2F) { - return T_XPM; - } - return null; - } -} diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java new file mode 100644 index 000000000..1cdac2d48 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageType.java @@ -0,0 +1,1534 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.util.texture; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Image type classification. + * <p> + * Allows to classify the {@link ImageType} of an {@link InputStream} via {@link #ImageType(InputStream)} + * or to simply define one {@link ImageType} via {@link #ImageType(String)}. + * </p> + * @since 2.3.2 + */ +public class ImageType { + /** + * Minimum number of bytes to determine the image data type, i.e. {@value} bytes. + */ + public static final int MAGIC_MAX_SIZE = 25; + + /** + * Constant which can be used as a file suffix to indicate a JPEG stream, value {@value}. + * <ul> + * <li>{@code http://www.faqs.org/faqs/jpeg-faq/part1/}</li> + * <li>{@code http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=54989}</li> + * </ul> + */ + public static final String T_JPG = "jpg"; + + /** + * Constant which can be used as a file suffix to indicate a PNG stream, value {@value}. + * <ul> + * <li>{@code http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html#R.PNG-file-signature}</li> + * </ul> + */ + public static final String T_PNG = "png"; + + /** + * Constant which can be used as a file suffix to indicate an Apple Icon Image stream, value {@value}. + * <p> + * {@code 'i' 'c' 'n' 's' ascii code} + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_ICNS = "icns"; + + /** + * Constant which can be used as a file suffix to indicate a GIF stream, value {@value}. + * <p> + * {@code GIF87A or GIF89A ascii code} + * </p> + * <ul> + * <li>{@code http://www.w3.org/Graphics/GIF/spec-gif87a.txt http://www.w3.org/Graphics/GIF/spec-gif89a.txt}</li> + * </ul> + */ + public static final String T_GIF = "gif"; + + /** + * Constant which can be used as a file suffix to indicate a GIF stream, value {@value}. + * <p> + * {@code BM ascii code} + * </p> + * <p> + * FIXME: Collision or supertype of {@link #T_DIB}? + * </p> + * <ul> + * <li>{@code http://www.fileformat.info/format/bmp/spec/e27073c25463436f8a64fa789c886d9c/view.htm}</li> + * </ul> + */ + public static final String T_BMP = "bmp"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * FIXME: Collision or subtype of {@link #T_BMP}? + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_DIB = "dib"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_DCX = "dcx"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_PCX = "pcx"; + + /** + * Constant which can be used as a file suffix to indicate a PAM stream, NetPbm magic 6 - binary RGB. + * <ul> + * <li>{@code http://netpbm.sourceforge.net/doc/ppm.html}</li> + * </ul> + */ + public static final String T_PPM = "ppm"; + + /** + * Constant which can be used as a file suffix to indicate a Adobe PhotoShop stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_PSD = "psd"; + + /** + * Constant which can be used as a file suffix to indicate a TIFF stream, value {@value}. + * <p> + * Intentionally detects only the little endian tiff images ("II" in the spec). + * </p> + * <p> + * FIXME: Collision or supertype of {@link #T_LDF}? + * </p> + * <ul> + * <li>{@code http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf}</li> + * </ul> + */ + public static final String T_TIFF = "tiff"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * FIXME: Collision or subtype of {@link #T_TIFF}? + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_LDF = "ldf"; + + /** + * Constant which can be used as a file suffix to indicate an SGI RGB stream, value {@value}. + * <p> + * "474 saved as a short" 474 = 0x01DA + * </p> + * <ul> + * <li>{@code http://paulbourke.net/dataformats/sgirgb/sgiversion.html}</li> + * </ul> + */ + public static final String T_SGI_RGB = "rgb"; + + /** + * Constant which can be used as a file suffix to indicate a DirectDraw Surface stream, value {@value}. + * <p> + * 'D' 'D' 'S' ' ' ascii code + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_DDS = "dds"; + + /** + * Constant which can be used as a file suffix to indicate a PAM stream, NetPbm magic 7 - binary RGB and RGBA. + * <ul> + * <li>{@code http://netpbm.sourceforge.net/doc/pam.html}</li> + * </ul> + */ + public static final String T_PAM = "pam"; + + /** + * Constant which can be used as a file suffix to indicate a PGM stream, NetPbm magic 5 - binary grayscale. + * <ul> + * <li>{@code http://netpbm.sourceforge.net/doc/pgm.html}</li> + * </ul> + */ + public static final String T_PGM = "pgm"; + + /** + * Constant which can be used as a file suffix to indicate a PGM stream, NetPbm magic 4 - binary monochrome. + * <ul> + * <li>{@code http://netpbm.sourceforge.net/doc/pbm.html}</li> + * </ul> + */ + public static final String T_PBM = "pbm"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_3D2 = "3d2"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_3DMF = "3dmf"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_92I = "92i"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_AMFF = "amff"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_ART = "art"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_CALS = "cals"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_CAM = "cam"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_CBD = "cbd"; + + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_CE2 = "ce2"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_CIN = "cin"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_COB = "cob"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_CPT = "cpt"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_CVG = "cvg"; + + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_DEM = "dem"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_DPX = "dpx"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_DRW = "drw"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_DWG = "dwg"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_ECW = "ecw"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_EMF = "emf"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_FPX = "fpx"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_FTS = "fts"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_GRO = "gro"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_HDR = "hdr"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_HRU = "hru"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_IMG = "img"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_INFINI_D = "infini-d"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_IWC = "iwc"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_J6I = "j6i"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_JIF = "jif"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_JP2 = "jp2"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_KDC = "kdc"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_L64 = "l64"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * FIXME: Collision or supertype of {@link #T_RAD}? + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_LBM = "lbm"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * FIXME: Collision or subtype of {@link #T_LBM}? + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_RAD = "rad"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_LWF = "lwf"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_MBM = "mbm"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_MGL = "mgl"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_MIF = "mif"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_MNG = "mng"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_MPW = "mpw"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_MSP = "msp"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_N64 = "n64"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_NCR = "ncr"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_NFF = "nff"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_NGG = "ngg"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_NLM = "nlm"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_NOL = "nol"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_PAL = "pal"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_PAX = "pax"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_PCD = "pcd"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_PCL = "pcl"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_PIX = "pix"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_POL = "pol"; + + /** + * Constant which can be used as a file suffix to indicate a {@code Paint Shop Pro} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_PSP = "psp"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_QFX = "qfx"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_QTM = "qtm"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_RAS = "ras"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_RIX = "rix"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_SID = "sid"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_SLD = "sld"; + + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_SOD = "sod"; + + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_WIC = "wic"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_WLM = "wlm"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_WMF = "wmf"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_WPG = "wpg"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_WRL = "wrl"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_XBM = "xbm"; + + /** + * Constant which can be used as a file suffix to indicate a {@code TBD} stream, value {@value}. + * <p> + * TODO + * </p> + * <ul> + * <li>{@code TODO}</li> + * </ul> + */ + public static final String T_XPM = "xpm"; + + /** + * Constant which can be used as a file suffix to indicate a Targa stream, value {@value}. + * <ul> + * <li>{@code }</li> + * </ul> + */ + public static final String T_TGA = "tga"; + + /** + * The determined unique type, e.g. {@link #T_PNG}, {@link #T_JPG}, etc. + * <p> + * Maybe {@code null} if undetermined, i.e. {@link #isDefined()} returns {@code false}. + * </p> + */ + public final String type; + + /** + * The optionally read header of size {@link #MAGIC_MAX_SIZE} bytes as used to determine the {@link #type}, + * i.e. {@link #ImageType(InputStream)}. + * <p> + * May be {@code null}, if {@link #type} has been determined otherwise, i.e {@link #ImageType(String)}. + * </p> + * <p> + * The header is <i>not</i> being used for {@link #hashCode()} and {@link #equals(Object)}! + * </p> + */ + public final byte[] header; + + private final int hash; + + /** + * Creates instance based on given stream. + * @param stream stream to parse, {@link InputStream#available()} must be ≥ {@link #MAGIC_MAX_SIZE} + * @throws java.io.IOException if an I/O exception occurred + */ + public ImageType(final InputStream stream) throws IOException { + final byte[] _header = new byte[MAGIC_MAX_SIZE]; + type = Util.getFileSuffix(stream, _header); + this.header = _header; + this.hash = null != this.type ? this.type.hashCode() : 0; + } + /** + * Creates instance based on the given type. + * @param type must be one of {@link #T_PNG}, {@link #T_JPG}, etc. + */ + public ImageType(final String type) { + this.header = null; + this.type = type; + this.hash = this.type.hashCode(); + } + /** Returns {@code true} if {@link #type} is determined, i.e. not {@code null}, otherwise {@code false}. */ + public final boolean isDefined() { return null != type; } + + @Override + public final int hashCode() { + return hash; + } + @Override + public boolean equals(final Object o) { + if( o == this ) { + return true; + } else if( o instanceof ImageType ) { + final ImageType t = (ImageType)o; + return this.type.equals(t.type); + } else { + return false; + } + } + public String toString() { return "ImageType["+type+"]"; } + + /** + * Static utility functions for {@link ImageType} + * to determine the {@link ImageType#type}. + * @since 2.3.2 + */ + public static class Util { + /** + * Determines the file suffix (i.e the image format) of the given InputStream. The given + * InputStream must return true from markSupported() and support a minimum of {@link #MAGIC_MAX_SIZE} bytes + * of read-ahead. + * + * @param stream stream to parse, {@link InputStream#available()} must be ≥ {@link #MAGIC_MAX_SIZE} + * @return the file suffix if any, otherwise <code>null</code> + * @throws java.io.IOException if an I/O exception occurred + */ + public static String getFileSuffix(final InputStream stream) throws IOException { + return getFileSuffix(stream, new byte[MAGIC_MAX_SIZE]); + } + /** + * Determines the file suffix (i.e the image format) of the given InputStream. The given + * InputStream must return true from markSupported() and support a minimum of {@link #MAGIC_MAX_SIZE} bytes + * of read-ahead. + * + * @param stream stream to parse, {@link InputStream#available()} must be ≥ {@link #MAGIC_MAX_SIZE} + * @param b byte array sink, size must be ≥ {@link #MAGIC_MAX_SIZE} + * @return the file suffix if any, otherwise <code>null</code> + * @throws java.io.IOException if an I/O exception occurred + */ + public static String getFileSuffix(InputStream stream, final byte[] b) throws IOException { + if (stream == null) { + throw new IOException("Stream was null"); + } + if (!(stream instanceof BufferedInputStream)) { + stream = new BufferedInputStream(stream); + } + if (!stream.markSupported()) { + throw new IOException("Mark not supported"); + } + if (stream.available() < MAGIC_MAX_SIZE) { + throw new IOException("Requires "+MAGIC_MAX_SIZE+" bytes, has "+stream.available()+" bytes"); + } + try { + stream.mark(MAGIC_MAX_SIZE); + final int bytesRead = stream.read(b); + if( MAGIC_MAX_SIZE > bytesRead ) { + throw new IOException("Could not read "+MAGIC_MAX_SIZE+" bytes, read "+bytesRead+" bytes"); + } + return getFileSuffix(b); + } finally { + stream.reset(); + } + + } + + /** + * Determines the file suffix (i.e the image format) of the given bytes from the header + * of a file. + * + * @param b byte array to parse, size must be ≥ {@link #MAGIC_MAX_SIZE} + * @return the file suffix if any, otherwise <code>null</code> + * @throws java.io.IOException if an I/O exception occurred + */ + public static String getFileSuffix(final byte[] b) { + if( b.length < MAGIC_MAX_SIZE ) { + throw new IllegalArgumentException("byte array must be >= "+MAGIC_MAX_SIZE+", has "+b.length); + } + final byte b0 = b[0]; + final byte b1 = b[1]; + final byte b2 = b[2]; + final byte b3 = b[3]; + final byte b4 = b[4]; + final byte b5 = b[5]; + + // T_TGA: NO Signature! + + if (b0 == (byte)0x00 && b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x0C && + b4 == (byte)0x6A && b5 == (byte)0x50 && + b[6] == (byte)0x20 && b[7] == (byte)0x20 && b[8] == (byte)0x0D && b[9] == (byte)0x0A && b[10] == (byte)0x87 && + b[11] == (byte)0x0A) { + return T_JP2; + } + else if (b0 == (byte)0x01) { + if (b1 == (byte)0xDA /* && b2 == (byte)0x01 && b3 == (byte)0x01 && b4 == (byte)0x00 && b5 == (byte)0x03 */) { + return T_SGI_RGB; + } + else if (b1 == (byte)0xFF && b2 == (byte)0x02 && b3 == (byte)0x04 && + b4 == (byte)0x03 && b5 == (byte)0x02) { + return T_DRW; + } + else if (b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x00 && + b4 == (byte)0x58 && b5 == (byte)0x00 && + b[6] == (byte)0x00 && b[7] == (byte)0x00) { + return T_EMF; + } + } + else if (b0 == (byte)0x07 && b1 == (byte)0x20 && b2 == (byte)0x4D && b3 == (byte)0x4D) { + return T_CAM; + } + else if (b0 == (byte)0x0A && b1 == (byte)0x05 && b2 == (byte)0x01 && b3 == (byte)0x08) { + return T_PCX; + } + else if (b0 == (byte)0x1B && b1 == (byte)0x45 && b2 == (byte)0x1B && b3 == (byte)0x26 && + b4 == (byte)0x6C && b5 == (byte)0x30 && + b[6] == (byte)0x4F && b[7] == (byte)0x1B && b[8] == (byte)0x26 && b[9] == (byte)0x6C && b[10] == (byte)0x30 && + b[11] == (byte)0x45 && b[12] == (byte)0x1B && b[13] == (byte)0x26) { + return T_PCL; + } + else if (b0 == (byte)0x20 && b1 == (byte)0x77 && b2 == (byte)0x00 && b3 == (byte)0x02) { + return T_CBD; + } + else if (b0 == (byte)0x23) { + if (b1 == (byte)0x20 && b2 == (byte)0x24 && b3 == (byte)0x49 && + b4 == (byte)0x64 && b5 == (byte)0x3A && + b[6] == (byte)0x20) { + return T_SID; + } + else if (b1 == (byte)0x56 && b2 == (byte)0x52 && b3 == (byte)0x4D && + b4 == (byte)0x4C && b5 == (byte)0x20 && + b[6] == (byte)0x56 && b[7] == (byte)0x32 && b[8] == (byte)0x2E && b[9] == (byte)0x30) { + return T_WRL; + } + else if (b1 == (byte)0x64 && b2 == (byte)0x65 && b3 == (byte)0x66 && + b4 == (byte)0x69 && b5 == (byte)0x6E && + b[6] == (byte)0x65) { + return T_XBM; + } + } + else if (b0 == (byte)0x2A && b1 == (byte)0x2A && b2 == (byte)0x54 && b3 == (byte)0x49 && + b4 == (byte)0x39 && b5 == (byte)0x32 && + b[6] == (byte)0x2A && b[7] == (byte)0x2A && b[8] == (byte)0x01 && b[9] == (byte)0x00 && b[10] == (byte)0x58 && + b[11] == (byte)0x6E && b[12] == (byte)0x56 && b[13] == (byte)0x69) { + return T_92I; + } + else if (b0 == (byte)0x2F && b1 == (byte)0x2A && b2 == (byte)0x20 && b3 == (byte)0x58 && + b4 == (byte)0x50 && b5 == (byte)0x4D && + b[6] == (byte)0x20 && b[7] == (byte)0x2A && b[8] == (byte)0x2F) { + return T_XPM; + } + else if (b0 == (byte)0x33 && b1 == (byte)0x44 && b2 == (byte)0x4D && b3 == (byte)0x46) { + return T_3DMF; + } + else if (b0 == (byte)0x35 && b1 == (byte)0x4B && b2 == (byte)0x50 && b3 == (byte)0x35 && + b4 == (byte)0x31 && b5 == (byte)0x5D && + b[6] == (byte)0x2A && b[7] == (byte)0x67 && b[8] == (byte)0x72 && b[9] == (byte)0x72 && b[10] == (byte)0x80 && + b[11] == (byte)0x83 && b[12] == (byte)0x85 && b[13] == (byte)0x63) { + return T_HRU; + } + else if (b0 == (byte)0x36 && b1 == (byte)0x34 && b2 == (byte)0x4C && b3 == (byte)0x41 && + b4 == (byte)0x4E && b5 == (byte)0x20 && + b[6] == (byte)0x49 && b[7] == (byte)0x44 && b[8] == (byte)0x42 && b[9] == (byte)0x4C && b[10] == (byte)0x4F && + b[11] == (byte)0x43 && b[12] == (byte)0x4B) { + return T_L64; + } + else if (b0 == (byte)0x37 && b1 == (byte)0x00 && b2 == (byte)0x00 && b3 == (byte)0x10 && + b4 == (byte)0x42 && b5 == (byte)0x00 && + b[6] == (byte)0x00 && b[7] == (byte)0x10 && b[8] == (byte)0x00 && b[9] == (byte)0x00 && b[10] == (byte)0x00 && + b[11] == (byte)0x00 && b[12] == (byte)0x39 && b[13] == (byte)0x64) { + return T_MBM; + } + else if (b0 == (byte)0x38 && b1 == (byte)0x42 && b2 == (byte)0x50 && b3 == (byte)0x53 && + b4 == (byte)0x00 && b5 == (byte)0x01 && + b[6] == (byte)0x00 && b[7] == (byte)0x00 && b[8] == (byte)0x00 && b[9] == (byte)0x00) { + return T_PSD; + } + else if (b0 == (byte)0x3A && b1 == (byte)0xDE && b2 == (byte)0x68 && b3 == (byte)0xB1) { + return T_DCX; + } + else if (b0 == (byte)0x3D && b1 == (byte)0x02) { + return T_3D2; + } + else if (b0 == (byte)0x41) { + if (b1 == (byte)0x43 && b2 == (byte)0x31 && b3 == (byte)0x30) { + return T_DWG; + } + else if (b1 == (byte)0x48) { + return T_PAL; + } + else if (b1 == (byte)0x4D && b2 == (byte)0x46 && b3 == (byte)0x46) { + return T_AMFF; + } + else if (b1 == (byte)0x75 && b2 == (byte)0x74 && b3 == (byte)0x6F && + b4 == (byte)0x43 && b5 == (byte)0x41 && + b[6] == (byte)0x44 && b[7] == (byte)0x20 && b[8] == (byte)0x53 && b[9] == (byte)0x6C && b[10] == (byte)0x69 && + b[11] == (byte)0x64 && b[12] == (byte)0x65) { + return T_SLD; + } + } + else if (b0 == (byte)0x42 && b1 == (byte)0x4D) { + if (b2 == (byte)0x36) { + // FIXME: Collision or subtype of T_BMP? + return T_DIB; + } else { + return T_BMP; + } + } + else if (b0 == (byte)0x43) { + if (b1 == (byte)0x36 && b2 == (byte)0x34) { + return T_N64; + } + else if (b1 == (byte)0x41 && b2 == (byte)0x4C && b3 == (byte)0x41 && + b4 == (byte)0x4D && b5 == (byte)0x55 && + b[6] == (byte)0x53 && b[7] == (byte)0x43 && b[8] == (byte)0x56 && b[9] == (byte)0x47) { + return T_CVG; + } + else if (b1 == (byte)0x50 && b2 == (byte)0x54 && b3 == (byte)0x46 && + b4 == (byte)0x49 && b5 == (byte)0x4C && + b[6] == (byte)0x45) { + return T_CPT; + } + else if (b1 == (byte)0x61 && b2 == (byte)0x6C && b3 == (byte)0x69 && + b4 == (byte)0x67 && b5 == (byte)0x61 && + b[6] == (byte)0x72 && b[7] == (byte)0x69) { + return T_COB; + } + } + else if (b0 == (byte)0x44) { + if (b1 == (byte)0x44 && b2 == (byte)0x53 && b3 == (byte)0x20) { + return T_DDS; + } + else if (b1 == (byte)0x61 && b2 == (byte)0x6E && b3 == (byte)0x4D) { + return T_MSP; + } + } + else if (b0 == (byte)0x45) { + if (b1 == (byte)0x59 && b2 == (byte)0x45 && b3 == (byte)0x53) { + return T_CE2; + } + else if (b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) { /* EXIF */ + /** + * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF + * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF + * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff + */ + return T_JPG; + } + } + else if (b0 == (byte)0x46 && b1 == (byte)0x4F && b2 == (byte)0x52 && b3 == (byte)0x4D) { + if (b4 == (byte)0x41 && b5 == (byte)0x54 && b[6] == (byte)0x3D) { + // FIXME: Collision or subtype of T_LBM? + return T_RAD; + } else { + return T_LBM; + } + } + else if (b0 == (byte)0x47 && b1 == (byte)0x49 && b2 == (byte)0x46 && b3 == (byte)0x38 && + (b4 == (byte)0x37 || b4 == (byte)0x39) && b5 == (byte)0x61) { + return T_GIF; + } + else if (b0 == (byte)0x48 && b1 == (byte)0x50 && b2 == (byte)0x48 && b3 == (byte)0x50 && + b4 == (byte)0x34 && b5 == (byte)0x38 && + b[6] == (byte)0x2D && b[7] == (byte)0x45 && b[8] == (byte)0x1E && b[9] == (byte)0x2B) { + return T_GRO; + } + else if (b0 == (byte)0x49) { + if (b1 == (byte)0x49 && b2 == (byte)0x2A && b3 == (byte)0x00) { + if (b4 == (byte)0x08 && b5 == (byte)0x00 && + b[6] == (byte)0x00 && b[7] == (byte)0x00 && b[8] == (byte)0x0E && b[9] == (byte)0x00 && b[10] == (byte)0x00 && + b[11] == (byte)0x01 && b[12] == (byte)0x04 && b[13] == (byte)0x00) { + // FIXME: Collision or subtype of T_TIFF? + return T_LDF; + } else { + return T_TIFF; + } + } + else if (b1 == (byte)0x57 && b2 == (byte)0x43 && b3 == (byte)0x01) { + return T_IWC; + } + } + else if (b0 == (byte)0x4A) { + if (b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) { /* JFIF */ + /** + * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF + * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF + * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff + */ + return T_JPG; + } + else if (b1 == (byte)0x47 && (b2 == (byte)0x03 || b2 == (byte)0x04) && b3 == (byte)0x0E && + b4 == (byte)0x00 && b5 == (byte)0x00 && + b[6] == (byte)0x00) { + return T_ART; + } + else if (b1 == (byte)0x49 && b2 == (byte)0x46 && b3 == (byte)0x39 && + b4 == (byte)0x39 && b5 == (byte)0x61) { + return T_JIF; + } + } + else if (b0 == (byte)0x4D) { + if (b1 == (byte)0x47 && b2 == (byte)0x4C) { + return T_MGL; + } + else if (b1 == (byte)0x4D && b2 == (byte)0x00 && b3 == (byte)0x2A) { + return T_KDC; + } + else if (b1 == (byte)0x50 && b2 == (byte)0x46) { + return T_MPW; + } + } + else if (b0 == (byte)0x4E) { + if (b1 == (byte)0x47 && b2 == (byte)0x47 && b3 == (byte)0x00 && + b4 == (byte)0x01 && b5 == (byte)0x00) { + return T_NGG; + } + else if (b1 == (byte)0x4C && b2 == (byte)0x4D && b3 == (byte)0x20 && + b4 == (byte)0x01 && b5 == (byte)0x02 && + b[6] == (byte)0x00) { + return T_NLM; + } + else if (b1 == (byte)0x4F && b2 == (byte)0x4C && b3 == (byte)0x00 && + b4 == (byte)0x01 && b5 == (byte)0x00 && + b[6] == (byte)0x06 && b[7] == (byte)0x01 && b[8] == (byte)0x03 && b[9] == (byte)0x00) { + return T_NOL; + } + } + else if (b0 == (byte)0x50) { + if (b1 == (byte)0x31 /* plain */|| b1 == (byte)0x34) { + return T_PBM; + } + else if (b1 == (byte)0x32 /* plain */|| b1 == (byte)0x35) { + return T_PGM; + } + else if (b1 == (byte)0x33 /* plain */|| b1 == (byte)0x36) { + return T_PPM; + } + else if (b1 == (byte)0x37) { + return T_PAM; + } + else if (b1 == (byte)0x41 && b2 == (byte)0x58) { + return T_PAX; + } + else if (b1 == (byte)0x49 && b2 == (byte)0x58 && b3 == (byte)0x20) { + return T_PIX; + } + else if (b1 == (byte)0x4F && b2 == (byte)0x4C && b3 == (byte)0x20 && + b4 == (byte)0x46 && b5 == (byte)0x6F && + b[6] == (byte)0x72 && b[7] == (byte)0x6D && b[8] == (byte)0x61 && b[9] == (byte)0x74) { + return T_POL; + } + else if (b1 == (byte)0x61 && b2 == (byte)0x69 && b3 == (byte)0x6E && + b4 == (byte)0x74 && b5 == (byte)0x20 && + b[6] == (byte)0x53 && b[7] == (byte)0x68 && b[8] == (byte)0x6F && b[9] == (byte)0x70 && b[10] == (byte)0x20 && + b[11] == (byte)0x50 && b[12] == (byte)0x72 && b[13] == (byte)0x6F && b[14] == (byte)0x20 && b[15] == (byte)0x49 && + b[16] == (byte)0x6D && b[17] == (byte)0x61 && b[18] == (byte)0x67 && b[19] == (byte)0x65 && b[20] == (byte)0x20 && + b[21] == (byte)0x46 && b[22] == (byte)0x69 && b[23] == (byte)0x6C && b[24] == (byte)0x65) { + return T_PSP; + } + } + else if (b0 == (byte)0x51 && b1 == (byte)0x4C && b2 == (byte)0x49 && b3 == (byte)0x49 && + b4 == (byte)0x46 && b5 == (byte)0x41 && + b[6] == (byte)0x58) { + return T_QFX; + } + else if (b0 == (byte)0x52 && b1 == (byte)0x49 && b2 == (byte)0x58 && b3 == (byte)0x33) { + return T_RIX; + } + else if (b0 == (byte)0x53) { + if (b1 == (byte)0x44 && b2 == (byte)0x50 && b3 == (byte)0x58) { + return T_DPX; + } + else if (b1 == (byte)0x49 && b2 == (byte)0x4D && b3 == (byte)0x50 && + b4 == (byte)0x4C && b5 == (byte)0x45 && + b[6] == (byte)0x20 && b[7] == (byte)0x20 && b[8] == (byte)0x3D) { + return T_FTS; + } + else if (b1 == (byte)0x74 && b2 == (byte)0x6F && b3 == (byte)0x72 && + b4 == (byte)0x6D && b5 == (byte)0x33 && + b[6] == (byte)0x44) { + return T_SOD; + } + } + else if (b0 == (byte)0x56 && b1 == (byte)0x69 && b2 == (byte)0x73 && b3 == (byte)0x74 && + b4 == (byte)0x61 && b5 == (byte)0x20 && + b[6] == (byte)0x44 && b[7] == (byte)0x45 && b[8] == (byte)0x4D && b[9] == (byte)0x20 && b[10] == (byte)0x46 && + b[11] == (byte)0x69 && b[12] == (byte)0x6C && b[13] == (byte)0x65) { + return T_DEM; + } + else if (b0 == (byte)0x57 && b1 == (byte)0x56 && b2 == (byte)0x02 && b3 == (byte)0x00 && + b4 == (byte)0x47 && b5 == (byte)0x45 && + b[6] == (byte)0x00 && b[7] == (byte)0x0E) { + return T_LWF; + } + else if (b0 == (byte)0x59 && b1 == (byte)0xA6 && b2 == (byte)0x6A && b3 == (byte)0x95) { + return T_RAS; + } + else if (b0 == (byte)0x63 && b1 == (byte)0x52 && b2 == (byte)0x01 && b3 == (byte)0x01 && + b4 == (byte)0x38 && b5 == (byte)0x09 && + b[6] == (byte)0x3D && b[7] == (byte)0x00) { + return T_PCD; + } + else if (b0 == (byte)0x65) { + if (b1 == (byte)0x02 && b2 == (byte)0x01 && b3 == (byte)0x02) { + return T_ECW; + } + else if (b1 == (byte)0x6C && b2 == (byte)0x6D && b3 == (byte)0x6F) { + return T_INFINI_D; + } + } + else if (b0 == (byte)0x69 && b1 == (byte)0x63 && b2 == (byte)0x6E && b3 == (byte)0x73) { + return T_ICNS; + } + else if (b0 == (byte)0x6D && b1 == (byte)0x6F && b2 == (byte)0x6F && b3 == (byte)0x76) { + return T_QTM; + } + else if (b0 == (byte)0x6E) { + if (b1 == (byte)0x63 && b2 == (byte)0x6F && b3 == (byte)0x6C && + b4 == (byte)0x73) { + return T_HDR; + } + else if (b1 == (byte)0x66 && b2 == (byte)0x66) { + return T_NFF; + } + else if (b1 == (byte)0x6E && b2 == (byte)0x0A && b3 == (byte)0x00 && + b4 == (byte)0x5E && b5 == (byte)0x00) { + return T_NCR; + } + } + else if (b0 == (byte)0x73 && b1 == (byte)0x72 && b2 == (byte)0x63 && b3 == (byte)0x64 && + b4 == (byte)0x6F && b5 == (byte)0x63 && + b[6] == (byte)0x69 && b[7] == (byte)0x64 && b[8] == (byte)0x3A) { + return T_CALS; + } + else if (b0 == (byte)0x7B && b1 == (byte)0x0A && b2 == (byte)0x20 && b3 == (byte)0x20 && + b4 == (byte)0x43 && b5 == (byte)0x72 && + b[6] == (byte)0x65 && b[7] == (byte)0x61 && b[8] == (byte)0x74 && b[9] == (byte)0x65 && b[10] == (byte)0x64) { + return T_MIF; + } + else if (b0 == (byte)0x7E && b1 == (byte)0x42 && b2 == (byte)0x4B && b3 == (byte)0x00) { + return T_PSP; + } + else if (b0 == (byte)0x80) { + if (b1 == (byte)0x2A && b2 == (byte)0x5F && b3 == (byte)0xD7 && + b4 == (byte)0x00 && b5 == (byte)0x00 && + b[6] == (byte)0x08 && b[7] == (byte)0x00 && b[8] == (byte)0x00 && b[9] == (byte)0x00 && b[10] == (byte)0x04 && + b[11] == (byte)0x00 && b[12] == (byte)0x00 && b[13] == (byte)0x00) { + return T_CIN; + } + else if (b1 == (byte)0x3E && b2 == (byte)0x44 && b3 == (byte)0x53 && + b4 == (byte)0x43 && b5 == (byte)0x49 && + b[6] == (byte)0x4D) { + return T_J6I; + } + } + else if (b0 == (byte)0x89 && b1 == (byte)0x50 && b2 == (byte)0x4E && b3 == (byte)0x47 && /* 'P' 'N' 'G', ascii code */ + b4 == (byte)0x0D && b5 == (byte)0x0A && b[6] == (byte)0x1A && b[7] == (byte)0x0A) { + // -119, 80, 78, 71, 13, 10, 26, 10 + return T_PNG; + } + else if (b0 == (byte)0x8A && b1 == (byte)0x4D && b2 == (byte)0x4E && b3 == (byte)0x47 && + b4 == (byte)0x0D && b5 == (byte)0x0A && + b[6] == (byte)0x1A && b[7] == (byte)0x0A) { + return T_MNG; + } + else if (b0 == (byte)0xD0 && b1 == (byte)0xCF && b2 == (byte)0x11 && b3 == (byte)0xE0 && + b4 == (byte)0xA1 && b5 == (byte)0xB1 && + b[6] == (byte)0x1A && b[7] == (byte)0xE1 && b[8] == (byte)0x00) { + return T_FPX; + } + else if (b0 == (byte)0xD3 && b1 == (byte)0x23 && b2 == (byte)0x00 && b3 == (byte)0x00 && + b4 == (byte)0x03 && b5 == (byte)0x00 && + b[6] == (byte)0x00 && b[7] == (byte)0x00) { + return T_WLM; + } + else if (b0 == (byte)0xD7 && b1 == (byte)0xCD && b2 == (byte)0xC6 && b3 == (byte)0x9A) { + return T_WMF; + } + else if (b0 == (byte)0xEB && b1 == (byte)0x3C && b2 == (byte)0x90 && b3 == (byte)0x2A) { + return T_IMG; + } + else if (b0 == (byte)0xFA && b1 == (byte)0xDE && b2 == (byte)0xBA && b3 == (byte)0xBE && + b4 == (byte)0x01 && b5 == (byte)0x01) { + return T_WIC; + } + else if (b0 == (byte)0xFF) { + if (b1 == (byte)0xD8 /* && b2 == (byte)0xff */) { + /** + * (b0 == (byte)0x45 && b1 == (byte)0x78 && b2 == (byte)0x69 && b3 == (byte)0x66) || // EXIF + * (b0 == (byte)0x4A && b1 == (byte)0x46 && b2 == (byte)0x49 && b3 == (byte)0x46) || // JFIF + * (b0 == (byte)0xff && b1 == (byte)0xd8 ) // && b2 == (byte)0xff + */ + return T_JPG; + } + else if (b1 == (byte)0x57 && b2 == (byte)0x50 && b3 == (byte)0x43 && b4 == (byte)0x10) { + return T_WPG; + } + } + return null; + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java index 615d8c24f..5799f95a6 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java @@ -83,6 +83,9 @@ public class TextureData { protected GLProfile glProfile; protected ColorSpace pixelCS = ColorSpace.RGB; + // TODO: final, and set via ctor for 2.4.X + /* pp */ ImageType srcImageType; + /** * Constructs a new TextureData object with the specified parameters * and data contained in the given Buffer. The optional Flusher can @@ -341,6 +344,14 @@ public class TextureData { /** Used only by subclasses */ protected TextureData(final GLProfile glp) { this.glProfile = glp; this.pixelAttributes = GLPixelAttributes.UNDEF; } + /** + * Returns the source {@link ImageType} if applicable and known, otherwise {@code null}. + * @since 2.3.2 + */ + public final ImageType getSourceImageType() { + return srcImageType; + } + /** Returns the width in pixels of the texture data. */ public int getWidth() { return width; } /** Returns the height in pixels of the texture data. */ @@ -501,8 +512,9 @@ public class TextureData { @Override public String toString() { + final String optImageType = null != srcImageType ? ", "+srcImageType : ""; return "TextureData["+width+"x"+height+", y-flip "+mustFlipVertically+", internFormat 0x"+Integer.toHexString(internalFormat)+", "+ - pixelAttributes+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength; + pixelAttributes+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength+optImageType; } //---------------------------------------------------------------------- diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java index ef4cc4409..e007309e2 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java @@ -52,8 +52,10 @@ import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import com.jogamp.nativewindow.util.Dimension; import com.jogamp.nativewindow.util.DimensionImmutable; @@ -72,6 +74,7 @@ import com.jogamp.common.util.IOUtil; import com.jogamp.opengl.util.GLPixelStorageModes; import com.jogamp.opengl.util.PNGPixelRect; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; +import com.jogamp.opengl.util.texture.ImageType; import com.jogamp.opengl.util.texture.spi.DDSImage; import com.jogamp.opengl.util.texture.spi.JPEGImage; import com.jogamp.opengl.util.texture.spi.NetPbmTextureWriter; @@ -134,64 +137,60 @@ import com.jogamp.opengl.util.texture.spi.TextureWriter; public class TextureIO { /** Constant which can be used as a file suffix to indicate a - DirectDraw Surface file. - @deprecated Use {@link ImageIOUtil#T_DDS}. + DirectDraw Surface file, value {@value}. + <p>Alias for {@link ImageType#T_DDS}.</p> */ - public static final String DDS = ImageIOUtil.T_DDS; + public static final String DDS = ImageType.T_DDS; - /** Constant which can be used as a file suffix to indicate an SGI - RGB file. - @deprecated Use {@link ImageIOUtil#T_SGI}. + /** + * Constant which can be used as a file suffix to indicate an SGI RGB file, value {@value}. + * <p> + * Same semantics as {@link ImageType#SGI_RGB} and {@link #SGI_RGB}. + * </p> */ - public static final String SGI = ImageIOUtil.T_SGI; + public static final String SGI = "sgi"; - /** Constant which can be used as a file suffix to indicate an SGI - RGB file. - @deprecated Use {@link ImageIOUtil#T_SGI_RGB}. + /** Constant which can be used as a file suffix to indicate an SGI RGB file, value {@value}. + <p>Alias for {@link ImageType#T_SGI_RGB}. </p> */ - public static final String SGI_RGB = ImageIOUtil.T_SGI_RGB; + public static final String SGI_RGB = ImageType.T_SGI_RGB; - /** Constant which can be used as a file suffix to indicate a GIF - file. - @deprecated Use {@link ImageIOUtil#T_GIF}. + /** Constant which can be used as a file suffix to indicate a GIF file, value {@value}. + <p>Alias for {@link ImageType#T_GIF}.</p> */ - public static final String GIF = ImageIOUtil.T_GIF; + public static final String GIF = ImageType.T_GIF; - /** Constant which can be used as a file suffix to indicate a JPEG - file. - @deprecated Use {@link ImageIOUtil#T_JPG}. + /** Constant which can be used as a file suffix to indicate a JPEG file, value {@value}. + <p>Alias for {@link ImageType#T_JPG}.</p> */ - public static final String JPG = ImageIOUtil.T_JPG; + public static final String JPG = ImageType.T_JPG; - /** Constant which can be used as a file suffix to indicate a PNG - file. - @deprecated Use {@link ImageIOUtil#T_PNG}. + /** Constant which can be used as a file suffix to indicate a PNG file, value {@value}. + <p>Alias for {@link ImageType#T_PNG}.</p> */ - public static final String PNG = ImageIOUtil.T_PNG; + public static final String PNG = ImageType.T_PNG; - /** Constant which can be used as a file suffix to indicate a Targa - file. - @deprecated Use {@link ImageIOUtil#T_TGA}. + /** Constant which can be used as a file suffix to indicate a Targa file, value {@value}. + <p>Alias for {@link ImageType#T_TGA}.</p> */ - public static final String TGA = ImageIOUtil.T_TGA; + public static final String TGA = ImageType.T_TGA; - /** Constant which can be used as a file suffix to indicate a TIFF - file. - @deprecated Use {@link ImageIOUtil#T_TIFF}. + /** Constant which can be used as a file suffix to indicate a TIFF file, value {@value}. + <p>Alias for {@link ImageType#T_TIFF}.</p> */ - public static final String TIFF = ImageIOUtil.T_TIFF; + public static final String TIFF = ImageType.T_TIFF; /** Constant which can be used as a file suffix to indicate a PAM - file, NetPbm magic 7 - binary RGB and RGBA. Write support only. - @deprecated Use {@link ImageIOUtil#T_PAM}. + file, NetPbm magic 7 - binary RGB and RGBA. Write support only, value {@value}. + <p>Alias for {@link ImageType#T_PAM}.</p> */ - public static final String PAM = ImageIOUtil.T_PAM; + public static final String PAM = ImageType.T_PAM; /** Constant which can be used as a file suffix to indicate a PAM - file, NetPbm magic 6 - binary RGB. Write support only. - @deprecated Use {@link ImageIOUtil#T_PPM}. + file, NetPbm magic 6 - binary RGB. Write support only, value {@value}. + <p>Alias for {@link ImageType#T_PPM}.</p> */ - public static final String PPM = ImageIOUtil.T_PPM; + public static final String PPM = ImageType.T_PPM; private static final boolean DEBUG = Debug.debug("TextureIO"); @@ -697,16 +696,30 @@ public class TextureIO { // /** - * Adds a TextureProvider to support reading of a new file format. + * Adds a {@link TextureProvider} to support reading of a new file format. * <p> * The last provider added, will be the first provider to be tested. * </p> + * <p> + * In case the {@link TextureProvider} also implements {@link TextureProvider.SupportsImageTypes}, + * the {@link TextureProvider} is being mapped to its supporting {@link ImageType}s + * allowing an O(1) association. + * </p> */ public static void addTextureProvider(final TextureProvider provider) { // Must always add at the front so the ImageIO provider is last, // so we don't accidentally use it instead of a user's possibly // more optimal provider textureProviders.add(0, provider); + + if( provider instanceof TextureProvider.SupportsImageTypes ) { + final ImageType[] imageTypes = ((TextureProvider.SupportsImageTypes)provider).getImageTypes(); + if( null != imageTypes ) { + for(int i=0; i<imageTypes.length; i++) { + imageType2TextureProvider.put(imageTypes[i], provider); + } + } + } } /** @@ -756,6 +769,7 @@ public class TextureIO { // private static List<TextureProvider> textureProviders = new ArrayList<TextureProvider>(); + private static Map<ImageType,TextureProvider> imageType2TextureProvider = new HashMap<ImageType,TextureProvider>(); private static List<TextureWriter> textureWriters = new ArrayList<TextureWriter>(); static { @@ -807,32 +821,6 @@ public class TextureIO { } // Implementation methods - private static TextureData newTextureDataImpl(final GLProfile glp, final File file, - final int internalFormat, - final int pixelFormat, - final boolean mipmap, - String fileSuffix) throws IOException { - if (file == null) { - throw new IOException("File was null"); - } - - fileSuffix = toLowerCase(fileSuffix); - - for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) { - final TextureProvider provider = iter.next(); - final TextureData data = provider.newTextureData(glp, file, - internalFormat, - pixelFormat, - mipmap, - fileSuffix); - if (data != null) { - return data; - } - } - - throw new IOException("No suitable reader for given file "+file.getAbsolutePath()); - } - private static TextureData newTextureDataImpl(final GLProfile glp, InputStream stream, final int internalFormat, final int pixelFormat, @@ -842,101 +830,137 @@ public class TextureIO { throw new IOException("Stream was null"); } - fileSuffix = toLowerCase(fileSuffix); - // Note: use of BufferedInputStream works around 4764639/4892246 if (!(stream instanceof BufferedInputStream)) { stream = new BufferedInputStream(stream); } + // First attempt to use an ImageType mapped TextureProvider for O(1) + // using stream parsed data, ignoring the given fileSuffix! + try { + final ImageType imageType = new ImageType(stream); + if( imageType.isDefined() ) { + final TextureProvider mappedProvider = imageType2TextureProvider.get(imageType); + if( null != mappedProvider ) { + final TextureData data = mappedProvider.newTextureData(glp, stream, + internalFormat, + pixelFormat, + mipmap, + imageType.type); + if (data != null) { + data.srcImageType = imageType; + return data; + } + } + } + } catch (final IOException ioe) { + if(DEBUG) { + System.err.println("Caught "+ioe.getMessage()); + ioe.printStackTrace(); + } + } + + fileSuffix = toLowerCase(fileSuffix); + for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) { final TextureProvider provider = iter.next(); final TextureData data = provider.newTextureData(glp, stream, - internalFormat, - pixelFormat, - mipmap, - fileSuffix); + internalFormat, + pixelFormat, + mipmap, + fileSuffix); if (data != null) { + if( provider instanceof TextureProvider.SupportsImageTypes ) { + data.srcImageType = ((TextureProvider.SupportsImageTypes)provider).getImageTypes()[0]; + } return data; } } throw new IOException("No suitable reader for given stream"); } - + private static TextureData newTextureDataImpl(final GLProfile glp, final File file, + final int internalFormat, + final int pixelFormat, + final boolean mipmap, + final String fileSuffix) throws IOException { + if (file == null) { + throw new IOException("File was null"); + } + final InputStream stream = new BufferedInputStream(new FileInputStream(file)); + try { + return newTextureDataImpl( glp, stream, internalFormat, pixelFormat, mipmap, + (fileSuffix != null) ? fileSuffix : IOUtil.getFileSuffix(file) ); + } catch(final IOException ioe) { + throw new IOException(ioe.getMessage()+", given file "+file.getAbsolutePath(), ioe); + } finally { + stream.close(); + } + } private static TextureData newTextureDataImpl(final GLProfile glp, final URL url, final int internalFormat, final int pixelFormat, final boolean mipmap, - String fileSuffix) throws IOException { + final String fileSuffix) throws IOException { if (url == null) { throw new IOException("URL was null"); } - - fileSuffix = toLowerCase(fileSuffix); - - for (final Iterator<TextureProvider> iter = textureProviders.iterator(); iter.hasNext(); ) { - final TextureProvider provider = iter.next(); - final TextureData data = provider.newTextureData(glp, url, - internalFormat, - pixelFormat, - mipmap, - fileSuffix); - if (data != null) { - return data; - } + final InputStream stream = new BufferedInputStream(url.openStream()); + try { + return newTextureDataImpl(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix); + } catch(final IOException ioe) { + throw new IOException(ioe.getMessage()+", given URL "+url, ioe); + } finally { + stream.close(); } - - throw new IOException("No suitable reader for given URL "+url); } //---------------------------------------------------------------------- - // DDS provider -- supports files only for now - static class DDSTextureProvider implements TextureProvider { + // Base class for internal image providers, only providing stream based data! + static abstract class StreamBasedTextureProvider implements TextureProvider, TextureProvider.SupportsImageTypes { @Override - public TextureData newTextureData(final GLProfile glp, final File file, + public final TextureData newTextureData(final GLProfile glp, final File file, final int internalFormat, final int pixelFormat, final boolean mipmap, final String fileSuffix) throws IOException { - if (DDS.equals(fileSuffix) || - DDS.equals(IOUtil.getFileSuffix(file))) { - final DDSImage image = DDSImage.read(file); - return newTextureData(glp, image, internalFormat, pixelFormat, mipmap); - } - - return null; + throw new UnsupportedOperationException("Only stream is supported"); } @Override - public TextureData newTextureData(final GLProfile glp, final InputStream stream, + public final TextureData newTextureData(final GLProfile glp, final URL url, final int internalFormat, final int pixelFormat, final boolean mipmap, final String fileSuffix) throws IOException { - if (DDS.equals(fileSuffix) || - DDS.equals(ImageIOUtil.getFileSuffix(stream))) { - final byte[] data = IOUtil.copyStream2ByteArray(stream); - final ByteBuffer buf = ByteBuffer.wrap(data); - final DDSImage image = DDSImage.read(buf); - return newTextureData(glp, image, internalFormat, pixelFormat, mipmap); - } + throw new UnsupportedOperationException("Only stream is supported"); + } + } - return null; + //---------------------------------------------------------------------- + // DDS image provider + static class DDSTextureProvider extends StreamBasedTextureProvider { + private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_DDS) }; + @Override + public final ImageType[] getImageTypes() { + return imageTypes; } @Override - public TextureData newTextureData(final GLProfile glp, final URL url, + public TextureData newTextureData(final GLProfile glp, final InputStream stream, final int internalFormat, final int pixelFormat, final boolean mipmap, final String fileSuffix) throws IOException { - final InputStream stream = new BufferedInputStream(url.openStream()); - try { - return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix); - } finally { - stream.close(); + if (ImageType.T_DDS.equals(fileSuffix) || + ImageType.T_DDS.equals(ImageType.Util.getFileSuffix(stream))) { + final byte[] data = IOUtil.copyStream2ByteArray(stream); + final ByteBuffer buf = ByteBuffer.wrap(data); + final DDSImage image = DDSImage.read(buf); + return newTextureData(glp, image, internalFormat, pixelFormat, mipmap); } + + return null; } private TextureData newTextureData(final GLProfile glp, final DDSImage image, @@ -1023,47 +1047,14 @@ public class TextureIO { } //---------------------------------------------------------------------- - // Base class for SGI RGB and TGA image providers - static abstract class StreamBasedTextureProvider implements TextureProvider { - @Override - public TextureData newTextureData(final GLProfile glp, final File file, - final int internalFormat, - final int pixelFormat, - final boolean mipmap, - final String fileSuffix) throws IOException { - final InputStream inStream = new BufferedInputStream(new FileInputStream(file)); - try { - // The SGIImage and TGAImage implementations use InputStreams - // anyway so there isn't much point in having a separate code - // path for files - return newTextureData(glp, inStream, - internalFormat, - pixelFormat, - mipmap, - ((fileSuffix != null) ? fileSuffix : IOUtil.getFileSuffix(file))); - } finally { - inStream.close(); - } - } - + // SGI RGB image provider + static class SGITextureProvider extends StreamBasedTextureProvider { + private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_SGI_RGB) }; @Override - public TextureData newTextureData(final GLProfile glp, final URL url, - final int internalFormat, - final int pixelFormat, - final boolean mipmap, - final String fileSuffix) throws IOException { - final InputStream stream = new BufferedInputStream(url.openStream()); - try { - return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix); - } finally { - stream.close(); - } + public final ImageType[] getImageTypes() { + return imageTypes; } - } - //---------------------------------------------------------------------- - // SGI RGB image provider - static class SGITextureProvider extends StreamBasedTextureProvider { @Override public TextureData newTextureData(final GLProfile glp, final InputStream stream, int internalFormat, @@ -1071,9 +1062,9 @@ public class TextureIO { final boolean mipmap, final String fileSuffix) throws IOException { if (SGI.equals(fileSuffix) || - SGI_RGB.equals(fileSuffix) || - SGI.equals(ImageIOUtil.getFileSuffix(stream)) || - SGI_RGB.equals(ImageIOUtil.getFileSuffix(stream))) { + ImageType.T_SGI_RGB.equals(fileSuffix) || + SGI.equals(ImageType.Util.getFileSuffix(stream)) || + ImageType.T_SGI_RGB.equals(ImageType.Util.getFileSuffix(stream))) { final SGIImage image = SGIImage.read(stream); if (pixelFormat == 0) { pixelFormat = image.getFormat(); @@ -1101,13 +1092,19 @@ public class TextureIO { //---------------------------------------------------------------------- // TGA (Targa) image provider static class TGATextureProvider extends StreamBasedTextureProvider { + private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_TGA) }; + @Override + public final ImageType[] getImageTypes() { + return imageTypes; + } + @Override public TextureData newTextureData(final GLProfile glp, final InputStream stream, int internalFormat, int pixelFormat, final boolean mipmap, final String fileSuffix) throws IOException { - if (TGA.equals(fileSuffix)) { + if (ImageType.T_TGA.equals(fileSuffix)) { final TGAImage image = TGAImage.read(glp, stream); if (pixelFormat == 0) { pixelFormat = image.getGLFormat(); @@ -1139,14 +1136,20 @@ public class TextureIO { //---------------------------------------------------------------------- // PNG image provider static class PNGTextureProvider extends StreamBasedTextureProvider { + private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_PNG) }; + @Override + public final ImageType[] getImageTypes() { + return imageTypes; + } + @Override public TextureData newTextureData(final GLProfile glp, final InputStream stream, int internalFormat, int pixelFormat, final boolean mipmap, final String fileSuffix) throws IOException { - if (PNG.equals(fileSuffix) || - PNG.equals(ImageIOUtil.getFileSuffix(stream))) { + if (ImageType.T_PNG.equals(fileSuffix) || + ImageType.T_PNG.equals(ImageType.Util.getFileSuffix(stream))) { final PNGPixelRect image = PNGPixelRect.read(stream, null, true /* directBuffer */, 0 /* destMinStrideInBytes */, true /* destIsGLOriented */); final GLPixelAttributes glpa = new GLPixelAttributes(glp, image.getPixelformat(), false /* pack */); if ( 0 == pixelFormat ) { @@ -1180,14 +1183,20 @@ public class TextureIO { //---------------------------------------------------------------------- // JPEG image provider static class JPGTextureProvider extends StreamBasedTextureProvider { + private static final ImageType[] imageTypes = new ImageType[] { new ImageType(ImageType.T_JPG) }; + @Override + public final ImageType[] getImageTypes() { + return imageTypes; + } + @Override public TextureData newTextureData(final GLProfile glp, final InputStream stream, int internalFormat, int pixelFormat, final boolean mipmap, final String fileSuffix) throws IOException { - if (JPG.equals(fileSuffix) || - JPG.equals(ImageIOUtil.getFileSuffix(stream))) { + if (ImageType.T_JPG.equals(fileSuffix) || + ImageType.T_JPG.equals(ImageType.Util.getFileSuffix(stream))) { final JPEGImage image = JPEGImage.read(/*glp, */ stream); if (pixelFormat == 0) { pixelFormat = image.getGLFormat(); @@ -1223,7 +1232,7 @@ public class TextureIO { @Override public boolean write(final File file, final TextureData data) throws IOException { - if (DDS.equals(IOUtil.getFileSuffix(file))) { + if (ImageType.T_DDS.equals(IOUtil.getFileSuffix(file))) { // See whether the DDS writer can handle this TextureData final GLPixelAttributes pixelAttribs = data.getPixelAttributes(); final int pixelFormat = pixelAttribs.format; @@ -1276,7 +1285,7 @@ public class TextureIO { final TextureData data) throws IOException { final String fileSuffix = IOUtil.getFileSuffix(file); if (SGI.equals(fileSuffix) || - SGI_RGB.equals(fileSuffix)) { + ImageType.T_SGI_RGB.equals(fileSuffix)) { // See whether the SGI writer can handle this TextureData final GLPixelAttributes pixelAttribs = data.getPixelAttributes(); final int pixelFormat = pixelAttribs.format; @@ -1320,7 +1329,7 @@ public class TextureIO { @Override public boolean write(final File file, final TextureData data) throws IOException { - if (TGA.equals(IOUtil.getFileSuffix(file))) { + if (ImageType.T_TGA.equals(IOUtil.getFileSuffix(file))) { // See whether the TGA writer can handle this TextureData final GLPixelAttributes pixelAttribs = data.getPixelAttributes(); final int pixelFormat = pixelAttribs.format; @@ -1370,7 +1379,7 @@ public class TextureIO { static class PNGTextureWriter implements TextureWriter { @Override public boolean write(final File file, final TextureData data) throws IOException { - if (PNG.equals(IOUtil.getFileSuffix(file))) { + if (ImageType.T_PNG.equals(IOUtil.getFileSuffix(file))) { // See whether the PNG writer can handle this TextureData final GLPixelAttributes pixelAttribs = data.getPixelAttributes(); final int pixelFormat = pixelAttribs.format; diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java index 36c44a409..6ad9f7cf1 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java @@ -53,8 +53,7 @@ import java.nio.channels.FileChannel; import com.jogamp.opengl.GL; import com.jogamp.common.nio.Buffers; import com.jogamp.common.util.IOUtil; -import com.jogamp.opengl.util.GLBuffers; -import com.jogamp.opengl.util.texture.ImageIOUtil; +import com.jogamp.opengl.util.texture.ImageType; /** A reader and writer for DirectDraw Surface (.dds) files, which are used to describe textures. These files can contain multiple mipmap @@ -246,7 +245,7 @@ public class DDSImage { @param in Stream to check @return true if input stream is DDS image or false otherwise @throws java.io.IOException if an I/O exception occurred - @deprecated rather call {@link ImageIOUtil#getFileSuffix(InputStream)} + @deprecated rather call {@link ImageType#getFileSuffix(InputStream)} */ @Deprecated public static boolean isDDSImage(InputStream in) throws IOException { diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java index ff8167bb0..1330696d1 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java @@ -42,7 +42,7 @@ package com.jogamp.opengl.util.texture.spi; import java.io.*; import com.jogamp.opengl.*; -import com.jogamp.opengl.util.texture.ImageIOUtil; +import com.jogamp.opengl.util.texture.ImageType; import com.jogamp.common.util.IOUtil; /** <p> Reads and writes SGI RGB/RGBA images. </p> @@ -196,7 +196,7 @@ public class SGIImage { * an SGI RGB image. The given InputStream must return true from * markSupported() and support a minimum of two bytes of read-ahead. * - * @deprecated rather call {@link ImageIOUtil#getFileSuffix(InputStream)} + * @deprecated rather call {@link ImageType#getFileSuffix(InputStream)} */ @Deprecated public static boolean isSGIImage(InputStream in) throws IOException { diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java index e84f300e2..5b316a975 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java @@ -54,6 +54,18 @@ import com.jogamp.opengl.util.texture.*; public interface TextureProvider { /** + * Optional additional interface for {@link TextureProvider} implementation + * exposing the supported {@link ImageType}s. + * <p> + * Use case: Mapping of {@link ImageType}s to {@link TextureProvider}. + * </p> + */ + public static interface SupportsImageTypes { + /** Returns the supported {@link ImageType}s. */ + ImageType[] getImageTypes(); + } + + /** * Produces a TextureData object from a file, or returns null if the * file format was not supported by this TextureProvider. Does not * do any OpenGL-related work. The resulting TextureData can be @@ -85,6 +97,7 @@ public interface TextureProvider { * file's contents * * @throws IOException if an error occurred while reading the file + * @deprecated Use {@link #newTextureData(GLProfile, InputStream, int, int, boolean, String) */ public TextureData newTextureData(GLProfile glp, File file, int internalFormat, @@ -163,6 +176,7 @@ public interface TextureProvider { * file's contents * * @throws IOException if an error occurred while reading the URL + * @deprecated Use {@link #newTextureData(GLProfile, InputStream, int, int, boolean, String) */ public TextureData newTextureData(GLProfile glp, URL url, int internalFormat, diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java index ba762baf3..5072c8c8f 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java @@ -39,7 +39,6 @@ package com.jogamp.opengl.util.texture.spi.awt; -import java.awt.Graphics; import java.awt.image.*; import java.io.*; import java.net.*; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/ImageTstFiles.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/ImageTstFiles.java new file mode 100644 index 000000000..dfd3f6366 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/ImageTstFiles.java @@ -0,0 +1,128 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.jogl.util.texture; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URLConnection; +import java.util.ArrayList; + +import com.jogamp.common.util.IOUtil; + +public class ImageTstFiles { + public static final String[] pngFileNames = new String[] { + "bug724-transparent-grey_gimpexp.png", + "bug724-transparent-grey_orig.png", + "cross-grey-alpha-16x16.png", + "grayscale_texture.png", + "pointer-grey-alpha-16x24.png", + "test-ntscI_3-01-160x90.png", + "test-ntscI_4-01-160x90.png", + "test-ntscIG3-01-160x90.png", + "test-ntscIG4-01-160x90.png", + "test-ntscN_3-01-160x90.png", + "test-ntscN_4-01-160x90.png", + "test-ntscNG4-01-160x90.png", + "test-ntscP_3-01-160x90.png", + "test-ntscP_4-01-160x90.png" + }; + + public static final String[] jpgFileNames = new String[] { + "bug745_qttdef_post_frame.jpg", + "darwin_03_N_4-YCCK-640x452.jpg", // local + "darwin_03_N_4-YCCK.jpg", // local + "j1-baseline.jpg", + "j2-progressive.jpg", + "j3-baseline_gray.jpg", + "test-cmyk-01.jpg", + "test-ntscN_3-01-160x90-60pct-yuv422h-base.jpg", + "test-ntscN_3-01-160x90-60pct-yuv422h-prog.jpg", + "test-ntscN_3-01-160x90-90pct-yuv444-base.jpg", + "test-ntscN_3-01-160x90-90pct-yuv444-prog.jpg", + "test-ycck-01.jpg" }; + + public static final String[] tgaFileNames = new String[] { + "bug744-rle32.tga", + "bug982.rle32.256x256.tga", + "test-u32.tga" + }; + public static final String[] ddsFileNames = new String[] { + "test-64x32_DXT1.dds", + "test-64x32_DXT5.dds", + "test-64x32_uncompressed.dds" + }; + + public static class NamedInputStream { + final String fullPath; + final String basePath; + final InputStream stream; + public NamedInputStream(final String fullPath, final String basePath, final InputStream stream) { + this.fullPath = fullPath; + this.basePath = basePath; + this.stream = stream; + } + } + public ArrayList<NamedInputStream> pngStreams; + public ArrayList<NamedInputStream> jpgStreams; + public ArrayList<NamedInputStream> tgaStreams; + public ArrayList<NamedInputStream> ddsStreams; + public ArrayList<NamedInputStream> allStreams; + + private final ArrayList<NamedInputStream> init(final String[] source) throws IOException { + final ArrayList<NamedInputStream> sink = new ArrayList<NamedInputStream>(); + for(int i=0; i<source.length; i++) { + final URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), source[i]); + if( null != testTextureUrlConn ) { + final InputStream s = testTextureUrlConn.getInputStream(); + if( null != s ) { + sink.add(new NamedInputStream(testTextureUrlConn.getURL().toString(), source[i], s)); + } + } + } + return sink; + } + + public void init() throws IOException { + pngStreams = init(pngFileNames); + jpgStreams = init(jpgFileNames); + tgaStreams = init(tgaFileNames); + ddsStreams = init(ddsFileNames); + allStreams = new ArrayList<NamedInputStream>(); + allStreams.addAll(pngStreams); + allStreams.addAll(jpgStreams); + allStreams.addAll(tgaStreams); + allStreams.addAll(ddsStreams); + } + public void clear() { + pngStreams.clear(); + jpgStreams.clear(); + tgaStreams.clear(); + ddsStreams.clear(); + allStreams.clear(); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestImageTypeNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestImageTypeNEWT.java new file mode 100644 index 000000000..952d54443 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestImageTypeNEWT.java @@ -0,0 +1,92 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.util.texture; + +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.util.texture.ImageType; + +import java.io.IOException; +import java.util.List; + +import org.junit.Assert; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestImageTypeNEWT extends UITestCase { + ImageTstFiles imageTstFiles; + + @Before + public void initTest() throws IOException { + imageTstFiles = new ImageTstFiles(); + imageTstFiles.init(); + } + + @After + public void cleanupTest() { + imageTstFiles.clear(); + } + + public void testImpl(final List<ImageTstFiles.NamedInputStream> streams, final ImageType expImageType) throws InterruptedException, IOException { + for(int i=0; i<streams.size(); i++) { + final ImageTstFiles.NamedInputStream s = streams.get(i); + final ImageType t = new ImageType(s.stream); + System.err.printf("Test %3d: path %s, exp-type %s, has-type %s%n", i, s.basePath, expImageType, t); + Assert.assertEquals(expImageType, t); + } + } + + @Test + public void test01AllPNG() throws InterruptedException, IOException { + testImpl(imageTstFiles.pngStreams, new ImageType(ImageType.T_PNG)); + } + + @Test + public void test02AllJPG() throws InterruptedException, IOException { + testImpl(imageTstFiles.jpgStreams, new ImageType(ImageType.T_JPG)); + } + + // TGA cannot be detected + // @Test + public void test03AllTGA() throws InterruptedException, IOException { + testImpl(imageTstFiles.tgaStreams, new ImageType(ImageType.T_TGA)); + } + + @Test + public void test04AllDDS() throws InterruptedException, IOException { + testImpl(imageTstFiles.ddsStreams, new ImageType(ImageType.T_DDS)); + } + + public static void main(final String args[]) throws IOException { + org.junit.runner.JUnitCore.main(TestImageTypeNEWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTextureIONEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTextureIONEWT.java new file mode 100644 index 000000000..c5c32280d --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTextureIONEWT.java @@ -0,0 +1,165 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.util.texture; + +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.GLAutoDrawable; +import com.jogamp.opengl.GLCapabilities; +import com.jogamp.opengl.GLEventListener; +import com.jogamp.opengl.GLProfile; +import com.jogamp.opengl.test.junit.jogl.demos.TextureDraw01Accessor; +import com.jogamp.opengl.test.junit.jogl.demos.es2.TextureDraw01ES2Listener; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.TextureDraw01GL2Listener; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.QuitAdapter; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.GLReadBufferUtil; +import com.jogamp.opengl.util.texture.ImageType; +import com.jogamp.opengl.util.texture.TextureData; +import com.jogamp.opengl.util.texture.TextureIO; + +import junit.framework.Assert; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestTextureIONEWT extends UITestCase { + static long duration = 100; // ms + + ImageTstFiles imageTstFiles; + + @Before + public void initTest() throws IOException { + imageTstFiles = new ImageTstFiles(); + imageTstFiles.init(); + } + + @After + public void cleanupTest() { + imageTstFiles.clear(); + } + + public void testImpl(final List<ImageTstFiles.NamedInputStream> streams, final ImageType expImageType) throws InterruptedException, IOException { + for(int i=0; i<streams.size(); i++) { + final ImageTstFiles.NamedInputStream s = streams.get(i); + System.err.printf("Test %3d: path %s, exp-type %s%n", i, s.basePath, expImageType); + testImpl(s.stream, expImageType); + } + } + public void testImpl(final InputStream istream, final ImageType expImageType) throws InterruptedException, IOException { + final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false); + final GLProfile glp = GLProfile.isAvailable(GLProfile.GL2ES2) ? GLProfile.getGL2ES2() : GLProfile.getDefault(); + final GLCapabilities caps = new GLCapabilities(glp); + caps.setAlphaBits(1); + + final TextureData texData = TextureIO.newTextureData(glp, istream, false /* mipmap */, expImageType.type); + System.err.println("TextureData: "+texData); + Assert.assertEquals(expImageType, texData.getSourceImageType()); + + final GLWindow glad = GLWindow.create(caps); + glad.setTitle("TestTextureIONEWT."+expImageType.type); + // Size OpenGL to Video Surface + glad.setSize(texData.getWidth(), texData.getHeight()); + + // load texture from file inside current GL context to match the way + // the bug submitter was doing it + final GLEventListener gle = glp.isGL2ES2() ? new TextureDraw01ES2Listener( texData, 0 ) : new TextureDraw01GL2Listener( texData ) ; + glad.addGLEventListener(gle); + glad.addGLEventListener(new GLEventListener() { + boolean shot = false; + + @Override public void init(final GLAutoDrawable drawable) {} + + public void display(final GLAutoDrawable drawable) { + // 1 snapshot + if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) { + shot = true; + snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null); + } + } + + @Override public void dispose(final GLAutoDrawable drawable) { } + @Override public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { } + }); + + final Animator animator = new Animator(glad); + animator.setUpdateFPSFrames(60, null); + final QuitAdapter quitAdapter = new QuitAdapter(); + glad.addKeyListener(quitAdapter); + glad.addWindowListener(quitAdapter); + glad.setVisible(true); + animator.start(); + + while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) { + Thread.sleep(100); + } + + animator.stop(); + glad.destroy(); + } + + @Test + public void test01AllPNG() throws InterruptedException, IOException { + testImpl(imageTstFiles.pngStreams, new ImageType(ImageType.T_PNG)); + } + + @Test + public void test02AllJPG() throws InterruptedException, IOException { + testImpl(imageTstFiles.jpgStreams, new ImageType(ImageType.T_JPG)); + } + + @Test + public void test03AllTGA() throws InterruptedException, IOException { + testImpl(imageTstFiles.tgaStreams, new ImageType(ImageType.T_TGA)); + } + + @Test + public void test04AllDDS() throws InterruptedException, IOException { + testImpl(imageTstFiles.ddsStreams, new ImageType(ImageType.T_DDS)); + } + + public static void main(final String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } + } + org.junit.runner.JUnitCore.main(TestTextureIONEWT.class.getName()); + } +} |