001    /*
002     * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003     *
004     * http://uio.imagero.com
005     *
006     * Redistribution and use in source and binary forms, with or without
007     * modification, are permitted provided that the following conditions are met:
008     *
009     *  o Redistributions of source code must retain the above copyright notice,
010     *    this list of conditions and the following disclaimer.
011     *
012     *  o Redistributions in binary form must reproduce the above copyright notice,
013     *    this list of conditions and the following disclaimer in the documentation
014     *    and/or other materials provided with the distribution.
015     *
016     *  o Neither the name of Andrey Kuznetsov nor the names of
017     *    its contributors may be used to endorse or promote products derived
018     *    from this software without specific prior written permission.
019     *
020     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
029     * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
030     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031     */
032    
033    package com.imagero.uio.io;
034    
035    import com.imagero.uio.RandomAccessIO;
036    
037    import java.io.IOException;
038    
039    /**
040     * InputStream over all strips
041     * @author Andrei Kouznetsov
042     */
043    public class TIFFStripInputStream extends RandomAccessInputStream {
044    
045            int[] stripOffsets, stripByteCount;
046    
047            int currentStrip = -1;
048            long stripLimit;
049            int markStrip;
050    
051            public TIFFStripInputStream(RandomAccessIO ra, int[] stripByteCount, int[] stripOffsets) {
052                    super(ra);
053                    this.stripByteCount = stripByteCount;
054                    this.stripOffsets = stripOffsets;
055            }
056    
057            public TIFFStripInputStream(RandomAccessIO ra, long startPos, int[] stripByteCount, int[] stripOffsets) {
058                    super(ra, startPos);
059                    this.stripByteCount = stripByteCount;
060                    this.stripOffsets = stripOffsets;
061            }
062    
063            protected void checkPos() throws IOException {
064                    if(pos > stripLimit || currentStrip == -1) {
065    //                      Sys.out.println("currentStrip:" + currentStrip);
066                            if(currentStrip >= stripOffsets.length) {
067                                    throw new IOException();
068                            }
069                            currentStrip++;
070                            stripLimit = stripOffsets[currentStrip] + stripByteCount[currentStrip];
071                            pos = stripOffsets[currentStrip];
072    
073    //                      File ft = new File(TiffReader.workDir + "tables" + currentStrip + ".jpg");
074    //                      FileOutputStream fout = new FileOutputStream(ft);
075    //                      in.seek(pos);
076    //                      byte [] b = new byte[256];
077    //                      for(int i = 0; i < stripByteCount[currentStrip];) {
078    //                              int r = in.read(b);
079    //                              if(r < 0) {
080    //                                      break;
081    //                              }
082    //                              fout.write(b, 0, r);
083    //                              i =+ r;
084    //                      }
085    //                      fout.close();
086                    }
087                    super.checkPos();
088            }
089    
090            synchronized public int read(byte[] b, int off, int len) throws IOException {
091                    return super.read(b, off, Math.min(len, (int)(stripLimit - pos)));
092            }
093    
094            public void mark(int i) {
095                    super.mark(i);
096                    markStrip = currentStrip;
097            }
098    
099            public void reset() throws IOException {
100                    super.reset();
101                    currentStrip = markStrip;
102            }
103    
104            public long skip(long l) throws IOException {
105                    int lsi = stripOffsets.length - 1;
106                    long limit = stripOffsets[lsi] + stripByteCount[lsi];
107                    long remaining = l;
108                    while(remaining > 0) {
109                            checkPos();
110                            long cs = Math.min(remaining, stripLimit - pos);
111                            if(cs > limit - pos) {
112                                    cs = limit - pos;
113                                    remaining -= cs;
114                                    pos += cs;
115                                    break;
116                            }
117                            remaining -= cs;
118                            pos += cs;
119                    }
120                    return l - remaining;
121            }
122    
123            public int available() {
124                    try {
125                            return super.available();
126                    }
127                    catch(IOException e) {
128                            e.printStackTrace();
129                    }
130                    return 0;
131            }
132    
133            public long getPos() {
134                    long res = 0;
135                    for(int i = 0; i < currentStrip; i++) {
136                            res += stripByteCount[i];
137                    }
138                    res += stripByteCount[currentStrip]
139                            - (stripByteCount[currentStrip] + stripOffsets[currentStrip] - pos);
140                    return res;
141            }
142    }