Esempio n. 1
0
  private void decodeTile(int ti, int tj, int band) throws IOException {
    if (DEBUG) {
      System.out.println("decodeTile(" + ti + "," + tj + "," + band + ")");
    }

    // Compute the region covered by the strip or tile
    Rectangle tileRect =
        new Rectangle(
            ti * tileOrStripWidth, tj * tileOrStripHeight, tileOrStripWidth, tileOrStripHeight);

    // Clip against the image bounds if the image is not tiled. If it
    // is tiled, the tile may legally extend beyond the image bounds.
    if (!isImageTiled(currIndex)) {
      tileRect = tileRect.intersection(new Rectangle(0, 0, width, height));
    }

    // Return if the intersection is empty.
    if (tileRect.width <= 0 || tileRect.height <= 0) {
      return;
    }

    int srcMinX = tileRect.x;
    int srcMinY = tileRect.y;
    int srcWidth = tileRect.width;
    int srcHeight = tileRect.height;

    // Determine dest region that can be derived from the
    // source region

    dstMinX = iceil(srcMinX - sourceXOffset, srcXSubsampling);
    int dstMaxX = ifloor(srcMinX + srcWidth - 1 - sourceXOffset, srcXSubsampling);

    dstMinY = iceil(srcMinY - sourceYOffset, srcYSubsampling);
    int dstMaxY = ifloor(srcMinY + srcHeight - 1 - sourceYOffset, srcYSubsampling);

    dstWidth = dstMaxX - dstMinX + 1;
    dstHeight = dstMaxY - dstMinY + 1;

    dstMinX += dstXOffset;
    dstMinY += dstYOffset;

    // Clip against image bounds

    Rectangle dstRect =
        new Rectangle(
            dstMinX, dstMinY,
            dstWidth, dstHeight);
    dstRect = dstRect.intersection(theImage.getRaster().getBounds());

    dstMinX = dstRect.x;
    dstMinY = dstRect.y;
    dstWidth = dstRect.width;
    dstHeight = dstRect.height;

    if (dstWidth <= 0 || dstHeight <= 0) {
      return;
    }

    // Backwards map dest region to source to determine
    // active source region

    int activeSrcMinX = (dstMinX - dstXOffset) * srcXSubsampling + sourceXOffset;
    int sxmax = (dstMinX + dstWidth - 1 - dstXOffset) * srcXSubsampling + sourceXOffset;
    int activeSrcWidth = sxmax - activeSrcMinX + 1;

    int activeSrcMinY = (dstMinY - dstYOffset) * srcYSubsampling + sourceYOffset;
    int symax = (dstMinY + dstHeight - 1 - dstYOffset) * srcYSubsampling + sourceYOffset;
    int activeSrcHeight = symax - activeSrcMinY + 1;

    decompressor.setSrcMinX(srcMinX);
    decompressor.setSrcMinY(srcMinY);
    decompressor.setSrcWidth(srcWidth);
    decompressor.setSrcHeight(srcHeight);

    decompressor.setDstMinX(dstMinX);
    decompressor.setDstMinY(dstMinY);
    decompressor.setDstWidth(dstWidth);
    decompressor.setDstHeight(dstHeight);

    decompressor.setActiveSrcMinX(activeSrcMinX);
    decompressor.setActiveSrcMinY(activeSrcMinY);
    decompressor.setActiveSrcWidth(activeSrcWidth);
    decompressor.setActiveSrcHeight(activeSrcHeight);

    int tileIndex = tj * tilesAcross + ti;

    if (planarConfiguration == BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR) {
      tileIndex += band * tilesAcross * tilesDown;
    }

    long offset = getTileOrStripOffset(tileIndex);
    long byteCount = getTileOrStripByteCount(tileIndex);

    //
    // Attempt to handle truncated streams, i.e., where reading the
    // compressed strip or tile would result in an EOFException. The
    // number of bytes to read is clamped to the number available
    // from the stream starting at the indicated position in the hope
    // that the decompressor will handle it.
    //
    long streamLength = stream.length();
    if (streamLength > 0 && offset + byteCount > streamLength) {
      processWarningOccurred("Attempting to process truncated stream.");
      if (Math.max(byteCount = streamLength - offset, 0) == 0) {
        processWarningOccurred("No bytes in strip/tile: skipping.");
        return;
      }
    }

    decompressor.setStream(stream);
    decompressor.setOffset(offset);
    decompressor.setByteCount((int) byteCount);

    decompressor.beginDecoding();

    stream.mark();
    decompressor.decode();
    stream.reset();
  }