Package com.sun.media.imageio.plugins.tiff

Examples of com.sun.media.imageio.plugins.tiff.TIFFField


        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;

        // Check that numBands > 1 here because TIFF requires that
        // SamplesPerPixel = numBands + numExtraSamples and numBands
        // 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)) {
                // Black/white image

                if (r0 == 0) {
                    nativePhotometricInterpretation =
                   BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
                } else {
                    nativePhotometricInterpretation =
                   BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
                }


                // If photometricInterpretation is already set to
                // 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];
                        }
                    }
                }

                // Ensure the compressor, if any, matches compression setting
                // 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(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(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(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 == ?
        } // compressor == null

        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) {
                //
                // Perform color conversion only if image has RGB color space.
                //
                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();
                }
            }
        }

        //
        // Cannot at this time do YCbCr subsampling so set the
        // YCbCrSubsampling field value to [1, 1] and the YCbCrPositioning
        // field value to "cosited".
        //
        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;
        }

        for (int i = 0; i < bitsPerSample.length; i++) {
            bitsPerSample[i] = (char)bitDepth;
        }

        // Emit BitsPerSample. If the image is bilevel, emit if and only
        // 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)) {
            // 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 {
                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);
        }

        // Emit ICCProfile if there is no ICCProfile field already in the
        // 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);

            // Don't force dimensionless if one of the other dimensional
            // 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:
                    resRational[0][0] = 100L*maxDimension; // divide out 100
                    resRational[0][1] = 4*254; // 2.54 cm/inch * 100
                    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),
                         TIFFTag.TIFF_LONG,
                         tilesDown);
            rootIFD.addTIFFField(stripOffsetsField);

            TIFFField stripByteCountsField =
                new TIFFField(
                         base.getTag(BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS),
                         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),
                         TIFFTag.TIFF_LONG,
                         tilesDown*tilesAcross);
            rootIFD.addTIFFField(tileOffsetsField);

            TIFFField tileByteCountsField =
                new TIFFField(
                         base.getTag(BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS),
                         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 { // Uncompressed
                // ImageWidth through PlanarConfiguration are set above.
                // XResolution and YResolution are handled above for all TIFFs.

                // 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) {
                // Handle EXIF private fields in order of increasing
                // tag number.

                // 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 {
View Full Code Here


        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }

        TIFFIFD rootIFD = readIFD(imageIndex);
        TIFFField f = rootIFD.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
        int compression = f.getAsInt(0);

        return compression == BaselineTIFFTagSet.COMPRESSION_NONE;
    }
View Full Code Here

            // Read the IFD for the pixel replacement index.
            TIFFIFD replacePixelsIFD = readIFD(imageIndex);

            // Ensure that compression is "none".
            TIFFField f =
                replacePixelsIFD.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
            int compression = f.getAsInt(0);
            if (compression != BaselineTIFFTagSet.COMPRESSION_NONE) {
                throw new UnsupportedOperationException
                    ("canReplacePixels(imageIndex) == false!");
            }

            // Get the image dimensions.
            f =
                replacePixelsIFD.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
            if(f == null) {
                throw new IIOException("Cannot read ImageWidth field.");
            }
            int w = f.getAsInt(0);

            f =
                replacePixelsIFD.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH);
            if(f == null) {
                throw new IIOException("Cannot read ImageHeight field.");
            }
            int h = f.getAsInt(0);

            // Create image bounds.
            Rectangle bounds = new Rectangle(0, 0, w, h);

            // Intersect region with bounds.
            region = region.intersection(bounds);

            // Check for empty intersection.
            if(region.isEmpty()) {
                throw new IIOException("Region does not intersect image bounds");
            }

            // Save the region.
            replacePixelsRegion = region;

            // Get the tile offsets.
            f = replacePixelsIFD.getTIFFField(BaselineTIFFTagSet.TAG_TILE_OFFSETS);
            if(f == null) {
                f = replacePixelsIFD.getTIFFField(BaselineTIFFTagSet.TAG_STRIP_OFFSETS);
            }
            replacePixelsTileOffsets = f.getAsLongs();

            // Get the byte counts.
            f = replacePixelsIFD.getTIFFField(BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS);
            if(f == null) {
                f = replacePixelsIFD.getTIFFField(BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS);
            }
            replacePixelsByteCounts = f.getAsLongs();

            replacePixelsOffsetsPosition =
                replacePixelsIFD.getStripOrTileOffsetsPosition();
            replacePixelsByteCountsPosition =
                replacePixelsIFD.getStripOrTileByteCountsPosition();
View Full Code Here

                // Replace the param.
                param = paramCopy;
            }

            // Check band count and bit depth compatibility.
            TIFFField f =
                replacePixelsMetadata.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
            if(f == null) {
                throw new IIOException
                    ("Cannot read destination BitsPerSample");
            }
            int[] dstBitsPerSample = f.getAsInts();
            int[] srcBitsPerSample = image.getSampleModel().getSampleSize();
            int[] sourceBands = param.getSourceBands();
            if(sourceBands != null) {
                if(sourceBands.length != dstBitsPerSample.length) {
                    throw new IIOException
View Full Code Here

            }, null);

        if(sofPresent) {
            // sofProcess -> Compression ?
            int compression = BaselineTIFFTagSet.COMPRESSION_JPEG;
            TIFFField compressionField =
                new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_COMPRESSION),
                              compression);
            dir.addTIFFField(compressionField);

            // samplePrecision -> BitsPerSample
            char[] bitsPerSample = new char[numFrameComponents];
            Arrays.fill(bitsPerSample, (char)(samplePrecision & 0xff));
            TIFFField bitsPerSampleField =
                new TIFFField(
                              base.getTag(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE),
                              TIFFTag.TIFF_SHORT,
                              bitsPerSample.length,
                              bitsPerSample);
            dir.addTIFFField(bitsPerSampleField);

            // numLines -> ImageLength
            TIFFField imageLengthField =
                new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_IMAGE_LENGTH),
                              numLines);
            dir.addTIFFField(imageLengthField);

            // samplesPerLine -> ImageWidth
            TIFFField imageWidthField =
                new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_IMAGE_WIDTH),
                              samplesPerLine);
            dir.addTIFFField(imageWidthField);

            // numFrameComponents -> SamplesPerPixel
            TIFFField samplesPerPixelField =
                new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL),
                              numFrameComponents);
            dir.addTIFFField(samplesPerPixelField);

            // componentId -> PhotometricInterpretation + ExtraSamples
            IIOMetadataNode chroma = getStandardChromaNode();
            if(chroma != null) {
                IIOMetadataNode csType =
                    (IIOMetadataNode)chroma.getElementsByTagName("ColorSpaceType").item(0);
                String name = csType.getAttribute("name");
                int photometricInterpretation = -1;
                if(name.equals("GRAY")) {
                    photometricInterpretation =
                        BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
                } else if(name.equals("YCbCr") || name.equals("PhotoYCC")) {
                    // NOTE: PhotoYCC -> YCbCr
                    photometricInterpretation =
                        BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR;
                } else if(name.equals("RGB")) {
                    photometricInterpretation =
                        BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
                } else if(name.equals("CMYK") || name.equals("YCCK")) {
                    // NOTE: YCCK -> CMYK
                    photometricInterpretation =
                        BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CMYK;
                }

                if(photometricInterpretation != -1) {
                    TIFFField photometricInterpretationField =
                        new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION),
                                      photometricInterpretation);
                    dir.addTIFFField(photometricInterpretationField);
                }

                if(hasAlpha) {
                    char[] extraSamples =
                        new char[] {BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA};
                    TIFFField extraSamplesField =
                        new TIFFField(
                                      base.getTag(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES),
                                      TIFFTag.TIFF_SHORT,
                                      extraSamples.length,
                                      extraSamples);
                    dir.addTIFFField(extraSamplesField);
                }
            } // chroma != null
        } // sofPresent

        // JFIF APP0 -> Resolution fields.
        if(app0JFIFPresent) {
            long[][] xResolution = new long[][] {{Xdensity, 1}};
            TIFFField XResolutionField =
                new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION),
                              TIFFTag.TIFF_RATIONAL,
                              1,
                              xResolution);
            dir.addTIFFField(XResolutionField);

            long[][] yResolution = new long[][] {{Ydensity, 1}};
            TIFFField YResolutionField =
                new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION),
                              TIFFTag.TIFF_RATIONAL,
                              1,
                              yResolution);
            dir.addTIFFField(YResolutionField);

            int resolutionUnit = BaselineTIFFTagSet.RESOLUTION_UNIT_NONE;
            switch(resUnits) {
            case JFIF_RESUNITS_ASPECT:
                resolutionUnit = BaselineTIFFTagSet.RESOLUTION_UNIT_NONE;
            case JFIF_RESUNITS_DPI:
                resolutionUnit = BaselineTIFFTagSet.RESOLUTION_UNIT_INCH;
                break;
            case JFIF_RESUNITS_DPC:
                resolutionUnit = BaselineTIFFTagSet.RESOLUTION_UNIT_CENTIMETER;
                break;
            }
            TIFFField ResolutionUnitField =
                new TIFFField(base.getTag
                              (BaselineTIFFTagSet.TAG_RESOLUTION_UNIT),
                              resolutionUnit);
            dir.addTIFFField(ResolutionUnitField);
        }

        // DQT + DHT -> JPEGTables.
        byte[] jpegTablesData = null;
        if(dqtPresent || dqtPresent) {
            // Determine length of JPEGTables data.
            int jpegTablesLength = 2; // SOI
            if(dqtPresent) {
                Iterator dqts = qtables.iterator();
                while(dqts.hasNext()) {
                    Iterator qtiter = ((List)dqts.next()).iterator();
                    while(qtiter.hasNext()) {
                        QTable qt = (QTable)qtiter.next();
                        jpegTablesLength += 4 + qt.length;
                    }
                }
            }
            if(dhtPresent) {
                Iterator dhts = htables.iterator();
                while(dhts.hasNext()) {
                    Iterator htiter = ((List)dhts.next()).iterator();
                    while(htiter.hasNext()) {
                        HuffmanTable ht = (HuffmanTable)htiter.next();
                        jpegTablesLength += 4 + ht.length;
                    }
                }
            }
            jpegTablesLength += 2; // EOI

            // Allocate space.
            jpegTablesData = new byte[jpegTablesLength];

            // SOI
            jpegTablesData[0] = (byte)0xff;
            jpegTablesData[1] = (byte)SOI;
            int jpoff = 2;

            if(dqtPresent) {
                Iterator dqts = qtables.iterator();
                while(dqts.hasNext()) {
                    Iterator qtiter = ((List)dqts.next()).iterator();
                    while(qtiter.hasNext()) {
                        jpegTablesData[jpoff++] = (byte)0xff;
                        jpegTablesData[jpoff++] = (byte)DQT;
                        QTable qt = (QTable)qtiter.next();
                        int qtlength = qt.length + 2;
                        jpegTablesData[jpoff++] =
                            (byte)((qtlength & 0xff00) >> 8);
                        jpegTablesData[jpoff++] = (byte)(qtlength & 0xff);
                        jpegTablesData[jpoff++] =
                            (byte)(((qt.elementPrecision & 0xf0) << 4) |
                                   (qt.tableID & 0x0f));
                        int[] table = qt.table.getTable();
                        int qlen = table.length;
                        for(int i = 0; i < qlen; i++) {
                            jpegTablesData[jpoff + zigzag[i]] = (byte)table[i];
                        }
                        jpoff += qlen;
                    }
                }
            }

            if(dhtPresent) {
                Iterator dhts = htables.iterator();
                while(dhts.hasNext()) {
                    Iterator htiter = ((List)dhts.next()).iterator();
                    while(htiter.hasNext()) {
                        jpegTablesData[jpoff++] = (byte)0xff;
                        jpegTablesData[jpoff++] = (byte)DHT;
                        HuffmanTable ht = (HuffmanTable)htiter.next();
                        int htlength = ht.length + 2;
                        jpegTablesData[jpoff++] =
                            (byte)((htlength & 0xff00) >> 8);
                        jpegTablesData[jpoff++] = (byte)(htlength & 0xff);
                        jpegTablesData[jpoff++] =
                            (byte)(((ht.tableClass & 0x0f) << 4) |
                                   (ht.tableID & 0x0f));
                        short[] lengths = ht.table.getLengths();
                        int numLengths = lengths.length;
                        for(int i = 0; i < numLengths; i++) {
                            jpegTablesData[jpoff++] = (byte)lengths[i];
                        }
                        short[] values = ht.table.getValues();
                        int numValues = values.length;
                        for(int i = 0; i < numValues; i++) {
                            jpegTablesData[jpoff++] = (byte)values[i];
                        }
                    }
                }
            }

            jpegTablesData[jpoff++] = (byte)0xff;
            jpegTablesData[jpoff] = (byte)EOI;           
        }
        if(jpegTablesData != null) {
            TIFFField JPEGTablesField =
                new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_JPEG_TABLES),
                              TIFFTag.TIFF_UNDEFINED,
                              jpegTablesData.length,
                              jpegTablesData);
            dir.addTIFFField(JPEGTablesField);
        }
View Full Code Here

            }

            // Add the field if its contents have been initialized which
            // will not be the case if an EOF was ignored above.
            if(obj != null) {
                TIFFField f = new TIFFField(tiffTag, type, count, obj);
                addTIFFField(f);
            }

            stream.seek(nextTagOffset);
        }
View Full Code Here

        long nextSpace = stream.getStreamPosition() + 12*numFields + 4;

        Iterator iter = iterator();
        while (iter.hasNext()) {
            TIFFField f = (TIFFField)iter.next();
           
            TIFFTag tag = f.getTag();

            int type = f.getType();
            int count = f.getCount();

            // Hack to deal with unknown tags
            if (type == 0) {
                type = TIFFTag.TIFF_UNDEFINED;
            }
            int size = count*TIFFTag.getSizeOfType(type);

            if (type == TIFFTag.TIFF_ASCII) {
                int chars = 0;
                for (int i = 0; i < count; i++) {
                    chars += f.getAsString(i).length() + 1;
                }
                count = chars;
                size = count;
            }

            int tagNumber = f.getTagNumber();
            stream.writeShort(tagNumber);
            stream.writeShort(type);
            stream.writeInt(count);

            // Write a dummy value to fill space
            stream.writeInt(0);
            stream.mark(); // Mark beginning of next field
            stream.skipBytes(-4);

            long pos;

            if (size > 4 || tag.isIFDPointer()) {
                // Ensure IFD or value is written on a word boundary
                nextSpace = (nextSpace + 3) & ~0x3;

                stream.writeInt((int)nextSpace);
                stream.seek(nextSpace);
                pos = nextSpace;

                if (tag.isIFDPointer()) {
                    TIFFIFD subIFD = (TIFFIFD)f.getData();
                    subIFD.writeToStream(stream);
                    nextSpace = subIFD.lastPosition;
                } else {
                    writeTIFFFieldToStream(f, stream);
                    nextSpace = stream.getStreamPosition();
View Full Code Here

        // Iterate over the fields in this IFD.
        Iterator fields = iterator();
        while(fields.hasNext()) {
            // Get the next field.
            TIFFField field = (TIFFField)fields.next();

            // Get its tag number.
            Integer tagNumber = new Integer(field.getTagNumber());

            // Branch based on membership in baseline set.
            TIFFField fieldClone;
            if(baselineTagNumbers.contains(tagNumber)) {
                // Copy by value.
                Object fieldData = field.getData();

                int fieldType = field.getType();

                try {
                    switch (fieldType) {
                    case TIFFTag.TIFF_BYTE:
                    case TIFFTag.TIFF_SBYTE:
                    case TIFFTag.TIFF_UNDEFINED:
                        fieldData = ((byte[])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_ASCII:
                        fieldData = ((String[])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_SHORT:
                        fieldData = ((char[])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_LONG:
                    case TIFFTag.TIFF_IFD_POINTER:
                        fieldData = ((long[])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_RATIONAL:
                        fieldData = ((long[][])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_SSHORT:
                        fieldData = ((short[])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_SLONG:
                        fieldData = ((int[])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_SRATIONAL:
                        fieldData = ((int[][])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_FLOAT:
                        fieldData = ((float[])fieldData).clone();
                        break;
                    case TIFFTag.TIFF_DOUBLE:
                        fieldData = ((double[])fieldData).clone();
                        break;
                    default:
                        // Shouldn't happen but do nothing ...
                    }
                } catch(Exception e) {
                    // Ignore it and copy by reference ...
                }

                fieldClone = new TIFFField(field.getTag(), fieldType,
                                           field.getCount(), fieldData);
            } else {
                // Copy by reference.
                fieldClone = field;
            }
View Full Code Here

        if(decompressor != null) {
            decompressor.beginDecoding();
        }

        TIFFImageMetadata tmetadata = (TIFFImageMetadata)metadata;
        TIFFField f;

        f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_SUBSAMPLING);
        if (f != null) {
            if (f.getCount() == 2) {
                this.chromaSubsampleH = f.getAsInt(0);
                this.chromaSubsampleV = f.getAsInt(1);

                if (chromaSubsampleH != 1 && chromaSubsampleH != 2 &&
                    chromaSubsampleH != 4) {
                    warning("Y_CB_CR_SUBSAMPLING[0] has illegal value " +
                            chromaSubsampleH +
                            " (should be 1, 2, or 4), setting to 1");
                    chromaSubsampleH = 1;
                }

                if (chromaSubsampleV != 1 && chromaSubsampleV != 2 &&
                    chromaSubsampleV != 4) {
                    warning("Y_CB_CR_SUBSAMPLING[1] has illegal value " +
                            chromaSubsampleV +
                            " (should be 1, 2, or 4), setting to 1");
                    chromaSubsampleV = 1;
                }
            } else {
                warning("Y_CB_CR_SUBSAMPLING count != 2, " +
                        "assuming no subsampling");
            }
        }

        f =
           tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_COEFFICIENTS);
        if (f != null) {
            if (f.getCount() == 3) {
                this.LumaRed = f.getAsFloat(0);
                this.LumaGreen = f.getAsFloat(1);
                this.LumaBlue = f.getAsFloat(2);
            } else {
                warning("Y_CB_CR_COEFFICIENTS count != 3, " +
                        "assuming default values for CCIR 601-1");
            }
        }

        f =
          tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_REFERENCE_BLACK_WHITE);
        if (f != null) {
            if (f.getCount() == 6) {
                this.referenceBlackY = f.getAsFloat(0);
                this.referenceWhiteY = f.getAsFloat(1);
                this.referenceBlackCb = f.getAsFloat(2);
                this.referenceWhiteCb = f.getAsFloat(3);
                this.referenceBlackCr = f.getAsFloat(4);
                this.referenceWhiteCr = f.getAsFloat(5);
            } else {
                warning("REFERENCE_BLACK_WHITE count != 6, ignoring it");
            }
        } else {
                warning("REFERENCE_BLACK_WHITE not found, assuming 0-255/128-255/128-255");
View Full Code Here

    public void setMetadata(IIOMetadata metadata) {
        super.setMetadata(metadata);

        if (metadata instanceof TIFFImageMetadata) {
            TIFFImageMetadata tim = (TIFFImageMetadata)metadata;
            TIFFField f = tim.getTIFFField(BaselineTIFFTagSet.TAG_T4_OPTIONS);
            if (f != null) {
                int options = f.getAsInt(0);
                is1DMode = (options & 0x1) == 0;
                isEOLAligned = (options & 0x4) == 0x4;
            } else {
                long[] oarray = new long[1];
                oarray[0] = (isEOLAligned ? 0x4 : 0x0) |
                    (is1DMode ? 0x0 : 0x1);
               
                BaselineTIFFTagSet base = BaselineTIFFTagSet.getInstance();
                TIFFField T4Options =
                  new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_T4_OPTIONS),
                                TIFFTag.TIFF_LONG,
                                1,
                                oarray);
                tim.rootIFD.addTIFFField(T4Options);
            }
View Full Code Here

TOP

Related Classes of com.sun.media.imageio.plugins.tiff.TIFFField

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.