diff options
12 files changed, 2126 insertions, 1507 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index d19631f02..844bbde5f 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -182,7 +182,7 @@ function jrun() { #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all" #D_ARGS="-Djogl.debug.GLArrayData" #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window" - D_ARGS="-Dnewt.debug.Window" + #D_ARGS="-Dnewt.debug.Window" #D_ARGS="-Dnewt.debug.Screen" #D_ARGS="-Dnewt.test.Screen.disableRandR13" #D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen" @@ -281,6 +281,7 @@ function jrun() { #D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil -Djogamp.debug.IOUtil" #D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil" #D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.debug.TempFileCache -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil -Djogamp.gluegen.UseTempJarCache=false" + #D_ARGS="-Djogamp.debug.JNILibLoader.Perf" #D_ARGS="-Dnewt.test.EDTMainThread -Dnewt.debug.MainThread" #C_ARG="com.jogamp.newt.util.MainThread" #D_ARGS="-Dnewt.debug.MainThread" @@ -420,7 +421,7 @@ function testawtswt() { # # HiDPI # -testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2SimpleNEWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $* @@ -812,6 +813,8 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestTexture01AWT $* #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestTexture02AWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestImageTypeNEWT $* +testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestTextureIONEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGImage01NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTCompareNewtAWT $* #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTBenchmarkNewtAWT $* 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()); + } +} |