Search in sources :

Example 1 with TIFFTag

use of it.geosolutions.imageio.plugins.tiff.TIFFTag in project imageio-ext by geosolutions-it.

the class TIFFIFD method getTag.

public static TIFFTag getTag(int tagNumber, List tagSets) {
    Iterator iter = tagSets.iterator();
    while (iter.hasNext()) {
        TIFFTagSet tagSet = (TIFFTagSet) iter.next();
        TIFFTag tag = tagSet.getTag(tagNumber);
        if (tag != null) {
            return tag;
        }
    }
    return null;
}
Also used : Iterator(java.util.Iterator) BaselineTIFFTagSet(it.geosolutions.imageio.plugins.tiff.BaselineTIFFTagSet) TIFFTagSet(it.geosolutions.imageio.plugins.tiff.TIFFTagSet) TIFFTag(it.geosolutions.imageio.plugins.tiff.TIFFTag)

Example 2 with TIFFTag

use of it.geosolutions.imageio.plugins.tiff.TIFFTag in project imageio-ext by geosolutions-it.

the class EmptyImage method setupMetadata.

/**
 * Sets up the output metadata adding, removing, and overriding fields
 * as needed. The destination image dimensions are provided as parameters
 * because these might differ from those of the source due to subsampling.
 *
 * @param cm The <code>ColorModel</code> of the image being written.
 * @param sm The <code>SampleModel</code> of the image being written.
 * @param destWidth The width of the written image after subsampling.
 * @param destHeight The height of the written image after subsampling.
 */
void setupMetadata(ColorModel cm, SampleModel sm, int destWidth, int destHeight) throws IIOException {
    // Get initial IFD from metadata
    // Always emit these fields:
    // 
    // Override values from metadata:
    // 
    // planarConfiguration -> chunky (planar not supported on output)
    // 
    // Override values from metadata with image-derived values:
    // 
    // bitsPerSample (if not bilivel)
    // colorMap (if palette color)
    // photometricInterpretation (derive from image)
    // imageLength
    // imageWidth
    // 
    // rowsPerStrip     \      /   tileLength
    // stripOffsets      | OR |   tileOffsets
    // stripByteCounts  /     |   tileByteCounts
    // \   tileWidth
    // 
    // 
    // Override values from metadata with write param values:
    // 
    // compression
    // Use values from metadata if present for these fields,
    // otherwise use defaults:
    // 
    // resolutionUnit
    // XResolution (take from metadata if present)
    // YResolution
    // rowsPerStrip
    // sampleFormat
    TIFFIFD rootIFD = imageMetadata.getRootIFD();
    BaselineTIFFTagSet base = BaselineTIFFTagSet.getInstance();
    // If PlanarConfiguration field present, set value to chunky.
    TIFFField f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION);
    if (f != null && f.getAsInt(0) != BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY) {
        // XXX processWarningOccurred()
        TIFFField planarConfigurationField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION), BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY);
        rootIFD.addTIFFField(planarConfigurationField);
    }
    char[] extraSamples = null;
    this.photometricInterpretation = -1;
    boolean forcePhotometricInterpretation = false;
    f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION);
    if (f != null) {
        photometricInterpretation = f.getAsInt(0);
        if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR && !(cm instanceof IndexColorModel)) {
            photometricInterpretation = -1;
        } else {
            forcePhotometricInterpretation = true;
        }
    }
    // f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES);
    // if (f != null) {
    // extraSamples = f.getAsChars();
    // }
    // f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
    // if (f != null) {
    // bitsPerSample = f.getAsChars();
    // }
    int[] sampleSize = sm.getSampleSize();
    int numBands = sm.getNumBands();
    int numExtraSamples = 0;
    // cannot be zero.
    if (numBands > 1 && cm != null && cm.hasAlpha()) {
        --numBands;
        numExtraSamples = 1;
        extraSamples = new char[1];
        if (cm.isAlphaPremultiplied()) {
            extraSamples[0] = BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA;
        } else {
            extraSamples[0] = BaselineTIFFTagSet.EXTRA_SAMPLES_UNASSOCIATED_ALPHA;
        }
    }
    if (numBands == 3) {
        this.nativePhotometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
        if (photometricInterpretation == -1) {
            photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
        }
    } else if (sm.getNumBands() == 1 && cm instanceof IndexColorModel) {
        IndexColorModel icm = (IndexColorModel) cm;
        int r0 = icm.getRed(0);
        int r1 = icm.getRed(1);
        if (icm.getMapSize() == 2 && (r0 == icm.getGreen(0)) && (r0 == icm.getBlue(0)) && (r1 == icm.getGreen(1)) && (r1 == icm.getBlue(1)) && (r0 == 0 || r0 == 255) && (r1 == 0 || r1 == 255) && (r0 != r1)) {
            if (r0 == 0) {
                nativePhotometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
            } else {
                nativePhotometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
            }
            // WhiteIsZero or BlackIsZero, leave it alone
            if (photometricInterpretation != BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO && photometricInterpretation != BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO) {
                photometricInterpretation = r0 == 0 ? BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO : BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
            }
        } else {
            nativePhotometricInterpretation = photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR;
        }
    } else {
        if (cm != null) {
            switch(cm.getColorSpace().getType()) {
                case ColorSpace.TYPE_Lab:
                    nativePhotometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB;
                    break;
                case ColorSpace.TYPE_YCbCr:
                    nativePhotometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR;
                    break;
                case ColorSpace.TYPE_CMYK:
                    nativePhotometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CMYK;
                    break;
                default:
                    nativePhotometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
            }
        } else {
            nativePhotometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
        }
        if (photometricInterpretation == -1) {
            photometricInterpretation = nativePhotometricInterpretation;
        }
    }
    // Set the compressor and color converter.
    this.compressor = null;
    this.colorConverter = null;
    if (param instanceof TIFFImageWriteParam) {
        TIFFImageWriteParam tparam = (TIFFImageWriteParam) param;
        if (tparam.getCompressionMode() == tparam.MODE_EXPLICIT) {
            compressor = tparam.getTIFFCompressor();
            String compressionType = param.getCompressionType();
            if (compressor != null && !compressor.getCompressionType().equals(compressionType)) {
                // Unset the TIFFCompressor if its compression type is
                // not the one selected.
                compressor = null;
            }
        } else {
            // Compression mode not MODE_EXPLICIT.
            compressor = null;
        }
        colorConverter = tparam.getColorConverter();
        if (colorConverter != null) {
            photometricInterpretation = tparam.getPhotometricInterpretation();
        }
    }
    // Emit compression tag
    int compressionMode = param instanceof TIFFImageWriteParam ? param.getCompressionMode() : ImageWriteParam.MODE_DEFAULT;
    switch(compressionMode) {
        case ImageWriteParam.MODE_EXPLICIT:
            {
                String compressionType = param.getCompressionType();
                if (compressionType == null) {
                    this.compression = BaselineTIFFTagSet.COMPRESSION_NONE;
                } else {
                    // Determine corresponding compression tag value.
                    int len = compressionTypes.length;
                    for (int i = 0; i < len; i++) {
                        if (compressionType.equals(compressionTypes[i])) {
                            this.compression = compressionNumbers[i];
                        }
                    }
                }
                // with the precedence described in TIFFImageWriteParam.
                if (compressor != null && compressor.getCompressionTagValue() != this.compression) {
                    // Does not match: unset the compressor.
                    compressor = null;
                }
            }
            break;
        case ImageWriteParam.MODE_COPY_FROM_METADATA:
            {
                TIFFField compField = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
                if (compField != null) {
                    this.compression = compField.getAsInt(0);
                    break;
                }
            }
        case ImageWriteParam.MODE_DEFAULT:
        case ImageWriteParam.MODE_DISABLED:
        default:
            this.compression = BaselineTIFFTagSet.COMPRESSION_NONE;
    }
    TIFFField predictorField = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_PREDICTOR);
    if (predictorField != null) {
        this.predictor = predictorField.getAsInt(0);
        // We only support Horizontal Predictor for a bitDepth of 8
        if (sampleSize[0] != 8 || // Check the value of the tag for validity
        (predictor != BaselineTIFFTagSet.PREDICTOR_NONE && predictor != BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING)) {
            // XXX processWarningOccured ???
            // Set to default
            predictor = BaselineTIFFTagSet.PREDICTOR_NONE;
            // Emit this changed predictor value to metadata
            TIFFField newPredictorField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_PREDICTOR), predictor);
            rootIFD.addTIFFField(newPredictorField);
        }
    // XXX Do we need to ensure that predictor is not passed on if
    // the compression is not either Deflate or LZW?
    }
    TIFFField compressionField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_COMPRESSION), compression);
    rootIFD.addTIFFField(compressionField);
    // Set EXIF flag. Note that there is no way to determine definitively
    // when an uncompressed thumbnail is being written as the EXIF IFD
    // pointer field is optional for thumbnails.
    boolean isEXIF = false;
    if (numBands == 3 && sampleSize[0] == 8 && sampleSize[1] == 8 && sampleSize[2] == 8) {
        // Three bands with 8 bits per sample.
        if (rootIFD.getTIFFField(EXIFParentTIFFTagSet.TAG_EXIF_IFD_POINTER) != null) {
            // EXIF IFD pointer present.
            if (compression == BaselineTIFFTagSet.COMPRESSION_NONE && (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB || photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR)) {
                // Uncompressed RGB or YCbCr.
                isEXIF = true;
            } else if (compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
                // Compressed.
                isEXIF = true;
            }
        } else if (compressionMode == ImageWriteParam.MODE_EXPLICIT && EXIF_JPEG_COMPRESSION_TYPE.equals(param.getCompressionType())) {
            // EXIF IFD pointer absent but EXIF JPEG compression set.
            isEXIF = true;
        }
    }
    // Initialize JPEG interchange format flag which is used to
    // indicate that the image is stored as a single JPEG stream.
    // This flag is separated from the 'isEXIF' flag in case JPEG
    // interchange format is eventually supported for non-EXIF images.
    boolean isJPEGInterchange = isEXIF && compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG;
    if (compressor == null) {
        if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) {
            if (PackageUtil.isCodecLibAvailable()) {
                try {
                    compressor = new TIFFCodecLibRLECompressor();
                    if (DEBUG) {
                        System.out.println("Using codecLib RLE compressor");
                    }
                } catch (RuntimeException e) {
                    if (DEBUG) {
                        System.out.println(e);
                    }
                }
            }
            if (compressor == null) {
                compressor = new TIFFRLECompressor();
                if (DEBUG) {
                    System.out.println("Using Java RLE compressor");
                }
            }
            if (!forcePhotometricInterpretation) {
                photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
            }
        } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_4) {
            if (PackageUtil.isCodecLibAvailable()) {
                try {
                    compressor = new TIFFCodecLibT4Compressor();
                    if (DEBUG) {
                        System.out.println("Using codecLib T.4 compressor");
                    }
                } catch (RuntimeException e) {
                    if (DEBUG) {
                        System.out.println(e);
                    }
                }
            }
            if (compressor == null) {
                compressor = new TIFFT4Compressor();
                if (DEBUG) {
                    System.out.println("Using Java T.4 compressor");
                }
            }
            if (!forcePhotometricInterpretation) {
                photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
            }
        } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) {
            if (PackageUtil.isCodecLibAvailable()) {
                try {
                    compressor = new TIFFCodecLibT6Compressor();
                    if (DEBUG) {
                        System.out.println("Using codecLib T.6 compressor");
                    }
                } catch (RuntimeException e) {
                    if (DEBUG) {
                        System.out.println(e);
                    }
                }
            }
            if (compressor == null) {
                compressor = new TIFFT6Compressor();
                if (DEBUG) {
                    System.out.println("Using Java T.6 compressor");
                }
            }
            if (!forcePhotometricInterpretation) {
                photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
            }
        } else if (compression == BaselineTIFFTagSet.COMPRESSION_LZW) {
            compressor = new TIFFLZWCompressor(predictor);
        } else if (compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
            if (isEXIF) {
                compressor = new TIFFEXIFJPEGCompressor(param);
            } else {
                throw new IIOException("Old JPEG compression not supported!");
            }
        } else if (compression == BaselineTIFFTagSet.COMPRESSION_JPEG) {
            if (numBands == 3 && sampleSize[0] == 8 && sampleSize[1] == 8 && sampleSize[2] == 8) {
                photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR;
            } else if (numBands == 1 && sampleSize[0] == 8) {
                photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
            } else {
                throw new IIOException("JPEG compression supported for 1- and 3-band byte images only!");
            }
            compressor = new TIFFJPEGCompressor(param);
        } else if (compression == BaselineTIFFTagSet.COMPRESSION_ZLIB) {
            compressor = new TIFFZLibCompressor(param, predictor);
        } else if (compression == BaselineTIFFTagSet.COMPRESSION_PACKBITS) {
            compressor = new TIFFPackBitsCompressor();
        } else if (compression == BaselineTIFFTagSet.COMPRESSION_DEFLATE) {
            compressor = new TIFFDeflateCompressor(param, predictor);
        } else {
            // Determine inverse fill setting.
            f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER);
            boolean inverseFill = (f != null && f.getAsInt(0) == 2);
            if (inverseFill) {
                compressor = new TIFFLSBCompressor();
            } else {
                compressor = new TIFFNullCompressor();
            }
        }
    // compression == ?
    }
    if (DEBUG) {
        if (param != null && param.getCompressionMode() == param.MODE_EXPLICIT) {
            System.out.println("compressionType = " + param.getCompressionType());
        }
        if (compressor != null) {
            System.out.println("compressor = " + compressor.getClass().getName());
        }
    }
    if (colorConverter == null) {
        if (cm != null && cm.getColorSpace().getType() == ColorSpace.TYPE_RGB) {
            // 
            if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR && compression != BaselineTIFFTagSet.COMPRESSION_JPEG) {
                // 
                // Convert RGB to YCbCr only if compression type is not
                // JPEG in which case this is handled implicitly by the
                // compressor.
                // 
                colorConverter = new TIFFYCbCrColorConverter(imageMetadata);
            } else if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB) {
                colorConverter = new TIFFCIELabColorConverter();
            }
        }
    }
    // 
    if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR && compression != BaselineTIFFTagSet.COMPRESSION_JPEG) {
        // Remove old subsampling and positioning fields.
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_SUBSAMPLING);
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_POSITIONING);
        // Add unity chrominance subsampling factors.
        rootIFD.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_Y_CB_CR_SUBSAMPLING), TIFFTag.TIFF_SHORT, 2, new char[] { (char) 1, (char) 1 }));
        // Add cosited positioning.
        rootIFD.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_Y_CB_CR_POSITIONING), TIFFTag.TIFF_SHORT, 1, new char[] { (char) BaselineTIFFTagSet.Y_CB_CR_POSITIONING_COSITED }));
    }
    TIFFField photometricInterpretationField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION), photometricInterpretation);
    rootIFD.addTIFFField(photometricInterpretationField);
    this.bitsPerSample = new char[numBands + numExtraSamples];
    this.bitDepth = 0;
    for (int i = 0; i < numBands; i++) {
        this.bitDepth = Math.max(bitDepth, sampleSize[i]);
    }
    if (bitDepth == 3) {
        bitDepth = 4;
    } else if (bitDepth > 4 && bitDepth <= 8) {
        bitDepth = 8;
    } else if (bitDepth > 8 && bitDepth <= 16) {
        bitDepth = 16;
    } else if (bitDepth > 16 && bitDepth <= 32) {
        bitDepth = 32;
    } else if (bitDepth > 32) {
        bitDepth = 64;
    }
    for (int i = 0; i < bitsPerSample.length; i++) {
        bitsPerSample[i] = (char) bitDepth;
    }
    // if already in the metadata and correct (count and value == 1).
    if (bitsPerSample.length != 1 || bitsPerSample[0] != 1) {
        TIFFField bitsPerSampleField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE), TIFFTag.TIFF_SHORT, bitsPerSample.length, bitsPerSample);
        rootIFD.addTIFFField(bitsPerSampleField);
    } else {
        // bitsPerSample.length == 1 && bitsPerSample[0] == 1
        TIFFField bitsPerSampleField = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
        if (bitsPerSampleField != null) {
            int[] bps = bitsPerSampleField.getAsInts();
            if (bps == null || bps.length != 1 || bps[0] != 1) {
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
            }
        }
    }
    // Prepare SampleFormat field.
    f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLE_FORMAT);
    if (f == null && (bitDepth == 16 || bitDepth == 32 || bitDepth == 64)) {
        // Set up default content for 16- and 32-bit cases.
        char sampleFormatValue;
        int dataType = sm.getDataType();
        if (bitDepth == 16 && dataType == DataBuffer.TYPE_USHORT) {
            sampleFormatValue = (char) BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER;
        } else if (bitDepth == 32 && dataType == DataBuffer.TYPE_FLOAT) {
            sampleFormatValue = (char) BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT;
        } else if (bitDepth == 64 && dataType == DataBuffer.TYPE_DOUBLE) {
            sampleFormatValue = (char) BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT;
        } else {
            sampleFormatValue = BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER;
        }
        this.sampleFormat = (int) sampleFormatValue;
        char[] sampleFormatArray = new char[bitsPerSample.length];
        Arrays.fill(sampleFormatArray, sampleFormatValue);
        // Update the metadata.
        TIFFTag sampleFormatTag = base.getTag(BaselineTIFFTagSet.TAG_SAMPLE_FORMAT);
        TIFFField sampleFormatField = new TIFFField(sampleFormatTag, TIFFTag.TIFF_SHORT, sampleFormatArray.length, sampleFormatArray);
        rootIFD.addTIFFField(sampleFormatField);
    } else if (f != null) {
        // Get whatever was provided.
        sampleFormat = f.getAsInt(0);
    } else {
        // Set default value for internal use only.
        sampleFormat = BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED;
    }
    if (extraSamples != null) {
        TIFFField extraSamplesField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES), TIFFTag.TIFF_SHORT, extraSamples.length, extraSamples);
        rootIFD.addTIFFField(extraSamplesField);
    } else {
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES);
    }
    TIFFField samplesPerPixelField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL), bitsPerSample.length);
    rootIFD.addTIFFField(samplesPerPixelField);
    // Emit ColorMap if image is of palette color type
    if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR && cm instanceof IndexColorModel) {
        char[] colorMap = new char[3 * (1 << bitsPerSample[0])];
        IndexColorModel icm = (IndexColorModel) cm;
        // mapSize is determined by BitsPerSample, not by incoming ICM.
        int mapSize = 1 << bitsPerSample[0];
        int indexBound = Math.min(mapSize, icm.getMapSize());
        for (int i = 0; i < indexBound; i++) {
            colorMap[i] = (char) ((icm.getRed(i) * 65535) / 255);
            colorMap[mapSize + i] = (char) ((icm.getGreen(i) * 65535) / 255);
            colorMap[2 * mapSize + i] = (char) ((icm.getBlue(i) * 65535) / 255);
        }
        TIFFField colorMapField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_COLOR_MAP), TIFFTag.TIFF_SHORT, colorMap.length, colorMap);
        rootIFD.addTIFFField(colorMapField);
    } else {
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_COLOR_MAP);
    }
    // metadata and the ColorSpace is non-standard ICC.
    if (cm != null && rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_ICC_PROFILE) == null && ImageUtil.isNonStandardICCColorSpace(cm.getColorSpace())) {
        ICC_ColorSpace iccColorSpace = (ICC_ColorSpace) cm.getColorSpace();
        byte[] iccProfileData = iccColorSpace.getProfile().getData();
        TIFFField iccProfileField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_ICC_PROFILE), TIFFTag.TIFF_UNDEFINED, iccProfileData.length, iccProfileData);
        rootIFD.addTIFFField(iccProfileField);
    }
    // Always emit XResolution and YResolution.
    TIFFField XResolutionField = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_X_RESOLUTION);
    TIFFField YResolutionField = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_Y_RESOLUTION);
    if (XResolutionField == null && YResolutionField == null) {
        long[][] resRational = new long[1][2];
        resRational[0] = new long[2];
        TIFFField ResolutionUnitField = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT);
        // quantities is present.
        if (ResolutionUnitField == null && rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_X_POSITION) == null && rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_Y_POSITION) == null) {
            // Set resolution to unit and units to dimensionless.
            resRational[0][0] = 1;
            resRational[0][1] = 1;
            ResolutionUnitField = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT), BaselineTIFFTagSet.RESOLUTION_UNIT_NONE);
            rootIFD.addTIFFField(ResolutionUnitField);
        } else {
            // Set resolution to a value which would make the maximum
            // image dimension equal to 4 inches as arbitrarily stated
            // in the description of ResolutionUnit in the TIFF 6.0
            // specification. If the ResolutionUnit field specifies
            // "none" then set the resolution to unity (1/1).
            int resolutionUnit = ResolutionUnitField != null ? ResolutionUnitField.getAsInt(0) : BaselineTIFFTagSet.RESOLUTION_UNIT_INCH;
            int maxDimension = Math.max(destWidth, destHeight);
            switch(resolutionUnit) {
                case BaselineTIFFTagSet.RESOLUTION_UNIT_INCH:
                    resRational[0][0] = maxDimension;
                    resRational[0][1] = 4;
                    break;
                case BaselineTIFFTagSet.RESOLUTION_UNIT_CENTIMETER:
                    // divide out 100
                    resRational[0][0] = 100L * maxDimension;
                    // 2.54 cm/inch * 100
                    resRational[0][1] = 4 * 254;
                    break;
                default:
                    resRational[0][0] = 1;
                    resRational[0][1] = 1;
            }
        }
        XResolutionField = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, resRational);
        rootIFD.addTIFFField(XResolutionField);
        YResolutionField = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, resRational);
        rootIFD.addTIFFField(YResolutionField);
    } else if (XResolutionField == null && YResolutionField != null) {
        // Set XResolution to YResolution.
        long[] yResolution = (long[]) YResolutionField.getAsRational(0).clone();
        XResolutionField = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, yResolution);
        rootIFD.addTIFFField(XResolutionField);
    } else if (XResolutionField != null && YResolutionField == null) {
        // Set YResolution to XResolution.
        long[] xResolution = (long[]) XResolutionField.getAsRational(0).clone();
        YResolutionField = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, xResolution);
        rootIFD.addTIFFField(YResolutionField);
    }
    // Set mandatory fields, overriding metadata passed in
    int width = destWidth;
    TIFFField imageWidthField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_IMAGE_WIDTH), width);
    rootIFD.addTIFFField(imageWidthField);
    int height = destHeight;
    TIFFField imageLengthField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_IMAGE_LENGTH), height);
    rootIFD.addTIFFField(imageLengthField);
    // Determine rowsPerStrip
    int rowsPerStrip;
    TIFFField rowsPerStripField = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_ROWS_PER_STRIP);
    if (rowsPerStripField != null) {
        rowsPerStrip = rowsPerStripField.getAsInt(0);
        if (rowsPerStrip < 0) {
            rowsPerStrip = height;
        }
    } else {
        int bitsPerPixel = bitDepth * (numBands + numExtraSamples);
        int bytesPerRow = (bitsPerPixel * width + 7) / 8;
        rowsPerStrip = Math.max(Math.max(DEFAULT_BYTES_PER_STRIP / bytesPerRow, 1), 8);
    }
    rowsPerStrip = Math.min(rowsPerStrip, height);
    // Tiling flag.
    boolean useTiling = false;
    // Analyze tiling parameters
    int tilingMode = param instanceof TIFFImageWriteParam ? param.getTilingMode() : ImageWriteParam.MODE_DEFAULT;
    if (tilingMode == ImageWriteParam.MODE_DISABLED || tilingMode == ImageWriteParam.MODE_DEFAULT) {
        this.tileWidth = width;
        this.tileLength = rowsPerStrip;
        useTiling = false;
    } else if (tilingMode == ImageWriteParam.MODE_EXPLICIT) {
        tileWidth = param.getTileWidth();
        tileLength = param.getTileHeight();
        useTiling = true;
    } else if (tilingMode == ImageWriteParam.MODE_COPY_FROM_METADATA) {
        f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_TILE_WIDTH);
        if (f == null) {
            tileWidth = width;
            useTiling = false;
        } else {
            tileWidth = f.getAsInt(0);
            useTiling = true;
        }
        f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_TILE_LENGTH);
        if (f == null) {
            tileLength = rowsPerStrip;
        } else {
            tileLength = f.getAsInt(0);
            useTiling = true;
        }
    } else {
        throw new IIOException("Illegal value of tilingMode!");
    }
    if (compression == BaselineTIFFTagSet.COMPRESSION_JPEG) {
        // Reset tile size per TTN2 spec for JPEG compression.
        int subX;
        int subY;
        if (numBands == 1) {
            subX = subY = 1;
        } else {
            subX = subY = TIFFJPEGCompressor.CHROMA_SUBSAMPLING;
        }
        if (useTiling) {
            int MCUMultipleX = 8 * subX;
            int MCUMultipleY = 8 * subY;
            tileWidth = Math.max(MCUMultipleX * ((tileWidth + MCUMultipleX / 2) / MCUMultipleX), MCUMultipleX);
            tileLength = Math.max(MCUMultipleY * ((tileLength + MCUMultipleY / 2) / MCUMultipleY), MCUMultipleY);
        } else if (rowsPerStrip < height) {
            int MCUMultiple = 8 * Math.max(subX, subY);
            rowsPerStrip = tileLength = Math.max(MCUMultiple * ((tileLength + MCUMultiple / 2) / MCUMultiple), MCUMultiple);
        }
    } else if (isJPEGInterchange) {
        // Force tile size to equal image size.
        tileWidth = width;
        tileLength = height;
    } else if (useTiling) {
        // Round tile size to multiple of 16 per TIFF 6.0 specification
        // (see pages 67-68 of version 6.0.1 from Adobe).
        int tileWidthRemainder = tileWidth % 16;
        if (tileWidthRemainder != 0) {
            // Round to nearest multiple of 16 not less than 16.
            tileWidth = Math.max(16 * ((tileWidth + 8) / 16), 16);
        // XXX insert processWarningOccurred(int,String);
        }
        int tileLengthRemainder = tileLength % 16;
        if (tileLengthRemainder != 0) {
            // Round to nearest multiple of 16 not less than 16.
            tileLength = Math.max(16 * ((tileLength + 8) / 16), 16);
        // XXX insert processWarningOccurred(int,String);
        }
    }
    this.tilesAcross = (width + tileWidth - 1) / tileWidth;
    this.tilesDown = (height + tileLength - 1) / tileLength;
    if (!useTiling) {
        this.isTiled = false;
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_TILE_WIDTH);
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_TILE_LENGTH);
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_TILE_OFFSETS);
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS);
        rowsPerStripField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_ROWS_PER_STRIP), rowsPerStrip);
        rootIFD.addTIFFField(rowsPerStripField);
        TIFFField stripOffsetsField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_STRIP_OFFSETS), isBtiff ? TIFFTag.TIFF_LONG8 : TIFFTag.TIFF_LONG, tilesDown);
        rootIFD.addTIFFField(stripOffsetsField);
        TIFFField stripByteCountsField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS), isBtiff ? TIFFTag.TIFF_LONG8 : TIFFTag.TIFF_LONG, tilesDown);
        rootIFD.addTIFFField(stripByteCountsField);
    } else {
        this.isTiled = true;
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_ROWS_PER_STRIP);
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_STRIP_OFFSETS);
        rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS);
        TIFFField tileWidthField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_TILE_WIDTH), tileWidth);
        rootIFD.addTIFFField(tileWidthField);
        TIFFField tileLengthField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_TILE_LENGTH), tileLength);
        rootIFD.addTIFFField(tileLengthField);
        TIFFField tileOffsetsField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_TILE_OFFSETS), isBtiff ? TIFFTag.TIFF_LONG8 : TIFFTag.TIFF_LONG, tilesDown * tilesAcross);
        rootIFD.addTIFFField(tileOffsetsField);
        TIFFField tileByteCountsField = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS), isBtiff ? TIFFTag.TIFF_LONG8 : TIFFTag.TIFF_LONG, tilesDown * tilesAcross);
        rootIFD.addTIFFField(tileByteCountsField);
    }
    if (isEXIF) {
        // 
        // Ensure presence of mandatory fields and absence of prohibited
        // fields and those that duplicate information in JPEG marker
        // segments per tables 14-18 of the EXIF 2.2 specification.
        // 
        // If an empty image is being written or inserted then infer
        // that the primary IFD is being set up.
        boolean isPrimaryIFD = isEncodingEmpty();
        // Handle TIFF fields in order of increasing tag number.
        if (compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
            // ImageWidth
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
            // ImageLength
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH);
            // BitsPerSample
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
            // Compression
            if (isPrimaryIFD) {
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
            }
            // PhotometricInterpretation
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION);
            // StripOffsets
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_STRIP_OFFSETS);
            // SamplesPerPixel
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL);
            // RowsPerStrip
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_ROWS_PER_STRIP);
            // StripByteCounts
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS);
            // XResolution and YResolution are handled above for all TIFFs.
            // PlanarConfiguration
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION);
            // ResolutionUnit
            if (rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT) == null) {
                f = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT), BaselineTIFFTagSet.RESOLUTION_UNIT_INCH);
                rootIFD.addTIFFField(f);
            }
            if (isPrimaryIFD) {
                // JPEGInterchangeFormat
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT);
                // JPEGInterchangeFormatLength
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
                // YCbCrSubsampling
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_SUBSAMPLING);
                // YCbCrPositioning
                if (rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_POSITIONING) == null) {
                    f = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_Y_CB_CR_POSITIONING), TIFFTag.TIFF_SHORT, 1, new char[] { (char) BaselineTIFFTagSet.Y_CB_CR_POSITIONING_CENTERED });
                    rootIFD.addTIFFField(f);
                }
            } else {
                // Thumbnail IFD
                // JPEGInterchangeFormat
                f = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT), TIFFTag.TIFF_LONG, 1);
                rootIFD.addTIFFField(f);
                // JPEGInterchangeFormatLength
                f = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH), TIFFTag.TIFF_LONG, 1);
                rootIFD.addTIFFField(f);
                // YCbCrSubsampling
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_SUBSAMPLING);
            }
        } else {
            // ResolutionUnit
            if (rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT) == null) {
                f = new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT), BaselineTIFFTagSet.RESOLUTION_UNIT_INCH);
                rootIFD.addTIFFField(f);
            }
            // JPEGInterchangeFormat
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT);
            // JPEGInterchangeFormatLength
            rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
            if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB) {
                // YCbCrCoefficients
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_COEFFICIENTS);
                // YCbCrSubsampling
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_SUBSAMPLING);
                // YCbCrPositioning
                rootIFD.removeTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_POSITIONING);
            }
        }
        // Get EXIF tags.
        TIFFTagSet exifTags = EXIFTIFFTagSet.getInstance();
        // Retrieve or create the EXIF IFD.
        TIFFIFD exifIFD = null;
        f = rootIFD.getTIFFField(EXIFParentTIFFTagSet.TAG_EXIF_IFD_POINTER);
        if (f != null) {
            // Retrieve the EXIF IFD.
            exifIFD = (TIFFIFD) f.getData();
        } else if (isPrimaryIFD) {
            // Create the EXIF IFD.
            List exifTagSets = new ArrayList(1);
            exifTagSets.add(exifTags);
            exifIFD = new TIFFIFD(exifTagSets);
            // Add it to the root IFD.
            TIFFTagSet tagSet = EXIFParentTIFFTagSet.getInstance();
            TIFFTag exifIFDTag = tagSet.getTag(EXIFParentTIFFTagSet.TAG_EXIF_IFD_POINTER);
            rootIFD.addTIFFField(new TIFFField(exifIFDTag, TIFFTag.TIFF_LONG, 1, exifIFD));
        }
        if (exifIFD != null) {
            // ExifVersion
            if (exifIFD.getTIFFField(EXIFTIFFTagSet.TAG_EXIF_VERSION) == null) {
                f = new TIFFField(exifTags.getTag(EXIFTIFFTagSet.TAG_EXIF_VERSION), TIFFTag.TIFF_UNDEFINED, 4, EXIFTIFFTagSet.EXIF_VERSION_2_2);
                exifIFD.addTIFFField(f);
            }
            if (compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
                // ComponentsConfiguration
                if (exifIFD.getTIFFField(EXIFTIFFTagSet.TAG_COMPONENTS_CONFIGURATION) == null) {
                    f = new TIFFField(exifTags.getTag(EXIFTIFFTagSet.TAG_COMPONENTS_CONFIGURATION), TIFFTag.TIFF_UNDEFINED, 4, new byte[] { (byte) EXIFTIFFTagSet.COMPONENTS_CONFIGURATION_Y, (byte) EXIFTIFFTagSet.COMPONENTS_CONFIGURATION_CB, (byte) EXIFTIFFTagSet.COMPONENTS_CONFIGURATION_CR, (byte) 0 });
                    exifIFD.addTIFFField(f);
                }
            } else {
                // ComponentsConfiguration
                exifIFD.removeTIFFField(EXIFTIFFTagSet.TAG_COMPONENTS_CONFIGURATION);
                // CompressedBitsPerPixel
                exifIFD.removeTIFFField(EXIFTIFFTagSet.TAG_COMPRESSED_BITS_PER_PIXEL);
            }
            // FlashpixVersion
            if (exifIFD.getTIFFField(EXIFTIFFTagSet.TAG_FLASHPIX_VERSION) == null) {
                f = new TIFFField(exifTags.getTag(EXIFTIFFTagSet.TAG_FLASHPIX_VERSION), TIFFTag.TIFF_UNDEFINED, 4, new byte[] { (byte) '0', (byte) '1', (byte) '0', (byte) '0' });
                exifIFD.addTIFFField(f);
            }
            // ColorSpace
            if (exifIFD.getTIFFField(EXIFTIFFTagSet.TAG_COLOR_SPACE) == null) {
                f = new TIFFField(exifTags.getTag(EXIFTIFFTagSet.TAG_COLOR_SPACE), TIFFTag.TIFF_SHORT, 1, new char[] { (char) EXIFTIFFTagSet.COLOR_SPACE_SRGB });
                exifIFD.addTIFFField(f);
            }
            if (compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
                // PixelXDimension
                if (exifIFD.getTIFFField(EXIFTIFFTagSet.TAG_PIXEL_X_DIMENSION) == null) {
                    f = new TIFFField(exifTags.getTag(EXIFTIFFTagSet.TAG_PIXEL_X_DIMENSION), width);
                    exifIFD.addTIFFField(f);
                }
                // PixelYDimension
                if (exifIFD.getTIFFField(EXIFTIFFTagSet.TAG_PIXEL_Y_DIMENSION) == null) {
                    f = new TIFFField(exifTags.getTag(EXIFTIFFTagSet.TAG_PIXEL_Y_DIMENSION), height);
                    exifIFD.addTIFFField(f);
                }
            } else {
                exifIFD.removeTIFFField(EXIFTIFFTagSet.TAG_INTEROPERABILITY_IFD_POINTER);
            }
        }
    }
// if(isEXIF)
}
Also used : TIFFImageWriteParam(it.geosolutions.imageio.plugins.tiff.TIFFImageWriteParam) ArrayList(java.util.ArrayList) BaselineTIFFTagSet(it.geosolutions.imageio.plugins.tiff.BaselineTIFFTagSet) TIFFField(it.geosolutions.imageio.plugins.tiff.TIFFField) ArrayList(java.util.ArrayList) List(java.util.List) IndexColorModel(java.awt.image.IndexColorModel) IIOException(javax.imageio.IIOException) Point(java.awt.Point) ICC_ColorSpace(java.awt.color.ICC_ColorSpace) BaselineTIFFTagSet(it.geosolutions.imageio.plugins.tiff.BaselineTIFFTagSet) TIFFTagSet(it.geosolutions.imageio.plugins.tiff.TIFFTagSet) EXIFParentTIFFTagSet(it.geosolutions.imageio.plugins.tiff.EXIFParentTIFFTagSet) EXIFTIFFTagSet(it.geosolutions.imageio.plugins.tiff.EXIFTIFFTagSet) TIFFTag(it.geosolutions.imageio.plugins.tiff.TIFFTag)

Example 3 with TIFFTag

use of it.geosolutions.imageio.plugins.tiff.TIFFTag in project imageio-ext by geosolutions-it.

the class TIFFImageMetadata method parseIFD.

public static TIFFIFD parseIFD(Node node) throws IIOInvalidTreeException {
    if (!node.getNodeName().equals("TIFFIFD")) {
        fatal(node, "Expected \"TIFFIFD\" node");
    }
    String tagSetNames = getAttribute(node, "tagSets");
    List tagSets = new ArrayList(5);
    if (tagSetNames != null) {
        StringTokenizer st = new StringTokenizer(tagSetNames, ",");
        while (st.hasMoreTokens()) {
            String className = st.nextToken();
            Object o = null;
            try {
                Class setClass = Class.forName(className);
                Method getInstanceMethod = setClass.getMethod("getInstance", (Class[]) null);
                o = getInstanceMethod.invoke(null, (Object[]) null);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            if (!(o instanceof TIFFTagSet)) {
                fatal(node, "Specified tag set class \"" + className + "\" is not an instance of TIFFTagSet");
            } else {
                tagSets.add((TIFFTagSet) o);
            }
        }
    }
    TIFFIFD ifd = new TIFFIFD(tagSets);
    node = node.getFirstChild();
    while (node != null) {
        String name = node.getNodeName();
        TIFFField f = null;
        if (name.equals("TIFFIFD")) {
            TIFFIFD subIFD = parseIFD(node);
            String parentTagName = getAttribute(node, "parentTagName");
            String parentTagNumber = getAttribute(node, "parentTagNumber");
            TIFFTag tag = null;
            if (parentTagName != null) {
                tag = TIFFIFD.getTag(parentTagName, tagSets);
            } else if (parentTagNumber != null) {
                int tagNumber = Integer.valueOf(parentTagNumber).intValue();
                tag = TIFFIFD.getTag(tagNumber, tagSets);
            }
            if (tag == null) {
                tag = new TIFFTag("unknown", 0, 0, null);
            }
            int type;
            if (tag.isDataTypeOK(TIFFTag.TIFF_IFD_POINTER)) {
                type = TIFFTag.TIFF_IFD_POINTER;
            } else {
                type = TIFFTag.TIFF_LONG;
            }
            f = new TIFFField(tag, type, 1, subIFD);
        } else if (name.equals("TIFFField")) {
            int number = Integer.parseInt(getAttribute(node, "number"));
            TIFFTagSet tagSet = null;
            Iterator iter = tagSets.iterator();
            while (iter.hasNext()) {
                TIFFTagSet t = (TIFFTagSet) iter.next();
                if (t.getTag(number) != null) {
                    tagSet = t;
                    break;
                }
            }
            f = TIFFField.createFromMetadataNode(tagSet, node);
        } else {
            fatal(node, "Expected either \"TIFFIFD\" or \"TIFFField\" node, got " + name);
        }
        ifd.addTIFFField(f);
        node = node.getNextSibling();
    }
    return ifd;
}
Also used : ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) StringTokenizer(java.util.StringTokenizer) TIFFField(it.geosolutions.imageio.plugins.tiff.TIFFField) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) NodeList(org.w3c.dom.NodeList) List(java.util.List) BaselineTIFFTagSet(it.geosolutions.imageio.plugins.tiff.BaselineTIFFTagSet) TIFFTagSet(it.geosolutions.imageio.plugins.tiff.TIFFTagSet) EXIFParentTIFFTagSet(it.geosolutions.imageio.plugins.tiff.EXIFParentTIFFTagSet) TIFFTag(it.geosolutions.imageio.plugins.tiff.TIFFTag)

Example 4 with TIFFTag

use of it.geosolutions.imageio.plugins.tiff.TIFFTag in project imageio-ext by geosolutions-it.

the class TIFFImageMetadata method mergeStandardTree.

private void mergeStandardTree(Node root) throws IIOInvalidTreeException {
    TIFFField f;
    TIFFTag tag;
    Node node = root;
    if (!node.getNodeName().equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
        fatal(node, "Root must be " + IIOMetadataFormatImpl.standardMetadataFormatName);
    }
    // Obtain the sample format and set the palette flag if appropriate.
    String sampleFormat = null;
    Node dataNode = getChildNode(root, "Data");
    boolean isPaletteColor = false;
    if (dataNode != null) {
        Node sampleFormatNode = getChildNode(dataNode, "SampleFormat");
        if (sampleFormatNode != null) {
            sampleFormat = getAttribute(sampleFormatNode, "value");
            isPaletteColor = sampleFormat.equals("Index");
        }
    }
    // If palette flag not set check for palette.
    if (!isPaletteColor) {
        Node chromaNode = getChildNode(root, "Chroma");
        if (chromaNode != null && getChildNode(chromaNode, "Palette") != null) {
            isPaletteColor = true;
        }
    }
    node = node.getFirstChild();
    while (node != null) {
        String name = node.getNodeName();
        if (name.equals("Chroma")) {
            String colorSpaceType = null;
            String blackIsZero = null;
            boolean gotPalette = false;
            Node child = node.getFirstChild();
            while (child != null) {
                String childName = child.getNodeName();
                if (childName.equals("ColorSpaceType")) {
                    colorSpaceType = getAttribute(child, "name");
                } else if (childName.equals("NumChannels")) {
                    tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL);
                    int samplesPerPixel = isPaletteColor ? 1 : Integer.parseInt(getAttribute(child, "value"));
                    f = new TIFFField(tag, samplesPerPixel);
                    rootIFD.addTIFFField(f);
                } else if (childName.equals("BlackIsZero")) {
                    blackIsZero = getAttribute(child, "value");
                } else if (childName.equals("Palette")) {
                    Node entry = child.getFirstChild();
                    HashMap palette = new HashMap();
                    int maxIndex = -1;
                    while (entry != null) {
                        String entryName = entry.getNodeName();
                        if (entryName.equals("PaletteEntry")) {
                            String idx = getAttribute(entry, "index");
                            int id = Integer.parseInt(idx);
                            if (id > maxIndex) {
                                maxIndex = id;
                            }
                            char red = (char) Integer.parseInt(getAttribute(entry, "red"));
                            char green = (char) Integer.parseInt(getAttribute(entry, "green"));
                            char blue = (char) Integer.parseInt(getAttribute(entry, "blue"));
                            palette.put(new Integer(id), new char[] { red, green, blue });
                            gotPalette = true;
                        }
                        entry = entry.getNextSibling();
                    }
                    if (gotPalette) {
                        int mapSize = maxIndex + 1;
                        int paletteLength = 3 * mapSize;
                        char[] paletteEntries = new char[paletteLength];
                        Iterator paletteIter = palette.keySet().iterator();
                        while (paletteIter.hasNext()) {
                            Integer index = (Integer) paletteIter.next();
                            char[] rgb = (char[]) palette.get(index);
                            int idx = index.intValue();
                            paletteEntries[idx] = (char) ((rgb[0] * 65535) / 255);
                            paletteEntries[mapSize + idx] = (char) ((rgb[1] * 65535) / 255);
                            paletteEntries[2 * mapSize + idx] = (char) ((rgb[2] * 65535) / 255);
                        }
                        tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_COLOR_MAP);
                        f = new TIFFField(tag, TIFFTag.TIFF_SHORT, paletteLength, paletteEntries);
                        rootIFD.addTIFFField(f);
                    }
                }
                child = child.getNextSibling();
            }
            int photometricInterpretation = -1;
            if ((colorSpaceType == null || colorSpaceType.equals("GRAY")) && blackIsZero != null && blackIsZero.equalsIgnoreCase("FALSE")) {
                photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
            } else if (colorSpaceType != null) {
                if (colorSpaceType.equals("GRAY")) {
                    boolean isTransparency = false;
                    if (root instanceof IIOMetadataNode) {
                        IIOMetadataNode iioRoot = (IIOMetadataNode) root;
                        NodeList siNodeList = iioRoot.getElementsByTagName("SubimageInterpretation");
                        if (siNodeList.getLength() == 1) {
                            Node siNode = siNodeList.item(0);
                            String value = getAttribute(siNode, "value");
                            if (value.equals("TransparencyMask")) {
                                isTransparency = true;
                            }
                        }
                    }
                    if (isTransparency) {
                        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_TRANSPARENCY_MASK;
                    } else {
                        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
                    }
                } else if (colorSpaceType.equals("RGB")) {
                    photometricInterpretation = gotPalette ? BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR : BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
                } else if (colorSpaceType.equals("YCbCr")) {
                    photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR;
                } else if (colorSpaceType.equals("CMYK")) {
                    photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CMYK;
                } else if (colorSpaceType.equals("Lab")) {
                    photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB;
                }
            }
            if (photometricInterpretation != -1) {
                tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION);
                f = new TIFFField(tag, photometricInterpretation);
                rootIFD.addTIFFField(f);
            }
        } else if (name.equals("Compression")) {
            Node child = node.getFirstChild();
            while (child != null) {
                String childName = child.getNodeName();
                if (childName.equals("CompressionTypeName")) {
                    int compression = -1;
                    String compressionTypeName = getAttribute(child, "value");
                    if (compressionTypeName.equalsIgnoreCase("None")) {
                        compression = BaselineTIFFTagSet.COMPRESSION_NONE;
                    } else {
                        String[] compressionNames = TIFFImageWriter.compressionTypes;
                        for (int i = 0; i < compressionNames.length; i++) {
                            if (compressionNames[i].equalsIgnoreCase(compressionTypeName)) {
                                compression = TIFFImageWriter.compressionNumbers[i];
                                break;
                            }
                        }
                    }
                    if (compression != -1) {
                        tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_COMPRESSION);
                        f = new TIFFField(tag, compression);
                        rootIFD.addTIFFField(f);
                    // Lossless is irrelevant.
                    }
                }
                child = child.getNextSibling();
            }
        } else if (name.equals("Data")) {
            Node child = node.getFirstChild();
            while (child != null) {
                String childName = child.getNodeName();
                if (childName.equals("PlanarConfiguration")) {
                    String pc = getAttribute(child, "value");
                    int planarConfiguration = -1;
                    if (pc.equals("PixelInterleaved")) {
                        planarConfiguration = BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY;
                    } else if (pc.equals("PlaneInterleaved")) {
                        planarConfiguration = BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR;
                    }
                    if (planarConfiguration != -1) {
                        tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION);
                        f = new TIFFField(tag, planarConfiguration);
                        rootIFD.addTIFFField(f);
                    }
                } else if (childName.equals("BitsPerSample")) {
                    String bps = getAttribute(child, "value");
                    char[] bitsPerSample = listToCharArray(bps);
                    tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
                    if (isPaletteColor) {
                        f = new TIFFField(tag, TIFFTag.TIFF_SHORT, 1, new char[] { bitsPerSample[0] });
                    } else {
                        f = new TIFFField(tag, TIFFTag.TIFF_SHORT, bitsPerSample.length, bitsPerSample);
                    }
                    rootIFD.addTIFFField(f);
                } else if (childName.equals("SampleMSB")) {
                    // Add FillOrder only if lsb-to-msb (right to left)
                    // for all bands, i.e., SampleMSB is zero for all
                    // channels.
                    String sMSB = getAttribute(child, "value");
                    int[] sampleMSB = listToIntArray(sMSB);
                    boolean isRightToLeft = true;
                    for (int i = 0; i < sampleMSB.length; i++) {
                        if (sampleMSB[i] != 0) {
                            isRightToLeft = false;
                            break;
                        }
                    }
                    int fillOrder = isRightToLeft ? BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT : BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT;
                    tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_FILL_ORDER);
                    f = new TIFFField(tag, fillOrder);
                    rootIFD.addTIFFField(f);
                }
                child = child.getNextSibling();
            }
        } else if (name.equals("Dimension")) {
            float pixelAspectRatio = -1.0f;
            boolean gotPixelAspectRatio = false;
            float horizontalPixelSize = -1.0f;
            boolean gotHorizontalPixelSize = false;
            float verticalPixelSize = -1.0f;
            boolean gotVerticalPixelSize = false;
            boolean sizeIsAbsolute = false;
            float horizontalPosition = -1.0f;
            boolean gotHorizontalPosition = false;
            float verticalPosition = -1.0f;
            boolean gotVerticalPosition = false;
            Node child = node.getFirstChild();
            while (child != null) {
                String childName = child.getNodeName();
                if (childName.equals("PixelAspectRatio")) {
                    String par = getAttribute(child, "value");
                    pixelAspectRatio = Float.parseFloat(par);
                    gotPixelAspectRatio = true;
                } else if (childName.equals("ImageOrientation")) {
                    String orientation = getAttribute(child, "value");
                    for (int i = 0; i < orientationNames.length; i++) {
                        if (orientation.equals(orientationNames[i])) {
                            char[] oData = new char[1];
                            oData[0] = (char) i;
                            f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_ORIENTATION), TIFFTag.TIFF_SHORT, 1, oData);
                            rootIFD.addTIFFField(f);
                            break;
                        }
                    }
                } else if (childName.equals("HorizontalPixelSize")) {
                    String hps = getAttribute(child, "value");
                    horizontalPixelSize = Float.parseFloat(hps);
                    gotHorizontalPixelSize = true;
                } else if (childName.equals("VerticalPixelSize")) {
                    String vps = getAttribute(child, "value");
                    verticalPixelSize = Float.parseFloat(vps);
                    gotVerticalPixelSize = true;
                } else if (childName.equals("HorizontalPosition")) {
                    String hp = getAttribute(child, "value");
                    horizontalPosition = Float.parseFloat(hp);
                    gotHorizontalPosition = true;
                } else if (childName.equals("VerticalPosition")) {
                    String vp = getAttribute(child, "value");
                    verticalPosition = Float.parseFloat(vp);
                    gotVerticalPosition = true;
                }
                child = child.getNextSibling();
            }
            sizeIsAbsolute = gotHorizontalPixelSize || gotVerticalPixelSize;
            // Fill in pixel size data from aspect ratio
            if (gotPixelAspectRatio) {
                if (gotHorizontalPixelSize && !gotVerticalPixelSize) {
                    verticalPixelSize = horizontalPixelSize / pixelAspectRatio;
                    gotVerticalPixelSize = true;
                } else if (gotVerticalPixelSize && !gotHorizontalPixelSize) {
                    horizontalPixelSize = verticalPixelSize * pixelAspectRatio;
                    gotHorizontalPixelSize = true;
                } else if (!gotHorizontalPixelSize && !gotVerticalPixelSize) {
                    horizontalPixelSize = pixelAspectRatio;
                    verticalPixelSize = 1.0f;
                    gotHorizontalPixelSize = true;
                    gotVerticalPixelSize = true;
                }
            }
            // Compute pixels/centimeter
            if (gotHorizontalPixelSize) {
                float xResolution = (sizeIsAbsolute ? 10.0f : 1.0f) / horizontalPixelSize;
                long[][] hData = new long[1][2];
                hData[0] = new long[2];
                hData[0][0] = (long) (xResolution * 10000.0f);
                hData[0][1] = (long) 10000;
                f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, hData);
                rootIFD.addTIFFField(f);
            }
            if (gotVerticalPixelSize) {
                float yResolution = (sizeIsAbsolute ? 10.0f : 1.0f) / verticalPixelSize;
                long[][] vData = new long[1][2];
                vData[0] = new long[2];
                vData[0][0] = (long) (yResolution * 10000.0f);
                vData[0][1] = (long) 10000;
                f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, vData);
                rootIFD.addTIFFField(f);
            }
            // Emit ResolutionUnit tag
            char[] res = new char[1];
            res[0] = (char) (sizeIsAbsolute ? BaselineTIFFTagSet.RESOLUTION_UNIT_CENTIMETER : BaselineTIFFTagSet.RESOLUTION_UNIT_NONE);
            f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT), TIFFTag.TIFF_SHORT, 1, res);
            rootIFD.addTIFFField(f);
            // Position
            if (sizeIsAbsolute) {
                if (gotHorizontalPosition) {
                    // Convert from millimeters to centimeters via
                    // numerator multiplier = denominator/10.
                    long[][] hData = new long[1][2];
                    hData[0][0] = (long) (horizontalPosition * 10000.0f);
                    hData[0][1] = (long) 100000;
                    f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_X_POSITION), TIFFTag.TIFF_RATIONAL, 1, hData);
                    rootIFD.addTIFFField(f);
                }
                if (gotVerticalPosition) {
                    // Convert from millimeters to centimeters via
                    // numerator multiplier = denominator/10.
                    long[][] vData = new long[1][2];
                    vData[0][0] = (long) (verticalPosition * 10000.0f);
                    vData[0][1] = (long) 100000;
                    f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_Y_POSITION), TIFFTag.TIFF_RATIONAL, 1, vData);
                    rootIFD.addTIFFField(f);
                }
            }
        } else if (name.equals("Document")) {
            Node child = node.getFirstChild();
            while (child != null) {
                String childName = child.getNodeName();
                if (childName.equals("SubimageInterpretation")) {
                    String si = getAttribute(child, "value");
                    int newSubFileType = -1;
                    if (si.equals("TransparencyMask")) {
                        newSubFileType = BaselineTIFFTagSet.NEW_SUBFILE_TYPE_TRANSPARENCY;
                    } else if (si.equals("ReducedResolution")) {
                        newSubFileType = BaselineTIFFTagSet.NEW_SUBFILE_TYPE_REDUCED_RESOLUTION;
                    } else if (si.equals("SinglePage")) {
                        newSubFileType = BaselineTIFFTagSet.NEW_SUBFILE_TYPE_SINGLE_PAGE;
                    }
                    if (newSubFileType != -1) {
                        tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_NEW_SUBFILE_TYPE);
                        f = new TIFFField(tag, newSubFileType);
                        rootIFD.addTIFFField(f);
                    }
                }
                if (childName.equals("ImageCreationTime")) {
                    String year = getAttribute(child, "year");
                    String month = getAttribute(child, "month");
                    String day = getAttribute(child, "day");
                    String hour = getAttribute(child, "hour");
                    String minute = getAttribute(child, "minute");
                    String second = getAttribute(child, "second");
                    StringBuffer sb = new StringBuffer();
                    sb.append(year);
                    sb.append(":");
                    if (month.length() == 1) {
                        sb.append("0");
                    }
                    sb.append(month);
                    sb.append(":");
                    if (day.length() == 1) {
                        sb.append("0");
                    }
                    sb.append(day);
                    sb.append(" ");
                    if (hour.length() == 1) {
                        sb.append("0");
                    }
                    sb.append(hour);
                    sb.append(":");
                    if (minute.length() == 1) {
                        sb.append("0");
                    }
                    sb.append(minute);
                    sb.append(":");
                    if (second.length() == 1) {
                        sb.append("0");
                    }
                    sb.append(second);
                    String[] dt = new String[1];
                    dt[0] = sb.toString();
                    f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_DATE_TIME), TIFFTag.TIFF_ASCII, 1, dt);
                    rootIFD.addTIFFField(f);
                }
                child = child.getNextSibling();
            }
        } else if (name.equals("Text")) {
            Node child = node.getFirstChild();
            String theAuthor = null;
            String theDescription = null;
            String theTitle = null;
            while (child != null) {
                String childName = child.getNodeName();
                if (childName.equals("TextEntry")) {
                    int tagNumber = -1;
                    NamedNodeMap childAttrs = child.getAttributes();
                    Node keywordNode = childAttrs.getNamedItem("keyword");
                    if (keywordNode != null) {
                        String keyword = keywordNode.getNodeValue();
                        String value = getAttribute(child, "value");
                        if (!keyword.equals("") && !value.equals("")) {
                            if (keyword.equalsIgnoreCase("DocumentName")) {
                                tagNumber = BaselineTIFFTagSet.TAG_DOCUMENT_NAME;
                            } else if (keyword.equalsIgnoreCase("ImageDescription")) {
                                tagNumber = BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION;
                            } else if (keyword.equalsIgnoreCase("Make")) {
                                tagNumber = BaselineTIFFTagSet.TAG_MAKE;
                            } else if (keyword.equalsIgnoreCase("Model")) {
                                tagNumber = BaselineTIFFTagSet.TAG_MODEL;
                            } else if (keyword.equalsIgnoreCase("PageName")) {
                                tagNumber = BaselineTIFFTagSet.TAG_PAGE_NAME;
                            } else if (keyword.equalsIgnoreCase("Software")) {
                                tagNumber = BaselineTIFFTagSet.TAG_SOFTWARE;
                            } else if (keyword.equalsIgnoreCase("Artist")) {
                                tagNumber = BaselineTIFFTagSet.TAG_ARTIST;
                            } else if (keyword.equalsIgnoreCase("HostComputer")) {
                                tagNumber = BaselineTIFFTagSet.TAG_HOST_COMPUTER;
                            } else if (keyword.equalsIgnoreCase("InkNames")) {
                                tagNumber = BaselineTIFFTagSet.TAG_INK_NAMES;
                            } else if (keyword.equalsIgnoreCase("Copyright")) {
                                tagNumber = BaselineTIFFTagSet.TAG_COPYRIGHT;
                            } else if (keyword.equalsIgnoreCase("author")) {
                                theAuthor = value;
                            } else if (keyword.equalsIgnoreCase("description")) {
                                theDescription = value;
                            } else if (keyword.equalsIgnoreCase("title")) {
                                theTitle = value;
                            }
                            if (tagNumber != -1) {
                                f = new TIFFField(rootIFD.getTag(tagNumber), TIFFTag.TIFF_ASCII, 1, new String[] { value });
                                rootIFD.addTIFFField(f);
                            }
                        }
                    }
                }
                child = child.getNextSibling();
            }
            // child != null
            if (theAuthor != null && getTIFFField(BaselineTIFFTagSet.TAG_ARTIST) == null) {
                f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_ARTIST), TIFFTag.TIFF_ASCII, 1, new String[] { theAuthor });
                rootIFD.addTIFFField(f);
            }
            if (theDescription != null && getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION) == null) {
                f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION), TIFFTag.TIFF_ASCII, 1, new String[] { theDescription });
                rootIFD.addTIFFField(f);
            }
            if (theTitle != null && getTIFFField(BaselineTIFFTagSet.TAG_DOCUMENT_NAME) == null) {
                f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_DOCUMENT_NAME), TIFFTag.TIFF_ASCII, 1, new String[] { theTitle });
                rootIFD.addTIFFField(f);
            }
        } else if (name.equals("Transparency")) {
            Node child = node.getFirstChild();
            while (child != null) {
                String childName = child.getNodeName();
                if (childName.equals("Alpha")) {
                    String alpha = getAttribute(child, "value");
                    f = null;
                    if (alpha.equals("premultiplied")) {
                        f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES), BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA);
                    } else if (alpha.equals("nonpremultiplied")) {
                        f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES), BaselineTIFFTagSet.EXTRA_SAMPLES_UNASSOCIATED_ALPHA);
                    }
                    if (f != null) {
                        rootIFD.addTIFFField(f);
                    }
                }
                child = child.getNextSibling();
            }
        }
        node = node.getNextSibling();
    }
    // Set SampleFormat.
    if (sampleFormat != null) {
        // Derive the value.
        int sf = -1;
        if (sampleFormat.equals("SignedIntegral")) {
            sf = BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER;
        } else if (sampleFormat.equals("UnsignedIntegral")) {
            sf = BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER;
        } else if (sampleFormat.equals("Real")) {
            sf = BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT;
        } else if (sampleFormat.equals("Index")) {
            sf = BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER;
        }
        if (sf != -1) {
            // Derive the count.
            int count = 1;
            // Try SamplesPerPixel first.
            f = getTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL);
            if (f != null) {
                count = f.getAsInt(0);
            } else {
                // Try BitsPerSample.
                f = getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
                if (f != null) {
                    count = f.getCount();
                }
            }
            char[] sampleFormatArray = new char[count];
            Arrays.fill(sampleFormatArray, (char) sf);
            // Add SampleFormat.
            tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_SAMPLE_FORMAT);
            f = new TIFFField(tag, TIFFTag.TIFF_SHORT, sampleFormatArray.length, sampleFormatArray);
            rootIFD.addTIFFField(f);
        }
    }
}
Also used : NamedNodeMap(org.w3c.dom.NamedNodeMap) HashMap(java.util.HashMap) IIOMetadataNode(javax.imageio.metadata.IIOMetadataNode) Node(org.w3c.dom.Node) NodeList(org.w3c.dom.NodeList) TIFFField(it.geosolutions.imageio.plugins.tiff.TIFFField) Iterator(java.util.Iterator) TIFFTag(it.geosolutions.imageio.plugins.tiff.TIFFTag) IIOMetadataNode(javax.imageio.metadata.IIOMetadataNode)

Example 5 with TIFFTag

use of it.geosolutions.imageio.plugins.tiff.TIFFTag in project imageio-ext by geosolutions-it.

the class TIFFImageMetadata method getIFDAsTree.

private Node getIFDAsTree(TIFFIFD ifd, String parentTagName, int parentTagNumber) {
    IIOMetadataNode IFDRoot = new IIOMetadataNode("TIFFIFD");
    if (parentTagNumber != 0) {
        IFDRoot.setAttribute("parentTagNumber", Integer.toString(parentTagNumber));
    }
    if (parentTagName != null) {
        IFDRoot.setAttribute("parentTagName", parentTagName);
    }
    List tagSets = ifd.getTagSetList();
    if (tagSets.size() > 0) {
        Iterator iter = tagSets.iterator();
        String tagSetNames = "";
        while (iter.hasNext()) {
            TIFFTagSet tagSet = (TIFFTagSet) iter.next();
            tagSetNames += tagSet.getClass().getName();
            if (iter.hasNext()) {
                tagSetNames += ",";
            }
        }
        IFDRoot.setAttribute("tagSets", tagSetNames);
    }
    Iterator iter = ifd.iterator();
    while (iter.hasNext()) {
        TIFFField f = (TIFFField) iter.next();
        int tagNumber = f.getTagNumber();
        TIFFTag tag = TIFFIFD.getTag(tagNumber, tagSets);
        Node node = null;
        if (tag == null) {
            node = f.getAsNativeNode();
        } else if (tag.isIFDPointer()) {
            TIFFIFD subIFD = (TIFFIFD) f.getData();
            // Recurse
            node = getIFDAsTree(subIFD, tag.getName(), tag.getNumber());
        } else {
            node = f.getAsNativeNode();
        }
        if (node != null) {
            IFDRoot.appendChild(node);
        }
    }
    return IFDRoot;
}
Also used : IIOMetadataNode(javax.imageio.metadata.IIOMetadataNode) Node(org.w3c.dom.Node) Iterator(java.util.Iterator) TIFFField(it.geosolutions.imageio.plugins.tiff.TIFFField) ArrayList(java.util.ArrayList) NodeList(org.w3c.dom.NodeList) List(java.util.List) BaselineTIFFTagSet(it.geosolutions.imageio.plugins.tiff.BaselineTIFFTagSet) TIFFTagSet(it.geosolutions.imageio.plugins.tiff.TIFFTagSet) EXIFParentTIFFTagSet(it.geosolutions.imageio.plugins.tiff.EXIFParentTIFFTagSet) IIOMetadataNode(javax.imageio.metadata.IIOMetadataNode) TIFFTag(it.geosolutions.imageio.plugins.tiff.TIFFTag)

Aggregations

TIFFTag (it.geosolutions.imageio.plugins.tiff.TIFFTag)10 TIFFField (it.geosolutions.imageio.plugins.tiff.TIFFField)7 TIFFTagSet (it.geosolutions.imageio.plugins.tiff.TIFFTagSet)6 Iterator (java.util.Iterator)6 BaselineTIFFTagSet (it.geosolutions.imageio.plugins.tiff.BaselineTIFFTagSet)5 List (java.util.List)5 ArrayList (java.util.ArrayList)4 IIOMetadataNode (javax.imageio.metadata.IIOMetadataNode)4 Node (org.w3c.dom.Node)4 EXIFParentTIFFTagSet (it.geosolutions.imageio.plugins.tiff.EXIFParentTIFFTagSet)3 NodeList (org.w3c.dom.NodeList)3 StringTokenizer (java.util.StringTokenizer)2 EXIFTIFFTagSet (it.geosolutions.imageio.plugins.tiff.EXIFTIFFTagSet)1 TIFFDirectory (it.geosolutions.imageio.plugins.tiff.TIFFDirectory)1 TIFFImageWriteParam (it.geosolutions.imageio.plugins.tiff.TIFFImageWriteParam)1 TIFFFieldNode (it.geosolutions.imageioimpl.plugins.tiff.TIFFFieldNode)1 Point (java.awt.Point)1 ICC_ColorSpace (java.awt.color.ICC_ColorSpace)1 IndexColorModel (java.awt.image.IndexColorModel)1 EOFException (java.io.EOFException)1