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 2008/01/07 04:39:12 UTC
svn commit: r609512 - 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/write/
test/java/org/apache/sanselan/formats/jpeg/
Author: cmchen
Date: Sun Jan 6 20:39:11 2008
New Revision: 609512
URL: http://svn.apache.org/viewvc?rev=609512&view=rev
Log:
refactor in preparation of starting work on lossless/cautious exif rewrite.
Added:
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossless.java (with props)
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossy.java (with props)
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSummary.java (with props)
Removed:
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
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/TiffImageParser.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterBase.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputDirectory.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=609512&r1=609511&r2=609512&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 20:39:11 2008
@@ -33,7 +33,9 @@
import org.apache.sanselan.formats.jpeg.segments.UnknownSegment;
import org.apache.sanselan.formats.tiff.TiffImageMetadata;
import org.apache.sanselan.formats.tiff.TiffImageParser;
-import org.apache.sanselan.formats.tiff.write.TiffImageWriter;
+import org.apache.sanselan.formats.tiff.write.TiffImageWriterLossy;
+import org.apache.sanselan.formats.tiff.write.TiffImageWriterBase;
+import org.apache.sanselan.formats.tiff.write.TiffImageWriterLossless;
import org.apache.sanselan.formats.tiff.write.TiffOutputDirectory;
import org.apache.sanselan.formats.tiff.write.TiffOutputSet;
import org.apache.sanselan.util.Debug;
@@ -144,29 +146,45 @@
writeSegmentsReplacingExif(os, pieces, null);
}
- public void rewriteExifMetadata(ByteSource byteSource, OutputStream os,
- 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);
-
- byte newBytes[] = writeExifSegment(exifMetadata, true);
- // exifSegment.bytes = newBytes;
-
- // ArrayList segments = readSegments(byteSource, null, false, true);
-
- // TiffImageMetadata exif = getExifMetadata(byteSource, params);
-
- writeSegmentsReplacingExif(os, pieces, newBytes);
- }
+// public void rewriteExifMetadataLossless(ByteSource byteSource,
+// OutputStream os, Map params) throws ImageReadException,
+// IOException, ImageWriteException
+// {
+//
+// rewriteExifMetadata(MODE_LOSSLESS, byteSource, os, params);
+// }
+//
+// public void rewriteExifMetadataLossy(ByteSource byteSource,
+// OutputStream os, Map params) throws ImageReadException,
+// IOException, ImageWriteException
+// {
+//
+// rewriteExifMetadata(MODE_LOSSY, byteSource, os, params);
+// }
+//
+// private void rewriteExifMetadata(int mode, ByteSource byteSource,
+// OutputStream os, 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);
+//
+// byte newBytes[] = writeExifSegment(mode, exifMetadata, true);
+// // exifSegment.bytes = newBytes;
+//
+// // ArrayList segments = readSegments(byteSource, null, false, true);
+//
+// // TiffImageMetadata exif = getExifMetadata(byteSource, params);
+//
+// writeSegmentsReplacingExif(os, pieces, newBytes);
+// }
// public void updateExifMetadata(ByteSource byteSource, OutputStream os,
// ArrayList outputDirectories, Map params) throws ImageReadException,
@@ -188,10 +206,26 @@
// writeSegmentsReplacingExif(os, pieces, newBytes);
// }
- public void updateExifMetadata(ByteSource byteSource, OutputStream os,
- TiffOutputSet outputSet
- // , Map params
- ) throws ImageReadException, IOException, ImageWriteException
+ private static final int MODE_LOSSY = -1;
+ private static final int MODE_LOSSLESS = -2;
+
+ public void updateExifMetadataLossless(ByteSource byteSource,
+ OutputStream os, TiffOutputSet outputSet)
+ throws ImageReadException, IOException, ImageWriteException
+ {
+ updateExifMetadata(MODE_LOSSLESS, byteSource, os, outputSet);
+ }
+
+ public void updateExifMetadataLossy(ByteSource byteSource, OutputStream os,
+ TiffOutputSet outputSet) throws ImageReadException, IOException,
+ ImageWriteException
+ {
+ updateExifMetadata(MODE_LOSSY, byteSource, os, outputSet);
+ }
+
+ private void updateExifMetadata(int mode, ByteSource byteSource,
+ OutputStream os, TiffOutputSet outputSet)
+ throws ImageReadException, IOException, ImageWriteException
{
List outputDirectories = outputSet.getDirectories();
JFIFPieces jfifPieces = analyzeJFIF(byteSource);
@@ -203,7 +237,8 @@
int byteOrder = outputSet.byteOrder;
- byte newBytes[] = writeExifSegment(outputDirectories, byteOrder, true);
+ byte newBytes[] = writeExifSegment(mode, byteOrder, outputDirectories,
+ true);
writeSegmentsReplacingExif(os, pieces, newBytes);
}
@@ -256,7 +291,7 @@
}
}
- public byte[] writeExifSegment(TiffImageMetadata exif,
+ private byte[] writeExifSegment(int mode, TiffImageMetadata exif,
boolean includeEXIFPrefix) throws IOException, ImageWriteException
{
if (exif == null)
@@ -278,20 +313,55 @@
outputDirectories.add(outputDirectory);
}
- return writeExifSegment(outputDirectories, byteOrder, includeEXIFPrefix);
+ return writeExifSegment(mode, byteOrder, outputDirectories,
+ includeEXIFPrefix);
}
- public byte[] writeExifSegment(TiffOutputSet outputSet,
- boolean includeEXIFPrefix) throws IOException, ImageWriteException
+// private byte[] writeExifSegment(int mode, TiffOutputSet outputSet,
+// boolean includeEXIFPrefix) throws IOException, ImageWriteException
+// {
+// List outputDirectories = outputSet.getDirectories();
+//
+// return writeExifSegment(mode, outputSet.byteOrder, outputDirectories,
+// includeEXIFPrefix);
+// }
+
+ //
+ // public byte[] writeExifSegmentLossy(List outputDirectories, int byteOrder,
+ // boolean includeEXIFPrefix) throws IOException, ImageWriteException
+ // {
+ // TiffImageWriterBase writer = new TiffImageWriter(byteOrder);
+ // return writeExifSegment(writer, outputDirectories, byteOrder,
+ // includeEXIFPrefix);
+ // }
+ //
+ // private byte[] writeExifSegmentLossless(List outputDirectories,
+ // int byteOrder, boolean includeEXIFPrefix) throws IOException,
+ // ImageWriteException
+ // {
+ // TiffImageWriterBase writer = new TiffImageWriter(byteOrder);
+ // return writeExifSegment(writer, outputDirectories, byteOrder,
+ // includeEXIFPrefix);
+ // }
+
+ private byte[] writeExifSegment(int mode, int byteOrder,
+ List outputDirectories, boolean includeEXIFPrefix)
+ throws IOException, ImageWriteException
{
- List outputDirectories = outputSet.getDirectories();
+ TiffImageWriterBase writer;
+ if (mode == MODE_LOSSLESS)
+ writer = new TiffImageWriterLossless(byteOrder);
+ else if (mode == MODE_LOSSY)
+ writer = new TiffImageWriterLossy(byteOrder);
+ else
+ throw new ImageWriteException("Unknown TIFF write mode.");
- return writeExifSegment(outputDirectories, outputSet.byteOrder,
- includeEXIFPrefix);
+ return writeExifSegment(writer, outputDirectories, includeEXIFPrefix);
}
- public byte[] writeExifSegment(List outputDirectories, int byteOrder,
- boolean includeEXIFPrefix) throws IOException, ImageWriteException
+ private byte[] writeExifSegment(TiffImageWriterBase writer,
+ List outputDirectories, boolean includeEXIFPrefix)
+ throws IOException, ImageWriteException
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
@@ -302,7 +372,7 @@
os.write(0);
}
- new TiffImageWriter(byteOrder).writeDirectories(os, outputDirectories);
+ writer.writeDirectories(os, outputDirectories);
return os.toByteArray();
}
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=609512&r1=609511&r2=609512&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 20:39:11 2008
@@ -50,7 +50,7 @@
import org.apache.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterPalette;
import org.apache.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterRGB;
import org.apache.sanselan.formats.tiff.photometricinterpreters.PhotometricInterpreterYCbCr;
-import org.apache.sanselan.formats.tiff.write.TiffImageWriter;
+import org.apache.sanselan.formats.tiff.write.TiffImageWriterLossy;
import org.apache.sanselan.util.Debug;
public class TiffImageParser extends ImageParser implements TiffConstants
@@ -138,12 +138,17 @@
int entryCount = read2Bytes("DirectoryEntryCount", is,
"Not a Valid TIFF File");
+// Debug.debug("dirType", dirType);
+// Debug.debug("offset", offset);
+
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");
+// Debug.debug("tag", tag);
+
byte valueOffsetBytes[] = readByteArray("ValueOffset", 4, is,
"Not a Valid TIFF File");
int valueOffset = convertByteArrayToInt("ValueOffset",
@@ -174,6 +179,8 @@
if (debug)
System.out.println("");
+// Debug.debug();
+
return new TiffDirectory(dirType, result, offset, nextDirectoryOffset);
}
@@ -1207,7 +1214,7 @@
public void writeImage(BufferedImage src, OutputStream os, Map params)
throws ImageWriteException, IOException
{
- new TiffImageWriter().writeImage(src, os, params);
+ new TiffImageWriterLossy().writeImage(src, os, params);
}
}
Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterBase.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterBase.java?rev=609512&r1=609511&r2=609512&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterBase.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterBase.java Sun Jan 6 20:39:11 2008
@@ -16,8 +16,18 @@
*/
package org.apache.sanselan.formats.tiff.write;
+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;
+
+import org.apache.sanselan.ImageWriteException;
import org.apache.sanselan.common.BinaryConstants;
import org.apache.sanselan.formats.tiff.constants.TiffConstants;
+import org.apache.sanselan.util.Debug;
public abstract class TiffImageWriterBase
implements
@@ -36,6 +46,192 @@
public TiffImageWriterBase(int byteOrder)
{
this.byteOrder = byteOrder;
+ }
+
+ public abstract void writeDirectories(OutputStream os, List directories)
+ throws IOException, ImageWriteException;
+
+ protected TiffOutputSummary 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 directoryTypeMap = 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);
+ directoryTypeMap.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);
+
+ TiffOutputDirectory previousDirectory = null;
+ for (int i = 0; i < directoryIndices.size(); i++)
+ {
+ Integer index = (Integer) directoryIndices.get(i);
+ if (index.intValue() != i)
+ throw new ImageWriteException("Missing directory: " + i + ".");
+
+ // set up chain of directory references for "normal" directories.
+ TiffOutputDirectory directory = (TiffOutputDirectory) directoryTypeMap
+ .get(index);
+ if (null != previousDirectory)
+ previousDirectory.setNextDirectory(directory);
+ previousDirectory = directory;
+ }
+
+ TiffOutputDirectory rootDirectory = (TiffOutputDirectory) directoryTypeMap
+ .get(new Integer(DIRECTORY_TYPE_ROOT));
+
+ // prepare results
+ TiffOutputSummary result = new TiffOutputSummary(rootDirectory,
+ directoryTypeMap);
+
+ // make sure offset fields and offset'd directories correspond.
+ 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)
+ {
+ if (exifDirectoryOffsetField == null)
+ {
+ exifDirectoryOffsetField = TiffOutputField.createOffsetField(
+ EXIF_TAG_EXIF_OFFSET, byteOrder);
+ rootDirectory.add(exifDirectoryOffsetField);
+ }
+
+ result.add(exifDirectory, 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)
+ {
+ if (gpsDirectoryOffsetField == null)
+ {
+ gpsDirectoryOffsetField = TiffOutputField.createOffsetField(
+ EXIF_TAG_GPSINFO, byteOrder);
+ rootDirectory.add(gpsDirectoryOffsetField);
+ }
+
+ result.add(gpsDirectory, 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)
+ {
+ if (interoperabilityDirectoryOffsetField == null)
+ {
+ interoperabilityDirectoryOffsetField = TiffOutputField
+ .createOffsetField(EXIF_TAG_INTEROP_OFFSET, byteOrder);
+ rootDirectory.add(interoperabilityDirectoryOffsetField);
+ }
+
+ result.add(interoperabilityDirectory,
+ interoperabilityDirectoryOffsetField);
+ }
+
+ return result;
+
+ // Debug.debug();
}
}
Added: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossless.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossless.java?rev=609512&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossless.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossless.java Sun Jan 6 20:39:11 2008
@@ -0,0 +1,593 @@
+/*
+ * 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.apache.sanselan.formats.tiff.write;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+import org.apache.sanselan.ImageWriteException;
+import org.apache.sanselan.common.BinaryOutputStream;
+import org.apache.sanselan.util.DebugOutputStream;
+
+public class TiffImageWriterLossless extends TiffImageWriterBase
+{
+
+ public TiffImageWriterLossless()
+ {
+ }
+
+ public TiffImageWriterLossless(int byteOrder)
+ {
+ super(byteOrder);
+ }
+
+ public void writeDirectories(OutputStream os, List directories)
+ throws IOException, ImageWriteException
+ {
+ TiffOutputSummary outputSummary = 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);
+
+ }
+
+ // 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;
+ // }
+ // }
+ // }
+
+}
Propchange: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossless.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossy.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossy.java?rev=609512&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossy.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossy.java Sun Jan 6 20:39:11 2008
@@ -0,0 +1,459 @@
+/*
+ * 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.apache.sanselan.formats.tiff.write;
+
+import java.awt.image.BufferedImage;
+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;
+
+import org.apache.sanselan.ImageWriteException;
+import org.apache.sanselan.common.BinaryOutputStream;
+import org.apache.sanselan.common.PackBits;
+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.util.Debug;
+import org.apache.sanselan.util.DebugOutputStream;
+
+public class TiffImageWriterLossy extends TiffImageWriterBase
+{
+
+ public TiffImageWriterLossy()
+ {
+ }
+
+ public TiffImageWriterLossy(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
+ {
+
+ TiffOutputSummary outputSummary = validateDirectories(directories);
+
+ // Collections.sort(directories, Directory.COMPARATOR);
+
+ /**/
+
+ // ImageDataInfo imageDataInfo = imageDataInfoStep(directories, imageData,
+ // stripsNotTiles);
+ /**/
+
+ // PointerDirectoriesInfo pointerDirectoriesInfo = pointerDirectoriesStep(directories);
+ /**/
+
+ // final int imageDataOffset =
+ calculateLengthsAndOffsetsStep(directories);
+
+ /**/
+
+ outputSummary.updateOffsets(byteOrder);
+
+ /**/
+
+ // 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;
+
+ 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
+ {
+ directory.calculateLengths(byteOrder);
+ offset += directory.totalLength;
+ }
+ }
+ // return offset;
+ }
+
+ 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;
+ }
+ }
+ }
+
+}
Propchange: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffImageWriterLossy.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputDirectory.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputDirectory.java?rev=609512&r1=609511&r2=609512&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputDirectory.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputDirectory.java Sun Jan 6 20:39:11 2008
@@ -36,9 +36,15 @@
public int internalLength = UNDEFINED_VALUE;
public int totalLength = UNDEFINED_VALUE;
public int offset = UNDEFINED_VALUE;
- public int nextDirectoryOffset = UNDEFINED_VALUE;
private final ArrayList fields = new ArrayList();
+ private TiffOutputDirectory nextDirectory = null;
+
+ public void setNextDirectory(TiffOutputDirectory nextDirectory)
+ {
+ this.nextDirectory = nextDirectory;
+ }
+
public TiffOutputDirectory(final int type)
{
this.type = type;
@@ -93,9 +99,9 @@
tiffImageDataInfoStep(byteOrder);
jpegImageDataInfoStep(byteOrder);
- internalLength = TiffImageWriter.TIFF_ENTRY_LENGTH * fields.size()
- + TiffImageWriter.TIFF_DIRECTORY_HEADER_LENGTH
- + TiffImageWriter.TIFF_DIRECTORY_FOOTER_LENGTH;
+ internalLength = TiffImageWriterLossy.TIFF_ENTRY_LENGTH * fields.size()
+ + TiffImageWriterLossy.TIFF_DIRECTORY_HEADER_LENGTH
+ + TiffImageWriterLossy.TIFF_DIRECTORY_FOOTER_LENGTH;
totalLength = internalLength;
@@ -116,7 +122,7 @@
{
int imageDataOffset = offset + totalLength;
totalLength += rawJpegImageData.length;
- totalLength += TiffImageWriter
+ totalLength += TiffImageWriterLossy
.imageDataPaddingLength(rawJpegImageData.length);
updateJpegImageDataOffsetsStep(imageDataOffset, byteOrder);
}
@@ -156,6 +162,10 @@
nextSeperateValueOffset);
}
+ int nextDirectoryOffset = 0;
+ if(nextDirectory!=null)
+ nextDirectoryOffset = nextDirectory.offset;
+
// Write nextDirectoryOffset
if (nextDirectoryOffset == UNDEFINED_VALUE)
bos.write4Bytes(0);
@@ -177,7 +187,7 @@
bos.writeByteArray(imageData[i]);
int imageDataByteCount = imageData[i].length;
- int remainder = TiffImageWriter
+ int remainder = TiffImageWriterLossy
.imageDataPaddingLength(imageDataByteCount);
for (int j = 0; j < remainder; j++)
bos.write(0);
@@ -188,7 +198,7 @@
{
// byte imageData[][] = rawJpegImageData.getRawImageData();
bos.writeByteArray(rawJpegImageData);
- int remainder = TiffImageWriter
+ int remainder = TiffImageWriterLossy
.imageDataPaddingLength(rawJpegImageData.length);
for (int j = 0; j < remainder; j++)
bos.write(0);
@@ -219,7 +229,7 @@
imageDataByteCounts[i] = imageData[i].length;
totalLength += imageData[i].length;
- totalLength += TiffImageWriter
+ totalLength += TiffImageWriterLossy
.imageDataPaddingLength(imageData[i].length);
}
@@ -227,17 +237,17 @@
{
TagInfo tagInfo;
if (stripsNotTiles)
- tagInfo = TiffImageWriter.TIFF_TAG_STRIP_OFFSETS;
+ tagInfo = TiffImageWriterLossy.TIFF_TAG_STRIP_OFFSETS;
else
- tagInfo = TiffImageWriter.TIFF_TAG_TILE_OFFSETS;
+ tagInfo = TiffImageWriterLossy.TIFF_TAG_TILE_OFFSETS;
imageDataOffsetsField = findField(tagInfo);
if (null == imageDataOffsetsField)
{
imageDataOffsetsField = new TiffOutputField(tagInfo,
- TiffImageWriter.FIELD_TYPE_LONG,
+ TiffImageWriterLossy.FIELD_TYPE_LONG,
imageDataOffsets.length,
- TiffImageWriter.FIELD_TYPE_LONG.writeData(
+ TiffImageWriterLossy.FIELD_TYPE_LONG.writeData(
imageDataOffsets, byteOrder));
add(imageDataOffsetsField);
}
@@ -245,17 +255,17 @@
{
TagInfo tagInfo;
if (stripsNotTiles)
- tagInfo = TiffImageWriter.TIFF_TAG_STRIP_BYTE_COUNTS;
+ tagInfo = TiffImageWriterLossy.TIFF_TAG_STRIP_BYTE_COUNTS;
else
- tagInfo = TiffImageWriter.TIFF_TAG_TILE_BYTE_COUNTS;
+ tagInfo = TiffImageWriterLossy.TIFF_TAG_TILE_BYTE_COUNTS;
- byte data[] = TiffImageWriter.FIELD_TYPE_LONG.writeData(
+ byte data[] = TiffImageWriterLossy.FIELD_TYPE_LONG.writeData(
imageDataByteCounts, byteOrder);
TiffOutputField field = findField(tagInfo);
if (null == field)
add(new TiffOutputField(tagInfo,
- TiffImageWriter.FIELD_TYPE_LONG,
+ TiffImageWriterLossy.FIELD_TYPE_LONG,
imageDataByteCounts.length, data));
else
field.setData(data);
@@ -279,30 +289,32 @@
// Append imageData-related fields to first directory
{
- TagInfo tagInfo = TiffImageWriter.TIFF_TAG_JPEG_INTERCHANGE_FORMAT;
+ TagInfo tagInfo = TiffImageWriterLossy.TIFF_TAG_JPEG_INTERCHANGE_FORMAT;
jpegImageDataOffsetField = findField(tagInfo);
if (null == jpegImageDataOffsetField)
{
jpegImageDataOffsetField = new TiffOutputField(tagInfo,
- TiffImageWriter.FIELD_TYPE_LONG, 1,
- TiffImageWriter.FIELD_TYPE_LONG.writeData(new int[]{
- 0,
- }, byteOrder));
+ TiffImageWriterLossy.FIELD_TYPE_LONG, 1,
+ TiffImageWriterLossy.FIELD_TYPE_LONG.writeData(
+ new int[]{
+ 0,
+ }, byteOrder));
add(jpegImageDataOffsetField);
}
}
{
- TagInfo tagInfo = TiffImageWriter.TIFF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH;
+ TagInfo tagInfo = TiffImageWriterLossy.TIFF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH;
- byte data[] = TiffImageWriter.FIELD_TYPE_LONG.writeData(new int[]{
- rawJpegImageData.length,
- }, byteOrder);
+ byte data[] = TiffImageWriterLossy.FIELD_TYPE_LONG.writeData(
+ new int[]{
+ rawJpegImageData.length,
+ }, byteOrder);
TiffOutputField field = findField(tagInfo);
if (null == field)
add(new TiffOutputField(tagInfo,
- TiffImageWriter.FIELD_TYPE_LONG, 1, data));
+ TiffImageWriterLossy.FIELD_TYPE_LONG, 1, data));
else
field.setData(data);
}
@@ -318,12 +330,12 @@
imageDataInfo.imageDataOffsets[i] = currentOffset;
currentOffset += imageDataInfo.imageDataByteCounts[i];
- currentOffset += TiffImageWriter
+ currentOffset += TiffImageWriterLossy
.imageDataPaddingLength(imageDataInfo.imageDataByteCounts[i]);
}
imageDataInfo.imageDataOffsetsField
- .setData(TiffImageWriter.FIELD_TYPE_LONG.writeData(
+ .setData(TiffImageWriterLossy.FIELD_TYPE_LONG.writeData(
imageDataInfo.imageDataOffsets, byteOrder));
// }
}
@@ -331,7 +343,7 @@
private void updateJpegImageDataOffsetsStep(final int imageDataOffset,
int byteOrder) throws IOException, ImageWriteException
{
- jpegImageDataOffsetField.setData(TiffImageWriter.FIELD_TYPE_LONG
+ jpegImageDataOffsetField.setData(TiffImageWriterLossy.FIELD_TYPE_LONG
.writeData(new int[]{
imageDataOffset,
}, byteOrder));
Added: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSummary.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSummary.java?rev=609512&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSummary.java (added)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSummary.java Sun Jan 6 20:39:11 2008
@@ -0,0 +1,98 @@
+/*
+ * 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.apache.sanselan.formats.tiff.write;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sanselan.formats.tiff.constants.TiffConstants;
+
+class TiffOutputSummary implements TiffConstants
+{
+ public final TiffOutputDirectory rootDirectory;
+ public final Map directoryTypeMap;
+
+ public TiffOutputSummary(final TiffOutputDirectory rootDirectory,
+ final Map directoryTypeMap)
+ {
+ this.rootDirectory = rootDirectory;
+ this.directoryTypeMap = directoryTypeMap;
+ }
+
+ private static class Offset
+ {
+ public final TiffOutputDirectory directory;
+ public final TiffOutputField directoryOffsetField;
+
+ public Offset(final TiffOutputDirectory directory,
+ final TiffOutputField directoryOffsetField)
+ {
+ super();
+ this.directoryOffsetField = directoryOffsetField;
+ this.directory = directory;
+ }
+ }
+
+ private List offsets = new ArrayList();
+
+ public void add(final TiffOutputDirectory directory,
+ final TiffOutputField directoryOffsetField)
+ {
+ offsets.add(new Offset(directory, directoryOffsetField));
+ }
+
+ public void updateOffsets(int byteOrder)
+ {
+ for (int i = 0; i < offsets.size(); i++)
+ {
+ Offset offset = (Offset) offsets.get(i);
+
+ byte value[] = FIELD_TYPE_LONG.writeData(new int[]{
+ offset.directory.offset,
+ }, byteOrder);
+ offset.directoryOffsetField.setData(value);
+ }
+ }
+
+ // public PointerDirectoriesInfo(
+ //){}
+ //
+ // public final TiffOutputField exifDirectoryOffsetField;
+ // public final TiffOutputDirectory exifDirectory;
+ // public final TiffOutputField gpsDirectoryOffsetField;
+ // public final TiffOutputDirectory gpsDirectory;
+ // public final TiffOutputField interoperabilityDirectoryOffsetField;
+ // public final TiffOutputDirectory interoperabilityDirectory;
+ //
+ // public PointerDirectoriesInfo(
+ // final TiffOutputField exifDirectoryOffsetField,
+ // final TiffOutputDirectory exifDirectory,
+ // final TiffOutputField gpsDirectoryOffsetField,
+ // final TiffOutputDirectory gpsDirectory,
+ // final TiffOutputField interoperabilityDirectoryOffsetField,
+ // final TiffOutputDirectory interoperabilityDirectory)
+ // {
+ // this.exifDirectoryOffsetField = exifDirectoryOffsetField;
+ // this.exifDirectory = exifDirectory;
+ // this.gpsDirectoryOffsetField = gpsDirectoryOffsetField;
+ // this.gpsDirectory = gpsDirectory;
+ // this.interoperabilityDirectoryOffsetField = interoperabilityDirectoryOffsetField;
+ // this.interoperabilityDirectory = interoperabilityDirectory;
+ // }
+
+}
\ No newline at end of file
Propchange: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/write/TiffOutputSummary.java
------------------------------------------------------------------------------
svn:eol-style = native
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=609512&r1=609511&r2=609512&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 20:39:11 2008
@@ -20,6 +20,7 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
@@ -82,8 +83,15 @@
}
}
- public void testRewrite() throws IOException, ImageReadException,
- ImageWriteException
+ private interface Rewriter
+ {
+ public void rewrite(ByteSource byteSource, OutputStream os,
+ TiffOutputSet outputSet) throws ImageReadException,
+ IOException, ImageWriteException;
+ }
+
+ public void rewrite(Rewriter rewriter) throws IOException,
+ ImageReadException, ImageWriteException
{
List images = getImagesWithExifData();
for (int i = 0; i < images.size(); i++)
@@ -107,10 +115,10 @@
// Photoshop photoshop = metadata.getPhotoshop();
TiffOutputSet outputSet = oldExifMetadata.getOutputSet();
- outputSet.dump();
+// outputSet.dump();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- new ExifRewriter().updateExifMetadata(byteSource, baos, outputSet);
+ rewriter.rewrite(byteSource, baos, outputSet);
byte bytes[] = baos.toByteArray();
File tempFile = File.createTempFile("test", ".jpg");
Debug.debug("tempFile", tempFile);
@@ -127,11 +135,45 @@
assertNotNull(newMetadata);
TiffImageMetadata newExifMetadata = newMetadata.getExif();
assertNotNull(newExifMetadata);
- newMetadata.dump();
+// newMetadata.dump();
compare(oldExifMetadata, newExifMetadata);
}
}
+
+ public void testRewriteLossy() throws IOException, ImageReadException,
+ ImageWriteException
+ {
+ Rewriter rewriter = new Rewriter()
+ {
+ public void rewrite(ByteSource byteSource, OutputStream os,
+ TiffOutputSet outputSet) throws ImageReadException,
+ IOException, ImageWriteException
+ {
+ new ExifRewriter().updateExifMetadataLossy(byteSource, os,
+ outputSet);
+ }
+ };
+
+ rewrite(rewriter);
+ }
+
+// public void testRewriteLossless() throws IOException, ImageReadException,
+// ImageWriteException
+// {
+// Rewriter rewriter = new Rewriter()
+// {
+// public void rewrite(ByteSource byteSource, OutputStream os,
+// TiffOutputSet outputSet) throws ImageReadException,
+// IOException, ImageWriteException
+// {
+// new ExifRewriter().updateExifMetadataLossless(byteSource, os,
+// outputSet);
+// }
+// };
+//
+// rewrite(rewriter);
+// }
private Hashtable makeDirectoryMap(ArrayList directories)
{