X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Forg%2Fxwt%2Ftranslators%2FPNG.java;h=c20263f2ef7fd6c388dd1cafdcf5cb5392076f03;hb=89afe7ee10eddb1876e2a94a5630748837c29e16;hp=9e6b8d54a53a85e3f84a5f0244ddc044b265e7bb;hpb=de71be6ed2ac0542abb790006896980b2c2211a8;p=org.ibex.core.git diff --git a/src/org/xwt/translators/PNG.java b/src/org/xwt/translators/PNG.java index 9e6b8d5..c20263f 100644 --- a/src/org/xwt/translators/PNG.java +++ b/src/org/xwt/translators/PNG.java @@ -22,42 +22,46 @@ import java.util.Enumeration; import java.util.zip.*; /** Converts an InputStream carrying a PNG image into an ARGB int[] */ -public class PNG extends ImageDecoder { +public class PNG { - // Public Methods /////////////////////////////////////////////////////////////////////////////// + public PNG() { } + + private static Queue instances = new Queue(10); - /** returns the ARGB int[] representing the last image processed */ - public final int[] getData() { return data; } + public static void load(InputStream is, Picture p) { + PNG g = (PNG)instances.remove(false); + if (g == null) g = new PNG(); + try { + g._load(is, p); + p.data = g.data; + } catch (Exception e) { + if (Log.on) Log.info(PNG.class, e); + return; + } + // FIXME: must reset fields + // if (instances.size() < 10) instances.append(g); + } - /** returns the width of the last image processed */ - public final int getWidth() { return width; } + // Public Methods /////////////////////////////////////////////////////////////////////////////// - /** returns the height of the last image processed */ - public final int getHeight() { return height; } + private Picture p; /** process a PNG as an inputstream; returns null if there is an error @param name A string describing the image, to be used when logging errors */ - public static PNG decode(InputStream is, String name) { - try { - return new PNG(is, name); - } catch (Exception e) { - if (Log.on) Log.log(PNG.class, e); - return null; - } - } - - private PNG(InputStream is, String name) throws IOException { - underlyingStream = is; + private void _load(InputStream is, Picture p) throws IOException { + this.p = p; + if (is instanceof BufferedInputStream) underlyingStream = (BufferedInputStream)is; + else underlyingStream = new BufferedInputStream(is); target_offset = 0; inputStream = new DataInputStream(underlyingStream); // consume the header if ((inputStream.read() != 137) || (inputStream.read() != 80) || (inputStream.read() != 78) || (inputStream.read() != 71) || (inputStream.read() != 13) || (inputStream.read() != 10) || (inputStream.read() != 26) || (inputStream.read() != 10)) { - Log.log(this, "PNG: error: input file " + name + " is not a PNG file"); - data = new int[] { }; - width = height = 0; + Log.info(this, "PNG: error: input file is not a PNG file"); + data = p.data = new int[] { }; + p.width = p.height = 0; return; } @@ -95,13 +99,14 @@ public class PNG extends ImageDecoder { int crc = inputStream.readInt(); needChunkInfo = true; } + p.isLoaded = true; } // Chunk Handlers /////////////////////////////////////////////////////////////////////// /** handle data chunk */ private void handleIDAT() throws IOException { - if (width == -1 || height == -1) throw new IOException("never got image width/height"); + if (p.width == -1 || p.height == -1) throw new IOException("never got image width/height"); switch (depth) { case 1: mask = 0x1; break; case 2: mask = 0x3; break; @@ -112,7 +117,7 @@ public class PNG extends ImageDecoder { if (depth < 8) smask = mask << depth; else smask = mask << 8; - int count = width * height; + int count = p.width * p.height; switch (colorType) { case 0: @@ -137,8 +142,8 @@ public class PNG extends ImageDecoder { private void handleIHDR() throws IOException { if (headerFound) throw new IOException("Extraneous IHDR chunk encountered."); if (chunkLength != 13) throw new IOException("IHDR chunk length wrong: " + chunkLength); - width = inputStream.readInt(); - height = inputStream.readInt(); + p.width = inputStream.readInt(); + p.height = inputStream.readInt(); depth = inputStream.read(); colorType = inputStream.read(); compressionMethod = inputStream.read(); @@ -161,7 +166,7 @@ public class PNG extends ImageDecoder { private void handletRNS() throws IOException { int chunkLen = chunkLength; if (palette == null) { - if (Log.on) Log.log(this, "warning: tRNS chunk encountered before pLTE; ignoring alpha channel"); + if (Log.on) Log.info(this, "warning: tRNS chunk encountered before pLTE; ignoring alpha channel"); inputStream.skip(chunkLength); return; } @@ -210,21 +215,21 @@ public class PNG extends ImageDecoder { int rInc = rowInc[pass]; int cInc = colInc[pass]; int sCol = startingCol[pass]; - int val = (width - sCol + cInc - 1) / cInc; + int val = (p.width - sCol + cInc - 1) / cInc; int samples = val * filterOffset; int rowSize = (val * bps)>>3; int sRow = startingRow[pass]; - if (height <= sRow || rowSize == 0) continue; - int sInc = rInc * width; + if (p.height <= sRow || rowSize == 0) continue; + int sInc = rInc * p.width; byte inbuf[] = new byte[rowSize]; int pix[] = new int[rowSize]; int upix[] = null; int temp[] = new int[rowSize]; int nextY = sRow; // next Y value and number of rows to report to sendPixels int rows = 0; - int rowStart = sRow * width; + int rowStart = sRow * p.width; - for (int y = sRow; y < height; y += rInc, rowStart += sInc) { + for (int y = sRow; y < p.height; y += rInc, rowStart += sInc) { rows += rInc; int rowFilter = dis.read(); dis.readFully(inbuf); @@ -420,7 +425,7 @@ public class PNG extends ImageDecoder { private void blockFill(int rowStart) { int counter; - int dw = width; + int dw = p.width; int pass = this.pass; int w = blockWidth[pass]; int sCol = startingCol[pass]; @@ -546,8 +551,6 @@ public class PNG extends ImageDecoder { // Private Data /////////////////////////////////////////////////////////////////////////////////////// private int target_offset = 0; - private int width = -1; - private int height = -1; private int sigmask = 0xffff; private Object pixels = null; private int ipixels[] = null; @@ -556,7 +559,7 @@ public class PNG extends ImageDecoder { private boolean complete = false; private boolean error = false; - private int[] data = null; + int[] data = null; private InputStream underlyingStream = null; private DataInputStream inputStream = null;