From sanselan-commits-return-84adamswilliam@example.net Mon Jan 07 03:40:35 2008 Return-Path: <sanselan-commits-return-84adamswilliam@example.net> Delivered-To: adamswilliam@example.net Received: (qmail 68577 invoked from network); 7 Jan 2008 03:40:35 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 7 Jan 2008 03:40:35 -0000 Received: (qmail 59472 invoked by uid 500); 7 Jan 2008 03:40:24 -0000 Delivered-To: adamswilliam@example.net Received: (qmail 59460 invoked by uid 500); 7 Jan 2008 03:40:24 -0000 Mailing-List: contact adamswilliam@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:adamswilliam@example.net> List-Unsubscribe: <mailto:adamswilliam@example.net> List-Post: <mailto:adamswilliam@example.net> List-Id: <sanselan-commits.incubator.apache.org> Reply-To: adamswilliam@example.net Delivered-To: mailing list adamswilliam@example.net Received: (qmail 59450 invoked by uid 99); 7 Jan 2008 03:40:24 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 06 Jan 2008 19:40:24 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 07 Jan 2008 03:40:07 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 869ED1A9896; Sun, 6 Jan 2008 19:40:12 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r609505 - in /incubator/sanselan/trunk/src: main/java/org/apache/sanselan/formats/jpeg/exifRewrite/ main/java/org/apache/sanselan/formats/tiff/ main/java/org/apache/sanselan/formats/tiff/constants/ main/java/org/apache/sanselan/formats/tiff... Date: Mon, 07 Jan 2008 03:40:11 -0000 To: adamswilliam@example.net From: adamswilliam@example.net X-Mailer: svnmailer-1.0.8 Message-Id: <adamswilliam@example.net> X-Virus-Checked: Checked by ClamAV on apache.org Author: cmchen Date: Sun Jan 6 19:40:10 2008 New Revision: 609505 URL: http://svn.apache.org/viewvc?rev=609505&view=rev Log: more work on exif/tiff rewrite. great deal of refactoring, elaborated unit test, fixed a few bugs. Removed: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TagInfo.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/TagInfo2Date.java Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/exifRewrite/ExifRewriter.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageParser.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/TagInfo2.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/PointerDirectoriesInfo.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriter.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputField.java incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSet.java incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/ExifRewriteTest.java Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/exifRewrite/ExifRewriter.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/exifRewrite/ExifRewriter.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/exifRewrite/ExifRewriter.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/exifRewrite/ExifRewriter.java Sun Jan 6 19:40:10 2008 @@ -50,7 +50,8 @@ public final ArrayList pieces; public final GenericSegment exifSegment; - public JFIFPieces(final ArrayList pieces, final GenericSegment exifSegment) + public JFIFPieces(final ArrayList pieces, + final GenericSegment exifSegment) { this.pieces = pieces; this.exifSegment = exifSegment; @@ -167,10 +168,32 @@ writeSegmentsReplacingExif(os, pieces, newBytes); } + // public void updateExifMetadata(ByteSource byteSource, OutputStream os, + // ArrayList outputDirectories, Map params) throws ImageReadException, + // IOException, ImageWriteException + // { + // JFIFPieces jfifPieces = analyzeJFIF(byteSource); + // ArrayList pieces = jfifPieces.pieces; + // GenericSegment exifSegment = jfifPieces.exifSegment; + // + // byte exifBytes[] = exifSegment.bytes; + // exifBytes = getBytearrayTail("trimmed exif bytes", exifBytes, 6); + // + // TiffImageMetadata exifMetadata = (TiffImageMetadata) new TiffImageParser() + // .getMetadata(exifBytes, params); + // int byteOrder = exifMetadata.contents.header.byteOrder; + // + // byte newBytes[] = writeExifSegment(outputDirectories, byteOrder, true); + // + // writeSegmentsReplacingExif(os, pieces, newBytes); + // } + public void updateExifMetadata(ByteSource byteSource, OutputStream os, - ArrayList outputDirectories, Map params) throws ImageReadException, - IOException, ImageWriteException + TiffOutputSet outputSet + // , Map params + ) throws ImageReadException, IOException, ImageWriteException { + List outputDirectories = outputSet.getDirectories(); JFIFPieces jfifPieces = analyzeJFIF(byteSource); ArrayList pieces = jfifPieces.pieces; GenericSegment exifSegment = jfifPieces.exifSegment; @@ -178,17 +201,16 @@ byte exifBytes[] = exifSegment.bytes; exifBytes = getBytearrayTail("trimmed exif bytes", exifBytes, 6); - TiffImageMetadata exifMetadata = (TiffImageMetadata) new TiffImageParser() - .getMetadata(exifBytes, params); - int byteOrder = exifMetadata.contents.header.byteOrder; + int byteOrder = outputSet.byteOrder; byte newBytes[] = writeExifSegment(outputDirectories, byteOrder, true); writeSegmentsReplacingExif(os, pieces, newBytes); } - private void writeSegmentsReplacingExif(OutputStream os, ArrayList segments, - byte newBytes[]) throws ImageWriteException, IOException + private void writeSegmentsReplacingExif(OutputStream os, + ArrayList segments, byte newBytes[]) throws ImageWriteException, + IOException { int byteOrder = getByteOrder(); @@ -258,18 +280,15 @@ return writeExifSegment(outputDirectories, byteOrder, includeEXIFPrefix); } - - public byte[] writeExifSegment(TiffOutputSet outputSet, + public byte[] writeExifSegment(TiffOutputSet outputSet, boolean includeEXIFPrefix) throws IOException, ImageWriteException { List outputDirectories = outputSet.getDirectories(); - - return writeExifSegment( outputDirectories, outputSet.byteOrder, - includeEXIFPrefix) ; - } - + return writeExifSegment(outputDirectories, outputSet.byteOrder, + includeEXIFPrefix); + } public byte[] writeExifSegment(List outputDirectories, int byteOrder, boolean includeEXIFPrefix) throws IOException, ImageWriteException Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java Sun Jan 6 19:40:10 2008 @@ -30,6 +30,7 @@ import org.apache.sanselan.formats.tiff.constants.TagInfo2; import org.apache.sanselan.formats.tiff.constants.TiffConstants; import org.apache.sanselan.formats.tiff.fieldtypes.FieldType; +import org.apache.sanselan.util.Debug; public class TiffField implements TiffConstants { @@ -62,6 +63,11 @@ tagInfo = getTag(directoryType, tag); } + public boolean isLocalValue() + { + return fieldType.isLocalValue(this); + } + public final class OversizeValueElement extends TiffElement { public OversizeValueElement(int offset, int length) @@ -151,8 +157,8 @@ private int getValueLengthInBytes() { int unit_length = fieldType.length; - int ValueLength = unit_length * length; - return ValueLength; + int valueLength = unit_length * length; + return valueLength; } public void fillInValue(ByteSource byteSource) throws ImageReadException, @@ -161,9 +167,9 @@ if (fieldType.isLocalValue(this)) return; - int ValueLength = getValueLengthInBytes(); + int valueLength = getValueLengthInBytes(); - byte bytes[] = byteSource.getBlock(valueOffset, ValueLength); + byte bytes[] = byteSource.getBlock(valueOffset, valueLength); setOversizeValue(bytes); } @@ -408,6 +414,12 @@ // Debug.debug("oversizeValue", oversizeValue); // Debug.debug("byteOrder", byteOrder); // } + + public String getDescriptionWithoutValue() + { + return tag + " (0x" + Integer.toHexString(tag) + ": " + tagInfo.name + + "): "; + } public String toString() { Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java Sun Jan 6 19:40:10 2008 @@ -112,23 +112,20 @@ .get(i); TiffField srcField = item.getTiffField(); - TagInfo2 tag = srcField.tagInfo; - FieldType tagtype = srcField.fieldType; + TagInfo2 tagInfo = srcField.tagInfo; + FieldType fieldType = srcField.fieldType; int count = srcField.length; // byte bytes[] = srcField.fieldType.getRawBytes(srcField); - // Debug.debug("\t" + "srcField", srcField); - // Debug.debug("\t" + "bytes", bytes); - Object value = srcField.getValue(); byte bytes2[]; - if (tag.isDate()) - bytes2 = tagtype.getRawBytes(srcField); + if (tagInfo.isDate()) + bytes2 = fieldType.getRawBytes(srcField); else - bytes2 = tagtype.writeData(value, byteOrder); + bytes2 = fieldType.writeData(value, byteOrder); // Debug.debug("\t" + "bytes2", bytes2); - TiffOutputField dstField = new TiffOutputField(tag, tagtype, + TiffOutputField dstField = new TiffOutputField(srcField.tag, tagInfo, fieldType, count, bytes2); dstDir.add(dstField); } Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageParser.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageParser.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageParser.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageParser.java Sun Jan 6 19:40:10 2008 @@ -138,9 +138,6 @@ 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"); @@ -154,13 +151,10 @@ if (keepField(tag, tags)) { - TiffField entry = new TiffField(tag, dirType, type, length, valueOffset, - valueOffsetBytes, getByteOrder()); + TiffField entry = new TiffField(tag, dirType, 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 @@ -257,7 +251,6 @@ try { is = byteSource.getInputStream(); - // Debug.debug("readSingleDirectory offset", offset); if (offset > 0) is.skip(offset); @@ -480,14 +473,8 @@ 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.add(i + 1, extraDir); } Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java Sun Jan 6 19:40:10 2008 @@ -558,7 +558,7 @@ public static final TagInfo2 EXIF_TAG_PHOTOSHOP_SETTINGS = new TagInfo2( "Photoshop Settings", 0x8649, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); - public static final TagInfo2 EXIF_TAG_EXIF_OFFSET = new TagInfo2( + public static final TagInfo2 EXIF_TAG_EXIF_OFFSET = new TagInfo2.Offset( "Exif Offset", 0x8769, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); public static final TagInfo2 EXIF_TAG_ICC_PROFILE = new TagInfo2( @@ -590,7 +590,7 @@ public static final TagInfo2 EXIF_TAG_SPECTRAL_SENSITIVITY = new TagInfo2( "Spectral Sensitivity", 0x8824, FIELD_TYPE_ASCII, 1, EXIF_DIRECTORY_EXIF_IFD); - public static final TagInfo2 EXIF_TAG_GPSINFO = new TagInfo2("GPSInfo", + public static final TagInfo2 EXIF_TAG_GPSINFO = new TagInfo2.Offset("GPSInfo", 0x8825, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); public static final TagInfo2 EXIF_TAG_ISO = new TagInfo2("ISO", 0x8827, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_EXIF_IFD); @@ -806,7 +806,7 @@ public static final TagInfo2 EXIF_TAG_RELATED_SOUND_FILE = new TagInfo2( "Related Sound File", 0xa004, FIELD_TYPE_ASCII, 1, EXIF_DIRECTORY_EXIF_IFD); - public static final TagInfo2 EXIF_TAG_INTEROP_OFFSET = new TagInfo2( + public static final TagInfo2 EXIF_TAG_INTEROP_OFFSET = new TagInfo2.Offset( "Interop Offset", 0xa005, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); public static final TagInfo2 EXIF_TAG_FLASH_ENERGY_EXIF_IFD = new TagInfo2( @@ -1032,12 +1032,14 @@ public static final TagInfo2 EXIF_TAG_HEIGHT_RESOLUTION = new TagInfo2( "Height Resolution", 0xbc83, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); + // might be an offset? public static final TagInfo2 EXIF_TAG_IMAGE_OFFSET = new TagInfo2( "Image Offset", 0xbcc0, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); public static final TagInfo2 EXIF_TAG_IMAGE_BYTE_COUNT = new TagInfo2( "Image Byte Count", 0xbcc1, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); + // might be an offset? public static final TagInfo2 EXIF_TAG_ALPHA_OFFSET = new TagInfo2( "Alpha Offset", 0xbcc2, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/TagInfo2.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/TagInfo2.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/TagInfo2.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/TagInfo2.java Sun Jan 6 19:40:10 2008 @@ -83,12 +83,39 @@ public String toString() { - return "[TagInfo. tag: " + tag + ", name: " + name + "]"; + return "[TagInfo. tag: " + tag + " (0x" + Integer.toHexString(tag) + + ", name: " + name + "]"; } public boolean isDate() { return false; + } + + public boolean isOffset() + { + return false; + } + + public static class Offset extends TagInfo2 + { + public Offset(String name, int tag, FieldType dataTypes[], int length, + ExifDirectoryType exifDirectory) + { + super(name, tag, dataTypes, length, exifDirectory); + } + + public Offset(String name, int tag, FieldType dataType, int length) + { + super(name, tag, dataType, length); + } + + // "Exif Offset", 0x8769, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, + // EXIF_DIRECTORY_UNKNOWN); + public boolean isOffset() + { + return true; + } } public static class Date extends TagInfo2 Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/PointerDirectoriesInfo.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/PointerDirectoriesInfo.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/PointerDirectoriesInfo.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/PointerDirectoriesInfo.java Sun Jan 6 19:40:10 2008 @@ -23,23 +23,23 @@ public final TiffOutputDirectory exifDirectory; public final TiffOutputField gpsDirectoryOffsetField; public final TiffOutputDirectory gpsDirectory; - public final TiffOutputField iteroperabilityDirectoryOffsetField; - public final TiffOutputDirectory iteroperabilityDirectory; + public final TiffOutputField interoperabilityDirectoryOffsetField; + public final TiffOutputDirectory interoperabilityDirectory; public PointerDirectoriesInfo( final TiffOutputField exifDirectoryOffsetField, final TiffOutputDirectory exifDirectory, final TiffOutputField gpsDirectoryOffsetField, final TiffOutputDirectory gpsDirectory, - final TiffOutputField iteroperabilityDirectoryOffsetField, - final TiffOutputDirectory iteroperabilityDirectory) + final TiffOutputField interoperabilityDirectoryOffsetField, + final TiffOutputDirectory interoperabilityDirectory) { this.exifDirectoryOffsetField = exifDirectoryOffsetField; this.exifDirectory = exifDirectory; this.gpsDirectoryOffsetField = gpsDirectoryOffsetField; this.gpsDirectory = gpsDirectory; - this.iteroperabilityDirectoryOffsetField = iteroperabilityDirectoryOffsetField; - this.iteroperabilityDirectory = iteroperabilityDirectory; + this.interoperabilityDirectoryOffsetField = interoperabilityDirectoryOffsetField; + this.interoperabilityDirectory = interoperabilityDirectory; } } Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriter.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriter.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriter.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriter.java Sun Jan 6 19:40:10 2008 @@ -1,4 +1,3 @@ - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -21,6 +20,7 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,536 +31,625 @@ import org.apache.sanselan.common.mylzw.MyLZWCompressor; import org.apache.sanselan.formats.tiff.RawTiffImageData; import org.apache.sanselan.formats.tiff.TiffDirectory; +import org.apache.sanselan.formats.tiff.TiffField; +import org.apache.sanselan.formats.tiff.constants.TagInfo2; import org.apache.sanselan.util.Debug; import org.apache.sanselan.util.DebugOutputStream; public class TiffImageWriter extends TiffImageWriterBase { - public TiffImageWriter() - { - } - - public TiffImageWriter(int byteOrder) - { - super(byteOrder); - } - - public byte[][] getStrips(BufferedImage src, int fSamplesPerPixel, - int bitsPerSample, int rowsPerStrip) - { - int width = src.getWidth(); - int height = src.getHeight(); - - int stripCount = (height + rowsPerStrip - 1) / rowsPerStrip; - - byte result[][] = null; - { // Write Strips - result = new byte[stripCount][]; - - int remaining_rows = height; - - for (int i = 0; i < stripCount; i++) - { - int rowsInStrip = Math.min(rowsPerStrip, remaining_rows); - remaining_rows -= rowsInStrip; - - int bitsInStrip = bitsPerSample * rowsInStrip * width - * fSamplesPerPixel; - int bytesInStrip = (bitsInStrip + 7) / 8; - - byte uncompressed[] = new byte[bytesInStrip]; - - int counter = 0; - int y = i * rowsPerStrip; - int stop = i * rowsPerStrip + rowsPerStrip; - - for (; (y < height) && (y < stop); y++) - { - for (int x = 0; x < width; x++) - { - int rgb = src.getRGB(x, y); - int red = 0xff & (rgb >> 16); - int green = 0xff & (rgb >> 8); - int blue = 0xff & (rgb >> 0); - - uncompressed[counter++] = (byte) red; - uncompressed[counter++] = (byte) green; - uncompressed[counter++] = (byte) blue; - } - } - - result[i] = uncompressed; - } - - } - - return result; - } - - public void writeImage(BufferedImage src, OutputStream os, Map params) - throws ImageWriteException, IOException - { - // writeImageNew(src, os, params); - // } - // - // public void writeImageNew(BufferedImage src, OutputStream os, Map params) - // throws ImageWriteException, IOException - // { - - // make copy of params; we'll clear keys as we consume them. - params = new HashMap(params); - - // clear format key. - if (params.containsKey(PARAM_KEY_FORMAT)) - params.remove(PARAM_KEY_FORMAT); - - int width = src.getWidth(); - int height = src.getHeight(); - - // BinaryOutputStream bos = new BinaryOutputStream(os, WRITE_BYTE_ORDER); - // - // writeImageFileHeader(bos, WRITE_BYTE_ORDER); - - // ArrayList directoryFields = new ArrayList(); - - final int photometricInterpretation = 2; // TODO: - - int compression = TIFF_COMPRESSION_LZW; // LZW is default - if (params.containsKey(PARAM_KEY_COMPRESSION)) - { - Object value = params.get(PARAM_KEY_COMPRESSION); - if (value != null) - { - if (!(value instanceof Number)) - throw new ImageWriteException( - "Invalid compression parameter: " + value); - compression = ((Number) value).intValue(); - } - params.remove(PARAM_KEY_COMPRESSION); - } - - final int samplesPerPixel = 3; // TODO: - final int bitsPerSample = 8; // TODO: - - // int fRowsPerStrip; // TODO: - int rowsPerStrip = 8000 / (width * samplesPerPixel); // TODO: - rowsPerStrip = Math.max(1, rowsPerStrip); // must have at least one. - - byte strips[][] = getStrips(src, samplesPerPixel, bitsPerSample, - rowsPerStrip); - - // int stripCount = (height + fRowsPerStrip - 1) / fRowsPerStrip; - // int stripCount = strips.length; - - if (params.size() > 0) - { - Object firstKey = params.keySet().iterator().next(); - throw new ImageWriteException("Unknown parameter: " + firstKey); - } - - // System.out.println("width: " + width); - // System.out.println("height: " + height); - // System.out.println("fRowsPerStrip: " + fRowsPerStrip); - // System.out.println("fSamplesPerPixel: " + fSamplesPerPixel); - // System.out.println("stripCount: " + stripCount); - - if (compression == TIFF_COMPRESSION_PACKBITS) - { - for (int i = 0; i < strips.length; i++) - strips[i] = new PackBits().compress(strips[i]); - } - else if (compression == TIFF_COMPRESSION_LZW) - { - for (int i = 0; i < strips.length; i++) - { - byte uncompressed[] = strips[i]; - - int LZWMinimumCodeSize = 8; - - MyLZWCompressor compressor = new MyLZWCompressor( - LZWMinimumCodeSize, BYTE_ORDER_MSB, true); - byte compressed[] = compressor.compress(uncompressed); - - strips[i] = compressed; - } - } - else if (compression == TIFF_COMPRESSION_UNCOMPRESSED) - { - // do nothing. - } - else - throw new ImageWriteException( - "Invalid compression parameter (Only LZW, Packbits and uncompressed supported)."); - - // int stripOffsets[] = new int[stripCount]; - // int stripByteCounts[] = new int[stripCount]; - // - // for (int i = 0; i < strips.length; i++) - // stripByteCounts[i] = strips[i].length; - - TiffOutputDirectory directory = new TiffOutputDirectory( - TiffDirectory.DIRECTORY_TYPE_ROOT); - - // WriteField stripOffsetsField; - - { - { - TiffOutputField field = new TiffOutputField( - TIFF_TAG_IMAGE_WIDTH, FIELD_TYPE_LONG, 1, - FIELD_TYPE_LONG.writeData(new int[]{ - width, - }, byteOrder)); - directory.add(field); - } - { - TiffOutputField field = new TiffOutputField( - TIFF_TAG_IMAGE_LENGTH, FIELD_TYPE_LONG, 1, - FIELD_TYPE_LONG.writeData(new int[]{ - height, - }, byteOrder)); - directory.add(field); - } - { - TiffOutputField field = new TiffOutputField( - TIFF_TAG_PHOTOMETRIC_INTERPRETATION, FIELD_TYPE_SHORT, - 1, FIELD_TYPE_SHORT.writeData(new int[]{ - photometricInterpretation, - }, byteOrder)); - directory.add(field); - } - { - TiffOutputField field = new TiffOutputField( - TIFF_TAG_COMPRESSION, FIELD_TYPE_SHORT, 1, - FIELD_TYPE_SHORT.writeData(new int[]{ - compression, - }, byteOrder)); - directory.add(field); - } - { - TiffOutputField field = new TiffOutputField( - TIFF_TAG_SAMPLES_PER_PIXEL, FIELD_TYPE_SHORT, 1, - FIELD_TYPE_SHORT.writeData(new int[]{ - samplesPerPixel, - }, byteOrder)); - directory.add(field); - } - { - TiffOutputField field = new TiffOutputField( - TIFF_TAG_BITS_PER_SAMPLE, FIELD_TYPE_SHORT, 3, - FIELD_TYPE_SHORT.writeData(new int[]{ - bitsPerSample, bitsPerSample, bitsPerSample, - }, byteOrder)); - directory.add(field); - } - // { - // stripOffsetsField = new WriteField(TIFF_TAG_STRIP_OFFSETS, - // FIELD_TYPE_LONG, stripOffsets.length, FIELD_TYPE_LONG - // .writeData(stripOffsets, byteOrder)); - // directory.add(stripOffsetsField); - // } - // { - // WriteField field = new WriteField(TIFF_TAG_STRIP_BYTE_COUNTS, - // FIELD_TYPE_LONG, stripByteCounts.length, - // FIELD_TYPE_LONG.writeData(stripByteCounts, - // WRITE_BYTE_ORDER)); - // directory.add(field); - // } - { - TiffOutputField field = new TiffOutputField( - TIFF_TAG_ROWS_PER_STRIP, FIELD_TYPE_LONG, 1, - FIELD_TYPE_LONG.writeData(new int[]{ - rowsPerStrip, - }, byteOrder)); - directory.add(field); - } - - { - int resolutionUnit = 2;// inches. - TiffOutputField field = new TiffOutputField( - TIFF_TAG_RESOLUTION_UNIT, FIELD_TYPE_SHORT, 1, - FIELD_TYPE_SHORT.writeData(new int[]{ - resolutionUnit, - }, byteOrder)); - directory.add(field); - } - - { - int xResolution = 72; - TiffOutputField field = new TiffOutputField( - TIFF_TAG_XRESOLUTION, FIELD_TYPE_RATIONAL, 1, - FIELD_TYPE_RATIONAL - .writeData(xResolution, 1, byteOrder)); - directory.add(field); - } - - { - int yResolution = 72; - TiffOutputField field = new TiffOutputField( - TIFF_TAG_YRESOLUTION, FIELD_TYPE_RATIONAL, 1, - FIELD_TYPE_RATIONAL - .writeData(yResolution, 1, byteOrder)); - directory.add(field); - } - - } - - RawTiffImageData rawTiffImageData = new RawTiffImageData.Strips(strips); - directory.setRawTiffImageData(rawTiffImageData); - - ArrayList directories = new ArrayList(); - directories.add(directory); - - writeDirectories(os, directories); - } - - private void writeImageFileHeader(BinaryOutputStream bos) - throws IOException, ImageWriteException - { - bos.write(byteOrder); - bos.write(byteOrder); - - bos.write2Bytes(42); // tiffVersion - - int foffsetToFirstIFD = TIFF_HEADER_SIZE; - - bos.write4Bytes(foffsetToFirstIFD); - } - - static int imageDataPaddingLength(int dataLength) - { - return (4 - (dataLength % 4)) % 4; - } - - private TiffOutputDirectory findDirectoryByType(List directories, - int type) - { - for (int i = 0; i < directories.size(); i++) - { - TiffOutputDirectory directory = (TiffOutputDirectory) directories - .get(i); - if (directory.type == type) - return directory; - } - return null; - } - - public void writeDirectories(OutputStream os, List directories) - throws IOException, ImageWriteException - { - // Collections.sort(directories, Directory.COMPARATOR); - - /**/ - - // ImageDataInfo imageDataInfo = imageDataInfoStep(directories, imageData, - // stripsNotTiles); - /**/ - - PointerDirectoriesInfo pointerDirectoriesInfo = pointerDirectoriesStep(directories); - - /**/ - - // final int imageDataOffset = - calculateLengthsAndOffsetsStep(directories); - - /**/ - - updateDirectoryPointersStep(pointerDirectoriesInfo); - - /**/ - - // updateImageDataOffsetsStep(imageDataInfo, imageDataOffset); - /**/ - - DebugOutputStream dos = null; - // DebugOutputStream dos = new DebugOutputStream(os); - // os = dos; - BinaryOutputStream bos = new BinaryOutputStream(os, byteOrder); - - /**/ - - writeStep(bos, directories, dos); - - /**/ - - // writeImageDataStep(bos, directories, imageDataInfo); - /**/ - } - - private PointerDirectoriesInfo pointerDirectoriesStep(List directories) - throws ImageWriteException - { - TiffOutputDirectory firstDirectory = (TiffOutputDirectory) directories - .get(0); - - TiffOutputField exifDirectoryOffsetField = null; - TiffOutputDirectory exifDirectory = findDirectoryByType(directories, - TiffDirectory.DIRECTORY_TYPE_EXIF); - if (null != exifDirectory) - { - exifDirectoryOffsetField = firstDirectory - .findField(EXIF_TAG_GPSINFO); - - if (null == exifDirectoryOffsetField) - { - exifDirectoryOffsetField = new TiffOutputField( - EXIF_TAG_GPSINFO, FIELD_TYPE_LONG, 1, - FIELD_TYPE_LONG.writeData(new int[]{ - 0, - }, byteOrder)); - firstDirectory.add(exifDirectoryOffsetField); - } - } - - TiffOutputField gpsDirectoryOffsetField = null; - TiffOutputDirectory gpsDirectory = findDirectoryByType(directories, - TiffDirectory.DIRECTORY_TYPE_GPS); - if (null != gpsDirectory) - { - gpsDirectoryOffsetField = firstDirectory - .findField(EXIF_TAG_GPSINFO); - if (null == gpsDirectoryOffsetField) - { - gpsDirectoryOffsetField = new TiffOutputField( - EXIF_TAG_GPSINFO, FIELD_TYPE_LONG, 1, - FIELD_TYPE_LONG.writeData(new int[]{ - 0, - }, byteOrder)); - firstDirectory.add(gpsDirectoryOffsetField); - } - } - - TiffOutputField iteroperabilityDirectoryOffsetField = null; - TiffOutputDirectory iteroperabilityDirectory = findDirectoryByType( - directories, TiffDirectory.DIRECTORY_TYPE_INTEROPERABILITY); - if (null != iteroperabilityDirectory) - { - if (null == exifDirectory) - throw new ImageWriteException( - "Can't write iteroperability directory without EXIF directory."); - - iteroperabilityDirectoryOffsetField = exifDirectory - .findField(EXIF_TAG_INTEROP_OFFSET); - if (null == iteroperabilityDirectoryOffsetField) - { - iteroperabilityDirectoryOffsetField = new TiffOutputField( - EXIF_TAG_INTEROP_OFFSET, FIELD_TYPE_LONG, - 1, FIELD_TYPE_LONG.writeData(new int[]{ - 0, - }, byteOrder)); - exifDirectory.add(iteroperabilityDirectoryOffsetField); - } - } - - return new PointerDirectoriesInfo(exifDirectoryOffsetField, - exifDirectory, gpsDirectoryOffsetField, gpsDirectory, - iteroperabilityDirectoryOffsetField, iteroperabilityDirectory); - - } - - private void calculateLengthsAndOffsetsStep(List directories) - throws IOException, ImageWriteException - // private int calculateLengthsAndOffsetsStep(ArrayList directories) - { - // Calculate lengths and offsets - int offset = TIFF_HEADER_SIZE; - - TiffOutputDirectory previousDirectory = null; - for (int i = 0; i < directories.size(); i++) - { - TiffOutputDirectory directory = (TiffOutputDirectory) directories - .get(i); - - // fields must be written in ascending order. - directory.sortFields(); - - directory.offset = offset; - - if (directory.type == TiffDirectory.DIRECTORY_TYPE_EXIF - || directory.type == TiffDirectory.DIRECTORY_TYPE_GPS - || directory.type == TiffDirectory.DIRECTORY_TYPE_INTEROPERABILITY) - { - // "pointer" directories don't partcipate in normal TIFF directory chain. - directory.calculateLengths(byteOrder); - offset += directory.totalLength; - } - else - { - if (null != previousDirectory) - previousDirectory.nextDirectoryOffset = offset; - - directory.calculateLengths(byteOrder); - offset += directory.totalLength; - - previousDirectory = directory; - } - } - // return offset; - } - - private void updateDirectoryPointersStep( - PointerDirectoriesInfo pointerDirectoriesInfo) - { - if (null != pointerDirectoriesInfo.exifDirectory) - { - byte value[] = FIELD_TYPE_LONG.writeData(new int[]{ - pointerDirectoriesInfo.exifDirectory.offset, - }, byteOrder); - pointerDirectoriesInfo.exifDirectoryOffsetField.setData(value); - } - - if (null != pointerDirectoriesInfo.gpsDirectory) - { - byte value[] = FIELD_TYPE_LONG.writeData(new int[]{ - pointerDirectoriesInfo.gpsDirectory.offset, - }, byteOrder); - pointerDirectoriesInfo.gpsDirectoryOffsetField.setData(value); - } - - if (null != pointerDirectoriesInfo.iteroperabilityDirectory) - { - byte value[] = FIELD_TYPE_LONG.writeData(new int[]{ - pointerDirectoriesInfo.iteroperabilityDirectory.offset, - }, byteOrder); - pointerDirectoriesInfo.iteroperabilityDirectoryOffsetField - .setData(value); - } - } - - private void writeStep(BinaryOutputStream bos, List directories, - DebugOutputStream dos) throws IOException, ImageWriteException - { - writeImageFileHeader(bos); - - long count, lastCount = 0; - - if (null != dos) - { - count = dos.count(); - Debug.debug("image header" + " start: " + lastCount + ", end: " - + dos.count() + ", length: " + (count - lastCount)); - lastCount = count; - } - - for (int i = 0; i < directories.size(); i++) - { - TiffOutputDirectory directory = (TiffOutputDirectory) directories - .get(i); - directory.write(bos); - - if (null != dos) - { - count = dos.count(); - Debug.debug("directory(" - + TiffDirectory.description(directory.type) + ")" - + " start: " + lastCount + ", end: " + dos.count() - + ", length: " + (count - lastCount) - + ", expected length: " + directory.totalLength); - lastCount = count; - } - } - } + public TiffImageWriter() + { + } + + public TiffImageWriter(int byteOrder) + { + super(byteOrder); + } + + public byte[][] getStrips(BufferedImage src, int fSamplesPerPixel, + int bitsPerSample, int rowsPerStrip) + { + int width = src.getWidth(); + int height = src.getHeight(); + + int stripCount = (height + rowsPerStrip - 1) / rowsPerStrip; + + byte result[][] = null; + { // Write Strips + result = new byte[stripCount][]; + + int remaining_rows = height; + + for (int i = 0; i < stripCount; i++) + { + int rowsInStrip = Math.min(rowsPerStrip, remaining_rows); + remaining_rows -= rowsInStrip; + + int bitsInStrip = bitsPerSample * rowsInStrip * width + * fSamplesPerPixel; + int bytesInStrip = (bitsInStrip + 7) / 8; + + byte uncompressed[] = new byte[bytesInStrip]; + + int counter = 0; + int y = i * rowsPerStrip; + int stop = i * rowsPerStrip + rowsPerStrip; + + for (; (y < height) && (y < stop); y++) + { + for (int x = 0; x < width; x++) + { + int rgb = src.getRGB(x, y); + int red = 0xff & (rgb >> 16); + int green = 0xff & (rgb >> 8); + int blue = 0xff & (rgb >> 0); + + uncompressed[counter++] = (byte) red; + uncompressed[counter++] = (byte) green; + uncompressed[counter++] = (byte) blue; + } + } + + result[i] = uncompressed; + } + + } + + return result; + } + + public void writeImage(BufferedImage src, OutputStream os, Map params) + throws ImageWriteException, IOException + { + // writeImageNew(src, os, params); + // } + // + // public void writeImageNew(BufferedImage src, OutputStream os, Map params) + // throws ImageWriteException, IOException + // { + + // make copy of params; we'll clear keys as we consume them. + params = new HashMap(params); + + // clear format key. + if (params.containsKey(PARAM_KEY_FORMAT)) + params.remove(PARAM_KEY_FORMAT); + + int width = src.getWidth(); + int height = src.getHeight(); + + // BinaryOutputStream bos = new BinaryOutputStream(os, WRITE_BYTE_ORDER); + // + // writeImageFileHeader(bos, WRITE_BYTE_ORDER); + + // ArrayList directoryFields = new ArrayList(); + + final int photometricInterpretation = 2; // TODO: + + int compression = TIFF_COMPRESSION_LZW; // LZW is default + if (params.containsKey(PARAM_KEY_COMPRESSION)) + { + Object value = params.get(PARAM_KEY_COMPRESSION); + if (value != null) + { + if (!(value instanceof Number)) + throw new ImageWriteException( + "Invalid compression parameter: " + value); + compression = ((Number) value).intValue(); + } + params.remove(PARAM_KEY_COMPRESSION); + } + + final int samplesPerPixel = 3; // TODO: + final int bitsPerSample = 8; // TODO: + + // int fRowsPerStrip; // TODO: + int rowsPerStrip = 8000 / (width * samplesPerPixel); // TODO: + rowsPerStrip = Math.max(1, rowsPerStrip); // must have at least one. + + byte strips[][] = getStrips(src, samplesPerPixel, bitsPerSample, + rowsPerStrip); + + // int stripCount = (height + fRowsPerStrip - 1) / fRowsPerStrip; + // int stripCount = strips.length; + + if (params.size() > 0) + { + Object firstKey = params.keySet().iterator().next(); + throw new ImageWriteException("Unknown parameter: " + firstKey); + } + + // System.out.println("width: " + width); + // System.out.println("height: " + height); + // System.out.println("fRowsPerStrip: " + fRowsPerStrip); + // System.out.println("fSamplesPerPixel: " + fSamplesPerPixel); + // System.out.println("stripCount: " + stripCount); + + if (compression == TIFF_COMPRESSION_PACKBITS) + { + for (int i = 0; i < strips.length; i++) + strips[i] = new PackBits().compress(strips[i]); + } + else if (compression == TIFF_COMPRESSION_LZW) + { + for (int i = 0; i < strips.length; i++) + { + byte uncompressed[] = strips[i]; + + int LZWMinimumCodeSize = 8; + + MyLZWCompressor compressor = new MyLZWCompressor( + LZWMinimumCodeSize, BYTE_ORDER_MSB, true); + byte compressed[] = compressor.compress(uncompressed); + + strips[i] = compressed; + } + } + else if (compression == TIFF_COMPRESSION_UNCOMPRESSED) + { + // do nothing. + } + else + throw new ImageWriteException( + "Invalid compression parameter (Only LZW, Packbits and uncompressed supported)."); + + // int stripOffsets[] = new int[stripCount]; + // int stripByteCounts[] = new int[stripCount]; + // + // for (int i = 0; i < strips.length; i++) + // stripByteCounts[i] = strips[i].length; + + TiffOutputDirectory directory = new TiffOutputDirectory( + TiffDirectory.DIRECTORY_TYPE_ROOT); + + // WriteField stripOffsetsField; + + { + { + TiffOutputField field = new TiffOutputField( + TIFF_TAG_IMAGE_WIDTH, FIELD_TYPE_LONG, 1, + FIELD_TYPE_LONG.writeData(new int[]{ + width, + }, byteOrder)); + directory.add(field); + } + { + TiffOutputField field = new TiffOutputField( + TIFF_TAG_IMAGE_LENGTH, FIELD_TYPE_LONG, 1, + FIELD_TYPE_LONG.writeData(new int[]{ + height, + }, byteOrder)); + directory.add(field); + } + { + TiffOutputField field = new TiffOutputField( + TIFF_TAG_PHOTOMETRIC_INTERPRETATION, FIELD_TYPE_SHORT, + 1, FIELD_TYPE_SHORT.writeData(new int[]{ + photometricInterpretation, + }, byteOrder)); + directory.add(field); + } + { + TiffOutputField field = new TiffOutputField( + TIFF_TAG_COMPRESSION, FIELD_TYPE_SHORT, 1, + FIELD_TYPE_SHORT.writeData(new int[]{ + compression, + }, byteOrder)); + directory.add(field); + } + { + TiffOutputField field = new TiffOutputField( + TIFF_TAG_SAMPLES_PER_PIXEL, FIELD_TYPE_SHORT, 1, + FIELD_TYPE_SHORT.writeData(new int[]{ + samplesPerPixel, + }, byteOrder)); + directory.add(field); + } + { + TiffOutputField field = new TiffOutputField( + TIFF_TAG_BITS_PER_SAMPLE, FIELD_TYPE_SHORT, 3, + FIELD_TYPE_SHORT.writeData(new int[]{ + bitsPerSample, bitsPerSample, bitsPerSample, + }, byteOrder)); + directory.add(field); + } + // { + // stripOffsetsField = new WriteField(TIFF_TAG_STRIP_OFFSETS, + // FIELD_TYPE_LONG, stripOffsets.length, FIELD_TYPE_LONG + // .writeData(stripOffsets, byteOrder)); + // directory.add(stripOffsetsField); + // } + // { + // WriteField field = new WriteField(TIFF_TAG_STRIP_BYTE_COUNTS, + // FIELD_TYPE_LONG, stripByteCounts.length, + // FIELD_TYPE_LONG.writeData(stripByteCounts, + // WRITE_BYTE_ORDER)); + // directory.add(field); + // } + { + TiffOutputField field = new TiffOutputField( + TIFF_TAG_ROWS_PER_STRIP, FIELD_TYPE_LONG, 1, + FIELD_TYPE_LONG.writeData(new int[]{ + rowsPerStrip, + }, byteOrder)); + directory.add(field); + } + + { + int resolutionUnit = 2;// inches. + TiffOutputField field = new TiffOutputField( + TIFF_TAG_RESOLUTION_UNIT, FIELD_TYPE_SHORT, 1, + FIELD_TYPE_SHORT.writeData(new int[]{ + resolutionUnit, + }, byteOrder)); + directory.add(field); + } + + { + int xResolution = 72; + TiffOutputField field = new TiffOutputField( + TIFF_TAG_XRESOLUTION, FIELD_TYPE_RATIONAL, 1, + FIELD_TYPE_RATIONAL + .writeData(xResolution, 1, byteOrder)); + directory.add(field); + } + + { + int yResolution = 72; + TiffOutputField field = new TiffOutputField( + TIFF_TAG_YRESOLUTION, FIELD_TYPE_RATIONAL, 1, + FIELD_TYPE_RATIONAL + .writeData(yResolution, 1, byteOrder)); + directory.add(field); + } + + } + + RawTiffImageData rawTiffImageData = new RawTiffImageData.Strips(strips); + directory.setRawTiffImageData(rawTiffImageData); + + ArrayList directories = new ArrayList(); + directories.add(directory); + + writeDirectories(os, directories); + } + + private void writeImageFileHeader(BinaryOutputStream bos) + throws IOException, ImageWriteException + { + bos.write(byteOrder); + bos.write(byteOrder); + + bos.write2Bytes(42); // tiffVersion + + int foffsetToFirstIFD = TIFF_HEADER_SIZE; + + bos.write4Bytes(foffsetToFirstIFD); + } + + static int imageDataPaddingLength(int dataLength) + { + return (4 - (dataLength % 4)) % 4; + } + + private TiffOutputDirectory findDirectoryByType(List directories, int type) + { + for (int i = 0; i < directories.size(); i++) + { + TiffOutputDirectory directory = (TiffOutputDirectory) directories + .get(i); + if (directory.type == type) + return directory; + } + return null; + } + + private PointerDirectoriesInfo validateDirectories(List directories) + throws ImageWriteException + { + if (1 > directories.size()) + throw new ImageWriteException("No directories."); + + TiffOutputDirectory exifDirectory = null; + TiffOutputDirectory gpsDirectory = null; + TiffOutputDirectory interoperabilityDirectory = null; + TiffOutputField exifDirectoryOffsetField = null; + TiffOutputField gpsDirectoryOffsetField = null; + TiffOutputField interoperabilityDirectoryOffsetField = null; + + ArrayList directoryIndices = new ArrayList(); + Map dirMap = new HashMap(); + for (int i = 0; i < directories.size(); i++) + { + TiffOutputDirectory directory = (TiffOutputDirectory) directories + .get(i); + int dirType = directory.type; + Integer key = new Integer(dirType); + dirMap.put(key, directory); + // Debug.debug("validating dirType", dirType + " (" + // + directory.getFields().size() + " fields)"); + + if (dirType < 0) + { + switch (dirType) + { + case DIRECTORY_TYPE_EXIF : + if (exifDirectory != null) + throw new ImageWriteException( + "More than one EXIF directory."); + exifDirectory = directory; + break; + + case DIRECTORY_TYPE_GPS : + if (gpsDirectory != null) + throw new ImageWriteException( + "More than one GPS directory."); + gpsDirectory = directory; + break; + + case DIRECTORY_TYPE_INTEROPERABILITY : + if (interoperabilityDirectory != null) + throw new ImageWriteException( + "More than one Interoperability directory."); + interoperabilityDirectory = directory; + break; + default : + throw new ImageWriteException("Unknown directory: " + + dirType); + } + } + else + { + if (directoryIndices.contains(key)) + throw new ImageWriteException( + "More than one directory with index: " + dirType + + "."); + directoryIndices.add(new Integer(dirType)); + // dirMap.put(arg0, arg1) + } + + ArrayList fields = directory.getFields(); + for (int j = 0; j < fields.size(); j++) + { + TiffOutputField field = (TiffOutputField) fields.get(j); + if (field.tagInfo.tag == EXIF_TAG_EXIF_OFFSET.tag) + { + if (exifDirectoryOffsetField != null) + throw new ImageWriteException( + "More than one Exif directory offset field."); + exifDirectoryOffsetField = field; + } + else if (field.tagInfo.tag == EXIF_TAG_INTEROP_OFFSET.tag) + { + if (interoperabilityDirectoryOffsetField != null) + throw new ImageWriteException( + "More than one Interoperability directory offset field."); + interoperabilityDirectoryOffsetField = field; + } + else if (field.tagInfo.tag == EXIF_TAG_GPSINFO.tag) + { + if (gpsDirectoryOffsetField != null) + throw new ImageWriteException( + "More than one GPS directory offset field."); + gpsDirectoryOffsetField = field; + } + } + // directory. + } + + if (directoryIndices.size() < 1) + throw new ImageWriteException("Missing root directory."); + + // "normal" TIFF directories should have continous indices starting with 0, ie. 0, 1, 2... + Collections.sort(directoryIndices); + for (int i = 0; i < directoryIndices.size(); i++) + { + Integer index = (Integer) directoryIndices.get(i); + if (index.intValue() != i) + throw new ImageWriteException("Missing directory: " + i + "."); + } + + TiffOutputDirectory rootDirectory = (TiffOutputDirectory) dirMap + .get(new Integer(DIRECTORY_TYPE_ROOT)); + + + if (exifDirectory == null && exifDirectoryOffsetField != null) + { + // perhaps we should just discard field? + throw new ImageWriteException( + "Output set has Exif Directory Offset field, but no Exif Directory"); + } + else if (exifDirectory != null && exifDirectoryOffsetField == null) + { + exifDirectoryOffsetField = TiffOutputField.createOffsetField( + EXIF_TAG_EXIF_OFFSET, byteOrder); + rootDirectory.add(exifDirectoryOffsetField); + } + + if (gpsDirectory == null && gpsDirectoryOffsetField != null) + { + // perhaps we should just discard field? + throw new ImageWriteException( + "Output set has GPS Directory Offset field, but no GPS Directory"); + } + else if (gpsDirectory != null && gpsDirectoryOffsetField == null) + { + gpsDirectoryOffsetField = TiffOutputField.createOffsetField( + EXIF_TAG_GPSINFO, byteOrder); + rootDirectory.add(gpsDirectoryOffsetField); + } + + + if (interoperabilityDirectory == null && interoperabilityDirectoryOffsetField != null) + { + // perhaps we should just discard field? + throw new ImageWriteException( + "Output set has Interoperability Directory Offset field, but no Interoperability Directory"); + } + else if (interoperabilityDirectory != null && interoperabilityDirectoryOffsetField == null) + { + interoperabilityDirectoryOffsetField = TiffOutputField.createOffsetField( + EXIF_TAG_INTEROP_OFFSET, byteOrder); + rootDirectory.add(interoperabilityDirectoryOffsetField); + } + + return new PointerDirectoriesInfo(exifDirectoryOffsetField, + exifDirectory, gpsDirectoryOffsetField, gpsDirectory, + interoperabilityDirectoryOffsetField, interoperabilityDirectory); + + // Debug.debug(); + } + + public void writeDirectories(OutputStream os, List directories) + throws IOException, ImageWriteException + { + + PointerDirectoriesInfo pointerDirectoriesInfo = validateDirectories(directories); + + // Collections.sort(directories, Directory.COMPARATOR); + + /**/ + + // ImageDataInfo imageDataInfo = imageDataInfoStep(directories, imageData, + // stripsNotTiles); + /**/ + +// PointerDirectoriesInfo pointerDirectoriesInfo = pointerDirectoriesStep(directories); + + /**/ + + // final int imageDataOffset = + calculateLengthsAndOffsetsStep(directories); + + /**/ + + updateDirectoryPointersStep(pointerDirectoriesInfo); + + /**/ + + // updateImageDataOffsetsStep(imageDataInfo, imageDataOffset); + /**/ + + DebugOutputStream dos = null; + // DebugOutputStream dos = new DebugOutputStream(os); + // os = dos; + BinaryOutputStream bos = new BinaryOutputStream(os, byteOrder); + + /**/ + + writeStep(bos, directories, dos); + + /**/ + + // writeImageDataStep(bos, directories, imageDataInfo); + /**/ + } + + + + private void calculateLengthsAndOffsetsStep(List directories) + throws IOException, ImageWriteException + // private int calculateLengthsAndOffsetsStep(ArrayList directories) + { + // Calculate lengths and offsets + int offset = TIFF_HEADER_SIZE; + + TiffOutputDirectory previousDirectory = null; + for (int i = 0; i < directories.size(); i++) + { + TiffOutputDirectory directory = (TiffOutputDirectory) directories + .get(i); + + // fields must be written in ascending order. + directory.sortFields(); + + directory.offset = offset; + + if (directory.type == TiffDirectory.DIRECTORY_TYPE_EXIF + || directory.type == TiffDirectory.DIRECTORY_TYPE_GPS + || directory.type == TiffDirectory.DIRECTORY_TYPE_INTEROPERABILITY) + { + // "pointer" directories don't partcipate in normal TIFF directory chain. + directory.calculateLengths(byteOrder); + offset += directory.totalLength; + } + else + { + if (null != previousDirectory) + previousDirectory.nextDirectoryOffset = offset; + + directory.calculateLengths(byteOrder); + offset += directory.totalLength; + + previousDirectory = directory; + } + } + // return offset; + } + + private void updateDirectoryPointersStep( + PointerDirectoriesInfo pointerDirectoriesInfo) + { + if (null != pointerDirectoriesInfo.exifDirectory) + { + byte value[] = FIELD_TYPE_LONG.writeData(new int[]{ + pointerDirectoriesInfo.exifDirectory.offset, + }, byteOrder); + pointerDirectoriesInfo.exifDirectoryOffsetField.setData(value); + } + + if (null != pointerDirectoriesInfo.gpsDirectory) + { + byte value[] = FIELD_TYPE_LONG.writeData(new int[]{ + pointerDirectoriesInfo.gpsDirectory.offset, + }, byteOrder); + pointerDirectoriesInfo.gpsDirectoryOffsetField.setData(value); + } + + if (null != pointerDirectoriesInfo.interoperabilityDirectory) + { + byte value[] = FIELD_TYPE_LONG.writeData(new int[]{ + pointerDirectoriesInfo.interoperabilityDirectory.offset, + }, byteOrder); + pointerDirectoriesInfo.interoperabilityDirectoryOffsetField + .setData(value); + } + } + + private void writeStep(BinaryOutputStream bos, List directories, + DebugOutputStream dos) throws IOException, ImageWriteException + { + writeImageFileHeader(bos); + + long count, lastCount = 0; + + if (null != dos) + { + count = dos.count(); + Debug.debug("image header" + " start: " + lastCount + ", end: " + + dos.count() + ", length: " + (count - lastCount)); + lastCount = count; + } + + for (int i = 0; i < directories.size(); i++) + { + TiffOutputDirectory directory = (TiffOutputDirectory) directories + .get(i); + directory.write(bos); + + if (null != dos) + { + count = dos.count(); + Debug.debug("directory(" + + TiffDirectory.description(directory.type) + ")" + + " start: " + lastCount + ", end: " + dos.count() + + ", length: " + (count - lastCount) + + ", expected length: " + directory.totalLength); + lastCount = count; + } + } + } } - - Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputField.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputField.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputField.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputField.java Sun Jan 6 19:40:10 2008 @@ -26,24 +26,42 @@ public class TiffOutputField implements TiffConstants { + public final int tag; public final TagInfo2 tagInfo; public final FieldType fieldType; public final int count; public byte bytes[]; - public TiffOutputField(TagInfo2 tag, FieldType tagtype, int count, byte bytes[]) + public TiffOutputField(TagInfo2 tagInfo, FieldType tagtype, int count, + byte bytes[]) { - this.tagInfo = tag; + this(tagInfo.tag, tagInfo, tagtype, count, bytes); + } + + public TiffOutputField(final int tag, TagInfo2 tagInfo, FieldType tagtype, + int count, byte bytes[]) + { + this.tag = tag; + this.tagInfo = tagInfo; this.fieldType = tagtype; this.count = count; this.bytes = bytes; } + public static final TiffOutputField createOffsetField(TagInfo2 tagInfo, + int byteOrder) + { + return new TiffOutputField(tagInfo, FIELD_TYPE_LONG, 1, FIELD_TYPE_LONG + .writeData(new int[]{ + 0, + }, byteOrder)); + } + public int writeDirectoryEntry(BinaryOutputStream bos, int seperateValuesOffset) throws ImageWriteException, IOException { - bos.write2Bytes(tagInfo.tag); + bos.write2Bytes(tag); bos.write2Bytes(fieldType.type); bos.write4Bytes(count); @@ -104,5 +122,33 @@ public void setData(byte bytes[]) { this.bytes = bytes; + } + + private static final String newline = System.getProperty("line.separator"); + + public String toString() + { + return toString(null); + } + + public String toString(String prefix) + { + if (prefix == null) + prefix = ""; + StringBuffer result = new StringBuffer(); + + result.append(prefix); + result.append(tagInfo); + result.append(newline); + + result.append(prefix); + result.append("count: " + count); + result.append(newline); + + result.append(prefix); + result.append(fieldType); + result.append(newline); + + return result.toString(); } } Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSet.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSet.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSet.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSet.java Sun Jan 6 19:40:10 2008 @@ -21,6 +21,7 @@ import org.apache.sanselan.ImageWriteException; import org.apache.sanselan.formats.tiff.constants.TiffConstants; +import org.apache.sanselan.util.Debug; public final class TiffOutputSet implements TiffConstants { @@ -124,5 +125,58 @@ // public static final int DIRECTORY_TYPE_DIR_2 = 2; // public static final int DIRECTORY_TYPE_DIR_3 = 3; // public static final int DIRECTORY_TYPE_DIR_4 = 4; + + + private static final String newline = System.getProperty("line.separator"); + + public String toString() + { + return toString(null); + } + + public String toString(String prefix) + { + if (prefix == null) + prefix = ""; + + StringBuffer result = new StringBuffer(); + + + result.append(prefix); + result.append("TiffOutputSet {"); + result.append(newline ); + + result.append(prefix); + result.append("byteOrder: " + byteOrder); + result.append(newline ); + + for(int i=0;i<directories.size();i++) + { + TiffOutputDirectory directory = (TiffOutputDirectory) directories.get(i); + result.append(prefix ); + result.append("\t" + "directory " + i + ": " + directory.description() + " (" + directory.type + ")"); + result.append(newline ); + + ArrayList fields = directory.getFields(); + for(int j=0;j<fields.size();j++) + { + TiffOutputField field = (TiffOutputField) fields.get(j); + result.append(prefix ); + result.append("\t\t" + "field " + i + ": " + field.tagInfo ); + result.append(newline ); + } + } + + result.append(prefix); + result.append("}"); + result.append(newline ); + + return result.toString(); + } + + public void dump() + { + Debug.debug(this.toString()); + } } Modified: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/ExifRewriteTest.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/ExifRewriteTest.java?rev=609505&r1=609504&r2=609505&view=diff ============================================================================== --- incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/ExifRewriteTest.java (original) +++ incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/ExifRewriteTest.java Sun Jan 6 19:40:10 2008 @@ -20,23 +20,27 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Hashtable; import java.util.List; -import org.apache.sanselan.ImageFormat; import org.apache.sanselan.ImageReadException; import org.apache.sanselan.ImageWriteException; import org.apache.sanselan.Sanselan; -import org.apache.sanselan.SanselanTest; import org.apache.sanselan.common.byteSources.ByteSource; import org.apache.sanselan.common.byteSources.ByteSourceArray; import org.apache.sanselan.common.byteSources.ByteSourceFile; -import org.apache.sanselan.formats.jpeg.JpegImageMetadata.Photoshop; import org.apache.sanselan.formats.jpeg.exifRewrite.ExifRewriter; +import org.apache.sanselan.formats.tiff.TiffField; import org.apache.sanselan.formats.tiff.TiffImageMetadata; +import org.apache.sanselan.formats.tiff.constants.AllTagConstants; +import org.apache.sanselan.formats.tiff.write.TiffOutputField; +import org.apache.sanselan.formats.tiff.write.TiffOutputSet; import org.apache.sanselan.util.Debug; import org.apache.sanselan.util.IOUtils; -public class ExifRewriteTest extends ExifBaseTest +public class ExifRewriteTest extends ExifBaseTest implements AllTagConstants { public ExifRewriteTest(String name) { @@ -92,37 +96,165 @@ Debug.debug("Source Segments:"); new JpegUtils().dumpJFIF(byteSource); - { - JpegImageMetadata metadata = (JpegImageMetadata) Sanselan - .getMetadata(imageFile); - assertNotNull(metadata.getExif()); - metadata.dump(); + JpegImageMetadata oldMetadata = (JpegImageMetadata) Sanselan + .getMetadata(imageFile); + assertNotNull(oldMetadata); + + TiffImageMetadata oldExifMetadata = oldMetadata.getExif(); + assertNotNull(oldExifMetadata); + oldMetadata.dump(); + + // TiffImageMetadata tiffImageMetadata = metadata.getExif(); + // Photoshop photoshop = metadata.getPhotoshop(); + + TiffOutputSet outputSet = oldExifMetadata.getOutputSet(); + outputSet.dump(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + new ExifRewriter().updateExifMetadata(byteSource, baos, outputSet); + byte bytes[] = baos.toByteArray(); + File tempFile = File.createTempFile("test", ".jpg"); + Debug.debug("tempFile", tempFile); + // tempFile.deleteOnExit(); + IOUtils.writeToFile(bytes, tempFile); + + Debug.debug("Output Segments:"); + new JpegUtils().dumpJFIF(new ByteSourceArray(bytes)); + + // assertTrue(!hasExifData(tempFile)); + + JpegImageMetadata newMetadata = (JpegImageMetadata) Sanselan + .getMetadata(tempFile); + assertNotNull(newMetadata); + TiffImageMetadata newExifMetadata = newMetadata.getExif(); + assertNotNull(newExifMetadata); + newMetadata.dump(); - // TiffImageMetadata tiffImageMetadata = metadata.getExif(); - // Photoshop photoshop = metadata.getPhotoshop(); - } + compare(oldExifMetadata, newExifMetadata); + } + } + + private Hashtable makeDirectoryMap(ArrayList directories) + { + Hashtable directoryMap = new Hashtable(); + for (int i = 0; i < directories.size(); i++) + { + TiffImageMetadata.Directory directory = (TiffImageMetadata.Directory) directories + .get(i); + directoryMap.put(new Integer(directory.type), directory); + } + return directoryMap; + } + private Hashtable makeFieldMap(ArrayList items) + { + Hashtable fieldMap = new Hashtable(); + for (int i = 0; i < items.size(); i++) + { + TiffImageMetadata.Item item = (TiffImageMetadata.Item) items.get(i); + TiffField field = item.getTiffField(); + fieldMap.put(new Integer(field.tag), field); + } + return fieldMap; + } + + private void compare(TiffImageMetadata oldExifMetadata, + TiffImageMetadata newExifMetadata) + { + assertNotNull(oldExifMetadata); + assertNotNull(newExifMetadata); + + ArrayList oldDirectories = oldExifMetadata.getDirectories(); + ArrayList newDirectories = newExifMetadata.getDirectories(); + + assertTrue(oldDirectories.size() == newDirectories.size()); + + Hashtable oldDirectoryMap = makeDirectoryMap(oldDirectories); + Hashtable newDirectoryMap = makeDirectoryMap(newDirectories); + + assertEquals(oldDirectories.size(), oldDirectoryMap.keySet().size()); + ArrayList oldDirectoryTypes = new ArrayList(oldDirectoryMap.keySet()); + Collections.sort(oldDirectoryTypes); + ArrayList newDirectoryTypes = new ArrayList(newDirectoryMap.keySet()); + Collections.sort(newDirectoryTypes); + assertEquals(oldDirectoryTypes, newDirectoryTypes); + + for (int i = 0; i < oldDirectoryTypes.size(); i++) + { + Integer dirType = (Integer) oldDirectoryTypes.get(i); + +// Debug.debug("dirType", dirType); + + TiffImageMetadata.Directory oldDirectory = (TiffImageMetadata.Directory) oldDirectoryMap + .get(dirType); + TiffImageMetadata.Directory newDirectory = (TiffImageMetadata.Directory) newDirectoryMap + .get(dirType); + assertNotNull(oldDirectory); + assertNotNull(newDirectory); + + ArrayList oldItems = oldDirectory.getItems(); + ArrayList newItems = newDirectory.getItems(); + + assertTrue(oldItems.size() == newItems.size()); + + Hashtable oldFieldMap = makeFieldMap(oldItems); + Hashtable newFieldMap = makeFieldMap(newItems); + + assertEquals(oldItems.size(), oldFieldMap.keySet().size()); + // assertEquals(oldFieldMap.keySet(), newFieldMap.keySet()); + // assertEquals(oldFieldMap.keySet(), newFieldMap.keySet()); + + ArrayList oldFieldTags = new ArrayList(oldFieldMap.keySet()); + Collections.sort(oldFieldTags); + ArrayList newFieldTags = new ArrayList(newFieldMap.keySet()); + Collections.sort(newFieldTags); + assertEquals(oldFieldTags, newFieldTags); + + for (int j = 0; j < oldFieldTags.size(); j++) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - new ExifRewriter().removeExifMetadata(byteSource, baos, null); - byte bytes[] = baos.toByteArray(); - File tempFile = File.createTempFile("test", ".jpg"); - Debug.debug("tempFile", tempFile); - tempFile.deleteOnExit(); - IOUtils.writeToFile(bytes, tempFile); + Integer fieldTag = (Integer) oldFieldTags.get(j); - Debug.debug("Output Segments:"); - new JpegUtils().dumpJFIF(new ByteSourceArray(bytes)); + TiffField oldField = (TiffField) oldFieldMap.get(fieldTag); + TiffField newField = (TiffField) newFieldMap.get(fieldTag); - assertTrue(!hasExifData(tempFile)); +// Debug.debug("fieldTag", fieldTag); + + // fieldTag. + assertNotNull(oldField); + assertNotNull(newField); + + assertEquals(oldField.tag, newField.tag); + assertEquals(dirType.intValue(), newField.directoryType); + assertEquals(oldField.directoryType, newField.directoryType); + assertEquals(oldField.length, newField.length); + assertEquals(oldField.isLocalValue(), newField.isLocalValue()); + + + if(!oldField.tagInfo.isOffset()) + { + if (oldField.isLocalValue()) + { + compare(oldField.valueOffsetBytes, + newField.valueOffsetBytes); + } + else + { + compare(oldField.oversizeValue, newField.oversizeValue); + } + } - JpegImageMetadata metadata = (JpegImageMetadata) Sanselan - .getMetadata(tempFile); - // assertNotNull(metadata); - // assertNotNull(metadata.getExif()); - // metadata.dump(); } + +// Debug.debug(); } } + private void compare(byte a[], byte b[]) + { + assertNotNull(a); + assertNotNull(b); + assertEquals(a.length, b.length); + for (int i = 0; i < a.length; i++) + assertEquals(a[i], b[i]); + } } From sanselan-commits-return-85adamswilliam@example.net Mon Jan 07 03:45:52 2008 Return-Path: <sanselan-commits-return-85adamswilliam@example.net> Delivered-To: adamswilliam@example.net Received: (qmail 70161 invoked from network); 7 Jan 2008 03:45:52 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 7 Jan 2008 03:45:52 -0000 Received: (qmail 63791 invoked by uid 500); 7 Jan 2008 03:45:42 -0000 Delivered-To: adamswilliam@example.net Received: (qmail 63770 invoked by uid 500); 7 Jan 2008 03:45:42 -0000 Mailing-List: contact adamswilliam@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:adamswilliam@example.net> List-Unsubscribe: <mailto:adamswilliam@example.net> List-Post: <mailto:adamswilliam@example.net> List-Id: <sanselan-commits.incubator.apache.org> Reply-To: adamswilliam@example.net Delivered-To: mailing list adamswilliam@example.net Received: (qmail 63756 invoked by uid 99); 7 Jan 2008 03:45:42 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 06 Jan 2008 19:45:41 -0800 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,UPPERCASE_50_75 X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 07 Jan 2008 03:45:25 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id EA53B1A9896; Sun, 6 Jan 2008 19:45:30 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r609506 [2/3] - 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/comm... Date: Mon, 07 Jan 2008 03:45:24 -0000 To: adamswilliam@example.net From: adamswilliam@example.net X-Mailer: svnmailer-1.0.8 Message-Id: <adamswilliam@example.net> X-Virus-Checked: Checked by ClamAV on apache.org Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java?rev=609506&r1=609505&r2=609506&view=diff ============================================================================== --- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java (original) +++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/constants/ExifTagConstants.java Sun Jan 6 19:45:20 2008 @@ -21,16 +21,16 @@ TiffDirectoryConstants, TiffFieldTypeConstants { /**/ - public static final TagInfo2 EXIF_TAG_INTEROP_INDEX = new TagInfo2( + public static final TagInfo EXIF_TAG_INTEROP_INDEX = new TagInfo( "Interop Index", 0x0001, FIELD_TYPE_ASCII, 1, EXIF_DIRECTORY_INTEROP_IFD); - public static final TagInfo2 EXIF_TAG_INTEROP_VERSION = new TagInfo2( + public static final TagInfo EXIF_TAG_INTEROP_VERSION = new TagInfo( "Interop Version", 0x0002, FIELD_TYPE_UNDEFINED, 1, EXIF_DIRECTORY_INTEROP_IFD); - public static final TagInfo2 EXIF_TAG_PROCESSING_SOFTWARE = new TagInfo2( + public static final TagInfo EXIF_TAG_PROCESSING_SOFTWARE = new TagInfo( "Processing Software", 0x000b, FIELD_TYPE_ASCII, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_SUBFILE_TYPE = new TagInfo2( + public static final TagInfo EXIF_TAG_SUBFILE_TYPE = new TagInfo( "Subfile Type", 0x00fe, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_IFD0); // tag constants public static final int SUBFILE_TYPE_VALUE_FULL_RESOLUTION_IMAGE = 0; public static final int SUBFILE_TYPE_VALUE_REDUCED_RESOLUTION_IMAGE = 1; @@ -40,20 +40,20 @@ public static final int SUBFILE_TYPE_VALUE_TRANSPARENCY_MASK_OF_REDUCED_RESOLUTION_IMAGE = 5; public static final int SUBFILE_TYPE_VALUE_TRANSPARENCY_MASK_OF_MULTI_PAGE_IMAGE = 6; public static final int SUBFILE_TYPE_VALUE_TRANSPARENCY_MASK_OF_REDUCED_RESOLUTION_MULTI_PAGE_IMAGE = 7; - public static final TagInfo2 EXIF_TAG_OLD_SUBFILE_TYPE = new TagInfo2( + public static final TagInfo EXIF_TAG_OLD_SUBFILE_TYPE = new TagInfo( "Old Subfile Type", 0x00ff, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); // tag constants public static final int OLD_SUBFILE_TYPE_VALUE_FULL_RESOLUTION_IMAGE = 1; public static final int OLD_SUBFILE_TYPE_VALUE_REDUCED_RESOLUTION_IMAGE = 2; public static final int OLD_SUBFILE_TYPE_VALUE_SINGLE_PAGE_OF_MULTI_PAGE_IMAGE = 3; - public static final TagInfo2 EXIF_TAG_IMAGE_WIDTH_IFD0 = new TagInfo2( + public static final TagInfo EXIF_TAG_IMAGE_WIDTH_IFD0 = new TagInfo( "Image Width", 0x0100, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_IMAGE_HEIGHT_IFD0 = new TagInfo2( + public static final TagInfo EXIF_TAG_IMAGE_HEIGHT_IFD0 = new TagInfo( "Image Height", 0x0101, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_BITS_PER_SAMPLE = new TagInfo2( + public static final TagInfo EXIF_TAG_BITS_PER_SAMPLE = new TagInfo( "Bits Per Sample", 0x0102, FIELD_TYPE_SHORT, -1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_COMPRESSION = new TagInfo2( + public static final TagInfo EXIF_TAG_COMPRESSION = new TagInfo( "Compression", 0x0103, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); // tag constants public static final int COMPRESSION_VALUE_UNCOMPRESSED = 1; public static final int COMPRESSION_VALUE_CCITT_1D = 2; @@ -85,7 +85,7 @@ public static final int COMPRESSION_VALUE_NIKON_NEF_COMPRESSED = 34713; public static final int COMPRESSION_VALUE_KODAK_DCR_COMPRESSED = 65000; public static final int COMPRESSION_VALUE_PENTAX_PEF_COMPRESSED = 65535; - public static final TagInfo2 EXIF_TAG_PHOTOMETRIC_INTERPRETATION = new TagInfo2( + public static final TagInfo EXIF_TAG_PHOTOMETRIC_INTERPRETATION = new TagInfo( "Photometric Interpretation", 0x0106, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); // tag constants public static final int PHOTOMETRIC_INTERPRETATION_VALUE_WHITE_IS_ZERO = 0; @@ -102,39 +102,39 @@ public static final int PHOTOMETRIC_INTERPRETATION_VALUE_PIXAR_LOG_L = 32844; public static final int PHOTOMETRIC_INTERPRETATION_VALUE_PIXAR_LOG_LUV = 32845; public static final int PHOTOMETRIC_INTERPRETATION_VALUE_LINEAR_RAW = 34892; - public static final TagInfo2 EXIF_TAG_THRESHOLDING = new TagInfo2( + public static final TagInfo EXIF_TAG_THRESHOLDING = new TagInfo( "Thresholding", 0x0107, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); // tag constants public static final int THRESHOLDING_VALUE_NO_DITHERING_OR_HALFTONING = 1; public static final int THRESHOLDING_VALUE_ORDERED_DITHER_OR_HALFTONE = 2; public static final int THRESHOLDING_VALUE_RANDOMIZED_DITHER = 3; - public static final TagInfo2 EXIF_TAG_CELL_WIDTH = new TagInfo2( - "Cell Width", 0x0108, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_CELL_LENGTH = new TagInfo2( + public static final TagInfo EXIF_TAG_CELL_WIDTH = new TagInfo("Cell Width", + 0x0108, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); + public static final TagInfo EXIF_TAG_CELL_LENGTH = new TagInfo( "Cell Length", 0x0109, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_FILL_ORDER = new TagInfo2( - "Fill Order", 0x010a, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); + public static final TagInfo EXIF_TAG_FILL_ORDER = new TagInfo("Fill Order", + 0x010a, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); // tag constants public static final int FILL_ORDER_VALUE_NORMAL = 1; public static final int FILL_ORDER_VALUE_REVERSED = 2; - public static final TagInfo2 EXIF_TAG_DOCUMENT_NAME = new TagInfo2( + public static final TagInfo EXIF_TAG_DOCUMENT_NAME = new TagInfo( "Document Name", 0x010d, FIELD_TYPE_ASCII, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_IMAGE_DESCRIPTION = new TagInfo2( + public static final TagInfo EXIF_TAG_IMAGE_DESCRIPTION = new TagInfo( "Image Description", 0x010e, FIELD_TYPE_ASCII, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_MAKE = new TagInfo2("Make", 0x010f, + public static final TagInfo EXIF_TAG_MAKE = new TagInfo("Make", 0x010f, FIELD_TYPE_ASCII, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_MODEL = new TagInfo2("Model", 0x0110, + public static final TagInfo EXIF_TAG_MODEL = new TagInfo("Model", 0x0110, FIELD_TYPE_ASCII, 1, EXIF_DIRECTORY_IFD0); // poly tag public static final TagInfo2 EXIF_TAG_STRIP_OFFSETS = new TagInfo2( "StripOffsets", 0x0111, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); - public static final TagInfo2 EXIF_TAG_PREVIEW_IMAGE_START_IFD0 = new TagInfo2( + public static final TagInfo EXIF_TAG_PREVIEW_IMAGE_START_IFD0 = new TagInfo( "Preview Image Start", 0x0111, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_PREVIEW_IMAGE_START_SUB_IFD1 = new TagInfo2( + public static final TagInfo EXIF_TAG_PREVIEW_IMAGE_START_SUB_IFD1 = new TagInfo( "Preview Image Start", 0x0111, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_SUB_IFD1); - public static final TagInfo2 EXIF_TAG_JPG_FROM_RAW_START_SUB_IFD2 = new TagInfo2( + public static final TagInfo EXIF_TAG_JPG_FROM_RAW_START_SUB_IFD2 = new TagInfo( "Jpg From Raw Start", 0x0111, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_SUB_IFD2); - public static final TagInfo2 EXIF_TAG_ORIENTATION = new TagInfo2( + public static final TagInfo EXIF_TAG_ORIENTATION = new TagInfo( "Orientation", 0x0112, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); // tag constants public static final int ORIENTATION_VALUE_HORIZONTAL_NORMAL = 1; public static final int ORIENTATION_VALUE_MIRROR_HORIZONTAL = 2; @@ -144,49 +144,49 @@ public static final int ORIENTATION_VALUE_ROTATE_90_CW = 6; public static final int ORIENTATION_VALUE_MIRROR_HORIZONTAL_AND_ROTATE_90_CW = 7; public static final int ORIENTATION_VALUE_ROTATE_270_CW = 8; - public static final TagInfo2 EXIF_TAG_SAMPLES_PER_PIXEL = new TagInfo2( + public static final TagInfo EXIF_TAG_SAMPLES_PER_PIXEL = new TagInfo( "Samples Per Pixel", 0x0115, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_ROWS_PER_STRIP = new TagInfo2( + public static final TagInfo EXIF_TAG_ROWS_PER_STRIP = new TagInfo( "Rows Per Strip", 0x0116, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_IFD0); // poly tag public static final TagInfo2 EXIF_TAG_STRIP_BYTE_COUNTS = new TagInfo2( "StripByteCounts", 0x0117, FIELD_TYPE_DESCRIPTION_UNKNOWN, 1, EXIF_DIRECTORY_UNKNOWN); - public static final TagInfo2 EXIF_TAG_PREVIEW_IMAGE_LENGTH_IFD0 = new TagInfo2( + public static final TagInfo EXIF_TAG_PREVIEW_IMAGE_LENGTH_IFD0 = new TagInfo( "Preview Image Length", 0x0117, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_PREVIEW_IMAGE_LENGTH_SUB_IFD1 = new TagInfo2( + public static final TagInfo EXIF_TAG_PREVIEW_IMAGE_LENGTH_SUB_IFD1 = new TagInfo( "Preview Image Length", 0x0117, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_SUB_IFD1); - public static final TagInfo2 EXIF_TAG_JPG_FROM_RAW_LENGTH_SUB_IFD2 = new TagInfo2( + public static final TagInfo EXIF_TAG_JPG_FROM_RAW_LENGTH_SUB_IFD2 = new TagInfo( "Jpg From Raw Length", 0x0117, FIELD_TYPE_LONG, 1, EXIF_DIRECTORY_SUB_IFD2); - public static final TagInfo2 EXIF_TAG_MIN_SAMPLE_VALUE = new TagInfo2( + public static final TagInfo EXIF_TAG_MIN_SAMPLE_VALUE = new TagInfo( "Min Sample Value", 0x0118, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_MAX_SAMPLE_VALUE = new TagInfo2( + public static final TagInfo EXIF_TAG_MAX_SAMPLE_VALUE = new TagInfo( "Max Sample Value", 0x0119, FIELD_TYPE_SHORT, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_XRESOLUTION = new TagInfo2( + public static final TagInfo EXIF_TAG_XRESOLUTION = new TagInfo( "XResolution", 0x011a, FIELD_TYPE_RATIONAL, 1, EXIF_DIRECTORY_IFD0); - public static final TagInfo2 EXIF_TAG_YRESOLUTION = new TagInfo2( + public static
{'source': 'Apache Software Foundation Public Mail Archives'}