001: /*
002: * $RCSfile: CodecRIFUtil.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.2 $
009: * $Date: 2006/06/17 00:02:28 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.opimage;
013:
014: import java.awt.RenderingHints;
015: import java.awt.image.RenderedImage;
016: import java.awt.image.renderable.ParameterBlock;
017: import java.awt.image.renderable.RenderedImageFactory;
018: import java.io.IOException;
019: import javax.media.jai.ImageLayout;
020: import javax.media.jai.JAI;
021: import javax.media.jai.OpImage;
022: import javax.media.jai.TileCache;
023: import javax.media.jai.util.ImagingException;
024: import javax.media.jai.util.ImagingListener;
025: import com.sun.media.jai.codec.ImageCodec;
026: import com.sun.media.jai.codec.ImageDecoder;
027: import com.sun.media.jai.codec.ImageDecodeParam;
028: import com.sun.media.jai.codec.SeekableStream;
029: import com.sun.media.jai.util.DisposableNullOpImage;
030: import com.sun.media.jai.util.ImageUtil;
031:
032: public class CodecRIFUtil {
033:
034: private CodecRIFUtil() {
035: }
036:
037: public static RenderedImage create(String type,
038: ParameterBlock paramBlock, RenderingHints renderHints) {
039: ImagingListener listener = ImageUtil
040: .getImagingListener(renderHints);
041:
042: SeekableStream source = (SeekableStream) paramBlock
043: .getObjectParameter(0);
044:
045: ImageDecodeParam param = null;
046: if (paramBlock.getNumParameters() > 1) {
047: param = (ImageDecodeParam) paramBlock.getObjectParameter(1);
048: }
049: int page = 0;
050: if (paramBlock.getNumParameters() > 2) {
051: page = paramBlock.getIntParameter(2);
052: }
053:
054: ImageDecoder dec = ImageCodec.createImageDecoder(type, source,
055: param);
056: try {
057: int bound = OpImage.OP_IO_BOUND;
058: ImageLayout layout = RIFUtil
059: .getImageLayoutHint(renderHints);
060:
061: if (renderHints != null) {
062: RenderingHints.Key key;
063:
064: key = JAI.KEY_OPERATION_BOUND;
065: if (renderHints.containsKey(key)) {
066: bound = ((Integer) renderHints.get(key)).intValue();
067: }
068: }
069:
070: // Set flag indicating that a recovery may be attempted if
071: // an OutOfMemoryError occurs during the decodeAsRenderedImage()
072: // call - which is only possible if the stream can seek backwards.
073: boolean canAttemptRecovery = source.canSeekBackwards();
074:
075: // Save the stream position prior to decodeAsRenderedImage().
076: long streamPosition = Long.MIN_VALUE;
077: if (canAttemptRecovery) {
078: try {
079: streamPosition = source.getFilePointer();
080: } catch (IOException ioe) {
081: listener.errorOccurred(JaiI18N
082: .getString("StreamRIF1"), ioe,
083: CodecRIFUtil.class, false);
084: // Unset the recovery attempt flag but otherwise
085: // ignore the exception.
086: canAttemptRecovery = false;
087: }
088: }
089:
090: OpImage image = null;
091: try {
092: // Attempt to create an OpImage from the decoder image.
093: image = new DisposableNullOpImage(dec
094: .decodeAsRenderedImage(page), layout,
095: renderHints, bound);
096: } catch (OutOfMemoryError memoryError) {
097: // Ran out of memory - may be due to the decoder being
098: // obliged to read the entire image when it creates the
099: // RenderedImage it returns.
100: if (canAttemptRecovery) {
101: // First flush the cache if one is defined.
102: TileCache cache = image != null ? image
103: .getTileCache() : RIFUtil
104: .getTileCacheHint(renderHints);
105: if (cache != null) {
106: cache.flush();
107: }
108:
109: // Force garbage collection.
110: System.gc(); //slow
111:
112: // Reposition the stream before the previous decoding.
113: source.seek(streamPosition);
114:
115: // Retry image decoding.
116: image = new DisposableNullOpImage(dec
117: .decodeAsRenderedImage(page), layout,
118: renderHints, bound);
119: } else {
120: // Re-throw the error.
121: String message = JaiI18N.getString("CodecRIFUtil0");
122: listener.errorOccurred(message,
123: new ImagingException(message, memoryError),
124: CodecRIFUtil.class, false);
125: // throw memoryError;
126: }
127: }
128:
129: return image;
130: } catch (Exception e) {
131: listener.errorOccurred(JaiI18N.getString("CodecRIFUtil1"),
132: e, CodecRIFUtil.class, false);
133: // e.printStackTrace();
134: return null;
135: }
136: }
137: }
|