X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Ftranslators%2FPNG.java;h=33440ea44ab7696be68607d527e1fee9218a2d6a;hb=7d832e12a5f66911b042885f8f07e37844501208;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..33440ea 100644 --- a/src/org/xwt/translators/PNG.java +++ b/src/org/xwt/translators/PNG.java @@ -22,86 +22,87 @@ 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 /////////////////////////////////////////////////////////////////////////////// - - /** returns the ARGB int[] representing the last image processed */ - public final int[] getData() { return data; } - - /** returns the width of the last image processed */ - public final int getWidth() { return width; } - - /** returns the height of the last image processed */ - public final int getHeight() { return height; } + public PNG() { } + + private static Queue instances = new Queue(10); + 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) { + public static void load(InputStream is, Picture p) { + PNG g = (PNG)instances.remove(false); + if (g == null) g = new PNG(); try { - return new PNG(is, name); + g._load(is, p); + p.data = g.data; } catch (Exception e) { - if (Log.on) Log.log(PNG.class, e); - return null; + if (Log.on) Log.info(PNG.class, e); + return; } + // FIXME: must reset fields + // if (instances.size() < 10) instances.append(g); } - private PNG(InputStream is, String name) throws IOException { - underlyingStream = is; + // Public Methods /////////////////////////////////////////////////////////////////////////////// + + /** 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 + */ + private void _load(InputStream is, Picture pic) throws IOException { + p = pic; + 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; } - DONE: while (!error) { + + while (!error) { if (needChunkInfo) { chunkLength = inputStream.readInt(); chunkType = inputStream.readInt(); needChunkInfo = false; } - switch (chunkType) { - case CHUNK_bKGD: inputStream.skip(chunkLength); break; - case CHUNK_cHRM: inputStream.skip(chunkLength); break; - case CHUNK_gAMA: inputStream.skip(chunkLength); break; - case CHUNK_hIST: inputStream.skip(chunkLength); break; - case CHUNK_pHYs: inputStream.skip(chunkLength); break; - case CHUNK_sBIT: inputStream.skip(chunkLength); break; - case CHUNK_tEXt: inputStream.skip(chunkLength); break; - case CHUNK_zTXt: inputStream.skip(chunkLength); break; - case CHUNK_tIME: inputStream.skip(chunkLength); break; - - case CHUNK_IHDR: handleIHDR(); break; - case CHUNK_PLTE: handlePLTE(); break; - case CHUNK_tRNS: handletRNS(); break; - - case CHUNK_IDAT: handleIDAT(); break; - - case CHUNK_IEND: break DONE; - default: - System.err.println("unrecognized chunk type " + - Integer.toHexString(chunkType) + ". skipping"); + // I rewrote this as an if/else to work around a JODE bug with switch() blocks + if (chunkType == CHUNK_bKGD) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_cHRM) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_gAMA) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_hIST) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_pHYs) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_sBIT) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_tEXt) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_zTXt) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_tIME) inputStream.skip(chunkLength); + else if (chunkType == CHUNK_IHDR) handleIHDR(); + else if (chunkType == CHUNK_PLTE) handlePLTE(); + else if (chunkType == CHUNK_tRNS) handletRNS(); + else if (chunkType == CHUNK_IDAT) handleIDAT(); + else if (chunkType == CHUNK_IEND) break; + else { + System.err.println("unrecognized chunk type " + Integer.toHexString(chunkType) + ". skipping"); inputStream.skip(chunkLength); } 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 +113,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 +138,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 +162,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 +211,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 +421,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 +547,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 +555,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;