33 import java.awt.image.ColorModel; |
33 import java.awt.image.ColorModel; |
34 import java.awt.image.ComponentColorModel; |
34 import java.awt.image.ComponentColorModel; |
35 import java.awt.image.Raster; |
35 import java.awt.image.Raster; |
36 import java.awt.image.RenderedImage; |
36 import java.awt.image.RenderedImage; |
37 import java.awt.image.SampleModel; |
37 import java.awt.image.SampleModel; |
|
38 import java.io.EOFException; |
38 import java.io.IOException; |
39 import java.io.IOException; |
39 import java.nio.ByteOrder; |
40 import java.nio.ByteOrder; |
40 import java.util.ArrayList; |
41 import java.util.ArrayList; |
41 import java.util.HashMap; |
42 import java.util.HashMap; |
42 import java.util.Iterator; |
43 import java.util.Iterator; |
187 "Bad magic number in header, continuing"); |
188 "Bad magic number in header, continuing"); |
188 } |
189 } |
189 |
190 |
190 // Seek to start of first IFD |
191 // Seek to start of first IFD |
191 long offset = stream.readUnsignedInt(); |
192 long offset = stream.readUnsignedInt(); |
|
193 stream.seek(offset); |
192 imageStartPosition.add(Long.valueOf(offset)); |
194 imageStartPosition.add(Long.valueOf(offset)); |
193 stream.seek(offset); |
|
194 } catch (IOException e) { |
195 } catch (IOException e) { |
195 throw new IIOException("I/O error reading header!", e); |
196 throw new IIOException("I/O error reading header!", e); |
196 } |
197 } |
197 |
198 |
198 gotHeader = true; |
199 gotHeader = true; |
199 } |
200 } |
200 |
201 |
201 private int locateImage(int imageIndex) throws IIOException { |
202 private int locateImage(int imageIndex) throws IIOException { |
202 readHeader(); |
203 readHeader(); |
203 |
204 |
|
205 // Find closest known index |
|
206 int index = Math.min(imageIndex, imageStartPosition.size() - 1); |
|
207 |
204 try { |
208 try { |
205 // Find closest known index |
|
206 int index = Math.min(imageIndex, imageStartPosition.size() - 1); |
|
207 |
|
208 // Seek to that position |
209 // Seek to that position |
209 Long l = imageStartPosition.get(index); |
210 Long l = imageStartPosition.get(index); |
210 stream.seek(l.longValue()); |
211 stream.seek(l.longValue()); |
211 |
212 |
212 // Skip IFDs until at desired index or last image found |
213 // Skip IFDs until at desired index or last image found |
213 while (index < imageIndex) { |
214 while (index < imageIndex) { |
214 int count = stream.readUnsignedShort(); |
215 int count = stream.readUnsignedShort(); |
|
216 // If zero-entry IFD, decrement the index and exit the loop |
|
217 if (count == 0) { |
|
218 imageIndex = index > 0 ? index - 1 : 0; |
|
219 break; |
|
220 } |
215 stream.skipBytes(12 * count); |
221 stream.skipBytes(12 * count); |
216 |
222 |
217 long offset = stream.readUnsignedInt(); |
223 long offset = stream.readUnsignedInt(); |
218 if (offset == 0) { |
224 if (offset == 0) { |
219 return index; |
225 return index; |
220 } |
226 } |
221 |
227 |
|
228 stream.seek(offset); |
222 imageStartPosition.add(Long.valueOf(offset)); |
229 imageStartPosition.add(Long.valueOf(offset)); |
223 stream.seek(offset); |
|
224 ++index; |
230 ++index; |
225 } |
231 } |
226 } catch (IOException e) { |
232 } catch (EOFException eofe) { |
227 throw new IIOException("Couldn't seek!", e); |
233 forwardWarningMessage("Ignored " + eofe); |
|
234 |
|
235 // Ran off the end of stream: decrement index |
|
236 imageIndex = index > 0 ? index - 1 : 0; |
|
237 } catch (IOException ioe) { |
|
238 throw new IIOException("Couldn't seek!", ioe); |
228 } |
239 } |
229 |
240 |
230 if (currIndex != imageIndex) { |
241 if (currIndex != imageIndex) { |
231 imageMetadata = null; |
242 imageMetadata = null; |
232 } |
243 } |