Package net.sourceforge.jiu.codecs.tiff

Source Code of net.sourceforge.jiu.codecs.tiff.TIFFImageFileDirectory

/*
* TIFFImageFileDirectory
*
* Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Marco Schmidt.
* All rights reserved.
*/

package net.sourceforge.jiu.codecs.tiff;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.Vector;
import net.sourceforge.jiu.codecs.InvalidFileStructureException;
import net.sourceforge.jiu.codecs.UnsupportedTypeException;
import net.sourceforge.jiu.codecs.tiff.TIFFConstants;
import net.sourceforge.jiu.codecs.tiff.TIFFTag;
import net.sourceforge.jiu.data.Palette;
import net.sourceforge.jiu.data.RGBIndex;

/**
* This class encapsulates all data of a TIFF image file directory (IFD).
* @author Marco Schmidt
*/
public class TIFFImageFileDirectory implements TIFFConstants
{
  public static final int TYPE_BILEVEL_PACKED = 0;
  public static final int TYPE_GRAY4 = 1;
  public static final int TYPE_GRAY8 = 2;
  public static final int TYPE_GRAY16 = 3;
  public static final int TYPE_PALETTED4 = 4;
  public static final int TYPE_PALETTED8 = 5;
  public static final int TYPE_RGB24_INTERLEAVED = 6;
  public static final int TYPE_RGB48_INTERLEAVED = 7;
  public static final int TYPE_BILEVEL_BYTE = 8;
  public static final int TYPE_CMYK32_INTERLEAVED = 9;
  public static final int TYPE_CMYK32_PLANAR = 10;
  public static final int TYPE_LOGLUV32_INTERLEAVED = 11;
  public static final int TYPE_LOGL = 12;

  private String artist;
  private int[] bitsPerSample;
  private int bitsPerPixel;
  private int bitsPerRow;
  private int bytesBetweenSamples;
  private int[] bytesPerSample;
  private int bytesPerRow;
  private int compression;
  private String copyright;
  private Date date;
  private String dateTime;
  private int dpiX;
  private int dpiY;
  private int[] extraSamples;
  private int height;
  private int horizontalTiles;
  private String hostComputer;
  private String imageDescription;
  private int imageType;
  private boolean invertGraySamples;
  private String make;
  private String model;
  private int numStrips;
  private int numTiles;
  private int orientation;
  private Palette palette;
  private int pixelsPerRow;
  private int planarConfiguration;
  private int photometricInterpretation;
  private int predictor;
  private int[] sampleTypes;
  private int resolutionUnit;
  private double resolutionX;
  private double resolutionY;
  private int rowsPerStrip;
  private int samplesPerPixel;
  private String software;
  private Vector stripByteCounts;
  private Vector stripOffsets;
  private int t4Options;
  private int t6Options;
  private Vector tags;
  private Vector tileByteCounts;
  private Vector tileOffsets;
  private TimeZone timeZone;
  private int tileWidth;
  private int tileHeight;
  private int verticalTiles;
  private int width;

  /**
   * Initializes all members to null or -1 and creates an internal list for
   * the tags that will be make up this directory.
   */
  public TIFFImageFileDirectory()
  {
    initMembers();
    tags = new Vector();
  }

  /**
   * Adds a tag to the end of the internal list of tags.
   * @param tag the TIFFTag instance to be appended
   */
  public void append(TIFFTag tag)
  {
    tags.addElement(tag);
  }

  private void checkContent() throws
    InvalidFileStructureException,
    UnsupportedTypeException
  {
    if (width < 1)
    {
      throw new InvalidFileStructureException("No valid width available.");
    }
    if (height < 1)
    {
      throw new InvalidFileStructureException("No valid width available.");
    }
    if (stripOffsets != null)
    {
      pixelsPerRow = width;
    }
    else
    if (tileOffsets != null)
    {
      pixelsPerRow = tileWidth;
    }
    if (rowsPerStrip == -1 && stripOffsets != null && stripOffsets.size() == 1)
    {
      rowsPerStrip = height;
    }
    // do more checks based on color type
    switch (photometricInterpretation)
    {
      case(PHOTOMETRIC_BLACK_IS_ZERO):
      case(PHOTOMETRIC_WHITE_IS_ZERO):
      {
        if (bitsPerSample[0] == 1)
        {
          imageType = TYPE_BILEVEL_PACKED;
        }
        else
        {
          if (bitsPerSample[0] == 4)
          {
            imageType = TYPE_GRAY4;
          }
          else
          if (bitsPerSample[0] == 8)
          {
            imageType = TYPE_GRAY8;
          }
          else
          {
            throw new UnsupportedTypeException("Only bit depths 1, 4 and 8 are supported for bilevel and grayscale images.");
          }
        }
        break;
      }
      case(PHOTOMETRIC_PALETTED):
      {
        if (getPalette() == null)
        {
          throw new InvalidFileStructureException("No palette found in paletted image.");
        }
        break;
      }
      case(PHOTOMETRIC_TRUECOLOR_RGB):
      {
        if (planarConfiguration != PLANAR_CONFIGURATION_CHUNKY)
        {
          throw new UnsupportedTypeException("Cannot handle planar configuration other than chunky for RGB images.");
        }
        if (bitsPerSample.length != 3)
        {
          throw new UnsupportedTypeException("Found RGB truecolor image, but instead of three " + bitsPerSample.length + " component(s).");
        }
        if (bitsPerPixel == 24)
        {
          imageType = TYPE_RGB24_INTERLEAVED;
        }
        else
        if (bitsPerPixel == 48)
        {
          imageType = TYPE_RGB48_INTERLEAVED;
        }
        else
        {
          throw new UnsupportedTypeException("Unsupported RGB truecolor image color depth: " + bitsPerPixel + ".");
        }
        break;
      }
      case(PHOTOMETRIC_TRUECOLOR_LOGLUV):
      {
        if (planarConfiguration == PLANAR_CONFIGURATION_CHUNKY)
        {
          imageType = TYPE_LOGLUV32_INTERLEAVED;
        }
        else
        {
          throw new UnsupportedTypeException("Cannot handle planar configuration other than chunky for RGB images.");
        }
        break;
      }
      case(PHOTOMETRIC_LOGL):
      {
        imageType = TYPE_LOGL;
        break;
      }
      case(PHOTOMETRIC_TRUECOLOR_CMYK):
      {
        if (planarConfiguration == PLANAR_CONFIGURATION_CHUNKY)
        {
          imageType = TYPE_CMYK32_INTERLEAVED;
        }
        /*else
        if (planarConfiguration == PLANAR_CONFIGURATION_PLANAR)
        {
          imageType = TYPE_CMYK32_PLANAR;
        }*/
        else
        {
          throw new UnsupportedTypeException("Cannot handle planar configuration other than chunky for CMYK images.");
        }
        break;
      }
      default:
      {
        throw new UnsupportedTypeException("Unsupported color type: "  + photometricInterpretation + ".");
      }
    }
    if (compression == COMPRESSION_CCITT_GROUP3_1D_MODIFIED_HUFFMAN)
    {
      if (bitsPerPixel != 1)
      {
        throw new UnsupportedTypeException("Number of bits per pixel must be 1 for " +
          "compression type: " + getCompressionName(compression) + ".");
      }
      imageType = TYPE_BILEVEL_BYTE;
    }
    // TODO more validity checks
  }

  /**
   * TODO: regard extra samples
   */
  public int computeNumBytes(int numPixels)
  {
    if (bitsPerPixel == 1)
    {
      if (imageType == TYPE_BILEVEL_BYTE)
      {
        return numPixels;
      }
      else
      {
        return (numPixels + 7) / 8;
      }
    }
    else
    if (bitsPerPixel <= 4)
    {
      return (numPixels + 1) / 2;
    }
    else
    if (bitsPerPixel <= 8)
    {
      return numPixels;
    }
    else
    if (bitsPerPixel == 16)
    {
      return numPixels * 2;
    }
    else
    if (bitsPerPixel == 24)
    {
      return numPixels * 3;
    }
    else
    if (bitsPerPixel == 32)
    {
      return numPixels * 4;
    }
    else
    if (bitsPerPixel == 48)
    {
      return numPixels * 6;
    }
    else
    {
      return -1;
    }
  }

  /**
   * Returns information on the person who created the image
   * (as stored in tag {@link TIFFConstants#TAG_ARTIST}).
   */
  public String getArtist()
  {
    return artist;
  }

  /**
   * Returns the number of bits per pixel (not including transparency information).
   */
  public int getBitsPerPixel()
  {
    return bitsPerPixel;
  }

  /**
   * Returns the number of compressed byte for a given tile.
   * Tile index must not be negative and must be smaller than the number of tiles.
   * @param tileIndex zero-based index of tile or strip for which the number of compressed bytes is to be returned
   */
  public int getByteCount(int tileIndex)
  {
    if (stripByteCounts != null)
    {
      return ((Number)stripByteCounts.elementAt(tileIndex)).intValue();
    }
    else
    if (tileByteCounts != null)
    {
      return ((Number)tileByteCounts.elementAt(tileIndex)).intValue();
    }
    else
    {
      return 0;
    }
  }

  public int getBytesPerRow()
  {
    return computeNumBytes(getTileWidth());
  }

  /**
   * Returns the compression method, encoded as a number as found in
   * {@link TIFFConstants} (more specifically, the COMPRESSION_xyz constants).
   * Use {@link #getCompressionName(int)} to get the English name
   * of this compression method.
   * @return compression method
   */
  public int getCompression()
  {
    return compression;
  }

  /**
   * Returns the name of a TIFF compression method.
   * If the name is unknown, <em>Unknown method</em> plus
   * the method number is returned.
   * This static method can be used in combination with the value from
   * {@link #getCompression}.
   * @param method the compression method number
   * @return the compression method name
   */
  public static String getCompressionName(int method)
  {
    switch(method)
    {
      case(COMPRESSION_CCITT_GROUP3_1D_MODIFIED_HUFFMAN): return "CCITT Group 3 1D Modified Huffman";
      case(COMPRESSION_CCITT_T4): return "CCITT T.4";
      case(COMPRESSION_CCITT_T6): return "CCITT T.6";
      case(COMPRESSION_DEFLATED_INOFFICIAL): return "Deflated (inofficial, 32496)";
      case(COMPRESSION_DEFLATED_OFFICIAL): return "Deflated (official, 8)";
      case(COMPRESSION_LZW): return "LZW";
      case(COMPRESSION_NONE): return "Uncompressed";
      case(COMPRESSION_PACKBITS): return "Packbits";
      case(6): return "JPEG (old style)";
      case(7):return "JPEG (new style)";
      case(103): return "Pegasus IMJ";
      case(32766): return "NeXT 2-bit RLE";
      case(32771): return "Uncompressed, word-aligned";
      case(32809): return "Thunderscan RLE";
      case(32895): return "IT8 CT with padding";
      case(32896): return "IT8 Linework RLE";
      case(32897): return "IT8 Monochrome picture";
      case(32898): return "IT8 Binary line art";
      case(32908): return "Pixar 10 bit LZW";
      case(32909): return "Pixar 11 bit ZIP";
      case(32947): return "Kodak DCS";
      case(34661): return "ISO JBIG";
      case(34676): return "SGI Log Luminance RLE";
      case(34677): return "SGI Log 24-bit packed";
      default: return "Unknown method (" + method + ")";
    }
  }

  public String getCopyright()
  {
    return copyright;
  }

  /**
   * If a date / time tag was found in this image file directory and
   * {@link #initFromTags} was called already, it was attempted to
   * create a {@link java.util.Date} object from it.
   * This object (or <code>null</code>) is returned.
   * Use {@link #setTimeZone} to provide a time zone before the date
   * parsing is done.
   * @see #getDateTimeString
   */
  public Date getDateTime()
  {
    return date;
  }

  /**
   * If there was a date / time tag in this IFD, its String value
   * is returned.
   * @see #getDateTime
   */
  public String getDateTimeString()
  {
    return dateTime;
  }

  public int getDpiX()
  {
    return dpiX;
  }

  public int getDpiY()
  {
    return dpiY;
  }

  public int getHeight()
  {
    return height;
  }

  public String getHostComputer()
  {
    return hostComputer;
  }

  public String getImageDescription()
  {
    return imageDescription;
  }

  public int getImageType()
  {
    return imageType;
  }

  public String getModel()
  {
    return model;
  }

  public int getNumHorizontalTiles()
  {
    return horizontalTiles;
  }

  public int getNumStrips()
  {
    return numStrips;
  }

  public int getNumTiles()
  {
    return numTiles;
  }

  public int getNumVerticalTiles()
  {
    return verticalTiles;
  }

  public Palette getPalette()
  {
    return palette;
  }

  public int getPhotometricInterpretation()
  {
    return photometricInterpretation;
  }

  public int getPredictor()
  {
    return predictor;
  }

  public int getRowsPerStrip()
  {
    return rowsPerStrip;
  }

  public int getSamplesPerPixel()
  {
    return samplesPerPixel;
  }

  public String getSoftware()
  {
    return software;
  }

  public Vector getStripOffsets()
  {
    return stripOffsets;
  }

  public int getT4Options()
  {
    return t4Options;
  }

  public int getT6Options()
  {
    return t6Options;
  }

  public int getTileHeight()
  {
    return tileHeight;
  }

  public long getTileOffset(int tileIndex)
  {
    if (stripOffsets != null)
    {
      Number number = (Number)stripOffsets.elementAt(tileIndex);
      return number.longValue();
    }
    else
    if (tileOffsets != null)
    {
      Number number = (Number)tileOffsets.elementAt(tileIndex);
      return number.longValue();
    }
    else
    {
      throw new IllegalArgumentException("Tile index invalid: " + tileIndex);
    }
  }

  public int getTileWidth()
  {
    return tileWidth;
  }

  public int getTileX1(int tileIndex)
  {
    if (tileIndex < 0 || tileIndex >= getNumTiles())
    {
      throw new IllegalArgumentException("Not a valid tile index: "  + tileIndex);
    }
    else
    {
      return (tileIndex % getNumHorizontalTiles()) * getTileWidth();
    }
  }

  public int getTileX2(int tileIndex)
  {
    if (tileIndex < 0 || tileIndex >= getNumTiles())
    {
      throw new IllegalArgumentException("Not a valid tile index: "  + tileIndex);
    }
    else
    {
      return ((tileIndex % getNumHorizontalTiles()) + 1) * getTileWidth() - 1;
    }
  }

  public int getTileY1(int tileIndex)
  {
    if (tileIndex < 0 || tileIndex >= getNumTiles())
    {
      throw new IllegalArgumentException("Not a valid tile index: "  + tileIndex);
    }
    else
    {
      return (tileIndex % getNumVerticalTiles()) * getTileHeight();
    }
  }

  public int getTileY2(int tileIndex)
  {
    if (tileIndex < 0 || tileIndex >= getNumTiles())
    {
      throw new IllegalArgumentException("Not a valid tile index: "  + tileIndex);
    }
    else
    {
      int result = ((tileIndex % getNumVerticalTiles()) + 1) * getTileHeight() - 1;
      if (result >= height)
      {
        result = height - 1;
      }
      return result;
    }
  }

  public int getWidth()
  {
    return width;
  }

  public void initMembers()
  {
    bitsPerPixel = -1;
    bitsPerSample = null;
    compression = -1;
    height = -1;
    horizontalTiles = -1;
    invertGraySamples = false;
    numStrips = -1;
    numTiles = -1;
    orientation = 1;
    photometricInterpretation = -1;
    planarConfiguration = -1;
    resolutionUnit = 2;
    resolutionX = -1.0;
    resolutionY = -1.0;
    rowsPerStrip = -1;
    stripOffsets = null;
    tags = null;
    tileOffsets = null;
    tileWidth = -1;
    tileHeight = -1;
    verticalTiles = -1;
    width = -1;
  }

  public void initFromTags(boolean check) throws
    InvalidFileStructureException,
    UnsupportedTypeException
  {
    int index = 0;
    while (index < tags.size())
    {
      TIFFTag tag = (TIFFTag)tags.elementAt(index++);
      int id = tag.getId();
      int count = tag.getCount();
      int type = tag.getType();
      boolean isNotInt = !tag.isInt();
      switch(id)
      {
        case(TAG_ARTIST):
        {
          artist = tag.getString();
          break;
        }
        case(TAG_BITS_PER_SAMPLE):
        {
          if (isNotInt)
          {
            throw new InvalidFileStructureException("Bits per " +
              "sample value(s) must be byte/short/long; type=" +
              type);
          }
          if (count == 1)
          {
            bitsPerSample = new int[1];
            bitsPerSample[0] = tag.getOffset();
            bitsPerPixel = bitsPerSample[0];
          }
          else
          {
            bitsPerPixel = 0;
            bitsPerSample = new int[count];
            for (int i = 0; i < count; i++)
            {
              bitsPerSample[i] = tag.getElementAsInt(i);
              if (bitsPerSample[i] < 1)
              {
                throw new InvalidFileStructureException("Bits per " +
                  "sample value #" + i + " is smaller than 1.");
              }
              bitsPerPixel += bitsPerSample[i];
            }
          }
          break;
        }
        case(TAG_COLOR_MAP):
        {
          if ((count % 3) != 0)
          {
            throw new InvalidFileStructureException("Number of palette entries must be divideable by three without rest; " + count);
          }
          if (count < 3 || count > 768)
          {
            throw new UnsupportedTypeException("Unsupported number of palette entries: " + count + ".");
          }
          if (type != TAG_TYPE_SHORT)
          {
            throw new UnsupportedTypeException("Unsupported number type for palette entries: " + type);
          }
          int numEntries = count / 3;
          palette = new Palette(numEntries, 255);
          int vectorIndex = 0;
          for (int paletteIndex = 0; paletteIndex < numEntries; paletteIndex++)
          {
            palette.putSample(RGBIndex.INDEX_RED, paletteIndex, tag.getElementAsInt(vectorIndex++) >> 8);
          }
          for (int paletteIndex = 0; paletteIndex < numEntries; paletteIndex++)
          {
            palette.putSample(RGBIndex.INDEX_GREEN, paletteIndex, tag.getElementAsInt(vectorIndex++) >> 8);
          }
          for (int paletteIndex = 0; paletteIndex < numEntries; paletteIndex++)
          {
            palette.putSample(RGBIndex.INDEX_BLUE, paletteIndex, tag.getElementAsInt(vectorIndex++) >> 8);
          }
          break;
        }
        case(TAG_COMPRESSION):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              " single byte/short/long value for compression " +
              "(count=" + count + ", type=" + type + ").");
          }
          compression = tag.getOffset();
          break;
        }
        case(TAG_DATE_TIME):
        {
          dateTime = tag.getString();
          if (dateTime != null)
          {
            dateTime = dateTime.trim();
          }
          if (dateTime != null)
          {
            SimpleDateFormat format = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
            if (timeZone != null)
            {
              format.setCalendar(new GregorianCalendar(timeZone));
            }
            try
            {
              date = format.parse(dateTime);
            }
            catch (ParseException pe)
            {
              date = null;
            }
          }
          break;
        }
        case(TAG_HOST_COMPUTER):
        {
          hostComputer = tag.getString();
          break;
        }
        case(TAG_IMAGE_DESCRIPTION):
        {
          imageDescription = tag.getString();
          break;
        }
        case(TAG_IMAGE_WIDTH):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for image width " +
              "(count=" + count + ", type=" + type + ").");
          }
          width = tag.getOffset();
          break;
        }
        case(TAG_IMAGE_LENGTH):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for image height " +
              "(count=" + count + ", type=" + type + ").");
          }
          height = tag.getOffset();
          break;
        }
        case(TAG_MAKE):
        {
          make = tag.getString();
          break;
        }
        case(TAG_MODEL):
        {
          model = tag.getString();
          break;
        }
        case(TAG_ORIENTATION):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for image height " +
              "(count=" + count + ", type=" + type + ").");
          }
          orientation = tag.getOffset();
          break;
        }
        case(TAG_PHOTOMETRIC_INTERPRETATION):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for photometric interpretation.");
          }
          photometricInterpretation = tag.getOffset();
          break;
        }
        case(TAG_RESOLUTION_UNIT):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for planar configuration.");
          }
          resolutionUnit = tag.getOffset();
          break;
        }
        case(TAG_RESOLUTION_X):
        {
          if (count != 1 || type != TAG_TYPE_RATIONAL)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for planar configuration.");
          }
          Object o = tag.getObject(0);
          if (o != null && o instanceof TIFFRational)
          {
            TIFFRational rational = (TIFFRational)o;
            resolutionX = rational.getAsDouble();
          }
          break;
        }
        case(TAG_RESOLUTION_Y):
        {
          if (count != 1 || type != TAG_TYPE_RATIONAL)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for planar configuration.");
          }
          Object o = tag.getObject(0);
          if (o != null && o instanceof TIFFRational)
          {
            TIFFRational rational = (TIFFRational)o;
            resolutionY = rational.getAsDouble();
          }
          break;
        }
        case(TAG_PLANAR_CONFIGURATION):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for planar configuration.");
          }
          planarConfiguration = tag.getOffset();
          break;
        }
        case(TAG_ROWS_PER_STRIP):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for image height.");
          }
          rowsPerStrip = tag.getOffset();
          break;
        }
        case(TAG_SAMPLES_PER_PIXEL):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for samples per pixel.");
          }
          samplesPerPixel = tag.getOffset();
          break;
        }
        case(TAG_SOFTWARE):
        {
          software = tag.getString();
          break;
        }
        case(TAG_STRIP_BYTE_COUNTS):
        {
          if (count < 1)
          {
            throw new InvalidFileStructureException("Need at least one strip offset.");
          }
          if (count == 1)
          {
            if (isNotInt)
            {
              throw new InvalidFileStructureException("There is " +
                "only one strip offset, but its type is not integer.");
            }
            stripByteCounts = new Vector();
            stripByteCounts.addElement(new Long(tag.getOffset()));
          }
          else
          {
            stripByteCounts = tag.getVector();
          }
          break;
        }
        case(TAG_STRIP_OFFSETS):
        {
          if (count < 1)
          {
            throw new InvalidFileStructureException("Need at least one strip offset.");
          }
          if (count == 1)
          {
            if (isNotInt)
            {
              throw new InvalidFileStructureException("There is " +
                "only one strip offset, but its type is not integer.");
            }
            stripOffsets = new Vector();
            stripOffsets.addElement(new Long(tag.getOffset()));
          }
          else
          {
            stripOffsets = tag.getVector();
          }
          numStrips = count;
          numTiles = count;
          horizontalTiles = 1;
          verticalTiles = count;
          break;
        }
        case(TAG_T4_OPTIONS):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for T4 Options.");
          }
          t4Options = tag.getOffset();
          break;
        }
        case(TAG_T6_OPTIONS):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for T6 Options.");
          }
          t6Options = tag.getOffset();
          break;
        }
        case(TAG_TILE_HEIGHT):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for image height " +
              "(count=" + count + ", type=" + type + ").");
          }
          tileHeight = tag.getOffset();
          if (tileHeight < 1)
          {
            throw new InvalidFileStructureException("Tile height must be one or larger.");
          }
          verticalTiles = height / tileHeight;
          if ((height % tileHeight) != 0)
          {
            verticalTiles++;
          }
          break;
        }
        case(TAG_TILE_OFFSETS):
        {
          if (count < 1)
          {
            throw new InvalidFileStructureException("Need at least one tile offset.");
          }
          if (count == 1)
          {
            if (isNotInt)
            {
              throw new InvalidFileStructureException("There is " +
                "only one tile offset, but its type is not integer.");
            }
            tileOffsets = new Vector();
            tileOffsets.addElement(new Long(tag.getOffset()));
          }
          else
          {
            tileOffsets = tag.getVector();
          }
          numStrips = count;
          numTiles = count;
          horizontalTiles = 1;
          verticalTiles = count;
          break;
        }
        case(TAG_TILE_WIDTH):
        {
          if (count != 1 || isNotInt)
          {
            throw new InvalidFileStructureException("Expected " +
              "single byte/short/long value for image height " +
              "(count=" + count + ", type=" + type + ").");
          }
          tileWidth = tag.getOffset();
          if (tileWidth < 1)
          {
            throw new InvalidFileStructureException("Tile width must be one or larger.");
          }
          horizontalTiles = width / tileWidth;
          if ((width % tileWidth) != 0)
          {
            horizontalTiles++;
          }
          break;
        }
      }
    }
    if (planarConfiguration == -1)
    {
      planarConfiguration = PLANAR_CONFIGURATION_CHUNKY;
    }
    if (photometricInterpretation == TIFFConstants.PHOTOMETRIC_PALETTED)
    {
      if (bitsPerPixel == 4)
      {
        imageType = TYPE_PALETTED4;
      }
      else
      if (bitsPerPixel == 8)
      {
        imageType = TYPE_PALETTED8;
      }
      else
      {
        throw new UnsupportedTypeException("Only paletted images with 4 or 8 bits per sample are supported.");
      }
    }
    if (resolutionUnit == 2 && resolutionX > 0.0 && resolutionY > 0.0)
    {
      dpiX = (int)resolutionX;
      dpiY = (int)resolutionY;
    }
    if (isStriped())
    {
      tileWidth = width;
      if (numStrips == 1 && rowsPerStrip == -1)
      {
        rowsPerStrip = height;
      }
      tileHeight = rowsPerStrip;
    }
    if (check)
    {
      checkContent();
    }
  }

  public boolean isGrayscale()
  {
    return getBitsPerPixel() > 1 &&
      (photometricInterpretation == PHOTOMETRIC_BLACK_IS_ZERO ||
       photometricInterpretation == PHOTOMETRIC_WHITE_IS_ZERO);
  }

  public boolean isPaletted()
  {
    return (photometricInterpretation == PHOTOMETRIC_PALETTED);
  }

  /**
   * Returns <code>true</code> if the image belonging to this IFD
   * is stored as strips, <code>false</code> otherwise.
   * @see #isTiled
   */
  public boolean isStriped()
  {
    return (stripOffsets != null);
  }

  /**
   * Returns <code>true</code> if the image belonging to this IFD
   * is stored as tiles, <code>false</code> otherwise.
   * @see #isStriped
   */
  public boolean isTiled()
  {
    return (tileOffsets != null);
  }

  /**
   * Sets the time zone to be used when trying to interpret dates
   * found in a {@link #TAG_DATE_TIME} tag.
   * Example call:
   * <code>setTimeZone(TimeZone.getTimeZone("America/New_York");</code>.
   * @param tz TimeZone object
   */
  public void setTimeZone(TimeZone tz)
  {
    timeZone = tz;
  }
}
TOP

Related Classes of net.sourceforge.jiu.codecs.tiff.TIFFImageFileDirectory

TOP
Copyright © 2018 www.massapi.com. 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.