Example #1
0
  /**
   * Paint the image onto a Graphics object. The painting is performed tile-by-tile, and includes a
   * grey region covering the unused portion of image tiles as well as the general background. At
   * this point the image must be byte data.
   */
  public synchronized void paintComponent(Graphics g) {

    Graphics2D g2D = null;
    if (g instanceof Graphics2D) {
      g2D = (Graphics2D) g;
    } else {
      return;
    }

    // if source is null, it's just a component
    if (source == null) {
      g2D.setColor(getBackground());
      g2D.fillRect(0, 0, componentWidth, componentHeight);
      return;
    }

    int transX = -originX;
    int transY = -originY;

    // Get the clipping rectangle and translate it into image coordinates.
    Rectangle clipBounds = g.getClipBounds();

    if (clipBounds == null) {
      clipBounds = new Rectangle(0, 0, componentWidth, componentHeight);
    }

    // clear the background (clip it) [minimal optimization here]
    if (transX > 0
        || transY > 0
        || transX < (componentWidth - source.getWidth())
        || transY < (componentHeight - source.getHeight())) {
      g2D.setColor(getBackground());
      g2D.fillRect(0, 0, componentWidth, componentHeight);
    }

    clipBounds.translate(-transX, -transY);

    // Determine the extent of the clipping region in tile coordinates.
    int txmin, txmax, tymin, tymax;
    int ti, tj;

    txmin = XtoTileX(clipBounds.x);
    txmin = Math.max(txmin, minTileX);
    txmin = Math.min(txmin, maxTileX);

    txmax = XtoTileX(clipBounds.x + clipBounds.width - 1);
    txmax = Math.max(txmax, minTileX);
    txmax = Math.min(txmax, maxTileX);

    tymin = YtoTileY(clipBounds.y);
    tymin = Math.max(tymin, minTileY);
    tymin = Math.min(tymin, maxTileY);

    tymax = YtoTileY(clipBounds.y + clipBounds.height - 1);
    tymax = Math.max(tymax, minTileY);
    tymax = Math.min(tymax, maxTileY);
    Insets insets = getInsets();

    // Loop over tiles within the clipping region
    for (tj = tymin; tj <= tymax; tj++) {
      for (ti = txmin; ti <= txmax; ti++) {
        int tx = TileXtoX(ti);
        int ty = TileYtoY(tj);

        Raster tile = source.getTile(ti, tj);
        if (tile != null) {
          DataBuffer dataBuffer = tile.getDataBuffer();

          WritableRaster wr = tile.createWritableRaster(sampleModel, dataBuffer, null);

          BufferedImage bi =
              new BufferedImage(colorModel, wr, colorModel.isAlphaPremultiplied(), null);

          // correctly handles band offsets
          if (brightnessEnabled == true) {
            SampleModel sm =
                sampleModel.createCompatibleSampleModel(tile.getWidth(), tile.getHeight());

            WritableRaster raster = RasterFactory.createWritableRaster(sm, null);

            BufferedImage bimg =
                new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);

            // don't move this code
            ByteLookupTable lutTable = new ByteLookupTable(0, lutData);
            LookupOp lookup = new LookupOp(lutTable, null);
            lookup.filter(bi, bimg);

            g2D.drawImage(bimg, biop, tx + transX + insets.left, ty + transY + insets.top);
          } else {
            AffineTransform transform;

            transform =
                AffineTransform.getTranslateInstance(
                    tx + transX + insets.left, ty + transY + insets.top);

            g2D.drawRenderedImage(bi, transform);
          }
        }
      }
    }
  }
  /**
   * Fills in the portions of a given <code>Raster</code> that lie outside the bounds of a given
   * <code>PlanarImage</code> with suitably reflected copies of the entire image.
   *
   * <p>The portion of <code>raster</code> that lies within <code>im.getBounds()</code> is not
   * altered.
   *
   * @param raster The <code>WritableRaster</code> the border area of which is to be filled with
   *     suitably reflected copies of portions of the specified image.
   * @param im The <code>PlanarImage</code> the data of which is to be reflected and used to fill
   *     the <code>WritableRaster</code> border.
   * @throws <code>IllegalArgumentException</code> if either parameter is <code>null</code>.
   */
  public final void extend(WritableRaster raster, PlanarImage im) {

    if (raster == null || im == null) {
      throw new IllegalArgumentException(JaiI18N.getString("Generic0"));
    }

    int width = raster.getWidth();
    int height = raster.getHeight();

    int minX = raster.getMinX();
    int maxX = minX + width;
    int minY = raster.getMinY();
    int maxY = minY + height;

    int imMinX = im.getMinX();
    int imMinY = im.getMinY();
    int imWidth = im.getWidth();
    int imHeight = im.getHeight();

    int validMinX = Math.max(imMinX, minX);
    int validMaxX = Math.min(imMinX + imWidth, maxX);
    int validMinY = Math.max(imMinY, minY);
    int validMaxY = Math.min(imMinY + imHeight, maxY);

    if (validMinX > validMaxX || validMinY > validMaxY) {
      // Raster does not intersect image. Determine the location
      // and size of the smallest rectangle containing the Raster
      // and which intersects the image.
      if (validMinX > validMaxX) { // no intersetion in X
        if (minX == validMinX) {
          minX = im.getMaxX() - 1;
        } else {
          maxX = im.getMinX();
        }
      }
      if (validMinY > validMaxY) { // no intersetion in Y
        if (minY == validMinY) {
          minY = im.getMaxY() - 1;
        } else {
          maxY = im.getMinY();
        }
      }

      // Create minimum Raster.
      WritableRaster wr =
          raster.createCompatibleWritableRaster(minX, minY, maxX - minX, maxY - minY);

      // Extend the data.
      extend(wr, im);

      // Create a child with same bounds as the target Raster.
      Raster child =
          wr.createChild(
              raster.getMinX(),
              raster.getMinY(),
              raster.getWidth(),
              raster.getHeight(),
              raster.getMinX(),
              raster.getMinY(),
              null);

      // Copy the data from the child.
      JDKWorkarounds.setRect(raster, child, 0, 0);

      return;
    }

    Rectangle rect = new Rectangle();

    // Notionally extend the source image by treating it as a single
    // tile of an infinite tiled image.  Adjacent tiles are reflections
    // of one another.

    // Compute the min and max X and Y tile indices of the area
    // intersected by the output raster.
    int minTileX = PlanarImage.XToTileX(minX, imMinX, imWidth);
    int maxTileX = PlanarImage.XToTileX(maxX - 1, imMinX, imWidth);
    int minTileY = PlanarImage.YToTileY(minY, imMinY, imHeight);
    int maxTileY = PlanarImage.YToTileY(maxY - 1, imMinY, imHeight);

    // Loop over the tiles
    for (int tileY = minTileY; tileY <= maxTileY; tileY++) {
      int ty = tileY * imHeight + imMinY;
      for (int tileX = minTileX; tileX <= maxTileX; tileX++) {
        int tx = tileX * imWidth + imMinX;

        // Don't touch the central "tile" (actual image)
        if (tileX == 0 && tileY == 0) {
          continue;
        }

        boolean flipX = (Math.abs(tileX) % 2) == 1;
        boolean flipY = (Math.abs(tileY) % 2) == 1;

        // Clip the tile bounds against the bounds of the Raster.
        // Keep track of the (x, y) offset of the start of the tile.
        rect.x = tx;
        rect.y = ty;
        rect.width = imWidth;
        rect.height = imHeight;

        int xOffset = 0;
        if (rect.x < minX) {
          xOffset = minX - rect.x;
          rect.x = minX;
          rect.width -= xOffset;
        }
        int yOffset = 0;
        if (rect.y < minY) {
          yOffset = minY - rect.y;
          rect.y = minY;
          rect.height -= yOffset;
        }
        if (rect.x + rect.width > maxX) {
          rect.width = maxX - rect.x;
        }
        if (rect.y + rect.height > maxY) {
          rect.height = maxY - rect.y;
        }

        int imX;
        if (flipX) {
          if (xOffset == 0) {
            imX = imMinX + imWidth - rect.width;
          } else {
            imX = imMinX;
          }
        } else {
          imX = imMinX + xOffset;
        }

        int imY;
        if (flipY) {
          if (yOffset == 0) {
            imY = imMinY + imHeight - rect.height;
          } else {
            imY = imMinY;
          }
        } else {
          imY = imMinY + yOffset;
        }

        // Create a child raster with coordinates within the
        // actual image.
        WritableRaster child =
            RasterFactory.createWritableChild(
                raster, rect.x, rect.y, rect.width, rect.height, imX, imY, null);

        // Copy the data into the Raster
        im.copyData(child);

        if (flipX) {
          flipX(child);
        }

        if (flipY) {
          flipY(child);
        }
      }
    }
  }