From 921b33825340d27deec2883ded21cb7434decc94 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 31 Dec 2012 16:39:15 +0100 Subject: Update PNGJ 0.85 -> 1.12 (w/ interlace read support) ; Added PNG Interlace read tests (TestPNGTextureFromFileNEWT) --- .../jogamp/opengl/util/pngj/PngHelperInternal.java | 264 +++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 src/jogl/classes/jogamp/opengl/util/pngj/PngHelperInternal.java (limited to 'src/jogl/classes/jogamp/opengl/util/pngj/PngHelperInternal.java') diff --git a/src/jogl/classes/jogamp/opengl/util/pngj/PngHelperInternal.java b/src/jogl/classes/jogamp/opengl/util/pngj/PngHelperInternal.java new file mode 100644 index 000000000..63edf8d17 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/util/pngj/PngHelperInternal.java @@ -0,0 +1,264 @@ +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.zip.CRC32; + +/** + * Some utility static methods for internal use. + *

+ * Client code should not normally use this class + *

+ */ +public class PngHelperInternal { + /** + * Default charset, used internally by PNG for several things + */ + public static Charset charsetLatin1 = Charset.forName("ISO-8859-1"); + /** + * UTF-8 is only used for some chunks + */ + public static Charset charsetUTF8 = Charset.forName("UTF-8"); + + static boolean DEBUG = false; + + /** + * PNG magic bytes + */ + public static byte[] getPngIdSignature() { + return new byte[] { -119, 80, 78, 71, 13, 10, 26, 10 }; + } + + 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 readByte(InputStream is) { + try { + return is.read(); + } catch (IOException e) { + throw new PngjInputException("error reading byte", 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 can't + */ + 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 PngjInputException("error reading bytes, " + n + " !=" + len); + read += n; + } + } catch (IOException e) { + throw new PngjInputException("error reading", e); + } + } + + public static void skipBytes(InputStream is, int len) { + byte[] buf = new byte[8192 * 4]; + int read, remain = len; + try { + while (remain > 0) { + read = is.read(buf, 0, remain > buf.length ? buf.length : remain); + if (read < 0) + throw new PngjInputException("error reading (skipping) : EOF"); + remain -= read; + } + } catch (IOException e) { + throw new PngjInputException("error reading (skipping)", 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); + } + + private static final ThreadLocal crcProvider = new ThreadLocal() { + protected CRC32 initialValue() { + return new CRC32(); + } + }; + + /** thread-singleton crc engine */ + public static CRC32 getCRC() { + return crcProvider.get(); + } + + // / filters + public static int filterRowNone(int r) { + return (int) (r & 0xFF); + } + + public static int filterRowSub(int r, int left) { + return ((int) (r - left) & 0xFF); + } + + public static int filterRowUp(int r, int up) { + return ((int) (r - up) & 0xFF); + } + + public static int filterRowAverage(int r, int left, int up) { + return (r - (left + up) / 2) & 0xFF; + } + + public static int filterRowPaeth(int r, int left, int up, int upleft) { // a = left, b = above, c = upper left + return (r - filterPaethPredictor(left, up, upleft)) & 0xFF; + } + + public static int unfilterRowNone(int r) { + return (int) (r & 0xFF); + } + + public static int unfilterRowSub(int r, int left) { + return ((int) (r + left) & 0xFF); + } + + public static int unfilterRowUp(int r, int up) { + return ((int) (r + up) & 0xFF); + } + + public static int unfilterRowAverage(int r, int left, int up) { + return (r + (left + up) / 2) & 0xFF; + } + + public static int unfilterRowPaeth(int r, int left, int up, int upleft) { // a = left, b = above, c = upper left + return (r + filterPaethPredictor(left, up, upleft)) & 0xFF; + } + + final static int filterPaethPredictor(final int a, final int b, final int c) { // a = left, b = above, c = upper + // left + // from http://www.libpng.org/pub/png/spec/1.2/PNG-Filters.html + + final int p = a + b - c;// ; initial estimate + final int pa = p >= a ? p - a : a - p; + final int pb = p >= b ? p - b : b - p; + final int pc = p >= c ? p - c : c - p; + // ; return nearest of a,b,c, + // ; breaking ties in order a,b,c. + if (pa <= pb && pa <= pc) + return a; + else if (pb <= pc) + return b; + else + return c; + } + + /* + * we put this methods here so as to not pollute the public interface of PngReader + */ + public final static void initCrcForTests(PngReader pngr) { + pngr.initCrctest(); + } + + public final static long getCrctestVal(PngReader pngr) { + return pngr.getCrctestVal(); + } + +} -- cgit v1.2.3