/** * Slow filter. * * @param src the src. * @param dst the dst. * @return the int. */ private int slowFilter(Raster src, WritableRaster dst) { // TODO: make correct interpolation // TODO: what if there are different data types? Rectangle srcBounds = src.getBounds(); Rectangle dstBounds = dst.getBounds(); Rectangle normDstBounds = new Rectangle(0, 0, dstBounds.width, dstBounds.height); Rectangle bounds = getBounds2D(src).getBounds().intersection(normDstBounds); AffineTransform inv = null; try { inv = at.createInverse(); } catch (NoninvertibleTransformException e) { return -1; } double[] m = new double[6]; inv.getMatrix(m); int minSrcX = srcBounds.x; int minSrcY = srcBounds.y; int maxSrcX = srcBounds.x + srcBounds.width; int maxSrcY = srcBounds.y + srcBounds.height; int minX = bounds.x + dstBounds.x; int minY = bounds.y + dstBounds.y; int maxX = minX + bounds.width; int maxY = minY + bounds.height; int hx = (int) (m[0] * 256); int hy = (int) (m[1] * 256); int vx = (int) (m[2] * 256); int vy = (int) (m[3] * 256); int sx = (int) (m[4] * 256) + hx * bounds.x + vx * bounds.y + (srcBounds.x) * 256; int sy = (int) (m[5] * 256) + hy * bounds.x + vy * bounds.y + (srcBounds.y) * 256; vx -= hx * bounds.width; vy -= hy * bounds.width; if (src.getTransferType() == dst.getTransferType()) { for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { int px = sx >> 8; int py = sy >> 8; if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) { Object val = src.getDataElements(px, py, null); dst.setDataElements(x, y, val); } sx += hx; sy += hy; } sx += vx; sy += vy; } } else { float pixel[] = null; for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { int px = sx >> 8; int py = sy >> 8; if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) { pixel = src.getPixel(px, py, pixel); dst.setPixel(x, y, pixel); } sx += hx; sy += hy; } sx += vx; sy += vy; } } return 0; }
/** * Loads PNG files and returns the result as an int[][]. The only PNG formats permitted are those * with up to 256 grays (including simple black and white) or indexed colors from an up to * 256-sized color table. Each integer value represents the gray level or the color table index * value of the pixel. The Y dimension is not flipped. */ public static int[][] loadPNGFile(InputStream str) throws IOException { // read the bytes into a byte array BufferedInputStream stream = new BufferedInputStream(str); ArrayList list = new ArrayList(); int count = 0; while (true) { byte[] buffer = new byte[16384 * 16]; int len = stream.read(buffer); if (len <= 0) // all done break; else if (len < buffer.length) { byte[] buf2 = new byte[len]; System.arraycopy(buffer, 0, buf2, 0, len); buffer = buf2; } count += len; list.add(buffer); } byte[] data = new byte[count]; int cur = 0; for (int i = 0; i < list.size(); i++) { byte[] b = (byte[]) (list.get(i)); System.arraycopy(b, 0, data, cur, b.length); cur += b.length; } // Next convert the byte array to a buffered image BufferedImage image = ((ToolkitImage) (new ImageIcon(data).getImage())).getBufferedImage(); // Is the color model something we can use? int type = image.getType(); if (type == BufferedImage.TYPE_BYTE_BINARY || type == BufferedImage.TYPE_BYTE_GRAY) { int w = image.getWidth(); int h = image.getHeight(); int[][] result = new int[w][h]; // obviously this could be done more efficiently for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) result[i][j] = (image.getRGB(i, j) & 0xFF); return result; } else if (type == BufferedImage.TYPE_BYTE_INDEXED) { Raster raster = image.getRaster(); if (raster.getTransferType() != DataBuffer.TYPE_BYTE) // uh oh throw new IOException("Input Stream must contain an image with byte data if indexed."); byte[] pixel = new byte[1]; int w = image.getWidth(); int h = image.getHeight(); int[][] result = new int[w][h]; // obviously this could be done more efficiently for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) { result[i][j] = ((byte[]) (raster.getDataElements(i, j, pixel)))[0]; if (result[i][j] < 0) result[i][j] += 256; } return result; } // else if (type == TYPE_USHORT_GRAY) // at present we don't handle shorts // { // } else throw new IOException( "Input Stream must contain a binary, byte-sized grayscale, or byte-sized indexed color scheme: " + image); }