コード例 #1
0
  public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
    prepareRead(imageIndex, param);
    this.theImage = getDestination(param, getImageTypes(imageIndex), width, height);

    srcXSubsampling = imageReadParam.getSourceXSubsampling();
    srcYSubsampling = imageReadParam.getSourceYSubsampling();

    Point p = imageReadParam.getDestinationOffset();
    dstXOffset = p.x;
    dstYOffset = p.y;

    // This could probably be made more efficient...
    Rectangle srcRegion = new Rectangle(0, 0, 0, 0);
    Rectangle destRegion = new Rectangle(0, 0, 0, 0);

    computeRegions(imageReadParam, width, height, theImage, srcRegion, destRegion);

    // Initial source pixel, taking source region and source
    // subsamplimg offsets into account
    sourceXOffset = srcRegion.x;
    sourceYOffset = srcRegion.y;

    pixelsToRead = destRegion.width * destRegion.height;
    pixelsRead = 0;

    processImageStarted(imageIndex);
    processImageProgress(0.0f);

    tilesAcross = (width + tileOrStripWidth - 1) / tileOrStripWidth;
    tilesDown = (height + tileOrStripHeight - 1) / tileOrStripHeight;

    int compression = getCompression();

    // Attempt to get decompressor and color converted from the read param

    TIFFColorConverter colorConverter = null;
    if (imageReadParam instanceof TIFFImageReadParam) {
      TIFFImageReadParam tparam = (TIFFImageReadParam) imageReadParam;
      this.decompressor = tparam.getTIFFDecompressor();
      colorConverter = tparam.getColorConverter();
    }

    // If we didn't find one, use a standard decompressor
    if (this.decompressor == null) {
      if (compression == BaselineTIFFTagSet.COMPRESSION_NONE) {
        // Get the fillOrder field.
        TIFFField fillOrderField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER);

        // Set the decompressor based on the fill order.
        if (fillOrderField != null && fillOrderField.getAsInt(0) == 2) {
          this.decompressor = new TIFFLSBDecompressor();
        } else {
          this.decompressor = new TIFFNullDecompressor();
        }
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) {
        this.decompressor = new TIFFFaxDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_4) {
        this.decompressor = new TIFFFaxDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) {
        this.decompressor = new TIFFFaxDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_PACKBITS) {
        if (DEBUG) {
          System.out.println("Using TIFFPackBitsDecompressor");
        }
        this.decompressor = new TIFFPackBitsDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_LZW) {
        if (DEBUG) {
          System.out.println("Using TIFFLZWDecompressor");
        }
        TIFFField predictorField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PREDICTOR);
        int predictor =
            ((predictorField == null)
                ? BaselineTIFFTagSet.PREDICTOR_NONE
                : predictorField.getAsInt(0));
        this.decompressor = new TIFFLZWDecompressor(predictor);
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_JPEG) {
        this.decompressor = new TIFFJPEGDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_ZLIB
          || compression == BaselineTIFFTagSet.COMPRESSION_DEFLATE) {
        TIFFField predictorField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PREDICTOR);
        int predictor =
            ((predictorField == null)
                ? BaselineTIFFTagSet.PREDICTOR_NONE
                : predictorField.getAsInt(0));
        this.decompressor = new TIFFDeflateDecompressor(predictor);
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
        TIFFField JPEGProcField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_PROC);
        if (JPEGProcField == null) {
          processWarningOccurred(
              "JPEGProc field missing; assuming baseline sequential JPEG process.");
        } else if (JPEGProcField.getAsInt(0) != BaselineTIFFTagSet.JPEG_PROC_BASELINE) {
          throw new IIOException(
              "Old-style JPEG supported for baseline sequential JPEG process only!");
        }
        this.decompressor = new TIFFOldJPEGDecompressor();
        // throw new IIOException("Old-style JPEG not supported!");
      } else {
        throw new IIOException("Unsupported compression type (tag number = " + compression + ")!");
      }

      if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR
          && compression != BaselineTIFFTagSet.COMPRESSION_JPEG
          && compression != BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
        boolean convertYCbCrToRGB =
            theImage.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_RGB;
        TIFFDecompressor wrappedDecompressor =
            this.decompressor instanceof TIFFNullDecompressor ? null : this.decompressor;
        this.decompressor = new TIFFYCbCrDecompressor(wrappedDecompressor, convertYCbCrToRGB);
      }
    }

    if (DEBUG) {
      System.out.println("\nDecompressor class = " + decompressor.getClass().getName() + "\n");
    }

    if (colorConverter == null) {
      if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB
          && theImage.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_RGB) {
        colorConverter = new TIFFCIELabColorConverter();
      } else if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR
          && !(this.decompressor instanceof TIFFYCbCrDecompressor)
          && compression != BaselineTIFFTagSet.COMPRESSION_JPEG
          && compression != BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
        colorConverter = new TIFFYCbCrColorConverter(imageMetadata);
      }
    }

    decompressor.setReader(this);
    decompressor.setMetadata(imageMetadata);
    decompressor.setImage(theImage);

    decompressor.setPhotometricInterpretation(photometricInterpretation);
    decompressor.setCompression(compression);
    decompressor.setSamplesPerPixel(samplesPerPixel);
    decompressor.setBitsPerSample(bitsPerSample);
    decompressor.setSampleFormat(sampleFormat);
    decompressor.setExtraSamples(extraSamples);
    decompressor.setColorMap(colorMap);

    decompressor.setColorConverter(colorConverter);

    decompressor.setSourceXOffset(sourceXOffset);
    decompressor.setSourceYOffset(sourceYOffset);
    decompressor.setSubsampleX(srcXSubsampling);
    decompressor.setSubsampleY(srcYSubsampling);

    decompressor.setDstXOffset(dstXOffset);
    decompressor.setDstYOffset(dstYOffset);

    decompressor.setSourceBands(sourceBands);
    decompressor.setDestinationBands(destinationBands);

    // Compute bounds on the tile indices for this source region.
    int minTileX = TIFFImageWriter.XToTileX(srcRegion.x, 0, tileOrStripWidth);
    int minTileY = TIFFImageWriter.YToTileY(srcRegion.y, 0, tileOrStripHeight);
    int maxTileX = TIFFImageWriter.XToTileX(srcRegion.x + srcRegion.width - 1, 0, tileOrStripWidth);
    int maxTileY =
        TIFFImageWriter.YToTileY(srcRegion.y + srcRegion.height - 1, 0, tileOrStripHeight);

    boolean isAbortRequested = false;
    if (planarConfiguration == BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR) {

      decompressor.setPlanar(true);

      int[] sb = new int[1];
      int[] db = new int[1];
      for (int tj = minTileY; tj <= maxTileY; tj++) {
        for (int ti = minTileX; ti <= maxTileX; ti++) {
          for (int band = 0; band < numBands; band++) {
            sb[0] = sourceBands[band];
            decompressor.setSourceBands(sb);
            db[0] = destinationBands[band];
            decompressor.setDestinationBands(db);
            // XXX decompressor.beginDecoding();

            // The method abortRequested() is synchronized
            // so check it only once per loop just before
            // doing any actual decoding.
            if (abortRequested()) {
              isAbortRequested = true;
              break;
            }

            decodeTile(ti, tj, band);
          }

          if (isAbortRequested) break;

          reportProgress();
        }

        if (isAbortRequested) break;
      }
    } else {
      // XXX decompressor.beginDecoding();

      for (int tj = minTileY; tj <= maxTileY; tj++) {
        for (int ti = minTileX; ti <= maxTileX; ti++) {
          // The method abortRequested() is synchronized
          // so check it only once per loop just before
          // doing any actual decoding.
          if (abortRequested()) {
            isAbortRequested = true;
            break;
          }

          decodeTile(ti, tj, -1);

          reportProgress();
        }

        if (isAbortRequested) break;
      }
    }

    if (isAbortRequested) {
      processReadAborted();
    } else {
      processImageComplete();
    }

    return theImage;
  }