You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by je...@apache.org on 2006/09/17 23:41:27 UTC
svn commit: r447150 -
/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoder.java
Author: jeremias
Date: Sun Sep 17 14:41:26 2006
New Revision: 447150
URL: http://svn.apache.org/viewvc?view=rev&rev=447150
Log:
Added an alternative approach to writing multiple images that does not involve passing in an Iterator.
Fixed some indentation issues.
Modified:
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoder.java
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoder.java?view=diff&rev=447150&r1=447149&r2=447150
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoder.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/codec/tiff/TIFFImageEncoder.java Sun Sep 17 14:41:26 2006
@@ -1,21 +1,22 @@
/*
+ * 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.
+ */
- 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.
+/* $Id$ */
- */
package org.apache.xmlgraphics.image.codec.tiff;
import java.awt.Rectangle;
@@ -90,10 +91,10 @@
private static final int DEFAULT_ROWS_PER_STRIP = 8;
public TIFFImageEncoder(OutputStream output, ImageEncodeParam param) {
- super(output, param);
- if (this.param == null) {
- this.param = new TIFFEncodeParam();
- }
+ super(output, param);
+ if (this.param == null) {
+ this.param = new TIFFEncodeParam();
+ }
}
/**
@@ -107,16 +108,16 @@
// Get the encoding parameters.
TIFFEncodeParam encodeParam = (TIFFEncodeParam)param;
- Iterator iter = encodeParam.getExtraImages();
- if(iter != null) {
+ Iterator iter = encodeParam.getExtraImages();
+ if (iter != null) {
int ifdOffset = 8;
- RenderedImage nextImage = im;
+ RenderedImage nextImage = im;
TIFFEncodeParam nextParam = encodeParam;
boolean hasNext;
do {
hasNext = iter.hasNext();
ifdOffset = encode(nextImage, nextParam, ifdOffset, !hasNext);
- if(hasNext) {
+ if(hasNext) {
Object obj = iter.next();
if(obj instanceof RenderedImage) {
nextImage = (RenderedImage)obj;
@@ -126,20 +127,78 @@
nextImage = (RenderedImage)o[0];
nextParam = (TIFFEncodeParam)o[1];
}
- }
+ }
} while(hasNext);
} else {
- encode(im, encodeParam, 8, true);
+ encode(im, encodeParam, 8, true);
+ }
+ }
+
+ /**
+ * Encodes a RenderedImage as part of a multi-page file and writes the output to the
+ * OutputStream associated with this ImageEncoder.
+ * <p>
+ * When you sent all pages, make sure you call finishMultiple() in the end. Otherwise,
+ * the generated file will be corrupted.
+ * @param context the context object you receive as return value to a previous call to
+ * encodeMultiple(). Set null for the first image.
+ * @param img the image
+ * @return a context object needed for writing multiple pages for a single image file
+ * @throws IOException In case of an I/O error
+ */
+ public Object encodeMultiple(Object context, RenderedImage img) throws IOException {
+ // Get the encoding parameters.
+ TIFFEncodeParam encodeParam = (TIFFEncodeParam)param;
+ if (encodeParam.getExtraImages() != null) {
+ throw new IllegalStateException(
+ "Extra images may not be used when calling encodeMultiple!");
+ }
+
+ Context c = (Context)context;
+ if (c == null) {
+ c = new Context();
+ // Write the file header (8 bytes).
+ writeFileHeader();
+ } else {
+ //write image
+ c.ifdOffset = encode(c.nextImage, encodeParam, c.ifdOffset, false);
}
+ c.nextImage = img;
+ return c;
+ }
+
+ /**
+ * Signals the encoder that you've finished sending pages for a multi-page image files.
+ * @param context the context object you receive as return value to a previous call to
+ * encodeMultiple()
+ * @throws IOException In case of an I/O error
+ */
+ public void finishMultiple(Object context) throws IOException {
+ if (context == null) {
+ throw new NullPointerException("context must not be null");
+ }
+ Context c = (Context)context;
+ // Get the encoding parameters.
+ TIFFEncodeParam encodeParam = (TIFFEncodeParam)param;
+
+ //write last image
+ c.ifdOffset = encode(c.nextImage, encodeParam, c.ifdOffset, true);
+ }
+
+ private class Context {
+ //TODO This approach causes always two images to be present at the same time.
+ //The encoder has to be changed a little to avoid that.
+ private RenderedImage nextImage;
+ private int ifdOffset = 8; //Initial offset
}
private int encode(RenderedImage im, TIFFEncodeParam encodeParam,
int ifdOffset, boolean isLast) throws IOException {
- // Currently all images are stored uncompressed.
- int compression = encodeParam.getCompression();
-
- // Get tiled output preference.
- boolean isTiled = encodeParam.getWriteTiled();
+ // Currently all images are stored uncompressed.
+ int compression = encodeParam.getCompression();
+
+ // Get tiled output preference.
+ boolean isTiled = encodeParam.getWriteTiled();
// Set bounds.
int minX = im.getMinX();
@@ -151,7 +210,7 @@
SampleModel sampleModel = im.getSampleModel();
// Retrieve and verify sample size.
- int sampleSize[] = sampleModel.getSampleSize();
+ int sampleSize[] = sampleModel.getSampleSize();
for(int i = 1; i < sampleSize.length; i++) {
if(sampleSize[i] != sampleSize[0]) {
throw new Error("TIFFImageEncoder0");
@@ -159,13 +218,13 @@
}
// Check low bit limits.
- int numBands = sampleModel.getNumBands();
+ int numBands = sampleModel.getNumBands();
if((sampleSize[0] == 1 || sampleSize[0] == 4) && numBands != 1) {
throw new Error("TIFFImageEncoder1");
}
// Retrieve and verify data type.
- int dataType = sampleModel.getDataType();
+ int dataType = sampleModel.getDataType();
switch(dataType) {
case DataBuffer.TYPE_BYTE:
if(sampleSize[0] != 1 && sampleSize[0] == 4 &&
@@ -1334,7 +1393,7 @@
*/
private int getDirectorySize(SortedSet fields) {
// Get the number of entries.
- int numEntries = fields.size();
+ int numEntries = fields.size();
// Initialize the size excluding that of any values > 4 bytes.
int dirSize = 2 + numEntries*12 + 4;
@@ -1342,14 +1401,14 @@
// Loop over fields adding the size of all values > 4 bytes.
Iterator iter = fields.iterator();
while(iter.hasNext()) {
- // Get the field.
- TIFFField field = (TIFFField)iter.next();
+ // Get the field.
+ TIFFField field = (TIFFField)iter.next();
// Determine the size of the field value.
int valueSize = field.getCount()*sizeOfType[field.getType()];
// Add any excess size.
- if(valueSize > 4) {
+ if(valueSize > 4) {
dirSize += valueSize;
}
}
@@ -1358,75 +1417,75 @@
}
private void writeFileHeader() throws IOException {
- // 8 byte image file header
-
- // Byte order used within the file - Big Endian
- output.write('M');
- output.write('M');
-
- // Magic value
- output.write(0);
- output.write(42);
-
- // Offset in bytes of the first IFD.
- writeLong(8);
+ // 8 byte image file header
+
+ // Byte order used within the file - Big Endian
+ output.write('M');
+ output.write('M');
+
+ // Magic value
+ output.write(0);
+ output.write(42);
+
+ // Offset in bytes of the first IFD.
+ writeLong(8);
}
private void writeDirectory(int thisIFDOffset, SortedSet fields,
int nextIFDOffset)
- throws IOException {
-
- // 2 byte count of number of directory entries (fields)
- int numEntries = fields.size();
-
- long offsetBeyondIFD = thisIFDOffset + 12 * numEntries + 4 + 2;
- ArrayList tooBig = new ArrayList();
-
- // Write number of fields in the IFD
- writeUnsignedShort(numEntries);
-
+ throws IOException {
+
+ // 2 byte count of number of directory entries (fields)
+ int numEntries = fields.size();
+
+ long offsetBeyondIFD = thisIFDOffset + 12 * numEntries + 4 + 2;
+ ArrayList tooBig = new ArrayList();
+
+ // Write number of fields in the IFD
+ writeUnsignedShort(numEntries);
+
Iterator iter = fields.iterator();
- while(iter.hasNext()) {
-
- // 12 byte field entry TIFFField
- TIFFField field = (TIFFField)iter.next();
-
- // byte 0-1 Tag that identifies a field
- int tag = field.getTag();
- writeUnsignedShort(tag);
-
- // byte 2-3 The field type
- int type = field.getType();
- writeUnsignedShort(type);
-
- // bytes 4-7 the number of values of the indicated type except
- // ASCII-valued fields which require the total number of bytes.
- int count = field.getCount();
+ while(iter.hasNext()) {
+
+ // 12 byte field entry TIFFField
+ TIFFField field = (TIFFField)iter.next();
+
+ // byte 0-1 Tag that identifies a field
+ int tag = field.getTag();
+ writeUnsignedShort(tag);
+
+ // byte 2-3 The field type
+ int type = field.getType();
+ writeUnsignedShort(type);
+
+ // bytes 4-7 the number of values of the indicated type except
+ // ASCII-valued fields which require the total number of bytes.
+ int count = field.getCount();
int valueSize = getValueSize(field);
- writeLong(type == TIFFField.TIFF_ASCII ? valueSize : count);
-
- // bytes 8 - 11 the value or value offset
- if (valueSize > 4) {
-
- // We need an offset as data won't fit into 4 bytes
- writeLong(offsetBeyondIFD);
- offsetBeyondIFD += valueSize;
- tooBig.add(field);
-
- } else {
-
- writeValuesAsFourBytes(field);
- }
-
- }
-
- // Address of next IFD
- writeLong(nextIFDOffset);
-
- // Write the tag values that did not fit into 4 bytes
- for (int i = 0; i < tooBig.size(); i++) {
- writeValues((TIFFField)tooBig.get(i));
- }
+ writeLong(type == TIFFField.TIFF_ASCII ? valueSize : count);
+
+ // bytes 8 - 11 the value or value offset
+ if (valueSize > 4) {
+
+ // We need an offset as data won't fit into 4 bytes
+ writeLong(offsetBeyondIFD);
+ offsetBeyondIFD += valueSize;
+ tooBig.add(field);
+
+ } else {
+
+ writeValuesAsFourBytes(field);
+ }
+
+ }
+
+ // Address of next IFD
+ writeLong(nextIFDOffset);
+
+ // Write the tag values that did not fit into 4 bytes
+ for (int i = 0; i < tooBig.size(); i++) {
+ writeValues((TIFFField)tooBig.get(i));
+ }
}
/**
---------------------------------------------------------------------
Apache XML Graphics Project URL: http://xmlgraphics.apache.org/
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org