예제 #1
0
  /**
   * Compute the source region and destination dimensions taking any parameter settings into
   * account.
   */
  private static void computeRegions(
      Rectangle sourceBounds, Dimension destSize, ImageWriteParam p) {
    ImageWriteParam param;
    int periodX = 1;
    int periodY = 1;
    if (p != null) {
      int[] sourceBands = p.getSourceBands();
      if (sourceBands != null && (sourceBands.length != 1 || sourceBands[0] != 0)) {
        throw new IllegalArgumentException("Cannot sub-band image!");
      }

      // Get source region and subsampling factors
      Rectangle sourceRegion = p.getSourceRegion();
      if (sourceRegion != null) {
        // Clip to actual image bounds
        sourceRegion = sourceRegion.intersection(sourceBounds);
        sourceBounds.setBounds(sourceRegion);
      }

      // Adjust for subsampling offsets
      int gridX = p.getSubsamplingXOffset();
      int gridY = p.getSubsamplingYOffset();
      sourceBounds.x += gridX;
      sourceBounds.y += gridY;
      sourceBounds.width -= gridX;
      sourceBounds.height -= gridY;

      // Get subsampling factors
      periodX = p.getSourceXSubsampling();
      periodY = p.getSourceYSubsampling();
    }

    // Compute output dimensions
    destSize.setSize(
        (sourceBounds.width + periodX - 1) / periodX,
        (sourceBounds.height + periodY - 1) / periodY);
    if (destSize.width <= 0 || destSize.height <= 0) {
      throw new IllegalArgumentException("Empty source region!");
    }
  }
예제 #2
0
  public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {

    if (iis == null) {
      throw new IllegalStateException(I18N.getString("WBMPImageReader1"));
    }

    checkIndex(imageIndex);
    clearAbortRequest();
    processImageStarted(imageIndex);
    if (param == null) param = getDefaultReadParam();

    // read header
    readHeader();

    Rectangle sourceRegion = new Rectangle(0, 0, 0, 0);
    Rectangle destinationRegion = new Rectangle(0, 0, 0, 0);

    computeRegions(
        param, this.width, this.height, param.getDestination(), sourceRegion, destinationRegion);

    int scaleX = param.getSourceXSubsampling();
    int scaleY = param.getSourceYSubsampling();
    int xOffset = param.getSubsamplingXOffset();
    int yOffset = param.getSubsamplingYOffset();

    // If the destination is provided, then use it.  Otherwise, create new one
    BufferedImage bi = param.getDestination();

    if (bi == null)
      bi =
          new BufferedImage(
              destinationRegion.x + destinationRegion.width,
              destinationRegion.y + destinationRegion.height,
              BufferedImage.TYPE_BYTE_BINARY);

    boolean noTransform =
        destinationRegion.equals(new Rectangle(0, 0, width, height))
            && destinationRegion.equals(new Rectangle(0, 0, bi.getWidth(), bi.getHeight()));

    // Get the image data.
    WritableRaster tile = bi.getWritableTile(0, 0);

    // Get the SampleModel.
    MultiPixelPackedSampleModel sm = (MultiPixelPackedSampleModel) bi.getSampleModel();

    if (noTransform) {
      if (abortRequested()) {
        processReadAborted();
        return bi;
      }

      // If noTransform is necessary, read the data.
      iis.read(
          ((DataBufferByte) tile.getDataBuffer()).getData(), 0, height * sm.getScanlineStride());
      processImageUpdate(bi, 0, 0, width, height, 1, 1, new int[] {0});
      processImageProgress(100.0F);
    } else {
      int len = (this.width + 7) / 8;
      byte[] buf = new byte[len];
      byte[] data = ((DataBufferByte) tile.getDataBuffer()).getData();
      int lineStride = sm.getScanlineStride();
      iis.skipBytes(len * sourceRegion.y);
      int skipLength = len * (scaleY - 1);

      // cache the values to avoid duplicated computation
      int[] srcOff = new int[destinationRegion.width];
      int[] destOff = new int[destinationRegion.width];
      int[] srcPos = new int[destinationRegion.width];
      int[] destPos = new int[destinationRegion.width];

      for (int i = destinationRegion.x, x = sourceRegion.x, j = 0;
          i < destinationRegion.x + destinationRegion.width;
          i++, j++, x += scaleX) {
        srcPos[j] = x >> 3;
        srcOff[j] = 7 - (x & 7);
        destPos[j] = i >> 3;
        destOff[j] = 7 - (i & 7);
      }

      for (int j = 0, y = sourceRegion.y, k = destinationRegion.y * lineStride;
          j < destinationRegion.height;
          j++, y += scaleY) {

        if (abortRequested()) break;
        iis.read(buf, 0, len);
        for (int i = 0; i < destinationRegion.width; i++) {
          // get the bit and assign to the data buffer of the raster
          int v = (buf[srcPos[i]] >> srcOff[i]) & 1;
          data[k + destPos[i]] |= v << destOff[i];
        }

        k += lineStride;
        iis.skipBytes(skipLength);
        processImageUpdate(bi, 0, j, destinationRegion.width, 1, 1, 1, new int[] {0});
        processImageProgress(100.0F * j / destinationRegion.height);
      }
    }

    if (abortRequested()) processReadAborted();
    else processImageComplete();
    return bi;
  }