/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/** PNG - Portable Network Graphics - image file reader.
See <a href=http://www.ietf.org/rfc/rfc2083.txt>RFC2083</a> for details. */
/* this is changed
public class PNGImageDecoder extends FilterInputStream implements Runnable
{ */
{
private int width;
private int height;
private int bitDepth;
private int colorType;
private int compressionMethod;
private int filterMethod;
private int interlaceMethod;
/* this is not needed
ImageConsumer target;
*/
/* this is not needed
PNGImageDecoder next;
*/
}
}
if(!b) {
e.printStackTrace();
throw e;
}
}
throws IOException {
switch(key) {
case bKGDChunk:
switch(colorType) {
case COLOR:
break;
break;
case GRAY:
c = new Color(t,t,t);
break;
}
break;
case cHRMChunk:
property("chromaticities",
new Chromaticities(
break;
case gAMAChunk:
break;
case hISTChunk: break;
case IDATChunk: return false;
case IENDChunk: break;
case IHDRChunk:
if(len!=13
) throw new PNGException("bogus IHDR");
/* this is not needed
if(target!=null) target.setDimensions(width,height);
*/
break;
case PLTEChunk:
}
}
break;
case pHYsChunk: break;
case sBITChunk: break;
case tEXtChunk:
int klen = 0;
}
break;
case tIMEChunk:
break;
case tRNSChunk:
switch(colorType) {
break;
case COLOR: // doesn't deal with 16 bit colors properly
if (bitDepth == 16) {
transparentPixel_16 = new byte[6];
for (int i = 0; i < 6; i++) {
}
} else {
}
break;
case GRAY: // doesn't deal with 16 bit colors properly
/* REMIND: Discarding the LSB for 16 bit depth here
* means that the all pixels which match the MSB
* will be treated as transparent.
*/
break;
}
break;
case zTXtChunk: break;
}
return true;
}
}
/* this is changed
public void run() {
*/
/* this is not needed
ImageConsumer t = target;
if(t!=null) try {
*/
try {
throw new PNGException("Chunk signature mismatch");
getData();
int rowStride;
int logDepth = 0;
switch(bitDepth) {
default: throw new PNGException("invalid depth");
}
else rowStride = 0;
//Figure out the color model
switch(colorType) {
else
break;
case GRAY:
if (transparentPixel == -1) {
} else {
(transparentPixel & 0xFF));
}
}
}
break;
case COLOR:
break;
default:
throw new PNGException("invalid color type");
}
/* this is going to be set in the pixel store
t.setColorModel(cm);
t.setHints(interlaceMethod !=0
? ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
: ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME);
*/
// code added to make it work with ImageDecoder architecture
// end of adding
// These loops are far from being tuned. They're this way to make them easy to
// debug. Tuning comes later.
/* code changed. target not needed here
while(++pass<=passLimit && (t=target)!=null) {
*/
if(rowByteWidth==0) continue;
boolean firstRow = true;
byte[] rowByteBuffer = new byte[rowByteWidth];
byte[] prevRowByteBuffer = new byte[rowByteWidth];
/* code changed. target not needed here
while (row < height && (t=target)!=null) {
*/
rowFillPos+=n;
}
int spos=0;
int pixel = 0;
switch(combinedType) {
spos+=4;
break;
spos+=8;
break;
pixel =
if (pixel != transparentPixel) {
pixel |= 0xff000000;
}
spos+=3;
break;
pixel =
}
if (!isTransparent) {
pixel |= 0xff000000;
}
spos+=6;
break;
spos+=2;
break;
spos+=4;
break;
default: throw new PNGException("illegal type/depth");
}
} else switch(bitDepth) {
case 1:
spos++;
break;
case 2:
spos++;
break;
case 4:
spos++;
break;
break;
break;
default: throw new PNGException("illegal type/depth");
}
/*visit (row, col,
min (bHeight, height - row),
min (bWidth, width - col)); */
}
if(interlaceMethod==0)
/* code changed. target not needed here
t.setPixels(0,row,width,1,cm,wPixels,0,width);
*/
// code added to make it work with ImageDecoder arch
// end of adding
}
else {
/* code changed. target not needed here
t.setPixels(0,row,width,1,cm,bPixels,0,width);
*/
// code added to make it work with ImageDecoder arch
//end of adding
}
byte[] T = rowByteBuffer;
prevRowByteBuffer = T;
firstRow = false;
}
if(interlaceMethod!=0)
/* code changed. target not needed here
t.setPixels(0,0,width,height,cm,wPixels,0,width);
*/
// code added to make it work with ImageDecoder arch
//end of adding
}
else {
/* code changed. target not needed here
t.setPixels(0,0,width,height,cm,bPixels,0,width);
*/
// code added to make it work with ImageDecoder arch
//end of adding
}
}
/* Here, the function "visit(row,column,height,width)" obtains the
next transmitted pixel and paints a rectangle of the specified
height and width, whose upper-left corner is at the specified row
and column, using the color indicated by the pixel. Note that row
and column are measured from 0,0 at the upper left corner. */
/* code not needed, don't deal with target
if((t=target)!=null) {
if(properties!=null) t.setProperties(properties);
t.imageComplete(ImageConsumer.STATICIMAGEDONE);
*/
/* code not needed }
is.close();
*/
} catch(IOException e) {
if(!aborted) {
/* code not needed
if((t=target)!=null) {
PNGEncoder.prChunk(e.toString(),inbuf,pos,limit-pos,true);
*/
property("error", e);
/* code not needed
t.setProperties(properties);
t.imageComplete(ImageConsumer.IMAGEERROR|ImageConsumer.STATICIMAGEDONE);
*/
throw e;
}
} finally {
/* code not needed
target = null;
endTurn();
*/
}
}
if (count <= 0) {
aborted = true;
}
return !aborted;
}
if (count <= 0) {
aborted = true;
}
return !aborted;
}
throws IOException {
int x = 0;
switch (rowFilter) {
case 0:
break;
case 1:
for (x = bytesPerSample; x < rowByteWidth; x++)
break;
case 2:
for ( ; x < rowByteWidth; x++)
rowByteBuffer[x] += prevRow[x];
break;
case 3:
for ( ; x < bytesPerSample; x++)
for ( ; x < rowByteWidth; x++)
} else
for (x = bytesPerSample; x < rowByteWidth; x++)
break;
case 4:
for ( ; x < bytesPerSample; x++)
rowByteBuffer[x] += prevRow[x];
for ( ; x < rowByteWidth; x++) {
b = prevRow[x]&0xFF;
p = a + b - c;
pa = p > a ? p - a : a - p;
pb = p > b ? p - b : b - p;
pc = p > c ? p - c : c - p;
}
} else
for (x = bytesPerSample; x < rowByteWidth; x++)
break;
default:
throw new PNGException("Illegal filter");
}
}
//abstract public class ChunkReader extends FilterInputStream {
int chunkStart;
boolean seenEOF;
(byte) 71, (byte) 13, (byte) 10, (byte) 26, (byte) 10 };
/* code changed
public PNGImageDecoder(InputStream in, ImageConsumer t) throws IOException {
*/
// code added
// end of adding
/* code changed
super(in);
target = t;
waitTurn();
new Thread(this).start();
*/
}
/* code changed to make it work with ImageDecoder architecture
static int ThreadLimit = 10;
private synchronized static void waitTurn() {
try {
while(ThreadLimit<=0) PNGImageDecoder.class.wait(1000);
} catch(InterruptedException e){}
ThreadLimit--;
}
private synchronized static void endTurn() {
if(ThreadLimit<=0) PNGImageDecoder.class.notify();
ThreadLimit++;
}
*/
if(!seenEOF) {
pos = 0;
}
if(n<=0) { seenEOF=true; break; }
limit += n;
}
}
}
fill();
if(seenEOF) return false;
byte nin[] = new byte[n+100];
pos = 0;
fill();
}
}
}
}
chunkLength = 0;
if (!need(8)) return false;
return true;
}
}
chunkLength = 0;
return chunkLength>0;
}
//abstract protected boolean handleChunk(int key, byte[] buf, int st, int len)
// throws IOException;
private static boolean checkCRC = true;
protected void wrc(int c) {
c = c&0xFF;
if(c<=' '||c>'z') c = '?';
}
protected void wrk(int n) {
wrc(n>>24);
wrc(n>>16);
wrc(n>>8);
wrc(n);
}
public void print() {
}
/* Table of CRCs of all 8-bit messages. */
/* Make the table for a fast CRC. */
static {
for (int n = 0; n < 256; n++) {
int c = n;
for (int k = 0; k < 8; k++)
if ((c & 1) != 0)
c = 0xedb88320 ^ (c >>> 1);
else
c = c >>> 1;
crc_table[n] = c;
}
}
/* Update a running CRC with the bytes buf[0..len-1]--the CRC
should be initialized to all 1's, and the transmitted value
is the 1's complement of the final running CRC (see the
crc() routine below)). */
int c = crc;
while (--len>=0)
return c;
}
/* Return the CRC of the bytes buf[0..len-1]. */
}
public static class Chromaticities {
}
}
}
}
// the following class are added to make it work with ImageDecoder architecture
super(is);
}
public boolean markSupported() { return false; }
owner.chunkLength--;
}
return len;
}
int i;
return i;
}
}