package jogamp.opengl.util.pngj; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.HashSet; import java.util.Set; import java.util.zip.CRC32; /** * Some utility static methods. *

* See also FileHelper (if not sandboxed). *

* Client code should rarely need these methods. */ public class PngHelper { /** * Default charset, used internally by PNG for several things */ public static Charset charsetLatin1 = Charset.forName("ISO-8859-1"); public static Charset charsetUTF8 = Charset.forName("UTF-8"); // only for some chunks static boolean DEBUG = false; public static int readByte(InputStream is) { try { return is.read(); } catch (IOException e) { throw new PngjOutputException(e); } } /** * -1 if eof * * PNG uses "network byte order" */ public static int readInt2(InputStream is) { try { int b1 = is.read(); int b2 = is.read(); if (b1 == -1 || b2 == -1) return -1; return (b1 << 8) + b2; } catch (IOException e) { throw new PngjInputException("error reading readInt2", e); } } /** * -1 if eof */ public static int readInt4(InputStream is) { try { int b1 = is.read(); int b2 = is.read(); int b3 = is.read(); int b4 = is.read(); if (b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1) return -1; return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4; } catch (IOException e) { throw new PngjInputException("error reading readInt4", e); } } public static int readInt1fromByte(byte[] b, int offset) { return (b[offset] & 0xff); } public static int readInt2fromBytes(byte[] b, int offset) { return ((b[offset] & 0xff) << 16) | ((b[offset + 1] & 0xff)); } public static int readInt4fromBytes(byte[] b, int offset) { return ((b[offset] & 0xff) << 24) | ((b[offset + 1] & 0xff) << 16) | ((b[offset + 2] & 0xff) << 8) | (b[offset + 3] & 0xff); } public static void writeByte(OutputStream os, byte b) { try { os.write(b); } catch (IOException e) { throw new PngjOutputException(e); } } public static void writeInt2(OutputStream os, int n) { byte[] temp = { (byte) ((n >> 8) & 0xff), (byte) (n & 0xff) }; writeBytes(os, temp); } public static void writeInt4(OutputStream os, int n) { byte[] temp = new byte[4]; writeInt4tobytes(n, temp, 0); writeBytes(os, temp); } public static void writeInt2tobytes(int n, byte[] b, int offset) { b[offset] = (byte) ((n >> 8) & 0xff); b[offset + 1] = (byte) (n & 0xff); } public static void writeInt4tobytes(int n, byte[] b, int offset) { b[offset] = (byte) ((n >> 24) & 0xff); b[offset + 1] = (byte) ((n >> 16) & 0xff); b[offset + 2] = (byte) ((n >> 8) & 0xff); b[offset + 3] = (byte) (n & 0xff); } /** * guaranteed to read exactly len bytes. throws error if it cant */ public static void readBytes(InputStream is, byte[] b, int offset, int len) { if (len == 0) return; try { int read = 0; while (read < len) { int n = is.read(b, offset + read, len - read); if (n < 1) throw new RuntimeException("error reading bytes, " + n + " !=" + len); read += n; } } catch (IOException e) { throw new PngjInputException("error reading", e); } } public static void writeBytes(OutputStream os, byte[] b) { try { os.write(b); } catch (IOException e) { throw new PngjOutputException(e); } } public static void writeBytes(OutputStream os, byte[] b, int offset, int n) { try { os.write(b, offset, n); } catch (IOException e) { throw new PngjOutputException(e); } } public static void logdebug(String msg) { if (DEBUG) System.out.println(msg); } public static Set asSet(String... values) { return new HashSet(java.util.Arrays.asList(values)); } public static Set unionSets(Set set1, Set set2) { Set s = new HashSet(); s.addAll(set1); s.addAll(set2); return s; } public static Set unionSets(Set set1, Set set2, Set set3) { Set s = new HashSet(); s.addAll(set1); s.addAll(set2); s.addAll(set3); return s; } private static final ThreadLocal crcProvider = new ThreadLocal() { protected CRC32 initialValue() { return new CRC32(); } }; /** thread-singleton crc engine */ public static CRC32 getCRC() { return crcProvider.get(); } static final byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 }; // png magic public static double resMetersToDpi(long res) { return (double) res * 0.0254; } public static long resDpiToMeters(double dpi) { return (long) (dpi / 0.0254 + 0.5); } public static int doubleToInt100000(double d) { return (int) (d * 100000.0 + 0.5); } public static double intToDouble100000(int i) { return i / 100000.0; } public static int clampTo_0_255(int i) { return i > 255 ? 255 : (i < 0 ? 0 : i); } public static int clampTo_0_65535(int i) { return i > 65535 ? 65535 : (i < 0 ? 0 : i); } public static int clampTo_128_127(int x) { return x > 127 ? 127 : (x < -128 ? -128 : x); } }