Package com.lightcrafts.media.jai.codec

Examples of com.lightcrafts.media.jai.codec.TIFFField


  // Create Directory
  SortedSet fields = new TreeSet();

  // Image Width
  fields.add(new TIFFField(TIFFImageDecoder.TIFF_IMAGE_WIDTH,
                                 TIFFField.TIFF_LONG, 1,
                                 (Object)(new long[] {(long)width})));

  // Image Length
  fields.add(new TIFFField(TIFFImageDecoder.TIFF_IMAGE_LENGTH,
                                 TIFFField.TIFF_LONG, 1,
                                 new long[] {(long)height}));

  fields.add(new TIFFField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE,
                                 TIFFField.TIFF_SHORT, numBands,
                                 intsToChars(sampleSize)));

  fields.add(new TIFFField(TIFFImageDecoder.TIFF_COMPRESSION,
                                 TIFFField.TIFF_SHORT, 1,
                                 new char[] {(char)compression}));

  fields.add(
      new TIFFField(TIFFImageDecoder.TIFF_PHOTOMETRIC_INTERPRETATION,
                          TIFFField.TIFF_SHORT, 1,
                          new char[] {(char)photometricInterpretation}));

        if(!isTiled) {
            fields.add(new TIFFField(TIFFImageDecoder.TIFF_STRIP_OFFSETS,
                                     TIFFField.TIFF_LONG, numTiles,
                                     (long[])tileOffsets));
        }
 
  fields.add(new TIFFField(TIFFImageDecoder.TIFF_SAMPLES_PER_PIXEL,
                                 TIFFField.TIFF_SHORT, 1,
                                 new char[] {(char)numBands}));

        if(!isTiled) {
            fields.add(new TIFFField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP,
                                     TIFFField.TIFF_LONG, 1,
                                     new long[] {(long)tileHeight}));

            fields.add(new TIFFField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS,
                                     TIFFField.TIFF_LONG, numTiles,
                                     (long[])tileByteCounts));
        }

  if (colormap != null) {
      fields.add(new TIFFField(TIFFImageDecoder.TIFF_COLORMAP,
                                     TIFFField.TIFF_SHORT, sizeOfColormap,
                                     intsToChars(colormap)));
  }

        if(isTiled) {
            fields.add(new TIFFField(TIFFImageDecoder.TIFF_TILE_WIDTH,
                                     TIFFField.TIFF_LONG, 1,
                                     new long[] {(long)tileWidth}));

            fields.add(new TIFFField(TIFFImageDecoder.TIFF_TILE_LENGTH,
                                     TIFFField.TIFF_LONG, 1,
                                     new long[] {(long)tileHeight}));

            fields.add(new TIFFField(TIFFImageDecoder.TIFF_TILE_OFFSETS,
                                     TIFFField.TIFF_LONG, numTiles,
                                     (long[])tileOffsets));

            fields.add(new TIFFField(TIFFImageDecoder.TIFF_TILE_BYTE_COUNTS,
                                     TIFFField.TIFF_LONG, numTiles,
                                     (long[])tileByteCounts));
        }

        if(numExtraSamples > 0) {
            int[] extraSamples = new int[numExtraSamples];
            for(int i = 0; i < numExtraSamples; i++) {
                extraSamples[i] = extraSampleType;
            }
            fields.add(new TIFFField(TIFFImageDecoder.TIFF_EXTRA_SAMPLES,
                                     TIFFField.TIFF_SHORT, numExtraSamples,
                                     intsToChars(extraSamples)));
        }

        // Data Sample Format Extension fields.
        if(dataType != DataBuffer.TYPE_BYTE) {
            // SampleFormat
            int[] sampleFormat = new int[numBands];
            if(dataType == DataBuffer.TYPE_FLOAT) {
                sampleFormat[0] = 3;
            } else if(dataType == DataBuffer.TYPE_USHORT) {
                sampleFormat[0] = 1;
            } else {
                sampleFormat[0] = 2;
            }
            for(int b = 1; b < numBands; b++) {
                sampleFormat[b] = sampleFormat[0];
            }
      fields.add(new TIFFField(TIFFImageDecoder.TIFF_SAMPLE_FORMAT,
                                     TIFFField.TIFF_SHORT, numBands,
                                     intsToChars(sampleFormat)));

            // NOTE: We don't bother setting the SMinSampleValue and
            // SMaxSampleValue fields as these both default to the
            // extrema of the respective data types.  Probably we should
            // check for the presence of the "extrema" property and
            // use it if available.
        }

        // Bilevel compression variables.
        boolean inverseFill = encodeParam.getReverseFillOrder();
        boolean T4encode2D = encodeParam.getT4Encode2D();
        boolean T4PadEOLs = encodeParam.getT4PadEOLs();
        TIFFFaxEncoder faxEncoder = null;

        // Add bilevel compression fields.
        if((imageType == TIFF_BILEVEL_BLACK_IS_ZERO ||
            imageType == TIFF_BILEVEL_WHITE_IS_ZERO) &&
           (compression == COMP_GROUP3_1D ||
            compression == COMP_GROUP3_2D ||
            compression == COMP_GROUP4)) {

            // Create the encoder.
            faxEncoder = new TIFFFaxEncoder(inverseFill);

            // FillOrder field.
            fields.add(new TIFFField(TIFFImageDecoder.TIFF_FILL_ORDER,
                                     TIFFField.TIFF_SHORT, 1,
                                     new char[] {inverseFill ?
                                                 (char)2 : (char)1}));

            if(compression == COMP_GROUP3_2D) {
                // T4Options field.
                long T4Options = 0x00000000;
                if(T4encode2D) {
                    T4Options |= 0x00000001;
                }
                if(T4PadEOLs) {
                    T4Options |= 0x00000004;
                }
                fields.add(new TIFFField(TIFFImageDecoder.TIFF_T4_OPTIONS,
                                         TIFFField.TIFF_LONG, 1,
                                         new long[] {T4Options}));
            } else if(compression == COMP_GROUP4) {
                // T6Options field.
                fields.add(new TIFFField(TIFFImageDecoder.TIFF_T6_OPTIONS,
                                         TIFFField.TIFF_LONG, 1,
                                         new long[] {(long)0x00000000}));
            }
        }

        // Initialize some JPEG variables.
        com.sun.image.codec.jpeg.JPEGEncodeParam jpegEncodeParam = null;
        com.sun.image.codec.jpeg.JPEGImageEncoder jpegEncoder = null;
        int jpegColorID = 0;

        if(compression == COMP_JPEG_TTN2) {

            // Initialize JPEG color ID.
            jpegColorID =
                com.sun.image.codec.jpeg.JPEGDecodeParam.COLOR_ID_UNKNOWN;
            switch(imageType) {
            case TIFF_GRAY:
            case TIFF_PALETTE:
                jpegColorID =
                    com.sun.image.codec.jpeg.JPEGDecodeParam.COLOR_ID_GRAY;
                break;
            case TIFF_RGB:
                jpegColorID =
                    com.sun.image.codec.jpeg.JPEGDecodeParam.COLOR_ID_RGB;
                break;
            case TIFF_YCBCR:
                jpegColorID =
                    com.sun.image.codec.jpeg.JPEGDecodeParam.COLOR_ID_YCbCr;
                break;
            }

            // Get the JDK encoding parameters.
            Raster tile00 = im.getTile(im.getMinTileX(), im.getMinTileY());
            jpegEncodeParam =
                com.sun.image.codec.jpeg.JPEGCodec.getDefaultJPEGEncodeParam(
                    tile00, jpegColorID);

            // Modify per values passed in.
            JPEGImageEncoder.modifyEncodeParam(jep, jpegEncodeParam, numBands);

            // JPEGTables field.
            if(jep.getWriteImageOnly()) {
                // Write an abbreviated tables-only stream to JPEGTables field.
                jpegEncodeParam.setImageInfoValid(false);
                jpegEncodeParam.setTableInfoValid(true);
                ByteArrayOutputStream tableStream =
                    new ByteArrayOutputStream();
                jpegEncoder =
                    com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(
                        tableStream,
                        jpegEncodeParam);
                jpegEncoder.encode(tile00);
                byte[] tableData = tableStream.toByteArray();
                fields.add(new TIFFField(TIFF_JPEG_TABLES,
                                         TIFFField.TIFF_UNDEFINED,
                                         tableData.length,
                                         tableData));

                // Reset encoder so it's recreated below.
                jpegEncoder = null;
            }
        }

        if(imageType == TIFF_YCBCR) {
            // YCbCrSubSampling: 2 is the default so we must write 1 as
            // we do not (yet) do any subsampling.
            int subsampleH = 1;
            int subsampleV = 1;

            // If JPEG, update values.
            if(compression == COMP_JPEG_TTN2) {
                // Determine maximum subsampling.
                subsampleH = jep.getHorizontalSubsampling(0);
                subsampleV = jep.getVerticalSubsampling(0);
                for(int i = 1; i < numBands; i++) {
                    int subH = jep.getHorizontalSubsampling(i);
                    if(subH > subsampleH) {
                        subsampleH = subH;
                    }
                    int subV = jep.getVerticalSubsampling(i);
                    if(subV > subsampleV) {
                        subsampleV = subV;
                    }
                }
            }

            fields.add(new TIFFField(TIFF_YCBCR_SUBSAMPLING,
                                     TIFFField.TIFF_SHORT, 2,
                                     new char[] {(char)subsampleH,
                                                 (char)subsampleV}));


            // YCbCr positioning.
            fields.add(new TIFFField(TIFF_YCBCR_POSITIONING,
                                     TIFFField.TIFF_SHORT, 1,
                                     new char[] {compression == COMP_JPEG_TTN2 ?
                                                 (char)1 : (char)2}));

            // Reference black/white.
            long[][] refbw;
            if(compression == COMP_JPEG_TTN2) {
                refbw =
                    new long[][] { // no headroon/footroom
                        {0, 1}, {255, 1}, {128, 1}, {255, 1}, {128, 1}, {255, 1}
                    };
            } else {
                refbw =
                    new long[][] { // CCIR 601.1 headroom/footroom (presumptive)
                        {15, 1}, {235, 1}, {128, 1}, {240, 1}, {128, 1}, {240, 1}
                    };
            }
            fields.add(new TIFFField(TIFF_REF_BLACK_WHITE,
                                     TIFFField.TIFF_RATIONAL, 6,
                                     refbw));
        }

        // ---- No more automatically generated fields should be added
        //      after this point. ----

        // Add extra fields specified via the encoding parameters.
        TIFFField[] extraFields = encodeParam.getExtraFields();
        if(extraFields != null) {
            ArrayList extantTags = new ArrayList(fields.size());
            Iterator fieldIter = fields.iterator();
            while(fieldIter.hasNext()) {
                TIFFField fld = (TIFFField)fieldIter.next();
                extantTags.add(new Integer(fld.getTag()));
            }

            int numExtraFields = extraFields.length;
            for(int i = 0; i < numExtraFields; i++) {
                TIFFField fld = extraFields[i];
                Integer tagValue = new Integer(fld.getTag());
                if(!extantTags.contains(tagValue)) {
                    fields.add(fld);
                    extantTags.add(tagValue);
                }
            }
View Full Code Here


        // Loop over fields adding the size of all values > 4 bytes.
        Iterator iter = fields.iterator();
        while(iter.hasNext()) {
      // Get the field.     
      TIFFField field = (TIFFField)iter.next();

            // Determine the size of the field value.
            int valueSize = getValueSize(field);

            // Add any excess size.
View Full Code Here

        Iterator iter = fields.iterator();
  while(iter.hasNext()) {
     
      // 12 byte field entry TIFFField     
      TIFFField field = (TIFFField)iter.next();

      // byte 0-1 Tag that identifies a field
      int tag = field.getTag();
      writeUnsignedShort(tag);

      // byte 2-3 The field type
      int type = field.getType();
      writeUnsignedShort(type);
     
      // bytes 4-7 the number of values of the indicated type except
            // ASCII-valued fields which require the total number of bytes.
      int count = field.getCount();
            int valueSize = getValueSize(field);
      writeLong(type == TIFFField.TIFF_ASCII ? valueSize : count);

      // bytes 8 - 11 the value or value offset
      if (valueSize > 4) {
View Full Code Here

     * Check whether the specified tag exists in the specified
     * TIFFDirectory. If not, throw an error message. Otherwise
     * return the TIFFField.
     */
    private TIFFField getField(TIFFDirectory dir, int tagID, String tagName) {
        TIFFField field = dir.getField(tagID);
        if (field == null) {
            MessageFormat mf =
                new MessageFormat(JaiI18N.getString("TIFFImage5"));
            mf.setLocale(Locale.getDefault());
            throw new RuntimeException(mf.format(new Object[] {tagName}));
View Full Code Here

        // Set a property "tiff_directory".
        properties.put("tiff_directory", dir);

  // Get the number of samples per pixel
  TIFFField sfield =
      dir.getField(TIFFImageDecoder.TIFF_SAMPLES_PER_PIXEL);
        int samplesPerPixel = sfield == null ? 1 : (int)sfield.getAsLong(0);

  // Read the TIFF_PLANAR_CONFIGURATION field
  TIFFField planarConfigurationField =
      dir.getField(TIFFImageDecoder.TIFF_PLANAR_CONFIGURATION);
  char[] planarConfiguration = planarConfigurationField == null ?
            new char[] {1} :
            planarConfigurationField.getAsChars();

        // Support planar format (band sequential) only for 1 sample/pixel.
        if (planarConfiguration[0] != 1 && samplesPerPixel != 1) {
            throw new RuntimeException(JaiI18N.getString("TIFFImage0"));
        }

  // Read the TIFF_BITS_PER_SAMPLE field
  TIFFField bitsField =
      dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE);
        char[] bitsPerSample = null;
        if(bitsField != null) {
            bitsPerSample = bitsField.getAsChars();
        } else {
            bitsPerSample = new char[] {1};

            // Ensure that all samples have the same bit depth.
            for (int i = 1; i < bitsPerSample.length; i++) {
                if (bitsPerSample[i] != bitsPerSample[0]) {
                    throw new RuntimeException(
               JaiI18N.getString("TIFFImage1"));
                }
            }
        }
        sampleSize = (int)bitsPerSample[0];

  // Read the TIFF_SAMPLE_FORMAT tag to see whether the data might be
  // signed or floating point
  TIFFField sampleFormatField =
      dir.getField(TIFFImageDecoder.TIFF_SAMPLE_FORMAT);

        char[] sampleFormat = null;
  if (sampleFormatField != null) {
      sampleFormat = sampleFormatField.getAsChars();

      // Check that all the samples have the same format
      for (int l=1; l<sampleFormat.length; l++) {
    if (sampleFormat[l] != sampleFormat[0]) {
        throw new RuntimeException(
               JaiI18N.getString("TIFFImage2"));
    }
      }

  } else {
      sampleFormat = new char[] {1};
  }

        // Set the data type based on the sample size and format.
        boolean isValidDataFormat = false;
        switch(sampleSize) {
        case 1:
        case 4:
        case 8:
            if(sampleFormat[0] != 3) {
                // Ignore whether signed or unsigned: treat all as unsigned.
    dataType = DataBuffer.TYPE_BYTE;
                isValidDataFormat = true;
            }
            break;
        case 16:
            if(sampleFormat[0] != 3) {
                dataType = sampleFormat[0] == 2 ?
                    DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
                isValidDataFormat = true;
            }
            break;
        case 32:
            dataType = sampleFormat[0] == 3 ?
                DataBuffer.TYPE_FLOAT : DataBuffer.TYPE_INT;
            isValidDataFormat = true;
            break;
        }

        if(!isValidDataFormat) {
            throw new RuntimeException(JaiI18N.getString("TIFFImage3"));
        }

  // Figure out what compression if any, is being used.
  TIFFField compField = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION);
        compression = compField == null ? COMP_NONE : compField.getAsInt(0);

        // Get the photometric interpretation field.
        TIFFField photoInterpField =
            dir.getField(TIFFImageDecoder.TIFF_PHOTOMETRIC_INTERPRETATION);

        // Set the photometric interpretation variable.
        int photometricType;
        if(photoInterpField != null) {
            // Set the variable from the photometric interpretation field.
            photometricType = (int)photoInterpField.getAsLong(0);
        } else {
            // The photometric interpretation field is missing; attempt
            // to infer the type from other information.
            if(dir.getField(TIFFImageDecoder.TIFF_COLORMAP) != null) {
                // There is a colormap so most likely a palette color image.
                photometricType = 3; // RGB Palette
            } else if(sampleSize == 1) {
                // Bilevel image so most likely a document; switch based
                // on the compression type of the image.
                if(compression == COMP_FAX_G3_1D ||
                   compression == COMP_FAX_G3_2D ||
                   compression == COMP_FAX_G4_2D) {
                    photometricType = 0; // WhiteIsZero
                } else {
                    photometricType = 1; // BlackIsZero
                }
            } else if(samplesPerPixel == 3 || samplesPerPixel == 4) {
                // Assume 3 bands is RGB and 4 bands is RGBA.
                photometricType = 2; // RGB
            } else {
                // Default to multi-band grayscale.
                photometricType = 1; // BlackIsZero
            }
        }

        // Determine which kind of image we are dealing with.
        imageType = TYPE_UNSUPPORTED;
  switch(photometricType) {
        case 0: // WhiteIsZero
            isWhiteZero = true;
        case 1: // BlackIsZero
            if(sampleSize == 1 && samplesPerPixel == 1) {
                imageType = TYPE_BILEVEL;
            } else if(sampleSize == 4 && samplesPerPixel == 1) {
                imageType = TYPE_GRAY_4BIT;
            } else if(sampleSize % 8 == 0) {
                if(samplesPerPixel == 1) {
                    imageType = TYPE_GRAY;
                } else if(samplesPerPixel == 2) {
                    imageType = TYPE_GRAY_ALPHA;
                } else {
                    imageType = TYPE_GENERIC;
                }
            }
            break;
        case 2: // RGB
            if(sampleSize % 8 == 0) {
                if(samplesPerPixel == 3) {
                    imageType = TYPE_RGB;
                } else if(samplesPerPixel == 4) {
                    imageType = TYPE_RGB_ALPHA;
                } else {
                    imageType = TYPE_GENERIC;
                }
            }
            break;
        case 3: // RGB Palette
            if(samplesPerPixel == 1 &&
               (sampleSize == 4 || sampleSize == 8 || sampleSize == 16)) {
                imageType = TYPE_PALETTE;
            }
            break;
        case 4: // Transparency mask
            if(sampleSize == 1 && samplesPerPixel == 1) {
                imageType = TYPE_BILEVEL;
            }
            break;
  case 5: // Separated image, usually CMYK
      if (sampleSize == 8 && samplesPerPixel == 4) {
    imageType = TYPE_CMYK;
      }
        case 6: // YCbCr
            if(compression == COMP_JPEG_TTN2 &&
               sampleSize == 8 && samplesPerPixel == 3) {
                // Set color conversion flag.
                colorConvertJPEG = param.getJPEGDecompressYCbCrToRGB();

                // Set type to RGB if color converting.
                imageType = colorConvertJPEG ? TYPE_RGB : TYPE_GENERIC;
            } else {
                TIFFField chromaField = dir.getField(TIFF_YCBCR_SUBSAMPLING);
                if(chromaField != null) {
                    chromaSubH = chromaField.getAsInt(0);
                    chromaSubV = chromaField.getAsInt(1);
                } else {
                    chromaSubH = chromaSubV = 2;
                }

                if(chromaSubH*chromaSubV == 1) {
                    imageType = TYPE_GENERIC;
                } else if(sampleSize == 8 && samplesPerPixel == 3) {
                    imageType = TYPE_YCBCR_SUB;
                }
            }
            break;
        default: // Other including CIE L*a*b*, unknown.
            if(sampleSize % 8 == 0) {
                imageType = TYPE_GENERIC;
            }
        }

        // Bail out if not one of the supported types.
        if(imageType == TYPE_UNSUPPORTED) {
            throw new RuntimeException(JaiI18N.getString("TIFFImage4"));
        }

  // Set basic image layout
        minX = minY = 0;
  width = (int)(getField(dir,
             TIFFImageDecoder.TIFF_IMAGE_WIDTH,
             "Image Width").getAsLong(0));

  height = (int)(getField(dir,
        TIFFImageDecoder.TIFF_IMAGE_LENGTH,
        "Image Length").getAsLong(0));

        // Set a preliminary band count. This may be changed later as needed.
        numBands = samplesPerPixel;

  // Figure out if any extra samples are present.
  TIFFField efield = dir.getField(TIFFImageDecoder.TIFF_EXTRA_SAMPLES);
        int extraSamples = efield == null ? 0 : (int)efield.getAsLong(0);

  if (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS) != null) {
      // Image is in tiled format
            isTiled = true;

            tileWidth = (int)(getField(dir,
               TIFFImageDecoder.TIFF_TILE_WIDTH,
               "Tile Width").getAsLong(0));
      tileHeight = (int)(getField(dir,
          TIFFImageDecoder.TIFF_TILE_LENGTH,
          "Tile Length").getAsLong(0));
      tileOffsets =
    (getField(dir,
       TIFFImageDecoder.TIFF_TILE_OFFSETS,
       "Tile Offsets")).getAsLongs();

      tileByteCounts = getFieldAsLongs(
                 getField(dir,
                          TIFFImageDecoder.TIFF_TILE_BYTE_COUNTS,
                          "Tile Byte Counts"));

        } else {

            // Image is in stripped format, looks like tiles to us
            isTiled = false;

            // Note: Some legacy files may have tile width and height
            // written but use the strip offsets and byte counts fields
            // instead of the tile offsets and byte counts. Therefore
            // we default here to the tile dimensions if they are written.
            tileWidth =
                dir.getField(TIFFImageDecoder.TIFF_TILE_WIDTH) != null ?
                (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH) :
                width;
      TIFFField field =
                dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP);
      if (field == null) {
    // Default is infinity (2^32 -1), basically the entire image
    // TODO: Can do a better job of tiling here
    tileHeight =
                    dir.getField(TIFFImageDecoder.TIFF_TILE_LENGTH) != null ?
                    (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH):
                    height;
      } else {
    long l = field.getAsLong(0);
    long infinity = 1;
    infinity = (infinity << 32) - 1;
    if (l == infinity || l > height) {
        // 2^32 - 1 (effectively infinity, entire image is 1 strip)
                    // or RowsPerStrip > ImageLength so clamp as having a tile
                    // larger than the image is pointless.
        tileHeight = height;
    } else {
        tileHeight = (int)l;
    }
      }

      TIFFField tileOffsetsField =
    getField(dir,
       TIFFImageDecoder.TIFF_STRIP_OFFSETS,
       "Strip Offsets");
      tileOffsets = getFieldAsLongs(tileOffsetsField);

      TIFFField tileByteCountsField =
                dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS);
            if(tileByteCountsField == null) {
                // Attempt to infer the number of bytes in each strip.
                int totalBytes = ((sampleSize+7)/8)*numBands*width*height;
                int bytesPerStrip =
                    ((sampleSize+7)/8)*numBands*width*tileHeight;
                int cumulativeBytes = 0;
                tileByteCounts = new long[tileOffsets.length];
                for(int i = 0; i < tileOffsets.length; i++) {
                    tileByteCounts[i] =
                        Math.min(totalBytes - cumulativeBytes,
                                 bytesPerStrip);
                    cumulativeBytes += bytesPerStrip;
                }

                if(compression != COMP_NONE) {
                    // Replace the stream with one that will not throw
                    // an EOFException when it runs past the end.
                    this.stream = new NoEOFStream(stream);
                }
            } else {
                tileByteCounts = getFieldAsLongs(tileByteCountsField);
            }

            // Uncompressed image provided in a single tile: clamp to max bytes.
            int maxBytes = width*height*numBands*((sampleSize + 7)/8);
            if(tileByteCounts.length == 1 &&
               compression == COMP_NONE &&
               tileByteCounts[0] > maxBytes) {
                tileByteCounts[0] = maxBytes;
            }
  }

  // Calculate number of tiles and the tileSize in bytes
        tilesX = (width + tileWidth - 1)/tileWidth;
        tilesY = (height + tileHeight - 1)/tileHeight;
        tileSize = tileWidth * tileHeight * numBands;

  // Check whether big endian or little endian format is used.
  isBigEndian = dir.isBigEndian();

  TIFFField fillOrderField =
      dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER);
  if (fillOrderField != null) {
      fillOrder = fillOrderField.getAsInt(0);
  } else {
      // Default Fill Order
      fillOrder = 1;
  }

  switch(compression) {
        case COMP_NONE:
        case COMP_PACKBITS:
            // Do nothing.
            break;
        case COMP_DEFLATE:
            inflater = new Inflater();
            break;
        case COMP_FAX_G3_1D:
        case COMP_FAX_G3_2D:
        case COMP_FAX_G4_2D:
            if(sampleSize != 1) {
                throw new RuntimeException(JaiI18N.getString("TIFFImage7"));
            }

            // Fax T.4 compression options
            if (compression == 3) {
                TIFFField t4OptionsField =
                    dir.getField(TIFFImageDecoder.TIFF_T4_OPTIONS);
                if (t4OptionsField != null) {
                    tiffT4Options = t4OptionsField.getAsLong(0);
                } else {
                    // Use default value
                    tiffT4Options = 0;
                }
            }

            // Fax T.6 compression options
            if (compression == 4) {
                TIFFField t6OptionsField =
                    dir.getField(TIFFImageDecoder.TIFF_T6_OPTIONS);
                if (t6OptionsField != null) {
                    tiffT6Options = t6OptionsField.getAsLong(0);
                } else {
                    // Use default value
                    tiffT6Options = 0;
                }
            }

            // Fax encoding, need to create the Fax decoder.
            decoder = new TIFFFaxDecoder(fillOrder,
                                         tileWidth, tileHeight);
            break;

        case COMP_LZW:
            // LZW compression used, need to create the LZW decoder.
            TIFFField predictorField =
                dir.getField(TIFFImageDecoder.TIFF_PREDICTOR);

            if (predictorField == null) {
                predictor = 1;
            } else {
                predictor = predictorField.getAsInt(0);

                if (predictor != 1 && predictor != 2) {
                    throw new RuntimeException(JaiI18N.getString("TIFFImage8"));
                }

                if (predictor == 2 && sampleSize != 8) {
                    throw new RuntimeException(sampleSize +
                                               JaiI18N.getString("TIFFImage9"));
                }
            }

            lzwDecoder = new TIFFLZWDecoder(tileWidth, predictor,
                                            samplesPerPixel);
            break;

        case COMP_JPEG_OLD:
            throw new RuntimeException(JaiI18N.getString("TIFFImage15"));

        case COMP_JPEG_TTN2:
            if(!(sampleSize == 8 &&
                 ((imageType == TYPE_GRAY && samplesPerPixel == 1) ||
                  (imageType == TYPE_PALETTE && samplesPerPixel == 1) ||
                  (imageType == TYPE_RGB && samplesPerPixel == 3)))) {
                throw new RuntimeException(JaiI18N.getString("TIFFImage16"));
            }

            // Create decodeParam from JPEGTables field if present.
            if(dir.isTagPresent(TIFF_JPEG_TABLES)) {
                TIFFField jpegTableField = dir.getField(TIFF_JPEG_TABLES);
                byte[] jpegTable = jpegTableField.getAsBytes();
                ByteArrayInputStream tableStream =
                    new ByteArrayInputStream(jpegTable);
                JPEGImageDecoder decoder =
                    JPEGCodec.createJPEGDecoder(tableStream);
                decoder.decodeAsRaster();
                decodeParam = decoder.getJPEGDecodeParam();
            }

            break;
        default:
            throw new RuntimeException(JaiI18N.getString("TIFFImage10"));
  }

        switch(imageType) {
        case TYPE_BILEVEL:
        case TYPE_GRAY_4BIT:
            sampleModel =
                new MultiPixelPackedSampleModel(dataType,
                                                tileWidth,
                                                tileHeight,
                                                sampleSize);
            if(imageType == TYPE_BILEVEL) {
                byte[] map = new byte[] {(byte)(isWhiteZero ? 255 : 0),
                                         (byte)(isWhiteZero ? 0 : 255)};
    colorModel = new IndexColorModel(1, 2, map, map, map);
            } else {
                colorModel =
                    ImageCodec.createGrayIndexColorModel(sampleModel,
                                                         !isWhiteZero);
            }
            break;

        case TYPE_GRAY:
        case TYPE_GRAY_ALPHA:
        case TYPE_RGB:
        case TYPE_RGB_ALPHA:
  case TYPE_CMYK:
            // Create a pixel interleaved SampleModel with decreasing
            // band offsets.
            int[] RGBOffsets = new int[numBands];
            if(compression == COMP_JPEG_TTN2) {
                for (int i=0; i<numBands; i++) {
                    RGBOffsets[i] = numBands - 1 - i;
                }
            } else {
                for (int i=0; i<numBands; i++) {
                    RGBOffsets[i] = i;
                }
            }
            sampleModel = createPixelInterleavedSampleModel(dataType,
                                                            tileWidth,
                                                            tileHeight,
                                                            numBands,
                                                            numBands*tileWidth,
                                                            RGBOffsets);

            if(imageType == TYPE_GRAY || imageType == TYPE_RGB) {
                colorModel =
                    ImageCodec.createComponentColorModel(sampleModel);
            } else if (imageType == TYPE_CMYK) {
    colorModel = ImageCodec.createComponentColorModel(sampleModel,
                  SimpleCMYKColorSpace.getInstance());
      } else { // hasAlpha
                // Transparency.OPAQUE signifies image data that is
                // completely opaque, meaning that all pixels have an alpha
                // value of 1.0. So the extra band gets ignored, which is
                // what we want.
                int transparency = Transparency.OPAQUE;
                if(extraSamples == 1 || extraSamples == 2) {
        // associated (premultiplied) alpha when == 1
        // unassociated alpha when ==2
        // Fix bug: 4699316
                    transparency = Transparency.TRANSLUCENT;
                }

                colorModel =
                    createAlphaComponentColorModel(dataType,
                                                   numBands,
                                                   extraSamples == 1,
               transparency);
            }
            break;

        case TYPE_GENERIC:
        case TYPE_YCBCR_SUB:
            // For this case we can't display the image, so we create a
            // SampleModel with increasing bandOffsets, and keep the
            // ColorModel as null, as there is no appropriate ColorModel.

            int[] bandOffsets = new int[numBands];
            for (int i=0; i<numBands; i++) {
                bandOffsets[i] = i;
            }

            sampleModel =
                createPixelInterleavedSampleModel(dataType,
                                                  tileWidth, tileHeight,
                                                  numBands, numBands * tileWidth,
                                                  bandOffsets);
            colorModel = null;
            break;

        case TYPE_PALETTE:
      // Get the colormap
      TIFFField cfield = getField(dir, TIFFImageDecoder.TIFF_COLORMAP,
          "Colormap");
      colormap = cfield.getAsChars();

      // Could be either 1 or 3 bands depending on whether we use
      // IndexColorModel or not.
      if (decodePaletteAsShorts) {
    numBands = 3;
View Full Code Here

TOP

Related Classes of com.lightcrafts.media.jai.codec.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.