Example #1
0
  private void prepareRead(int imageIndex, ImageReadParam param) throws IOException {
    if (stream == null) {
      throw new IllegalStateException("Input not set!");
    }

    // A null ImageReadParam means we use the default
    if (param == null) {
      param = getDefaultReadParam();
    }

    this.imageReadParam = param;

    seekToImage(imageIndex);

    this.tileOrStripWidth = getTileOrStripWidth();
    this.tileOrStripHeight = getTileOrStripHeight();
    this.planarConfiguration = getPlanarConfiguration();

    this.sourceBands = param.getSourceBands();
    if (sourceBands == null) {
      sourceBands = new int[numBands];
      for (int i = 0; i < numBands; i++) {
        sourceBands[i] = i;
      }
    }

    // Initialize the destination image
    Iterator imageTypes = getImageTypes(imageIndex);
    ImageTypeSpecifier theImageType = ImageUtil.getDestinationType(param, imageTypes);

    int destNumBands = theImageType.getSampleModel().getNumBands();

    this.destinationBands = param.getDestinationBands();
    if (destinationBands == null) {
      destinationBands = new int[destNumBands];
      for (int i = 0; i < destNumBands; i++) {
        destinationBands[i] = i;
      }
    }

    if (sourceBands.length != destinationBands.length) {
      throw new IllegalArgumentException("sourceBands.length != destinationBands.length");
    }

    for (int i = 0; i < sourceBands.length; i++) {
      int sb = sourceBands[i];
      if (sb < 0 || sb >= numBands) {
        throw new IllegalArgumentException("Source band out of range!");
      }
      int db = destinationBands[i];
      if (db < 0 || db >= destNumBands) {
        throw new IllegalArgumentException("Destination band out of range!");
      }
    }
  }
  /**
   * Creates a copy of <code>param</code>. The source subsampling and and bands settings and the
   * destination bands and offset settings are copied. If <code>param</code> is a <code>
   * TIFFImageReadParam</code> then the <code>TIFFDecompressor</code> and <code>TIFFColorConverter
   * </code> settings are also copied; otherwise they are explicitly set to <code>null</code>.
   *
   * @param param the parameters to be copied.
   * @param copyTagSets whether the <code>TIFFTagSet</code> settings should be copied if set.
   * @return copied parameters.
   */
  private ImageReadParam cloneImageReadParam(ImageReadParam param, boolean copyTagSets) {
    // Create a new TIFFImageReadParam.
    TIFFImageReadParam newParam = new TIFFImageReadParam();

    // Copy the basic settings.
    newParam.setSourceSubsampling(
        param.getSourceXSubsampling(),
        param.getSourceYSubsampling(),
        param.getSubsamplingXOffset(),
        param.getSubsamplingYOffset());
    newParam.setSourceBands(param.getSourceBands());
    newParam.setDestinationBands(param.getDestinationBands());
    newParam.setDestinationOffset(param.getDestinationOffset());

    // Set the decompressor and color converter.
    if (param instanceof TIFFImageReadParam) {
      // Copy the settings from the input parameter.
      TIFFImageReadParam tparam = (TIFFImageReadParam) param;
      newParam.setTIFFDecompressor(tparam.getTIFFDecompressor());
      newParam.setColorConverter(tparam.getColorConverter());

      if (copyTagSets) {
        List tagSets = tparam.getAllowedTagSets();
        if (tagSets != null) {
          Iterator tagSetIter = tagSets.iterator();
          if (tagSetIter != null) {
            while (tagSetIter.hasNext()) {
              TIFFTagSet tagSet = (TIFFTagSet) tagSetIter.next();
              newParam.addAllowedTagSet(tagSet);
            }
          }
        }
      }
    } else {
      // Set the decompressor and color converter to null.
      newParam.setTIFFDecompressor(null);
      newParam.setColorConverter(null);
    }

    return newParam;
  }
Example #3
0
  public RawRenderedImage(
      RawImageInputStream iis, RawImageReader reader, ImageReadParam param, int imageIndex)
      throws IOException {
    this.iis = iis;
    this.reader = reader;
    this.param = param;
    this.imageIndex = imageIndex;
    this.position = iis.getImageOffset(imageIndex);
    this.originalDimension = iis.getImageDimension(imageIndex);

    ImageTypeSpecifier type = iis.getImageType();
    sampleModel = originalSampleModel = type.getSampleModel();
    colorModel = type.getColorModel();

    // If the destination band is set used it
    sourceBands = (param == null) ? null : param.getSourceBands();

    if (sourceBands == null) {
      nComp = originalSampleModel.getNumBands();
      sourceBands = new int[nComp];
      for (int i = 0; i < nComp; i++) sourceBands[i] = i;
    } else {
      sampleModel = originalSampleModel.createSubsetSampleModel(sourceBands);
      colorModel = ImageUtil.createColorModel(null, sampleModel);
    }

    nComp = sourceBands.length;

    destinationBands = (param == null) ? null : param.getDestinationBands();
    if (destinationBands == null) {
      destinationBands = new int[nComp];
      for (int i = 0; i < nComp; i++) destinationBands[i] = i;
    }

    Dimension dim = iis.getImageDimension(imageIndex);
    this.width = dim.width;
    this.height = dim.height;

    Rectangle sourceRegion = new Rectangle(0, 0, this.width, this.height);

    originalRegion = (Rectangle) sourceRegion.clone();

    destinationRegion = (Rectangle) sourceRegion.clone();

    if (param != null) {
      RawImageReader.computeRegionsWrapper(
          param, this.width, this.height, param.getDestination(), sourceRegion, destinationRegion);
      scaleX = param.getSourceXSubsampling();
      scaleY = param.getSourceYSubsampling();
      xOffset = param.getSubsamplingXOffset();
      yOffset = param.getSubsamplingYOffset();
    }

    sourceOrigin = new Point(sourceRegion.x, sourceRegion.y);
    if (!destinationRegion.equals(sourceRegion)) noTransform = false;

    this.tileDataSize = ImageUtil.getTileSize(originalSampleModel);

    this.tileWidth = originalSampleModel.getWidth();
    this.tileHeight = originalSampleModel.getHeight();
    this.tileGridXOffset = destinationRegion.x;
    this.tileGridYOffset = destinationRegion.y;
    this.originalNumXTiles = getNumXTiles();

    this.width = destinationRegion.width;
    this.height = destinationRegion.height;
    this.minX = destinationRegion.x;
    this.minY = destinationRegion.y;

    sampleModel = sampleModel.createCompatibleSampleModel(tileWidth, tileHeight);

    maxXTile = originalDimension.width / tileWidth;
    maxYTile = originalDimension.height / tileHeight;
  }
Example #4
0
  public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
    checkIndex(imageIndex);
    readHeader();

    if (iis == null) throw new IllegalStateException("input is null");

    BufferedImage img;

    clearAbortRequest();
    processImageStarted(imageIndex);

    if (param == null) param = getDefaultReadParam();

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

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

    scaleX = param.getSourceXSubsampling();
    scaleY = param.getSourceYSubsampling();

    // If the destination band is set used it
    sourceBands = param.getSourceBands();
    destBands = param.getDestinationBands();

    seleBand = (sourceBands != null) && (destBands != null);
    noTransform = destinationRegion.equals(new Rectangle(0, 0, width, height)) || seleBand;

    if (!seleBand) {
      sourceBands = new int[colorPlanes];
      destBands = new int[colorPlanes];
      for (int i = 0; i < colorPlanes; i++) destBands[i] = sourceBands[i] = i;
    }

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

    // Get the image data.
    WritableRaster raster = null;

    if (bi == null) {
      if (sampleModel != null && colorModel != null) {
        sampleModel =
            sampleModel.createCompatibleSampleModel(
                destinationRegion.width + destinationRegion.x,
                destinationRegion.height + destinationRegion.y);
        if (seleBand) sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
        raster = Raster.createWritableRaster(sampleModel, new Point(0, 0));
        bi = new BufferedImage(colorModel, raster, false, null);
      }
    } else {
      raster = bi.getWritableTile(0, 0);
      sampleModel = bi.getSampleModel();
      colorModel = bi.getColorModel();

      noTransform &= destinationRegion.equals(raster.getBounds());
    }

    byte bdata[] = null; // buffer for byte data

    if (sampleModel.getDataType() == DataBuffer.TYPE_BYTE)
      bdata = (byte[]) ((DataBufferByte) raster.getDataBuffer()).getData();

    readImage(bdata);

    if (abortRequested()) processReadAborted();
    else processImageComplete();

    return bi;
  }
  @Override
  public BufferedImage read(final int imageIndex, final ImageReadParam param) throws IOException {
    Iterator<ImageTypeSpecifier> imageTypes = getImageTypes(imageIndex);
    ImageTypeSpecifier rawType = getRawImageType(imageIndex);

    if (header.getPaletteInfo() != PCX.PALETTEINFO_COLOR
        && header.getPaletteInfo() != PCX.PALETTEINFO_GRAY) {
      processWarningOccurred(
          String.format(
              "Unsupported color mode: %d, colors may look incorrect", header.getPaletteInfo()));
    }

    int width = getWidth(imageIndex);
    int height = getHeight(imageIndex);

    BufferedImage destination = getDestination(param, imageTypes, width, height);

    Rectangle srcRegion = new Rectangle();
    Rectangle destRegion = new Rectangle();
    computeRegions(param, width, height, destination, srcRegion, destRegion);

    WritableRaster destRaster =
        clipToRect(
            destination.getRaster(),
            destRegion,
            param != null ? param.getDestinationBands() : null);
    checkReadParamBandSettings(param, rawType.getNumBands(), destRaster.getNumBands());

    int compression = header.getCompression();

    // Wrap input (COMPRESSION_RLE is really the only value allowed)
    DataInput input =
        compression == PCX.COMPRESSION_RLE
            ? new DataInputStream(
                new DecoderStream(IIOUtil.createStreamAdapter(imageInput), new RLEDecoder()))
            : imageInput;

    int xSub = param != null ? param.getSourceXSubsampling() : 1;
    int ySub = param != null ? param.getSourceYSubsampling() : 1;

    processImageStarted(imageIndex);

    if (rawType.getColorModel() instanceof IndexColorModel && header.getChannels() > 1) {
      // Bit planes!
      // Create raster from a default 8 bit layout
      WritableRaster rowRaster = GRAYSCALE.createBufferedImage(header.getWidth(), 1).getRaster();

      // Clip to source region
      Raster clippedRow =
          clipRowToRect(
              rowRaster,
              srcRegion,
              param != null ? param.getSourceBands() : null,
              param != null ? param.getSourceXSubsampling() : 1);

      int planeWidth = header.getBytesPerLine();
      byte[] planeData = new byte[planeWidth * 8];

      byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData();

      for (int y = 0; y < height; y++) {
        switch (header.getBitsPerPixel()) {
          case 1:
            readRowByte(
                input,
                srcRegion,
                xSub,
                ySub,
                planeData,
                0,
                planeWidth * header.getChannels(),
                destRaster,
                clippedRow,
                y);
            break;
          default:
            throw new AssertionError();
        }

        int pixelPos = 0;
        for (int planePos = 0; planePos < planeWidth; planePos++) {
          BitRotator.bitRotateCW(planeData, planePos, planeWidth, rowDataByte, pixelPos, 1);
          pixelPos += 8;
        }

        processImageProgress(100f * y / height);

        if (y >= srcRegion.y + srcRegion.height) {
          break;
        }

        if (abortRequested()) {
          processReadAborted();
          break;
        }
      }
    } else if (header.getBitsPerPixel() == 24 || header.getBitsPerPixel() == 32) {
      // Can't use width here, as we need to take bytesPerLine into account, and re-create a width
      // based on this
      int rowWidth = (header.getBytesPerLine() * 8) / header.getBitsPerPixel();
      WritableRaster rowRaster = rawType.createBufferedImage(rowWidth, 1).getRaster();

      // Clip to source region
      Raster clippedRow =
          clipRowToRect(
              rowRaster,
              srcRegion,
              param != null ? param.getSourceBands() : null,
              param != null ? param.getSourceXSubsampling() : 1);

      for (int y = 0; y < height; y++) {
        byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData();
        readRowByte(
            input,
            srcRegion,
            xSub,
            ySub,
            rowDataByte,
            0,
            rowDataByte.length,
            destRaster,
            clippedRow,
            y);

        processImageProgress(100f * y / height);

        if (y >= srcRegion.y + srcRegion.height) {
          break;
        }

        if (abortRequested()) {
          processReadAborted();
          break;
        }
      }
    } else {
      // Can't use width here, as we need to take bytesPerLine into account, and re-create a width
      // based on this
      int rowWidth = (header.getBytesPerLine() * 8) / header.getBitsPerPixel();
      WritableRaster rowRaster = rawType.createBufferedImage(rowWidth, 1).getRaster();

      // Clip to source region
      Raster clippedRow =
          clipRowToRect(
              rowRaster,
              srcRegion,
              param != null ? param.getSourceBands() : null,
              param != null ? param.getSourceXSubsampling() : 1);

      for (int y = 0; y < height; y++) {
        for (int c = 0; c < header.getChannels(); c++) {
          WritableRaster destChannel =
              destRaster.createWritableChild(
                  destRaster.getMinX(),
                  destRaster.getMinY(),
                  destRaster.getWidth(),
                  destRaster.getHeight(),
                  0,
                  0,
                  new int[] {c});
          Raster srcChannel =
              clippedRow.createChild(
                  clippedRow.getMinX(), 0, clippedRow.getWidth(), 1, 0, 0, new int[] {c});

          switch (header.getBitsPerPixel()) {
            case 1:
            case 2:
            case 4:
            case 8:
              byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData(c);
              readRowByte(
                  input,
                  srcRegion,
                  xSub,
                  ySub,
                  rowDataByte,
                  0,
                  rowDataByte.length,
                  destChannel,
                  srcChannel,
                  y);
              break;
            default:
              throw new AssertionError();
          }

          if (abortRequested()) {
            break;
          }
        }

        processImageProgress(100f * y / height);

        if (y >= srcRegion.y + srcRegion.height) {
          break;
        }

        if (abortRequested()) {
          processReadAborted();
          break;
        }
      }
    }

    processImageComplete();

    return destination;
  }