You are viewing a plain text version of this content. The canonical link for it is here.
Posted to sanselan-commits@incubator.apache.org by cm...@apache.org on 2007/11/17 21:58:40 UTC
svn commit: r596008 [11/15] - in /incubator/sanselan/trunk/src:
main/java/org/apache/sanselan/ main/java/org/apache/sanselan/color/
main/java/org/apache/sanselan/common/
main/java/org/apache/sanselan/common/byteSources/
main/java/org/apache/sanselan/co...
Added: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/TiffImageParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/TiffImageParser.java?rev=596008&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/TiffImageParser.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/TiffImageParser.java Sat Nov 17 13:58:22 2007
@@ -0,0 +1,1222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cmc.sanselan.formats.tiff;
+
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.Vector;
+
+import org.cmc.sanselan.FormatCompliance;
+import org.cmc.sanselan.ImageFormat;
+import org.cmc.sanselan.ImageInfo;
+import org.cmc.sanselan.ImageParser;
+import org.cmc.sanselan.ImageReadException;
+import org.cmc.sanselan.ImageWriteException;
+import org.cmc.sanselan.common.IImageMetadata;
+import org.cmc.sanselan.common.byteSources.ByteSource;
+import org.cmc.sanselan.common.byteSources.ByteSourceArray;
+import org.cmc.sanselan.common.byteSources.ByteSourceFile;
+import org.cmc.sanselan.formats.tiff.TiffDirectory.ImageDataElement;
+import org.cmc.sanselan.formats.tiff.datareaders.DataReader;
+import org.cmc.sanselan.formats.tiff.datareaders.DataReaderStrips;
+import org.cmc.sanselan.formats.tiff.datareaders.DataReaderTiled;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreter;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterBiLevel;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterCIELAB;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterCMYK;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterLogLUV;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterPalette;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterRGB;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterYCbCr;
+import org.cmc.sanselan.formats.tiff.write.TiffImageWriter;
+import org.cmc.sanselan.util.Debug;
+
+public class TiffImageParser extends ImageParser implements TiffConstants
+{
+ public TiffImageParser()
+ {
+ // setDebug(true);
+ }
+
+ public String getName()
+ {
+ return "Tiff-Custom";
+ }
+
+ public String getDefaultExtension()
+ {
+ return DEFAULT_EXTENSION;
+ }
+
+ private static final String DEFAULT_EXTENSION = ".tif";
+
+ private static final String ACCEPTED_EXTENSIONS[] = {
+ ".tif", ".tiff",
+ };
+
+ protected String[] getAcceptedExtensions()
+ {
+ return ACCEPTED_EXTENSIONS;
+ }
+
+ protected ImageFormat[] getAcceptedTypes()
+ {
+ return new ImageFormat[]{
+ ImageFormat.IMAGE_FORMAT_TIFF, //
+ };
+ }
+
+ private TiffHeader readTiffHeader(InputStream is,
+ FormatCompliance formatCompliance) throws ImageReadException,
+ IOException
+ {
+ int BYTE_ORDER_1 = readByte("BYTE_ORDER_1", is, "Not a Valid TIFF File");
+ int BYTE_ORDER_2 = readByte("BYTE_ORDER_2", is, "Not a Valid TIFF File");
+ setByteOrder(BYTE_ORDER_1, BYTE_ORDER_2);
+
+ int tiffVersion = read2Bytes("tiffVersion", is, "Not a Valid TIFF File");
+ if (tiffVersion != 42)
+ throw new ImageReadException("Unknown Tiff Version: " + tiffVersion);
+
+ int offsetToFirstIFD = read4Bytes("offsetToFirstIFD", is,
+ "Not a Valid TIFF File");
+
+ skipBytes(is, offsetToFirstIFD - 8,
+ "Not a Valid TIFF File: couldn't find IFDs");
+
+ if (debug)
+ System.out.println("");
+
+ return new TiffHeader(BYTE_ORDER_1, tiffVersion, offsetToFirstIFD);
+
+ }
+
+ private boolean keepField(int Tag, int tags[])
+ {
+ if (tags == null)
+ return true;
+
+ for (int i = 0; i < tags.length; i++)
+ {
+ if (tags[i] == Tag)
+ return true;
+ }
+
+ return false;
+ }
+
+ private static final int TAG_ICC_PROFILE = 34675;
+
+ private TiffDirectory readDirectory(InputStream is, int dirType,
+ int offset, int tags[], int maxEntriesToMatch)
+ throws ImageReadException, IOException
+ {
+ Vector result = new Vector();
+
+ int entryCount = read2Bytes("DirectoryEntryCount", is,
+ "Not a Valid TIFF File");
+
+ // Debug.debug();
+ // Debug.debug("readDirectory entryCount", entryCount);
+
+ for (int i = 0; i < entryCount; i++)
+ {
+ int tag = read2Bytes("Tag", is, "Not a Valid TIFF File");
+ int type = read2Bytes("Type", is, "Not a Valid TIFF File");
+ int length = read4Bytes("Length", is, "Not a Valid TIFF File");
+
+ byte valueOffsetBytes[] = readByteArray("ValueOffset", 4, is,
+ "Not a Valid TIFF File");
+ int valueOffset = convertByteArrayToInt("ValueOffset",
+ valueOffsetBytes);
+
+ if (keepField(tag, tags))
+ {
+ TiffField entry = new TiffField(tag, type, length, valueOffset,
+ valueOffsetBytes, getByteOrder());
+ result.add(entry);
+
+ // Debug.debug("read field tag", tag + ", 0x"
+ // + Integer.toHexString(tag));
+
+ if (debug)
+ for (int j = 0; j < 4; j++)
+ System.out
+ .println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+
+ if ((maxEntriesToMatch > 0)
+ && (result.size() >= maxEntriesToMatch))
+ {
+ return new TiffDirectory(dirType, result, offset, -1);
+ }
+ }
+
+ }
+
+ int nextDirectoryOffset = read4Bytes("nextDirectoryOffset", is,
+ "Not a Valid TIFF File");
+ if (debug)
+ System.out.println("");
+
+ return new TiffDirectory(dirType, result, offset, nextDirectoryOffset);
+ }
+
+ private TiffContents readDirectories(ByteSource byteSource, int tags[],
+ FormatCompliance formatCompliance) throws ImageReadException,
+ IOException
+ {
+ return readDirectories(byteSource, tags, -1, -1, formatCompliance);
+ }
+
+ private TiffContents readDirectories(ByteSource byteSource, int tags[],
+ int maxDirectoriesToRead, int maxEntriesToMatch,
+ FormatCompliance formatCompliance) throws ImageReadException,
+ IOException
+ {
+ TiffHeader tiffHeader;
+ InputStream is = null;
+ try
+ {
+ is = byteSource.getInputStream();
+ tiffHeader = readTiffHeader(is, formatCompliance);
+ }
+ finally
+ {
+ try
+ {
+ if (is != null)
+ is.close();
+ }
+ catch (Exception e)
+ {
+ Debug.debug(e);
+ }
+ }
+
+ Vector directories = new Vector();
+
+ int offset = tiffHeader.offsetToFirstIFD;
+ for (int count = 0; (offset > 0)
+ && ((maxDirectoriesToRead < 1) || (directories.size() < maxDirectoriesToRead)); count++)
+ {
+ int dirType;
+ if (0 == count)
+ dirType = TiffDirectory.DIRECTORY_TYPE_ROOT;
+ else
+ dirType = TiffDirectory.DIRECTORY_TYPE_SUB;
+
+ TiffDirectory directory = readSingleDirectory(byteSource, dirType,
+ offset, formatCompliance);
+ if (directory.entries.size() > 0)
+ directories.add(directory);
+ offset = directory.nextDirectoryOffset;
+ }
+
+ return new TiffContents(tiffHeader, directories);
+
+ }
+
+ private TiffDirectory readSingleDirectory(ByteSource byteSource,
+ int dirType, int offset, FormatCompliance formatCompliance)
+ throws ImageReadException, IOException
+ {
+ int tags[] = null;
+ int maxEntriesToMatch = -1;
+ return readSingleDirectory(byteSource, dirType, offset, tags,
+ maxEntriesToMatch, formatCompliance);
+ }
+
+ private TiffDirectory readSingleDirectory(ByteSource byteSource,
+ int dirType, int offset, int tags[], int maxEntriesToMatch,
+ FormatCompliance formatCompliance) throws ImageReadException,
+ IOException
+ {
+ InputStream is = null;
+ try
+ {
+ is = byteSource.getInputStream();
+ // Debug.debug("readSingleDirectory offset", offset);
+ if (offset > 0)
+ is.skip(offset);
+
+ TiffDirectory directory = readDirectory(is, dirType, offset, tags,
+ maxEntriesToMatch);
+
+ directory.fillInValues(byteSource);
+
+ return directory;
+ }
+ finally
+ {
+ try
+ {
+ if (is != null)
+ is.close();
+ }
+ catch (Exception e)
+ {
+ Debug.debug(e);
+ }
+ }
+ }
+
+ public byte[] getICCProfileBytes(ByteSource byteSource)
+ throws ImageReadException, IOException
+ {
+ int FieldTypes[] = new int[]{
+ TAG_ICC_PROFILE,
+ };
+
+ TiffContents contents = readDirectories(byteSource, FieldTypes, -1, 1,
+ getDefaultFormatCompliance());
+ if (contents == null)
+ throw new ImageReadException("TIFF missing contents");
+
+ Vector directories = contents.directories;
+
+ if ((directories == null) || (directories.size() < 1))
+ return null;
+ // throw new ImageReadException("TIFF missing directories");
+
+ TiffDirectory directory = (TiffDirectory) directories.get(0);
+ Vector entries = directory.entries;
+
+ if ((entries == null) || (entries.size() != 1))
+ throw new ImageReadException("TIFF missing entries");
+
+ TiffField de = (TiffField) entries.get(0);
+ byte bytes[] = de.oversizeValue;
+ return (bytes);
+
+ }
+
+ private TiffField findField(Vector directories, int tag)
+ throws ImageReadException, IOException
+ {
+ if ((directories == null) || (directories.size() < 1))
+ throw new ImageReadException("TIFF missing directories");
+
+ TiffDirectory directory = (TiffDirectory) directories.get(0);
+ Vector entries = directory.entries;
+
+ if ((entries == null) || (entries.size() < 1))
+ throw new ImageReadException("TIFF missing entries");
+
+ for (int i = 0; i < entries.size(); i++)
+ {
+ TiffField field = (TiffField) entries.get(i);
+ if (field.tag == tag)
+ return field;
+ }
+
+ return null;
+ }
+
+ private TiffField findField(Vector entries, TagInfo tag)
+ {
+ if (entries == null)
+ return null;
+
+ for (int i = 0; i < entries.size(); i++)
+ {
+ TiffField field = (TiffField) entries.get(i);
+ if (field.tag == tag.tag)
+ return field;
+ }
+
+ return null;
+ }
+
+ public Dimension getImageSize(ByteSource byteSource)
+ throws ImageReadException, IOException
+ {
+ int fieldTypes[] = new int[]{
+ TIFF_TAG_ImageWidth.tag, TIFF_TAG_ImageLength.tag,
+ };
+
+ TiffContents contents = readDirectories(byteSource, fieldTypes, -1, 2,
+ getDefaultFormatCompliance());
+ if (contents == null)
+ throw new ImageReadException("TIFF missing contents");
+
+ Vector directories = contents.directories;
+
+ TiffField widthField = findField(directories, TIFF_TAG_ImageWidth.tag);
+ TiffField heightField = findField(directories, TIFF_TAG_ImageLength.tag);
+
+ if ((widthField == null) || (heightField == null))
+ throw new ImageReadException("TIFF image has invalid size.");
+
+ Number width = (Number) widthField.getValue();
+ Number height = (Number) heightField.getValue();
+
+ if ((width == null) || (height == null))
+ throw new ImageReadException("TIFF image missing size info.");
+
+ return new Dimension(width.intValue(), height.intValue());
+ }
+
+ public byte[] embedICCProfile(byte image[], byte profile[])
+ {
+ return null;
+ }
+
+ public boolean embedICCProfile(File src, File dst, byte profile[])
+ {
+ return false;
+ }
+
+ public TiffContents readDirectories(byte bytes[])
+ throws ImageReadException, IOException
+ {
+ return readDirectories(new ByteSourceArray(bytes), null,
+ getDefaultFormatCompliance());
+ }
+
+ public TiffContents readDirectories(File file) throws ImageReadException,
+ IOException
+ {
+ return readDirectories(new ByteSourceFile(file), null,
+ getDefaultFormatCompliance());
+ }
+
+ private boolean readThumbnails(Map params)
+ {
+ if (params == null)
+ return false;
+ Object o = params.get(PARAM_KEY_READ_THUMBNAILS);
+ if (o == null)
+ return false;
+ if (!(o instanceof Boolean))
+ return false;
+ return o.equals(Boolean.TRUE);
+ }
+
+ public IImageMetadata getMetadata(ByteSource byteSource, Map params)
+ throws ImageReadException, IOException
+ {
+ TiffContents contents = readDirectories(byteSource, null,
+ getDefaultFormatCompliance());
+ if (contents == null)
+ throw new ImageReadException("TIFF missing contents");
+
+ Vector directories = contents.directories;
+
+ TiffImageMetadata result = new TiffImageMetadata(contents);
+
+ for (int i = 0; i < directories.size(); i++)
+ {
+ TiffDirectory dir = (TiffDirectory) directories.get(i);
+
+ TiffImageMetadata.Directory metadataDirectory = new TiffImageMetadata.Directory(
+ dir);
+
+ if (readThumbnails(params))
+ {
+ if (dir.hasTiffImageData())
+ {
+ BufferedImage thumbnail = getBufferedImage(byteSource, dir,
+ null);
+ metadataDirectory.setThumbnail(thumbnail);
+
+ RawTiffImageData rawImageData = getTiffRawImageData(
+ byteSource, dir);
+ metadataDirectory.setRawTiffImageData(rawImageData);
+ }
+ if (dir.hasJpegImageData())
+ {
+ // BufferedImage thumbnail = getBufferedImage(byteSource, dir,
+ // null);
+ // metadataDirectory.setThumbnail(thumbnail);
+
+ byte rawJpegImageData[] = getJpegRawImageData(byteSource,
+ dir);
+ metadataDirectory.setRawJpegImageData(rawJpegImageData);
+ }
+ }
+
+ Vector entries = dir.getDirectoryEntrys();
+
+ for (int j = 0; j < entries.size(); j++)
+ {
+ TiffField entry = (TiffField) entries.get(j);
+
+ if (entry.tag == TiffConstants.TIFF_TAG_Exif_IFD_Pointer.tag
+ || entry.tag == TiffConstants.TIFF_TAG_GPSInfo_IFD_Pointer.tag
+ || entry.tag == TiffConstants.TIFF_TAG_Interoperability_IFD_Pointer.tag)
+ {
+ int offset = ((Number) entry.getValue()).intValue();
+ int dirType;
+ if (entry.tag == TiffConstants.TIFF_TAG_Exif_IFD_Pointer.tag)
+ dirType = TiffDirectory.DIRECTORY_TYPE_EXIF;
+ else if (entry.tag == TiffConstants.TIFF_TAG_GPSInfo_IFD_Pointer.tag)
+ dirType = TiffDirectory.DIRECTORY_TYPE_GPS;
+ else if (entry.tag == TiffConstants.TIFF_TAG_Interoperability_IFD_Pointer.tag)
+ dirType = TiffDirectory.DIRECTORY_TYPE_INTEROPERABILITY;
+ else
+ throw new ImageReadException(
+ "Unknown subdirectory type.");
+
+ // Debug.debug();
+ // Debug.debug("extra dir child of ", dir.description());
+ // Debug.debug("extra dir offset", offset);
+ // Debug.debug("extra dir type", TiffDirectory.description(dirType));
+ TiffDirectory extraDir = readSingleDirectory(byteSource,
+ dirType, offset, getDefaultFormatCompliance());
+ // Debug.debug("extraDir", extraDir);
+ // directories.add(extraDir);
+ directories.insertElementAt(extraDir, i + 1);
+ }
+
+ metadataDirectory.add(entry);
+ }
+
+ result.add(metadataDirectory);
+ }
+
+ return result;
+ }
+
+ private double[] getValueAsDoubleArray(TiffField field)
+ {
+ if (field == null)
+ return null;
+
+ Object o = field.getValue();
+ if (o == null)
+ return null;
+
+ if (o instanceof Number)
+ {
+ return new double[]{
+ ((Number) o).doubleValue()
+ };
+ }
+ else if (o instanceof Number[])
+ {
+ Number numbers[] = (Number[]) o;
+ double result[] = new double[numbers.length];
+ for (int i = 0; i < numbers.length; i++)
+ result[i] = numbers[i].doubleValue();
+ return result;
+ }
+ else if (o instanceof int[])
+ {
+ int numbers[] = (int[]) o;
+ double result[] = new double[numbers.length];
+ for (int i = 0; i < numbers.length; i++)
+ result[i] = numbers[i];
+ return result;
+ }
+ else if (o instanceof float[])
+ {
+ float numbers[] = (float[]) o;
+ double result[] = new double[numbers.length];
+ for (int i = 0; i < numbers.length; i++)
+ result[i] = numbers[i];
+ return result;
+ }
+ else if (o instanceof double[])
+ {
+ double numbers[] = (double[]) o;
+ double result[] = new double[numbers.length];
+ for (int i = 0; i < numbers.length; i++)
+ result[i] = numbers[i];
+ return result;
+ }
+
+ return null;
+ }
+
+ private int[] getValueAsIntArray(TiffField field)
+ {
+ if (field == null)
+ return null;
+
+ Object o = field.getValue();
+ if (o == null)
+ return null;
+
+ if (o instanceof Number)
+ return new int[]{
+ ((Number) o).intValue()
+ };
+ else if (o instanceof Number[])
+ {
+ Number numbers[] = (Number[]) o;
+ int result[] = new int[numbers.length];
+ for (int i = 0; i < numbers.length; i++)
+ result[i] = numbers[i].intValue();
+ return result;
+ }
+ else if (o instanceof int[])
+ {
+ int numbers[] = (int[]) o;
+ int result[] = new int[numbers.length];
+ for (int i = 0; i < numbers.length; i++)
+ result[i] = numbers[i];
+ return result;
+ }
+
+ return null;
+ }
+
+ private int getValueOrArraySum(TiffField field)
+ {
+ if (field == null)
+ return -1;
+
+ Object o = field.getValue();
+ if (o == null)
+ return -1;
+
+ if (o instanceof Number)
+ return ((Number) o).intValue();
+ else if (o instanceof Number[])
+ {
+ Number numbers[] = (Number[]) o;
+ int sum = 0;
+ for (int i = 0; i < numbers.length; i++)
+ sum += numbers[i].intValue();
+ return sum;
+ }
+ else if (o instanceof int[])
+ {
+ int numbers[] = (int[]) o;
+ int sum = 0;
+ for (int i = 0; i < numbers.length; i++)
+ sum += numbers[i];
+ return sum;
+ }
+
+ return -1;
+ }
+
+ public ImageInfo getImageInfo(ByteSource byteSource)
+ throws ImageReadException, IOException
+ {
+ int FieldTypes[] = new int[]{
+ TIFF_TAG_ImageWidth.tag, TIFF_TAG_ImageLength.tag,
+ TIFF_TAG_ResolutionUnit.tag, TIFF_TAG_XResolution.tag,
+ TIFF_TAG_YResolution.tag, TIFF_TAG_BitsPerSample.tag,
+ TIFF_TAG_ColorMap.tag, TIFF_TAG_SamplesPerPixel.tag,
+ TIFF_TAG_Compression.tag,
+ };
+
+ TiffContents contents = readDirectories(byteSource, FieldTypes, -1, -1,
+ getDefaultFormatCompliance());
+ if (contents == null)
+ throw new ImageReadException("TIFF missing contents");
+
+ Vector dirs = contents.directories;
+ if ((dirs == null) || (dirs.size() < 1))
+ throw new ImageReadException("TIFF image missing directories");
+
+ TiffDirectory directory = (TiffDirectory) dirs.get(0);
+
+ Vector entries = directory.entries;
+
+ if (entries == null)
+ throw new ImageReadException("TIFF missing entries");
+
+ TiffField widthField = findField(entries, TIFF_TAG_ImageWidth);
+ TiffField heightField = findField(entries, TIFF_TAG_ImageLength);
+
+ if ((widthField == null) || (heightField == null))
+ throw new ImageReadException("TIFF image missing size info.");
+
+ int height = ((Number) heightField.getValue()).intValue();
+ int width = ((Number) widthField.getValue()).intValue();
+
+ //-------------------
+
+ TiffField resolutionUnitField = findField(entries,
+ TIFF_TAG_ResolutionUnit);
+ int resolutionUnit = 2; // Inch
+ if ((resolutionUnitField != null)
+ && (resolutionUnitField.getValue() != null))
+ {
+ resolutionUnit = ((Number) resolutionUnitField.getValue())
+ .intValue();
+ }
+ double unitsPerInch = -1;
+ switch (resolutionUnit)
+ {
+ case 1 :
+ break;
+ case 2 : // Inch
+ unitsPerInch = 1.0;
+ break;
+ case 3 : // Meter
+ unitsPerInch = 0.0254;
+ break;
+ default :
+ break;
+
+ }
+ TiffField xResolutionField = findField(entries, TIFF_TAG_XResolution);
+ TiffField yResolutionField = findField(entries, TIFF_TAG_YResolution);
+
+ int physicalWidthDpi = -1;
+ float physicalWidthInch = -1;
+ int physicalHeightDpi = -1;
+ float physicalHeightInch = -1;
+
+ if (unitsPerInch > 0)
+ {
+ if ((xResolutionField != null)
+ && (xResolutionField.getValue() != null))
+ {
+ double XResolutionPixelsPerUnit = ((Number) xResolutionField
+ .getValue()).doubleValue();
+ physicalWidthDpi = (int) (XResolutionPixelsPerUnit / unitsPerInch);
+ physicalWidthInch = (float) ((double) width / (XResolutionPixelsPerUnit * unitsPerInch));
+ }
+ if ((yResolutionField != null)
+ && (yResolutionField.getValue() != null))
+ {
+ double YResolutionPixelsPerUnit = ((Number) yResolutionField
+ .getValue()).doubleValue();
+ physicalHeightDpi = (int) (YResolutionPixelsPerUnit / unitsPerInch);
+ physicalHeightInch = (float) ((double) height / (YResolutionPixelsPerUnit * unitsPerInch));
+ }
+ }
+
+ //-------------------
+
+ TiffField bitsPerSampleField = findField(entries,
+ TIFF_TAG_BitsPerSample);
+// TiffField samplesPerPixelField = findField(entries,
+// TIFF_TAG_SamplesPerPixel);
+
+ int bitsPerSample = -1;
+
+ if ((bitsPerSampleField != null)
+ && (bitsPerSampleField.getValue() != null))
+ {
+ bitsPerSample = getValueOrArraySum(bitsPerSampleField);
+ }
+
+ int bitsPerPixel = bitsPerSample; // assume grayscale;
+ // dunno if this handles colormapped images correctly.
+
+ //-------------------
+
+ Vector comments = new Vector();
+ for (int i = 0; i < entries.size(); i++)
+ {
+ TiffField field = (TiffField) entries.get(i);
+ String comment = field.toString();
+ comments.add(comment);
+ }
+
+ ImageFormat format = ImageFormat.IMAGE_FORMAT_TIFF;
+ String formatName = "TIFF Tag-based Image File Format";
+ String mimeType = "image/tiff";
+ // we ought to count images, but don't yet.
+ int numberOfImages = -1;
+ // not accurate ... only reflects first
+ boolean isProgressive = false;
+ // is TIFF ever interlaced/progressive?
+
+ String formatDetails = "Tiff v." + contents.header.tiffVersion;
+
+ boolean isTransparent = false; // TODO: wrong
+ boolean usesPalette = false;
+ TiffField colorMapField = findField(entries, TIFF_TAG_ColorMap);
+ if (colorMapField != null)
+ usesPalette = true;
+
+ int colorType = ImageInfo.COLOR_TYPE_RGB;
+
+ int compression = getTagAsNumber(entries, TIFF_TAG_Compression)
+ .intValue();
+ String compressionAlgorithm;
+
+ switch (compression)
+ {
+ case TIFF_COMPRESSION_UNCOMPRESSED_1 :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_NONE;
+ break;
+ case TIFF_COMPRESSION_CCITT_1D :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_CCITT_1D;
+ break;
+ case TIFF_COMPRESSION_CCITT_GROUP_3 :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_CCITT_GROUP_3;
+ break;
+ case TIFF_COMPRESSION_CCITT_GROUP_4 :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_CCITT_GROUP_4;
+ break;
+ case TIFF_COMPRESSION_LZW :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_LZW;
+ break;
+ case TIFF_COMPRESSION_JPEG :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_JPEG;
+ break;
+ case TIFF_COMPRESSION_UNCOMPRESSED_2 :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_NONE;
+ break;
+ case TIFF_COMPRESSION_PACKBITS :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_PACKBITS;
+ break;
+ default :
+ compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_UNKNOWN;
+ break;
+ }
+
+ ImageInfo result = new ImageInfo(formatDetails, bitsPerPixel, comments,
+ format, formatName, height, mimeType, numberOfImages,
+ physicalHeightDpi, physicalHeightInch, physicalWidthDpi,
+ physicalWidthInch, width, isProgressive, isTransparent,
+ usesPalette, colorType, compressionAlgorithm);
+
+ return result;
+ }
+
+ public boolean dumpImageFile(PrintWriter pw, ByteSource byteSource)
+ throws ImageReadException, IOException
+ {
+ pw.println("tiff.dumpImageFile");
+
+ {
+ ImageInfo imageData = getImageInfo(byteSource);
+ if (imageData == null)
+ return false;
+
+ imageData.toString(pw, "");
+ }
+
+ pw.println("");
+
+ try
+ {
+ TiffContents contents = readDirectories(byteSource, null, -1, -1,
+ getDefaultFormatCompliance());
+ if (contents == null)
+ return false;
+
+ Vector directories = contents.directories;
+
+ if (directories == null)
+ return false;
+
+ for (int d = 0; d < directories.size(); d++)
+ {
+ TiffDirectory directory = (TiffDirectory) directories.get(d);
+
+ Vector entries = directory.entries;
+
+ if (entries == null)
+ return false;
+
+ Debug.debug("directory offset", directory.offset);
+ Debug.debug("directory offset", directory.offset);
+
+ for (int i = 0; i < entries.size(); i++)
+ {
+ TiffField field = (TiffField) entries.get(i);
+
+ field.dump(pw, d + "");
+ }
+ }
+
+ pw.println("");
+ }
+ catch (Exception e)
+ {
+ Debug.debug(e);
+ pw.println("");
+ return false;
+ }
+
+ return true;
+ }
+
+ private Number getTagAsNumber(Vector entries, TagInfo tag)
+ throws ImageReadException, IOException
+ {
+ TiffField entry = findField(entries, tag);
+ if (entry == null)
+ throw new ImageReadException("Tiff: Missing Tag: " + tag.name
+ + " (" + tag.tag + ")");
+
+ Object o = entry.getValue();
+
+ // Debug.debug("getTagAsNumber:" + entry.tagInfo.name, o);
+ // Debug.debug("getTagAsNumber:" + entry.tagInfo.name, Debug.getType(o));
+
+ Number result = (Number) o;
+
+ if (debug)
+ this.debugNumber(tag.name + " (" + tag.tag + ")",
+ result.intValue(), 4);
+
+ return result;
+ }
+
+ private int getTagAsValueOrArraySum(Vector entries, TagInfo tag)
+ throws ImageReadException, IOException
+ {
+ TiffField entry = findField(entries, tag);
+ if (entry == null)
+ throw new ImageReadException("Tiff: Missing Tag: " + tag.name
+ + " (" + tag.tag + ")");
+
+ int result = getValueOrArraySum(entry);
+
+ if (debug)
+ this.debugNumber(tag.name + " (" + tag.tag + ")", result, 4);
+
+ return result;
+ }
+
+ private double[] getTagAsDoubleArray(Vector entries, TagInfo tag,
+ boolean throwExceptionIfMissing) throws ImageReadException,
+ IOException
+ {
+ TiffField entry = findField(entries, tag);
+ if (entry == null)
+ {
+ if (throwExceptionIfMissing)
+ throw new ImageReadException("Tiff: Missing Tag: " + tag.name
+ + " (" + tag.tag + ")");
+ else
+ return null;
+ }
+
+ double result[] = getValueAsDoubleArray(entry);
+
+ return result;
+ }
+
+ private int[] getTagAsIntArray(Vector entries, TagInfo tag,
+ boolean throwExceptionIfMissing) throws ImageReadException,
+ IOException
+ {
+ TiffField entry = findField(entries, tag);
+ if (entry == null)
+ {
+ if (throwExceptionIfMissing)
+ throw new ImageReadException("Tiff: Missing Tag: " + tag.name
+ + " (" + tag.tag + ")");
+ else
+ return null;
+ }
+
+ int result[] = getValueAsIntArray(entry);
+
+ if (debug)
+ this.debugNumberArray(tag.name + " (" + tag.tag + ")", result, 4);
+
+ return result;
+ }
+
+ private int dumpOptionalNumberTag(Vector entries, TagInfo tag)
+ {
+ TiffField entry = findField(entries, tag);
+
+ if (entry != null)
+ {
+ Object o = entry.getValue();
+ if (o instanceof Number)
+ {
+ int value = ((Number) o).intValue();
+ System.out.println(tag.name + ": " + value);
+ return value;
+ }
+ }
+ return -1;
+ }
+
+ public FormatCompliance getFormatCompliance(ByteSource byteSource)
+ throws ImageReadException, IOException
+ {
+ FormatCompliance result = new FormatCompliance(byteSource
+ .getDescription());
+
+ readDirectories(byteSource, null, -1, -1, result);
+
+ return result;
+ }
+
+ public BufferedImage getBufferedImage(ByteSource byteSource, Map params)
+ throws ImageReadException, IOException
+ {
+ TiffContents contents = readDirectories(byteSource, null, -1, -1,
+ getDefaultFormatCompliance());
+ if (contents == null)
+ throw new ImageReadException("TIFF missing contents");
+
+ Vector directories = contents.directories;
+
+ if ((directories == null) || (directories.size() < 1))
+ throw new ImageReadException("TIFF missing TiffDirectories");
+
+ TiffDirectory directory = (TiffDirectory) directories.get(0);
+
+ return getBufferedImage(byteSource, directory, params);
+ }
+
+ public RawTiffImageData getTiffRawImageData(ByteSource byteSource,
+ TiffDirectory directory) throws ImageReadException, IOException
+ {
+ Vector elements = directory.getTiffRawImageDataElements();
+ byte result[][] = new byte[elements.size()][];
+ for (int i = 0; i < elements.size(); i++)
+ {
+ TiffDirectory.ImageDataElement element = (TiffDirectory.ImageDataElement) elements
+ .get(i);
+ result[i] = byteSource.getBlock(element.offset, element.length);
+ }
+
+ if (directory.imageDataInStrips())
+ return new RawTiffImageData.Strips(result);
+ else
+ return new RawTiffImageData.Tiles(result);
+ }
+
+ public byte[] getJpegRawImageData(ByteSource byteSource,
+ TiffDirectory directory) throws ImageReadException, IOException
+ {
+ ImageDataElement element = directory.getJpegRawImageDataElement();
+ byte result[] = byteSource.getBlock(element.offset, element.length);
+ return result;
+ }
+
+ public BufferedImage getBufferedImage(ByteSource byteSource,
+ TiffDirectory directory, Map params) throws ImageReadException,
+ IOException
+ {
+ Vector entries = directory.entries;
+
+ if (entries == null)
+ throw new ImageReadException("TIFF missing entries");
+
+ // this.setDebug(true);
+
+ TiffField imageWidthField = findField(entries, TIFF_TAG_ImageWidth);
+ if (imageWidthField == null)
+ throw new ImageReadException(
+ "Tiff: Missing Tag: TIFF_TAG_ImageWidth");
+ TiffField imageLengthField = findField(entries, TIFF_TAG_ImageLength);
+ if (imageLengthField == null)
+ throw new ImageReadException(
+ "Tiff: Missing Tag: TIFF_TAG_ImageLength");
+
+ int photometricInterpretation = getTagAsNumber(entries,
+ TIFF_TAG_PhotometricInterpretation).intValue();
+ int compression = getTagAsNumber(entries, TIFF_TAG_Compression)
+ .intValue();
+ int width = getTagAsNumber(entries, TIFF_TAG_ImageWidth).intValue();
+ int height = getTagAsNumber(entries, TIFF_TAG_ImageLength).intValue();
+ int samplesPerPixel = getTagAsNumber(entries, TIFF_TAG_SamplesPerPixel)
+ .intValue();
+ int bitsPerSample[] = getTagAsIntArray(entries, TIFF_TAG_BitsPerSample,
+ true);
+ int bitsPerPixel = getTagAsValueOrArraySum(entries,
+ TIFF_TAG_BitsPerSample);
+
+ int predictor;
+ {
+ dumpOptionalNumberTag(entries, TIFF_TAG_FillOrder);
+ dumpOptionalNumberTag(entries, TIFF_TAG_FreeByteCounts);
+ dumpOptionalNumberTag(entries, TIFF_TAG_FreeOffsets);
+ dumpOptionalNumberTag(entries, TIFF_TAG_Orientation);
+ dumpOptionalNumberTag(entries, TIFF_TAG_PlanarConfiguration);
+ predictor = dumpOptionalNumberTag(entries, TIFF_TAG_Predictor);
+ }
+
+ if (samplesPerPixel != bitsPerSample.length)
+ throw new ImageReadException("Tiff: fSamplesPerPixel ("
+ + samplesPerPixel + ")!=fBitsPerSample.length ("
+ + bitsPerSample.length + ")");
+
+ BufferedImage result = getBufferedImageFactory(params)
+ .getColorBufferedImage(width, height);
+
+ PhotometricInterpreter photometricInterpreter = getPhotometricInterpreter(
+ entries, photometricInterpretation, bitsPerPixel,
+ bitsPerSample, predictor, samplesPerPixel, width, height);
+
+ // this.setDebug(false);
+
+ DataReader dataReader = getDataReader(entries, photometricInterpreter,
+ bitsPerPixel, bitsPerSample, predictor, samplesPerPixel, width,
+ height, compression);
+
+ dataReader.readImageData(result, byteSource);
+
+ photometricInterpreter.dumpstats();
+
+ return result;
+ }
+
+ private PhotometricInterpreter getPhotometricInterpreter(Vector entries,
+ int photometricInterpretation, int bitsPerPixel,
+ int bitsPerSample[], int predictor, int samplesPerPixel, int width,
+ int height) throws IOException, ImageReadException
+ {
+ switch (photometricInterpretation)
+ {
+ case 0 :
+ case 1 :
+ boolean invert = photometricInterpretation == 0;
+
+ return new PhotometricInterpreterBiLevel(bitsPerPixel,
+ samplesPerPixel, bitsPerSample, predictor, width,
+ height, invert);
+ case 3 : // Palette
+ {
+ int[] colorMap = getTagAsIntArray(entries, TIFF_TAG_ColorMap,
+ false);
+
+ int expected_colormap_size = 3 * (1 << bitsPerPixel);
+
+ if (colorMap.length != expected_colormap_size)
+ throw new ImageReadException("Tiff: fColorMap.length ("
+ + colorMap.length + ")!=expected_colormap_size ("
+ + expected_colormap_size + ")");
+
+ return new PhotometricInterpreterPalette(samplesPerPixel,
+ bitsPerSample, predictor, width, height, colorMap);
+ }
+ case 2 : // RGB
+ return new PhotometricInterpreterRGB(samplesPerPixel,
+ bitsPerSample, predictor, width, height);
+ case 5 : // CMYK
+ return new PhotometricInterpreterCMYK(samplesPerPixel,
+ bitsPerSample, predictor, width, height);
+ case 6 : //
+ {
+ double[] fYCbCrCoefficients = getTagAsDoubleArray(entries,
+ TIFF_TAG_YCbCrCoefficients, false);
+ int[] fYCbCrPositioning = getTagAsIntArray(entries,
+ TIFF_TAG_YCbCrPositioning, false);
+ int[] fYCbCrSubSampling = getTagAsIntArray(entries,
+ TIFF_TAG_YCbCrSubSampling, false);
+ double[] referenceBlackWhite = getTagAsDoubleArray(entries,
+ TIFF_TAG_ReferenceBlackWhite, false);
+
+ return new PhotometricInterpreterYCbCr(fYCbCrCoefficients,
+ fYCbCrPositioning, fYCbCrSubSampling,
+ referenceBlackWhite, samplesPerPixel, bitsPerSample,
+ predictor, width, height);
+ }
+
+ case 8 :
+ return new PhotometricInterpreterCIELAB(samplesPerPixel,
+ bitsPerSample, predictor, width, height);
+
+ case 32844 :
+ case 32845 : {
+ boolean yonly = (photometricInterpretation == 32844);
+ return new PhotometricInterpreterLogLUV(samplesPerPixel,
+ bitsPerSample, predictor, width, height, yonly);
+ }
+
+ default :
+ throw new ImageReadException(
+ "TIFF: Unknown fPhotometricInterpretation: "
+ + photometricInterpretation);
+ }
+ }
+
+ private DataReader getDataReader(Vector entries,
+ PhotometricInterpreter photometricInterpreter, int bitsPerPixel,
+ int bitsPerSample[], int predictor, int samplesPerPixel, int width,
+ int height, int compression) throws IOException, ImageReadException
+ {
+ int[] tileOffsets = getTagAsIntArray(entries, TIFF_TAG_TileOffsets,
+ false);
+ int[] tileByteCounts = getTagAsIntArray(entries,
+ TIFF_TAG_TileByteCounts, false);
+
+ int[] stripOffsets = getTagAsIntArray(entries, TIFF_TAG_StripOffsets,
+ false);
+ int[] stripByteCounts = getTagAsIntArray(entries,
+ TIFF_TAG_StripByteCounts, false);
+
+ TiffField tileWidthField = findField(entries, TIFF_TAG_TileWidth);
+ TiffField tileLengthField = findField(entries, TIFF_TAG_TileLength);
+
+ if ((tileOffsets != null) && (tileByteCounts != null))
+ {
+ if (tileOffsets.length != tileByteCounts.length)
+ throw new ImageReadException("Tiff: fTileOffsets.length ("
+ + tileOffsets.length + ")!=fTileByteCounts.length ("
+ + tileByteCounts.length + ")");
+
+ int tileWidth = getTagAsNumber(entries, TIFF_TAG_TileWidth)
+ .intValue();
+ int tileLength = getTagAsNumber(entries, TIFF_TAG_TileLength)
+ .intValue();
+
+ return new DataReaderTiled(photometricInterpreter, tileOffsets,
+ tileByteCounts, tileWidth, tileLength, bitsPerPixel,
+ bitsPerSample, predictor, samplesPerPixel, width, height,
+ compression, getByteOrder());
+ }
+ else if ((tileWidthField != null) && (tileLengthField != null)
+ && (stripOffsets != null) && (stripByteCounts != null))
+ {
+ if (stripOffsets.length != stripByteCounts.length)
+ throw new ImageReadException("Tiff: fStripOffsets.length ("
+ + stripOffsets.length + ")!=fStripByteCounts.length ("
+ + stripByteCounts.length + ")");
+
+ int tileWidth = getTagAsNumber(entries, TIFF_TAG_TileWidth)
+ .intValue();
+ int tileLength = getTagAsNumber(entries, TIFF_TAG_TileLength)
+ .intValue();
+
+ return new DataReaderTiled(photometricInterpreter, stripOffsets,
+ stripByteCounts, tileWidth, tileLength, bitsPerPixel,
+ bitsPerSample, predictor, samplesPerPixel, width, height,
+ compression, getByteOrder());
+ }
+ else if ((stripOffsets != null) && (stripByteCounts != null))
+ {
+ int rowsPerStrip = getTagAsNumber(entries, TIFF_TAG_RowsPerStrip)
+ .intValue();
+
+ if (stripOffsets.length != stripByteCounts.length)
+ throw new ImageReadException("Tiff: fStripOffsets.length ("
+ + stripOffsets.length + ")!=fStripByteCounts.length ("
+ + stripByteCounts.length + ")");
+
+ return new DataReaderStrips(photometricInterpreter, bitsPerPixel,
+ bitsPerSample, predictor, samplesPerPixel, width, height,
+ stripOffsets, stripByteCounts, compression, rowsPerStrip,
+ getByteOrder());
+ }
+ else
+ throw new ImageReadException("Tiff: Neither Strip nor Tile.");
+ }
+
+ public void writeImage(BufferedImage src, OutputStream os, Map params)
+ throws ImageWriteException, IOException
+ {
+ new TiffImageWriter().writeImage(src, os, params);
+ }
+
+}
\ No newline at end of file
Propchange: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/TiffImageParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReader.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReader.java?rev=596008&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReader.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReader.java Sat Nov 17 13:58:22 2007
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cmc.sanselan.formats.tiff.datareaders;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.cmc.sanselan.ImageReadException;
+import org.cmc.sanselan.common.BinaryConstants;
+import org.cmc.sanselan.common.BitInputStream;
+import org.cmc.sanselan.common.PackBits;
+import org.cmc.sanselan.common.byteSources.ByteSource;
+import org.cmc.sanselan.common.mylzw.MyLZWDecompressor;
+import org.cmc.sanselan.formats.tiff.TiffConstants;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreter;
+
+public abstract class DataReader implements TiffConstants, BinaryConstants
+{
+ protected final PhotometricInterpreter photometricInterpreter;
+ protected final int bitsPerSample[];
+ protected final int last[];
+
+ protected final int predictor;
+ protected final int samplesPerPixel;
+
+ protected final int byteOrder;
+
+ public DataReader(PhotometricInterpreter fPhotometricInterpreter,
+ int fBitsPerSample[], int Predictor, int fSamplesPerPixel,
+ int byteOrder)
+ {
+ this.photometricInterpreter = fPhotometricInterpreter;
+ this.bitsPerSample = fBitsPerSample;
+ this.samplesPerPixel = fSamplesPerPixel;
+ this.predictor = Predictor;
+ this.byteOrder = byteOrder;
+ last = new int[fSamplesPerPixel];
+ }
+
+ public abstract void readImageData(BufferedImage bi, ByteSource byteSource)
+ throws ImageReadException, IOException;
+
+ protected int[] getSamplesAsBytes(BitInputStream bis)
+ throws ImageReadException, IOException
+ {
+ int result[] = new int[bitsPerSample.length];
+ for (int i = 0; i < bitsPerSample.length; i++)
+ {
+ int bits = bitsPerSample[i];
+ int sample = bis.readBits(bits);
+ if (bits < 8)
+ {
+ int sign = sample & 1;
+ sample = sample << (8 - bits); // scale to byte.
+ if (sign > 0)
+ sample = sample | ((1 << (8 - bits)) - 1); // extend to byte
+ }
+ else if (bits > 8)
+ {
+ sample = sample >> (bits - 8); // extend to byte.
+ }
+ result[i] = sample;
+ }
+
+ return result;
+ }
+
+ protected int[] applyPredictor(int samples[], int x)
+ {
+ if (predictor == 2) // Horizontal differencing.
+ {
+ for (int i = 0; i < samples.length; i++)
+ {
+ if (x > 0)
+ {
+ samples[i] = 0xff & (samples[i] + last[i]);
+ }
+ last[i] = samples[i];
+ }
+ }
+
+ return samples;
+ }
+
+ private int count = 0;
+
+ protected byte[] decompress(byte compressed[], int compression,
+ int expected_size) throws ImageReadException, IOException
+ {
+ switch (compression)
+ {
+ case 1 : // None;
+ return compressed;
+ case 2 : // CCITT Group 3 1-Dimensional Modified Huffman run-length encoding.
+ throw new ImageReadException("Tiff: unknown compression: "
+ + compression);
+ case TIFF_COMPRESSION_LZW : // LZW
+ {
+ InputStream is = new ByteArrayInputStream(compressed);
+
+ int LZWMinimumCodeSize = 8;
+
+ MyLZWDecompressor fMyLzwDecompressor = new MyLZWDecompressor(
+ LZWMinimumCodeSize, BYTE_ORDER_NETWORK);
+
+ fMyLzwDecompressor.setTiffLZWMode();
+
+ byte[] result = fMyLzwDecompressor
+ .decompress(is, expected_size);
+
+ return result;
+ }
+
+ case TIFF_COMPRESSION_PACKBITS : // Packbits
+ {
+ byte unpacked[] = new PackBits().decompress(compressed,
+ expected_size);
+ count++;
+
+ return unpacked;
+ }
+
+ default :
+ throw new ImageReadException("Tiff: unknown compression: "
+ + compression);
+ }
+ }
+
+}
\ No newline at end of file
Propchange: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderStrips.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderStrips.java?rev=596008&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderStrips.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderStrips.java Sat Nov 17 13:58:22 2007
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cmc.sanselan.formats.tiff.datareaders;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.cmc.sanselan.ImageReadException;
+import org.cmc.sanselan.common.BitInputStream;
+import org.cmc.sanselan.common.byteSources.ByteSource;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreter;
+
+public class DataReaderStrips extends DataReader
+{
+
+ private final int bitsPerPixel;
+
+ private final int width, height;
+
+ private final int stripOffsets[];
+ private final int stripByteCounts[];
+ private final int compression;
+ private final int rowsPerStrip;
+
+ public DataReaderStrips(PhotometricInterpreter fPhotometricInterpreter,
+ int fBitsPerPixel, int fBitsPerSample[], int Predictor,
+ int fSamplesPerPixel, int width, int height, int fStripOffsets[],
+ int fStripByteCounts[], int fCompression, int fRowsPerStrip,
+ int byteOrder)
+ {
+ super(fPhotometricInterpreter, fBitsPerSample, Predictor,
+ fSamplesPerPixel, byteOrder);
+
+ this.bitsPerPixel = fBitsPerPixel;
+ this.width = width;
+ this.height = height;
+ this.stripOffsets = fStripOffsets;
+ this.stripByteCounts = fStripByteCounts;
+ this.compression = fCompression;
+ this.rowsPerStrip = fRowsPerStrip;
+
+ }
+
+ public void interpretStrip(BufferedImage bi, byte bytes[],
+ int pixels_per_strip) throws ImageReadException, IOException
+ {
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ BitInputStream bis = new BitInputStream(bais);
+
+ for (int i = 0; i < pixels_per_strip; i++)
+ {
+ int samples[] = getSamplesAsBytes(bis);
+
+ if ((x < width) && (y < height))
+ {
+ samples = applyPredictor(samples, x);
+
+ photometricInterpreter.interpretPixel(bi, samples, x, y);
+ }
+
+ x++;
+ if (x >= width)
+ {
+ x = 0;
+ y++;
+ bis.flushCache();
+ if (y >= height)
+ break;
+ }
+ }
+ }
+
+ int x = 0, y = 0;
+
+ public void readImageData(BufferedImage bi, ByteSource byteSource)
+ throws ImageReadException, IOException
+ {
+
+ for (int strip = 0; strip < stripOffsets.length; strip++)
+ {
+ int rows_remaining = height - (strip * rowsPerStrip);
+ int rows_in_this_strip = Math.min(rows_remaining, rowsPerStrip);
+ int pixels_per_strip = rows_in_this_strip * width;
+ int bytes_per_strip = ((pixels_per_strip * bitsPerPixel) + 7) / 8;
+
+ int fStripOffset = stripOffsets[strip];
+ int fStripByteCount = stripByteCounts[strip];
+
+ byte compressed[] = byteSource.getBlock(fStripOffset,
+ fStripByteCount);
+
+ byte decompressed[] = decompress(compressed, compression,
+ bytes_per_strip);
+
+ interpretStrip(bi, decompressed, pixels_per_strip);
+
+ }
+ }
+
+}
\ No newline at end of file
Propchange: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderStrips.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderTiled.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderTiled.java?rev=596008&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderTiled.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderTiled.java Sat Nov 17 13:58:22 2007
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.cmc.sanselan.formats.tiff.datareaders;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.cmc.sanselan.ImageReadException;
+import org.cmc.sanselan.common.BitInputStream;
+import org.cmc.sanselan.common.byteSources.ByteSource;
+import org.cmc.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreter;
+
+public class DataReaderTiled extends DataReader
+{
+
+ private final int tileWidth;
+ private final int tileLength;
+ private final int tileOffsets[];
+ private final int tileByteCounts[];
+
+// private final int predictor;
+ private final int bitsPerPixel;
+
+ private final int width, height;
+
+ private final int compression;
+
+ public DataReaderTiled(PhotometricInterpreter fPhotometricInterpreter,
+ int fTileOffsets[], int fTileByteCounts[], int TileWidth,
+ int TileLength, int fBitsPerPixel, int fBitsPerSample[],
+ int Predictor, int fSamplesPerPixel, int width, int height,
+ int fCompression, int byteOrder)
+ {
+ super(fPhotometricInterpreter, fBitsPerSample, Predictor,
+ fSamplesPerPixel, byteOrder);
+
+ this.tileOffsets = fTileOffsets;
+ this.tileByteCounts = fTileByteCounts;
+ this.tileWidth = TileWidth;
+ this.tileLength = TileLength;
+
+ this.bitsPerPixel = fBitsPerPixel;
+// this.predictor = Predictor;
+ this.width = width;
+ this.height = height;
+ this.compression = fCompression;
+ }
+
+ private void interpretTile(BufferedImage bi, byte bytes[], int start_x,
+ int start_y) throws ImageReadException, IOException
+ {
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ BitInputStream bis = new BitInputStream(bais);
+
+ int pixels_per_tile = tileWidth * tileLength;
+
+ int tile_x = 0, tile_y = 0;
+
+ for (int i = 0; i < pixels_per_tile; i++)
+ {
+
+ int x = tile_x + start_x;
+ int y = tile_y + start_y;
+
+ int samples[] = getSamplesAsBytes(bis);
+
+ if ((x < width) && (y < height))
+ {
+ samples = applyPredictor(samples, x);
+ photometricInterpreter.interpretPixel(bi, samples, x, y);
+ }
+
+ tile_x++;
+
+ if (tile_x >= tileWidth)
+ {
+ tile_x = 0;
+ tile_y++;
+ bis.flushCache();
+ if (tile_y >= tileLength)
+ break;
+ }
+
+ }
+ }
+
+ public void readImageData(BufferedImage bi, ByteSource byteSource)
+ throws ImageReadException, IOException
+ {
+ int bits_per_row = tileWidth * bitsPerPixel;
+ int bytes_per_row = (bits_per_row + 7) / 8;
+ int bytes_per_tile = bytes_per_row * tileLength;
+ int x = 0, y = 0;
+
+ for (int tile = 0; tile < tileOffsets.length; tile++)
+ {
+ int fTileOffset = tileOffsets[tile];
+ int fTileByteCount = tileByteCounts[tile];
+
+ byte compressed[] = byteSource
+ .getBlock(fTileOffset, fTileByteCount);
+
+ byte decompressed[] = decompress(compressed, compression,
+ bytes_per_tile);
+
+ interpretTile(bi, decompressed, x, y);
+
+ x += tileWidth;
+ if (x >= width)
+ {
+ x = 0;
+ y += tileLength;
+ if (y >= height)
+ break;
+ }
+
+ }
+ }
+}
\ No newline at end of file
Propchange: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/datareaders/DataReaderTiled.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst.java?rev=596008&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst.java Sat Nov 17 13:58:22 2007
@@ -0,0 +1,233 @@
+package org.cmc.sanselan.formats.tiff.debug;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.cmc.sanselan.formats.tiff.TiffField;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldType;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldTypeASCII;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldTypeByte;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldTypeDouble;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldTypeFloat;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldTypeLong;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldTypeRational;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldTypeShort;
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldTypeUnknown;
+import org.cmc.sanselan.util.Debug;
+
+public class TiffConst
+{
+ public static class ExifDirectory
+ {
+ public final String name;
+
+ public ExifDirectory(final String name)
+ {
+ this.name = name;
+ }
+ }
+
+ public static final int TIFF_COMPRESSION_UNCOMPRESSED_1 = 1;
+ public static final int TIFF_COMPRESSION_UNCOMPRESSED = TIFF_COMPRESSION_UNCOMPRESSED_1;
+ public static final int TIFF_COMPRESSION_CCITT_1D = 2;
+ public static final int TIFF_COMPRESSION_CCITT_GROUP_3 = 3;
+ public static final int TIFF_COMPRESSION_CCITT_GROUP_4 = 4;
+ public static final int TIFF_COMPRESSION_LZW = 5;
+ public static final int TIFF_COMPRESSION_JPEG = 6;
+ public static final int TIFF_COMPRESSION_UNCOMPRESSED_2 = 32771;
+ public static final int TIFF_COMPRESSION_PACKBITS = 32773;
+
+ public static final int PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO = 0;
+ public static final int PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO = 1;
+ public static final int PHOTOMETRIC_INTERPRETATION_RGB = 2;
+ public static final int PHOTOMETRIC_INTERPRETATION_RGB_PALETTE = 3;
+ public static final int PHOTOMETRIC_INTERPRETATION_TRANSPARENCY_MASK = 4;
+ public static final int PHOTOMETRIC_INTERPRETATION_CMYK = 5;
+ public static final int PHOTOMETRIC_INTERPRETATION_YCBCR = 6;
+ public static final int PHOTOMETRIC_INTERPRETATION_CIELAB = 8;
+
+ public static final FieldTypeByte FIELD_TYPE_BYTE = new FieldTypeByte(1,
+ "Byte");
+
+ public static final FieldTypeASCII FIELD_TYPE_ASCII = new FieldTypeASCII(2,
+ "ASCII");
+
+ public static final FieldTypeShort FIELD_TYPE_SHORT = new FieldTypeShort(3,
+ "Short");
+
+ public static final FieldTypeLong FIELD_TYPE_LONG = new FieldTypeLong(4,
+ "Long");
+
+ public static final FieldTypeRational FIELD_TYPE_RATIONAL = new FieldTypeRational(
+ 5, "Rational");
+
+ public static final FieldType FIELD_TYPE_SBYTE = new FieldTypeByte(6,
+ "SByte");
+ public static final FieldType FIELD_TYPE_UNDEFINED = new FieldTypeByte(7,
+ "Undefined");
+ public static final FieldType FIELD_TYPE_SSHORT = new FieldTypeShort(8,
+ "SShort");
+
+ public static final FieldType FIELD_TYPE_SLONG = new FieldTypeLong(9,
+ "SLong");
+
+ public static final FieldType FIELD_TYPE_SRATIONAL = new FieldTypeRational(
+ 10, "SRational");
+
+ public static final FieldType FIELD_TYPE_FLOAT = new FieldTypeFloat();
+
+ public static final FieldType FIELD_TYPE_DOUBLE = new FieldTypeDouble();
+
+ public static final FieldType FIELD_TYPE_UNKNOWN = new FieldTypeUnknown();
+
+ public static final FieldType FIELD_TYPES[] = {
+ FIELD_TYPE_BYTE, FIELD_TYPE_ASCII, FIELD_TYPE_SHORT,
+ FIELD_TYPE_LONG, FIELD_TYPE_RATIONAL, FIELD_TYPE_SBYTE,
+ FIELD_TYPE_UNDEFINED, FIELD_TYPE_SSHORT, FIELD_TYPE_SLONG,
+ FIELD_TYPE_SRATIONAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE,
+ };
+
+ public static final FieldType FIELD_TYPE_ANY[] = FIELD_TYPES;
+
+ public static class TagInfo2
+ {
+ protected static final int LENGTH_UNKNOWN = -1;
+
+ public TagInfo2(String name, int tag, FieldType dataType, int length,
+ ExifDirectory exifDirectory)
+ {
+ this(name, tag, dataType, length);
+ }
+
+ public TagInfo2(String name, int tag, FieldType dataType, int length)
+ {
+ this(name, tag, new FieldType[]{
+ dataType
+ }, length, null);
+ }
+
+ public TagInfo2(String name, int tag, FieldType dataType,
+ String lengthDescription)
+ {
+ this(name, tag, new FieldType[]{
+ dataType
+ }, LENGTH_UNKNOWN, lengthDescription);
+ }
+
+ public TagInfo2(String name, int tag, FieldType dataTypes[], int length)
+ {
+ this(name, tag, dataTypes, length, null);
+ }
+
+ public TagInfo2(String name, int tag, FieldType dataTypes[],
+ String lengthDescription)
+ {
+ this(name, tag, dataTypes, LENGTH_UNKNOWN, lengthDescription);
+ }
+
+ public TagInfo2(String name, int tag, FieldType dataType)
+ {
+ this(name, tag, dataType, LENGTH_UNKNOWN);
+ }
+
+ public final String name;
+ public final int tag;
+ public final FieldType dataTypes[];
+ public final int length;
+ public final String lengthDescription;
+
+ public TagInfo2(String name, int tag, FieldType dataTypes[],
+ int length, String lengthDescription)
+ {
+ this.name = name;
+ this.tag = tag;
+ this.dataTypes = dataTypes;
+ this.length = length;
+ this.lengthDescription = lengthDescription;
+ }
+
+ public Object getValue(TiffField entry)
+ {
+ Object o = entry.fieldType.getSimpleValue(entry);
+ return o;
+ }
+
+ public String toString()
+ {
+ return "[TagInfo. tag: " + tag + ", name: " + name + "]";
+ }
+
+ }
+
+ public static class TagInfo2Date extends TagInfo2
+ {
+ public TagInfo2Date(String name, int tag, FieldType dataType, int length)
+ {
+ super(name, tag, dataType, length);
+ }
+ //
+ // public TagInfo2Date(String name, int tag, FieldType dataType,
+ // String lengthDescription)
+ // {
+ // this(name, tag, new FieldType[]{
+ // dataType
+ // }, LENGTH_UNKNOWN, lengthDescription);
+ // }
+ //
+ // public TagInfo2Date(String name, int tag, FieldType dataTypes[], int length)
+ // {
+ // this(name, tag, dataTypes, length, null);
+ // }
+ //
+ // public TagInfo2Date(String name, int tag, FieldType dataTypes[],
+ // String lengthDescription)
+ // {
+ // this(name, tag, dataTypes, LENGTH_UNKNOWN, lengthDescription);
+ // }
+ //
+ // public TagInfo2Date(String name, int tag, FieldType dataType)
+ // {
+ // this(name, tag, dataType, LENGTH_UNKNOWN);
+ // }
+
+ private static final DateFormat DATE_FORMAT_1 = new SimpleDateFormat(
+ "yyyy:MM:dd HH:mm:ss");
+ private static final DateFormat DATE_FORMAT_2 = new SimpleDateFormat(
+ "yyyy:MM:dd:HH:mm:ss");
+
+ public Object getValue(TiffField entry)
+ {
+ Object o = entry.fieldType.getSimpleValue(entry);
+
+ String s = (String) o;
+ try
+ {
+ Date date = DATE_FORMAT_1.parse(s);
+ return date;
+ }
+ catch (Exception e)
+ {
+ // Debug.debug(e);
+ }
+ try
+ {
+ Date date = DATE_FORMAT_2.parse(s);
+ return date;
+ }
+ catch (Exception e)
+ {
+ Debug.debug(e);
+ }
+
+ return o;
+ }
+
+ public String toString()
+ {
+ return "[TagInfo. tag: " + tag + ", name: " + name + " (data)"
+ + "]";
+ }
+ }
+
+}
Propchange: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst1.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst1.java?rev=596008&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst1.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst1.java Sat Nov 17 13:58:22 2007
@@ -0,0 +1,180 @@
+package org.cmc.sanselan.formats.tiff.debug;
+
+import org.cmc.sanselan.formats.tiff.fieldtypes.FieldType;
+
+public class TiffConst1 extends TiffConst
+{
+
+ public static final TagInfo2 TAG_INFO_NEW_SUB_FILE_TYPE = new TagInfo2(
+ "NewSubfileType", 254, FIELD_TYPE_LONG, 1);
+ public static final TagInfo2 TAG_INFO_SUB_FILE_TYPE = new TagInfo2(
+ "SubfileType", 255, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_IMAGE_WIDTH = new TagInfo2(
+ "ImageWidth", 256, new FieldType[]{
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG
+ }, 1);
+ public static final TagInfo2 TAG_INFO_IMAGE_LENGTH = new TagInfo2(
+ "ImageLength", 257, new FieldType[]{
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG
+ }, 1);
+ public static final TagInfo2 TAG_INFO_BITS_PER_SAMPLE = new TagInfo2(
+ "BitsPerSample", 258, FIELD_TYPE_SHORT, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_COMPRESSION = new TagInfo2(
+ "Compression", 259, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_PHOTOMETRIC_INTERPRETATION = new TagInfo2(
+ "PhotometricInterpretation", 262, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_THRESHHOLDING = new TagInfo2(
+ "Threshholding", 263, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_CELL_WIDTH = new TagInfo2(
+ "CellWidth", 264, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_CELL_LENGTH = new TagInfo2(
+ "CellLength", 265, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_FILL_ORDER = new TagInfo2(
+ "FillOrder", 266, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_DOCUMENT_NAME = new TagInfo2(
+ "DocumentName", 269, FIELD_TYPE_ASCII);
+ public static final TagInfo2 TAG_INFO_IMAGE_DESCRIPTION = new TagInfo2(
+ "ImageDescription", 270, FIELD_TYPE_ASCII);
+ public static final TagInfo2 TAG_INFO_MAKE = new TagInfo2("Make", 271,
+ FIELD_TYPE_ASCII);
+ public static final TagInfo2 TAG_INFO_MODEL = new TagInfo2("Model", 272,
+ FIELD_TYPE_ASCII);
+ public static final TagInfo2 TAG_INFO_STRIP_OFFSETS = new TagInfo2(
+ "StripOffsets", 273, new FieldType[]{
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG
+ }, "StripsPerImage");
+ public static final TagInfo2 TAG_INFO_ORIENTATION = new TagInfo2(
+ "Orientation", 274, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_SAMPLES_PER_PIXEL = new TagInfo2(
+ "SamplesPerPixel", 277, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_ROWS_PER_STRIP = new TagInfo2(
+ "RowsPerStrip", 278, new FieldType[]{
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG
+ }, 1);
+ public static final TagInfo2 TAG_INFO_STRIP_BYTE_COUNTS = new TagInfo2(
+ "StripByteCounts", 279, new FieldType[]{
+ FIELD_TYPE_LONG, FIELD_TYPE_SHORT
+ }, "StripsPerImage");
+ public static final TagInfo2 TAG_INFO_MIN_SAMPLE_VALUE = new TagInfo2(
+ "MinSampleValue", 280, FIELD_TYPE_SHORT, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_MAX_SAMPLE_VALUE = new TagInfo2(
+ "MaxSampleValue", 281, FIELD_TYPE_SHORT, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_X_RESOLUTION = new TagInfo2(
+ "XResolution", 282, FIELD_TYPE_RATIONAL, 1);
+ public static final TagInfo2 TAG_INFO_Y_RESOLUTION = new TagInfo2(
+ "YResolution", 283, FIELD_TYPE_RATIONAL, 1);
+ public static final TagInfo2 TAG_INFO_PLANAR_CONFIGURATION = new TagInfo2(
+ "PlanarConfiguration", 284, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_PAGE_NAME = new TagInfo2("PageName",
+ 285, FIELD_TYPE_ASCII);
+ public static final TagInfo2 TAG_INFO_X_POSITION = new TagInfo2(
+ "XPosition", 286, FIELD_TYPE_RATIONAL);
+ public static final TagInfo2 TAG_INFO_Y_POSITION = new TagInfo2(
+ "YPosition", 287, FIELD_TYPE_RATIONAL);
+ public static final TagInfo2 TAG_INFO_FREE_OFFSETS = new TagInfo2(
+ "FreeOffsets", 288, FIELD_TYPE_LONG);
+ public static final TagInfo2 TAG_INFO_FREE_BYTE_COUNTS = new TagInfo2(
+ "FreeByteCounts", 289, FIELD_TYPE_LONG);
+ public static final TagInfo2 TAG_INFO_GRAY_RESPONSE_UNIT = new TagInfo2(
+ "GrayResponseUnit", 290, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_GRAY_RESPONSE_CURVE = new TagInfo2(
+ "GrayResponseCurve", 291, FIELD_TYPE_SHORT, "2**BitsPerSample");
+ public static final TagInfo2 TAG_INFO_T4_OPTIONS = new TagInfo2(
+ "T4Options", 292, FIELD_TYPE_LONG, 1);
+ public static final TagInfo2 TAG_INFO_T6_OPTIONS = new TagInfo2(
+ "T6Options", 293, FIELD_TYPE_LONG, 1);
+ public static final TagInfo2 TAG_INFO_RESOLUTION_UNIT = new TagInfo2(
+ "ResolutionUnit", 296, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_PAGE_NUMBER = new TagInfo2(
+ "PageNumber", 297, FIELD_TYPE_SHORT, 2);
+ public static final TagInfo2 TAG_INFO_TRANSFER_FUNCTION = new TagInfo2(
+ "TransferFunction", 301, FIELD_TYPE_SHORT,
+ "{1 or SamplesPerPixel}* 2** BitsPerSample");
+ public static final TagInfo2 TAG_INFO_SOFTWARE = new TagInfo2("Software",
+ 305, FIELD_TYPE_ASCII);
+ public static final TagInfo2 TAG_INFO_DATE_TIME = new TagInfo2Date(
+ "DateTime", 306, FIELD_TYPE_ASCII, 20);
+ public static final TagInfo2 TAG_INFO_ARTIST = new TagInfo2("Artist", 315,
+ FIELD_TYPE_ASCII);
+ public static final TagInfo2 TAG_INFO_HOST_COMPUTER = new TagInfo2(
+ "HostComputer", 316, FIELD_TYPE_ASCII);
+ public static final TagInfo2 TAG_INFO_PREDICTOR = new TagInfo2("Predictor",
+ 317, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_WHITE_POINT = new TagInfo2(
+ "WhitePoint", 318, FIELD_TYPE_RATIONAL, 2);
+ public static final TagInfo2 TAG_INFO_PRIMARY_CHROMATICITIES = new TagInfo2(
+ "PrimaryChromaticities", 319, FIELD_TYPE_RATIONAL, 6);
+ public static final TagInfo2 TAG_INFO_COLOR_MAP = new TagInfo2("ColorMap",
+ 320, FIELD_TYPE_SHORT, "3 * (2**BitsPerSample)");
+ public static final TagInfo2 TAG_INFO_HALFTONE_HINTS = new TagInfo2(
+ "HalftoneHints", 321, FIELD_TYPE_SHORT, 2);
+ public static final TagInfo2 TAG_INFO_TILE_WIDTH = new TagInfo2(
+ "TileWidth", 322, new FieldType[]{
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG
+ }, 1);
+ public static final TagInfo2 TAG_INFO_TILE_LENGTH = new TagInfo2(
+ "TileLength", 323, new FieldType[]{
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG
+ }, 1);
+ public static final TagInfo2 TAG_INFO_TILE_OFFSETS = new TagInfo2(
+ "TileOffsets", 324, FIELD_TYPE_LONG, "TilesPerImage");
+ public static final TagInfo2 TAG_INFO_TILE_BYTE_COUNTS = new TagInfo2(
+ "TileByteCounts", 325, new FieldType[]{
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG
+ }, "TilesPerImage");
+ public static final TagInfo2 TAG_INFO_INK_SET = new TagInfo2("InkSet", 332,
+ FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_INK_NAMES = new TagInfo2("InkNames",
+ 333, FIELD_TYPE_ASCII,
+ "total number of characters in all ink name strings, including zeros");
+ public static final TagInfo2 TAG_INFO_NUMBER_OF_INKS = new TagInfo2(
+ "NumberOfInks", 334, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_DOT_RANGE = new TagInfo2("DotRange",
+ 336, new FieldType[]{
+ FIELD_TYPE_BYTE, FIELD_TYPE_SHORT
+ }, "2, or 2* NumberOfInks");
+ public static final TagInfo2 TAG_INFO_TARGET_PRINTER = new TagInfo2(
+ "TargetPrinter", 337, FIELD_TYPE_ASCII, "any");
+ public static final TagInfo2 TAG_INFO_EXTRA_SAMPLES = new TagInfo2(
+ "ExtraSamples", 338, FIELD_TYPE_BYTE,
+ "number of extra components per pixel");
+ public static final TagInfo2 TAG_INFO_SAMPLE_FORMAT = new TagInfo2(
+ "SampleFormat", 339, FIELD_TYPE_SHORT, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_S_MIN_SAMPLE_VALUE = new TagInfo2(
+ "SMinSampleValue", 340, FIELD_TYPE_ANY, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_S_MAX_SAMPLE_VALUE = new TagInfo2(
+ "SMaxSampleValue", 341, FIELD_TYPE_ANY, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_TRANSFER_RANGE = new TagInfo2(
+ "TransferRange", 342, FIELD_TYPE_SHORT, 6);
+ public static final TagInfo2 TAG_INFO_JPEG_PROC = new TagInfo2("JPEGProc",
+ 512, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_JPEG_INTERCHANGE_FORMAT = new TagInfo2(
+ "JPEGInterchangeFormat", 513, FIELD_TYPE_LONG, 1);
+ public static final TagInfo2 TAG_INFO_JPEG_INTERCHANGE_FORMAT_LENGTH = new TagInfo2(
+ "JPEGInterchangeFormatLength", 514, FIELD_TYPE_LONG, 1);
+ public static final TagInfo2 TAG_INFO_JPEG_RESTART_INTERVAL = new TagInfo2(
+ "JPEGRestartInterval", 515, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_JPEG_LOSSLESS_PREDICTORS = new TagInfo2(
+ "JPEGLosslessPredictors", 517, FIELD_TYPE_SHORT, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_JPEG_POINT_TRANSFORMS = new TagInfo2(
+ "JPEGPointTransforms", 518, FIELD_TYPE_SHORT, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_JPEG_Q_TABLES = new TagInfo2(
+ "JPEGQTables", 519, FIELD_TYPE_LONG, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_JPEG_DC_TABLES = new TagInfo2(
+ "JPEGDCTables", 520, FIELD_TYPE_LONG, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_JPEG_AC_TABLES = new TagInfo2(
+ "JPEGACTables", 521, FIELD_TYPE_LONG, "SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_YCBCR_COEFFICIENTS = new TagInfo2(
+ "YCbCrCoefficients", 529, FIELD_TYPE_RATIONAL, 3);
+ public static final TagInfo2 TAG_INFO_YCBCR_SUBSAMPLING = new TagInfo2(
+ "YCbCrSubSampling", 530, FIELD_TYPE_SHORT, 2);
+ public static final TagInfo2 TAG_INFO_YCBCR_POSITIONING = new TagInfo2(
+ "YCbCrPositioning", 531, FIELD_TYPE_SHORT, 1);
+ public static final TagInfo2 TAG_INFO_REFERENCE_BLACK_WHITE = new TagInfo2(
+ "ReferenceBlackWhite", 532, FIELD_TYPE_LONG, "2*SamplesPerPixel");
+ public static final TagInfo2 TAG_INFO_COPYRIGHT = new TagInfo2("Copyright",
+ 33432, FIELD_TYPE_ASCII, "Any");
+
+}
+
+/**/
Propchange: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst1.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst2.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst2.java?rev=596008&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst2.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst2.java Sat Nov 17 13:58:22 2007
@@ -0,0 +1,131 @@
+package org.cmc.sanselan.formats.tiff.debug;
+
+public class TiffConst2
+{
+ /*
+
+ between Exif Tags and Flashpix Property Set (1) (TIFF Tags)
+ Exif FPX
+ Tag Code Field Name
+ Dec Hex
+ Property Set Group Name
+ ImageWidth 256 100 - - -
+ ImageLength 257 101 - - -
+ BitsPerSample 258 102 - - -
+ Compression 259 103 - - -
+ PhotometricInterpretation 262 106 - - -
+ ImageDescription 270 10E Image Info Content Description Caption text
+ Make 271 10F Image Info Camera Information Camera manufacturer name
+ Model 272 110 Image Info Camera Information Camera model name
+ StripOffsets 273 111 - - -
+ Orientation 274 112 Transform - Spatial Orientation
+ SamplesPerPixel 277 115 - - -
+ RowsPerStrip 278 116 - - -
+ StripByteCounts 279 117 - - -
+ XResolution 282 11A Image Contents Primary description Default display width
+ YResolution 283 11B Image Contents Primary description Default display height
+ PlanarConfiguration 284 11C - - -
+ ResolutionUnit 296 128 Image Contents Primary description Display height/width units
+ TransferFunction 301 12D - - -
+ Software 305 131 Image Info File source Software Name
+ DateTime 306 132 Ignore Ignore Ignore
+ Artist 315 13B Image Info Intellectual Property Authorship
+ WhitePoint 318 13E - - -
+ PrimaryChromaticities 319 13F - - -
+ YCbCrCoefficients 529 211 - - -
+ YCbCrSubSampling 530 212 - - -
+ YCbCrPositioning 531 213 Ignore Ignore Ignore
+ ReferenceBlackWhite 532 214 - - -
+ Copyright 33432 8298 Image Info Intellectual Property Copyright message
+ Exif IFD Pointer 34665 8769 - - -
+ GPS Info IFD Pointer 34853 8825 - - -
+ JEITA CP-3451
+ - 129 -
+ Table 50 Conversion between Exif Tags and Flashpix Property Set (2) (Exif Private Tags)
+ Exif FPX
+ Tag Code Field Name
+ Dec Hex
+ Property Set Group Name
+ ExposureTime 33434 829A Image Info Per Picture Camera Setting Exposure time
+ FNumber 33437 829D Image Info Per Picture Camera Setting F-number
+ ExposureProgram 34850 8822 Image Info Per Picture Camera Setting Exposure program
+ SpectralSensitivity 34852 8824 Image Info Digital Camera Characterization Spectral sensitivity
+ ISOSpeedRatings 34855 8827 Image Info Digital Camera Characterization ISO speed ratings
+ OECF 34857 8829 Image Info Digital Camera Characterization OECF
+ ExifVersion 36864 9000 - - -
+ DateTimeOriginal 36867 9003 Image Info Content Description Date of the original image
+ Image Info Per Picture Camera Setting Capture date
+ DateTimeDigitized 36868 9004 Summary Info - Create date/time
+ ComponentsConfiguration 37121 9101 Ignore Ignore Ignore
+ CompressedBitsPerPixel 37122 9102 Ignore Ignore Ignore
+ ShutterSpeedValue 37377 9201 Image Info Per Picture Camera Setting Exposure time
+ ApertureValue 37378 9202 Image Info Per Picture Camera Setting F-number
+ BrightnessValue 37379 9203 Image Info Per Picture Camera Setting Brightness value
+ ExposureBiasValue 37380 9204 Image Info Per Picture Camera Setting Exposure bias value
+ MaxApertureValue 37381 9205 Image Info Per Picture Camera Setting Maximum aperture value
+ SubjectDistance 37382 9206 Image Info Per Picture Camera Setting Subject distance
+ MeteringMode 37383 9207 Image Info Per Picture Camera Setting Metering mode
+ LightSource 37384 9208 Image Info Per Picture Camera Setting Scene illuminant
+ Flash 37385 9209 Image Info Per Picture Camera Setting Flash
+ Image Info Per Picture Camera Setting Flash return
+ FocalLength 37386 920A Image Info Per Picture Camera Setting Focal length
+ MakerNote 37500 927C - - -
+ UserComment 37510 9286 Image Info Content description Content description note
+ SubSecTime 37520 9290 Ignore Ignore Ignore
+ SubSecTimeOriginal 37521 9291 Image Info Content Description Date of the original image
+ Image Info Per Picture Camera Setting Capture date
+ SubSecTimeDigitized 37522 9292 Summary Info - Create date/time
+ FlashpixVersion 40960 A000 - - -
+ ColorSpace 40961 A001 Image Contents resolution description Subimage color
+ PixelXDimension 40962 A002 Image Contents Primary description Highest resolution width
+ PixelYDimension 40963 A003 Image Contents Primary description Highest resolution height
+ RelatedSoundFile 40964 A004 - - -
+ FlashEnergy 41483 A20B Image Info Per Picture Camera Setting Flash Energy
+ SpatialFrequencyResponse 41484 A20C Image Info Digital Camera Characterization Spatial frequency response
+ FocalplaneXResolution 41486 A20E Image Info Digital Camera Characterization Focal plane X resolution
+ FocalplaneYResolution 41487 A20F Image Info Digital Camera Characterization Focal plane Y resolution
+ FocalplaneResolutionUnit 41488 A210 Image Info Digital Camera Characterization Focal plane resolution unit
+ SubjectLocation 41492 A214 Image Info Per Picture Camera Setting Subject location
+ ExposureIndex 41493 A215 Image Info Per Picture Camera Setting Exposure index
+ SensingMethod 41495 A217 Image Info Digital Camera Characterization Sensing method
+ FileSource 41728 A300 Image Info File Source File source
+ SceneType 41729 A301 Image Info File Source Scene type
+ CFAPattern 41730 A302 Image Info Digital Camera Characterization CFA pattern
+ JEITA CP-3451
+ - 130 -
+ Table 51 Conversion between Exif Tags and Flashpix Property Set (3) (GPS Info Tags)
+ Exif FPX
+ Tag Code Field Name
+ Dec Hex
+ Property Set Group Name
+ GPSVersionID 0 0 GPS Info extension - GPSVersionID
+ GPSLatitudeRef 1 1 GPS Info extension - GPSLatitudeRef
+ GPSLatitude 2 2 GPS Info extension - GPSLatitude
+ GPSLongitudeRef 3 3 GPS Info extension - GPSLongitudeRef
+ GPSLongitude 4 4 GPS Info extension - GPSLongitude
+ GPSAltitudeRef 5 5 GPS Info extension - GPSAltitudeRef
+ GPSAltitude 6 6 GPS Info extension - GPSAltitude
+ GPSTimeStamp 7 7 GPS Info extension - GPSTimeStamp
+ GPSSatellites 8 8 GPS Info extension - GPSSatellites
+ GPSStatus 9 9 GPS Info extension - GPSStatus
+ GPSMeasureMode 10 A GPS Info extension - GPSMeasureMode
+ GPSDOP 11 B GPS Info extension - GPSDOP
+ GPSSpeedRef 12 C GPS Info extension - GPSSpeedRef
+ GPSSpeed 13 D GPS Info extension - GPSSpeed
+ GPSTrackRef 14 E GPS Info extension - GPSTrackRef
+ GPSTrack 15 F GPS Info extension - GPSTrack
+ GPSImgDirectionRef 16 10 GPS Info extension - GPSImgDirectionRef
+ GPSImgDirection 17 11 GPS Info extension - GPSImgDirection
+ GPSMapDatum 18 12 GPS Info extension - GPSMapDatum
+ GPSDestLatitudeRef 19 13 GPS Info extension - GPSDestLatitudeRef
+ GPSDestLatitude 20 14 GPS Info extension - GPSDestLatitude
+ GPSDestLongitudeRef 21 15 GPS Info extension - GPSDestLongitudeRef
+ GPSDestLongitude 22 16 GPS Info extension - GPSDestLongitude
+ GPSDestBearingRef 23 17 GPS Info extension - GPSDestBearingRef
+ GPSDestBearing 24 18 GPS Info extension - GPSDestBearing
+ GPSDestDistanceRef 25 19 GPS Info extension - GPSDestDistanceRef
+ GPSDestDistance 26 1A GPS Info extension - GPSDestDistance
+
+ /**/
+
+}
Propchange: incubator/sanselan/trunk/src/main/java/org/cmc/sanselan/formats/tiff/debug/TiffConst2.java
------------------------------------------------------------------------------
svn:eol-style = native