001/*
002 * $RCSfile: CLibImageReader.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.11 $
042 * $Date: 2006/02/28 01:33:31 $
043 * $State: Exp $
044 */
045package com.github.jaiimageio.impl.plugins.clib;
046
047import java.awt.Point;
048import java.awt.Rectangle;
049import java.awt.Transparency;
050import java.awt.color.ColorSpace;
051import java.awt.geom.AffineTransform;
052import java.awt.image.AffineTransformOp;
053import java.awt.image.BufferedImage;
054import java.awt.image.ColorModel;
055import java.awt.image.ComponentColorModel;
056import java.awt.image.ComponentSampleModel;
057import java.awt.image.DataBuffer;
058import java.awt.image.DataBufferByte;
059import java.awt.image.DataBufferUShort;
060import java.awt.image.IndexColorModel;
061import java.awt.image.MultiPixelPackedSampleModel;
062import java.awt.image.PixelInterleavedSampleModel;
063import java.awt.image.Raster;
064import java.awt.image.SampleModel;
065import java.awt.image.WritableRaster;
066import java.io.InputStream;
067import java.io.IOException;
068import java.util.ArrayList;
069import java.util.Iterator;
070import java.util.NoSuchElementException;
071import javax.imageio.IIOException;
072import javax.imageio.ImageReader;
073import javax.imageio.ImageReadParam;
074import javax.imageio.ImageTypeSpecifier;
075import javax.imageio.metadata.IIOMetadata;
076import javax.imageio.spi.ImageReaderSpi;
077import javax.imageio.stream.ImageInputStream;
078//import com.sun.medialib.codec.jiio.Constants;
079//import com.sun.medialib.codec.jiio.mediaLibImage;
080
081// XXX Need to verify compliance of all methods with ImageReader specificaiton.
082public abstract class CLibImageReader extends ImageReader {
083    // The current image index.
084    private int currIndex = -1;
085
086    // The position of the byte after the last byte read so far.
087    private long highWaterMark = Long.MIN_VALUE;
088
089    // An <code>ArrayList</code> of <code>Long</code>s indicating the stream
090    // positions of the start of each image. Entries are added as needed.
091    private ArrayList imageStartPosition = new ArrayList();
092
093    // The number of images in the stream, if known, otherwise -1.
094    private int numImages = -1;
095
096//    // The image returned by the codecLib Decoder.
097//    private mediaLibImage mlibImage = null;
098
099    // The index of the cached image.
100    private int mlibImageIndex = -1;
101
102    /**
103     * Returns true if and only if both arguments are null or
104     * both are non-null and have the same length and content.
105     */
106    private static boolean subBandsMatch(int[] sourceBands,
107                                         int[] destinationBands) {
108        if(sourceBands == null && destinationBands == null) {
109            return true;
110        } else if(sourceBands != null && destinationBands != null) {
111            if (sourceBands.length != destinationBands.length) {
112                // Shouldn't happen ...
113                return false;
114            }
115            for (int i = 0; i < sourceBands.length; i++) {
116                if (sourceBands[i] != destinationBands[i]) {
117                    return false;
118                }
119            }
120            return true;
121        }
122
123        return false;
124    }
125
126    private static final void subsample(Raster src, int subX, int subY,
127                                        WritableRaster dst) {
128        int sx0 = src.getMinX();
129        int sy0 = src.getMinY();
130        int sw = src.getWidth();
131        int syUB = sy0 + src.getHeight();
132
133        int dx0 = dst.getMinX();
134        int dy0 = dst.getMinY();
135        int dw = dst.getWidth();
136
137        int b = src.getSampleModel().getNumBands();
138        int t = src.getSampleModel().getDataType();
139
140        int numSubSamples = (sw + subX - 1)/subX;
141
142        if(t == DataBuffer.TYPE_FLOAT || t == DataBuffer.TYPE_DOUBLE) {
143            float[] fsamples = new float[sw];
144            float[] fsubsamples = new float[numSubSamples];
145
146            for(int k = 0; k < b; k++) {
147                for(int sy = sy0, dy = dy0; sy < syUB; sy += subY, dy++) {
148                    src.getSamples(sx0, sy, sw, 1, k, fsamples);
149                    for(int i = 0, s = 0; i < sw; s++, i += subX) {
150                        fsubsamples[s] = fsamples[i];
151                    }
152                    dst.setSamples(dx0, dy, dw, 1, k, fsubsamples);
153                }
154            }
155        } else {
156            int[] samples = new int[sw];
157            int[] subsamples = new int[numSubSamples];
158
159            for(int k = 0; k < b; k++) {
160                for(int sy = sy0, dy = dy0; sy < syUB; sy += subY, dy++) {
161                    src.getSamples(sx0, sy, sw, 1, k, samples);
162                    for(int i = 0, s = 0; i < sw; s++, i += subX) {
163                        subsamples[s] = samples[i];
164                    }
165                    dst.setSamples(dx0, dy, dw, 1, k, subsamples);
166                }
167            }
168        }
169    }                                 
170
171    protected CLibImageReader(ImageReaderSpi originatingProvider) {
172        super(originatingProvider);
173    }
174
175    /**
176     * An <code>Iterator</code> over a single element.
177     */
178    private class SoloIterator implements Iterator {
179        Object theObject;
180
181        SoloIterator(Object o) {
182            if(o == null) {
183                new IllegalArgumentException
184                    (I18N.getString("CLibImageReader0"));
185            }
186            theObject = o;
187        }
188
189        public boolean hasNext() {
190            return theObject != null;
191        }
192
193        public Object next() {
194            if(theObject == null) {
195                throw new NoSuchElementException();
196            }
197            Object theNextObject = theObject;
198            theObject = null;
199            return theNextObject;
200        }
201
202        public void remove() {
203            throw new UnsupportedOperationException();
204        }
205    }
206
207    
208
209
210    /**
211     * Returns the index of the image cached in the private
212     * <code>mlibImage</code> instance variable or -1 if no
213     * image is currently cached.
214     */
215    protected int getImageIndex() {
216        return mlibImageIndex;
217    }
218
219
220    public IIOMetadata getStreamMetadata() throws IOException {
221        return null;
222    }
223}