public final static Image decode(InputStream is) throws IOException {
		BufferedInputStream bis = new BufferedInputStream(is, defaultBufferSize);

		checkEquality(read(bis, 12), PNGHelper.ID);

		checkEquality(read(bis, 4), PNGHelper.IHDR);
		
		int width = readInt(bis);
		int height = readInt(bis);
		
		Image result = new Image(width, height);
		
		checkEquality(read(bis, 5), PNGHelper.HEAD);

		read(bis, 4);

		int size = readInt(bis);
		
		checkEquality(read(bis, 4), PNGHelper.IDAT);
		
		byte[] pixdata = read(bis, size);

		Inflater inflater = new Inflater();
		inflater.setInput(pixdata, 0, size);
		
		try {
			byte[] row = new byte[width * 4];
			for (int y = 0; y < height; y++) {
				inflater.inflate(new byte[1]);
				inflater.inflate(row);
				for (int x = 0; x < width; x++) {
					result.setPixel(x, y, 
							((row[x*4 + 0] & 0xFF) << 16) +//R
							((row[x*4 + 1] & 0xFF) << 8) +//G
							((row[x*4 + 2] & 0xFF)) +//B
							((row[x*4 + 3] & 0xFF) << 24));//A
				}
			}
		} catch(DataFormatException e) {
			throw new RuntimeException("ZIP error", e);
		}

		inflater.end();
		
		readInt(bis);
		readInt(bis);

		checkEquality(read(bis, 4), PNGHelper.IEND);
		
		bis.close();
		
		return result;
	}