/**
   * 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;
  }
Beispiel #2
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);
  }