TiffRasterData getRasterData()

in src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java [743:897]


    TiffRasterData getRasterData(
            final TiffDirectory directory,
            final ByteOrder byteOrder,
            TiffImagingParameters params)
            throws ImagingException, IOException {
        if (params == null) {
            params = this.getDefaultParameters();
        }

        final short[] sSampleFmt = directory.getFieldValue(
                TiffTagConstants.TIFF_TAG_SAMPLE_FORMAT, true);
        if (sSampleFmt == null || sSampleFmt.length < 1) {
            throw new ImagingException(
                    "Directory does not specify numeric raster data");
        }

        int samplesPerPixel = 1;
        final TiffField samplesPerPixelField = directory.findField(
                TiffTagConstants.TIFF_TAG_SAMPLES_PER_PIXEL);
        if (samplesPerPixelField != null) {
            samplesPerPixel = samplesPerPixelField.getIntValue();
        }

        int[] bitsPerSample = {1};
        int bitsPerPixel = samplesPerPixel;
        final TiffField bitsPerSampleField = directory.findField(
                TiffTagConstants.TIFF_TAG_BITS_PER_SAMPLE);
        if (bitsPerSampleField != null) {
            bitsPerSample = bitsPerSampleField.getIntArrayValue();
            bitsPerPixel = bitsPerSampleField.getIntValueOrArraySum();
        }

        final short compressionFieldValue;
        if (directory.findField(TiffTagConstants.TIFF_TAG_COMPRESSION) != null) {
            compressionFieldValue
                    = directory.getFieldValue(TiffTagConstants.TIFF_TAG_COMPRESSION);
        } else {
            compressionFieldValue = TIFF_COMPRESSION_UNCOMPRESSED_1;
        }
        final int compression = 0xffff & compressionFieldValue;

        final int width
                = directory.getSingleFieldValue(TiffTagConstants.TIFF_TAG_IMAGE_WIDTH);
        final int height
                = directory.getSingleFieldValue(TiffTagConstants.TIFF_TAG_IMAGE_LENGTH);

        Rectangle subImage = checkForSubImage(params);
        if (subImage != null) {
            // Check for valid subimage specification. The following checks
            // are consistent with BufferedImage.getSubimage()
            if (subImage.width <= 0) {
                throw new ImagingException("Negative or zero subimage width.");
            }
            if (subImage.height <= 0) {
                throw new ImagingException("Negative or zero subimage height.");
            }
            if (subImage.x < 0 || subImage.x >= width) {
                throw new ImagingException("Subimage x is outside raster.");
            }
            if (subImage.x + subImage.width > width) {
                throw new ImagingException("Subimage (x+width) is outside raster.");
            }
            if (subImage.y < 0 || subImage.y >= height) {
                throw new ImagingException("Subimage y is outside raster.");
            }
            if (subImage.y + subImage.height > height) {
                throw new ImagingException("Subimage (y+height) is outside raster.");
            }

            // if the subimage is just the same thing as the whole
            // image, suppress the subimage processing
            if (subImage.x == 0
                    && subImage.y == 0
                    && subImage.width == width
                    && subImage.height == height) {
                subImage = null;
            }
        }

        // int bitsPerPixel = getTagAsValueOrArraySum(entries,
        // TIFF_TAG_BITS_PER_SAMPLE);
        int predictor = -1;
        {
            // dumpOptionalNumberTag(entries, TIFF_TAG_FILL_ORDER);
            // dumpOptionalNumberTag(entries, TIFF_TAG_FREE_BYTE_COUNTS);
            // dumpOptionalNumberTag(entries, TIFF_TAG_FREE_OFFSETS);
            // dumpOptionalNumberTag(entries, TIFF_TAG_ORIENTATION);
            // dumpOptionalNumberTag(entries, TIFF_TAG_PLANAR_CONFIGURATION);
            final TiffField predictorField = directory.findField(
                    TiffTagConstants.TIFF_TAG_PREDICTOR);
            if (null != predictorField) {
                predictor = predictorField.getIntValueOrArraySum();
            }
        }

        // Obtain the planar configuration
        final TiffField pcField = directory.findField(
                TiffTagConstants.TIFF_TAG_PLANAR_CONFIGURATION);
        final TiffPlanarConfiguration planarConfiguration
                = pcField == null
                        ? TiffPlanarConfiguration.CHUNKY
                        : TiffPlanarConfiguration.lenientValueOf(pcField.getIntValue());

        if (sSampleFmt[0] == TiffTagConstants.SAMPLE_FORMAT_VALUE_IEEE_FLOATING_POINT) {
            if (bitsPerSample[0] != 32 && bitsPerSample[0] != 64) {
                throw new ImagingException(
                        "TIFF floating-point data uses unsupported bits-per-sample: "
                        + bitsPerSample[0]);
            }

            if (predictor != -1
                    && predictor != TiffTagConstants.PREDICTOR_VALUE_NONE
                    && predictor != TiffTagConstants.PREDICTOR_VALUE_FLOATING_POINT_DIFFERENCING) {
                throw new ImagingException(
                        "TIFF floating-point data uses unsupported horizontal-differencing predictor");
            }
        } else if (sSampleFmt[0] == TiffTagConstants.SAMPLE_FORMAT_VALUE_TWOS_COMPLEMENT_SIGNED_INTEGER) {

            if (samplesPerPixel != 1) {
                throw new ImagingException(
                        "TIFF integer data uses unsupported samples per pixel: "
                        + samplesPerPixel);
            }

            if (bitsPerPixel != 16 && bitsPerPixel != 32) {
                throw new ImagingException(
                        "TIFF integer data uses unsupported bits-per-pixel: "
                        + bitsPerPixel);
            }

            if (predictor != -1
                    && predictor != TiffTagConstants.PREDICTOR_VALUE_NONE
                    && predictor != TiffTagConstants.PREDICTOR_VALUE_HORIZONTAL_DIFFERENCING) {
                throw new ImagingException(
                        "TIFF integer data uses unsupported horizontal-differencing predictor");
            }
        } else {
            throw new ImagingException("TIFF does not provide a supported raster-data format");
        }

        // The photometric interpreter is not used, but the image-based
        // data reader classes require one.  So we create a dummy interpreter.
        final PhotometricInterpreter photometricInterpreter
                = new PhotometricInterpreterBiLevel(samplesPerPixel,
                        bitsPerSample, predictor, width, height, false);

        final TiffImageData imageData = directory.getTiffImageData();

        final ImageDataReader dataReader = imageData.getDataReader(directory,
                photometricInterpreter, bitsPerPixel, bitsPerSample, predictor,
                samplesPerPixel, width, height, compression,
                planarConfiguration, byteOrder);

        return dataReader.readRasterData(subImage);
    }