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