001: /*
002: * $RCSfile: ImageWriteCIF.java,v $
003: *
004: *
005: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * - Redistribution of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * - Redistribution in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * Neither the name of Sun Microsystems, Inc. or the names of
020: * contributors may be used to endorse or promote products derived
021: * from this software without specific prior written permission.
022: *
023: * This software is provided "AS IS," without a warranty of any
024: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
025: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
026: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027: * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
028: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
029: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
031: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035: * POSSIBILITY OF SUCH DAMAGES.
036: *
037: * You acknowledge that this software is not designed or intended for
038: * use in the design, construction, operation or maintenance of any
039: * nuclear facility.
040: *
041: * $Revision: 1.1 $
042: * $Date: 2005/02/11 05:01:55 $
043: * $State: Exp $
044: */
045: package com.sun.media.jai.imageioimpl;
046:
047: import java.awt.RenderingHints;
048: import java.awt.image.BufferedImage;
049: import java.awt.image.RenderedImage;
050: import java.awt.image.renderable.ParameterBlock;
051: import java.io.IOException;
052: import java.util.ArrayList;
053: import java.util.Collection;
054: import java.util.Iterator;
055: import javax.imageio.ImageIO;
056: import javax.imageio.ImageWriteParam;
057: import javax.imageio.ImageWriter;
058: import javax.imageio.metadata.IIOMetadata;
059: import javax.imageio.stream.ImageOutputStream;
060: import javax.media.jai.CollectionImage;
061: import javax.media.jai.CollectionImageFactory;
062: import javax.media.jai.CollectionOp;
063: import javax.media.jai.PropertySource;
064: import com.sun.media.jai.operator.ImageWriteDescriptor;
065:
066: public final class ImageWriteCIF implements CollectionImageFactory {
067: /** Constructor. */
068: public ImageWriteCIF() {
069: }
070:
071: public CollectionImage create(ParameterBlock args,
072: RenderingHints hints) {
073:
074: // Get the writer.
075: ImageWriter writer = (ImageWriter) args.getObjectParameter(13);
076:
077: // Find a writer if null.
078: if (writer == null) {
079: // Get the format. Should be non-null from OperationDescriptor.
080: String format = (String) args.getObjectParameter(1);
081:
082: // Find a writer.
083: Iterator writers = ImageIO
084: .getImageWritersByFormatName(format);
085:
086: // Get the writer.
087: if (writers != null) {
088: writer = (ImageWriter) writers.next();
089: } else {
090: throw new RuntimeException(I18N
091: .getString("ImageWriteCIF0")
092: + " " + format);
093: }
094: }
095:
096: // Get the source Collection.
097: Collection collection = (Collection) args.getSource(0);
098:
099: // Determine the number of RenderedImages in the Collection.
100: int numRenderedImages = 0;
101: Iterator iter = collection.iterator();
102: while (iter.hasNext()) {
103: if (iter.next() instanceof RenderedImage) {
104: numRenderedImages++;
105: }
106: }
107:
108: // Set the sequence flag.
109: boolean writeToSequence = writer.canWriteSequence();
110:
111: // Check that the writer can write sequences.
112: if (numRenderedImages > 1 && !writeToSequence) {
113: throw new RuntimeException(I18N.getString("ImageWriteCIF1"));
114: }
115:
116: // Get the stream metadata.
117: IIOMetadata streamMetadata = (IIOMetadata) args
118: .getObjectParameter(7);
119:
120: // Get the property use flag.
121: boolean useProperties = ((Boolean) args.getObjectParameter(2))
122: .booleanValue();
123:
124: // If null, get stream metadata from source properties if allowed.
125: if (streamMetadata == null && useProperties
126: && collection instanceof PropertySource) {
127: Object streamMetadataProperty = ((PropertySource) collection)
128: .getProperty(ImageWriteDescriptor.PROPERTY_NAME_METADATA_STREAM);
129: if (streamMetadataProperty instanceof IIOMetadata) {
130: streamMetadata = (IIOMetadata) streamMetadataProperty;
131: }
132: }
133:
134: // Get the writer parameters.
135: ImageWriteParam param = (ImageWriteParam) args
136: .getObjectParameter(12);
137:
138: // Transcode the stream metadata if requested.
139: if (streamMetadata != null) {
140: // Get the transcoding flag.
141: boolean transcode = ((Boolean) args.getObjectParameter(3))
142: .booleanValue();
143:
144: if (transcode) {
145: // Overwrite the stream metadata with transcoded metadata.
146: streamMetadata = writer.convertStreamMetadata(
147: streamMetadata, param);
148: }
149: }
150:
151: if (writeToSequence) {
152: // Write the stream metadata to the sequence.
153: try {
154: // Get the output.
155: Object output = args.getObjectParameter(0);
156:
157: // Try to get an ImageOutputStream.
158: ImageOutputStream stream = ImageWriteCRIF
159: .getImageOutputStream(output);
160:
161: // Set the writer's output.
162: writer.setOutput(stream != null ? stream : output);
163:
164: // Prepare the sequence.
165: writer.prepareWriteSequence(streamMetadata);
166: } catch (IOException e) {
167: throw new RuntimeException(e);
168: }
169: }
170:
171: // Clone the ParameterBlock as the writer, image metadata, and
172: // thumbnail parameters will be replaced.
173: ParameterBlock imagePB = (ParameterBlock) args.clone();
174:
175: // Clear the stream metadata.
176: imagePB.set(null, 7);
177:
178: // Set the ImageWriter.
179: imagePB.set(writer, 13);
180:
181: // Get the image metadata array.
182: IIOMetadata[] imageMetadata = (IIOMetadata[]) args
183: .getObjectParameter(8);
184:
185: // Get the thumbnail array.
186: BufferedImage[] thumbnails = (BufferedImage[]) args
187: .getObjectParameter(9);
188:
189: // Create a new Iterator.
190: iter = collection.iterator();
191:
192: // Create an ImageIOCollectionImage to contain the result:
193: ImageIOCollectionImage imageList = new ImageIOCollectionImage(
194: collection.size());
195:
196: // Iterate over the collection.
197: int imageIndex = 0;
198: while (iter.hasNext()) {
199: // Get the next element.
200: Object nextElement = iter.next();
201:
202: // Process if a RenderedImage.
203: if (nextElement instanceof RenderedImage) {
204: // Replace source with current RenderedImage.
205: imagePB.setSource((RenderedImage) nextElement, 0);
206:
207: // Replace image metadata.
208: if (imageMetadata != null) {
209: imagePB.set(imageMetadata[imageIndex], 8);
210: }
211:
212: // Replace thumbnail array.
213: if (thumbnails != null) {
214: imagePB.set(thumbnails[imageIndex], 9);
215: }
216:
217: // Write the image to the sequence
218: RenderedImage nextImage = ImageWriteCRIF.create(
219: imageIndex, writeToSequence, imagePB, hints);
220:
221: // If the ImageWriteParam passed in was null, replace it
222: // with the first non-null ImageWriteParam property value
223: // and set the value in the local ParameterBlock.
224: if (param == null) {
225: Object paramPropertyValue = nextImage
226: .getProperty(ImageWriteDescriptor.PROPERTY_NAME_IMAGE_WRITE_PARAM);
227:
228: if (paramPropertyValue instanceof ImageWriteParam) {
229: param = (ImageWriteParam) paramPropertyValue;
230:
231: // Replace the ImageWriteParam so the CRIF doesn't
232: // have to re-do the tile size initialization.
233: imagePB.set(param, 12);
234: }
235: }
236:
237: // Add the image to the collection to be returned.
238: imageList.add(nextImage);
239:
240: // Increment the index.
241: imageIndex++;
242: }
243: }
244:
245: // Get the pixel replacement parameter.
246: boolean allowPixelReplacement = ((Boolean) args
247: .getObjectParameter(5)).booleanValue();
248:
249: if (writeToSequence && !allowPixelReplacement) {
250: // Complete writing the sequence.
251: try {
252: // XXX What about pixel replacement? If this is invoked here
253: // it will not be possible. How can this be invoked such that
254: // pixel replacement can occur but the user is not obliged to
255: // call this method manually?
256: // Answer: document that the user must obtain the writer from
257: // the collection-level ImageWriter property and invoke
258: // endWriteSequence() on it.
259: writer.endWriteSequence();
260: } catch (IOException e) {
261: throw new RuntimeException(e);
262: }
263: }
264:
265: // Set collection-level properties.
266: if (param != null) {
267: imageList
268: .setProperty(
269: ImageWriteDescriptor.PROPERTY_NAME_IMAGE_WRITE_PARAM,
270: param);
271: }
272: imageList
273: .setProperty(
274: ImageWriteDescriptor.PROPERTY_NAME_IMAGE_WRITER,
275: writer);
276: if (streamMetadata != null) {
277: imageList.setProperty(
278: ImageWriteDescriptor.PROPERTY_NAME_METADATA_STREAM,
279: streamMetadata);
280: }
281:
282: // Return CollectionImage.
283: return imageList;
284: }
285:
286: // Forget it.
287: public CollectionImage update(ParameterBlock oldParamBlock,
288: RenderingHints oldHints, ParameterBlock newParamBlock,
289: RenderingHints newHints, CollectionImage oldRendering,
290: CollectionOp op) {
291: return null;
292: }
293: }
|