1:
37:
38: package ;
39:
40: import ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58:
59: public class GIFImageReader extends ImageReader
60: {
61: private GIFFile file;
62:
63: protected GIFImageReader(ImageReaderSpi originatingProvider)
64: {
65: super( originatingProvider );
66: file = null;
67: }
68:
69: private void readImage() throws IOException
70: {
71: if( file != null )
72: return;
73:
74: try
75: {
76: if( input instanceof InputStream )
77: file = new GIFFile( (InputStream)input );
78: else
79: file = new GIFFile( new IIOInputStream((ImageInputStream)input) );
80: }
81: catch(GIFFile.GIFException ge)
82: {
83: throw new IIOException(ge.getMessage());
84: }
85: }
86:
87:
90: private IndexColorModel getPalette(int index)
91: {
92: GIFFile f = file.getImage( index );
93: byte[] data = f.getRawPalette();
94: int nc = f.getNColors();
95: byte[] r = new byte[nc];
96: byte[] g = new byte[nc];
97: byte[] b = new byte[nc];
98:
99: for(int i = 0; i < nc; i ++ )
100: {
101: r[i] = data[ i * 3 ];
102: g[i] = data[ i * 3 + 1 ];
103: b[i] = data[ i * 3 + 2 ];
104: }
105:
106: if( f.hasTransparency() )
107: {
108: byte[] a = new byte[nc];
109: for(int i = 0; i < nc; i ++ )
110: a[i] = (byte)0xFF;
111: a[f.getTransparentIndex()] = 0;
112: return new IndexColorModel(8, nc, r, g, b, a);
113: }
114:
115: return new IndexColorModel(8, nc, r, g, b);
116: }
117:
118: private void validateIndex(int imageIndex)
119: throws IndexOutOfBoundsException
120: {
121: if( imageIndex < 0 || imageIndex >= getNumImages(false) )
122: throw new IndexOutOfBoundsException("Invalid image index.");
123: }
124:
125: public void setInput(Object input)
126: {
127: super.setInput(input);
128: }
129:
130: public void setInput(Object input,
131: boolean seekForwardOnly,
132: boolean ignoreMetadata)
133: {
134: super.setInput(input, seekForwardOnly, ignoreMetadata);
135: }
136:
137: public void setInput(Object input, boolean isStreamable)
138: {
139: super.setInput(input, isStreamable);
140:
141: if (!(input instanceof ImageInputStream) &&
142: !(input instanceof InputStream))
143: throw new IllegalArgumentException("Input not an ImageInputStream.");
144: }
145:
146: private void checkStream() throws IOException
147: {
148: if (!(input instanceof ImageInputStream) &&
149: !(input instanceof InputStream))
150: throw new IllegalStateException("Input not an ImageInputStream or InputStream.");
151:
152: if(input == null)
153: throw new IllegalStateException("No input stream.");
154: }
155:
156: public int getWidth(int imageIndex) throws IOException
157: {
158: validateIndex( imageIndex );
159: return file.getImage( imageIndex ).getWidth();
160: }
161:
162: public int getHeight(int imageIndex) throws IOException
163: {
164: validateIndex( imageIndex );
165: return file.getImage( imageIndex ).getHeight();
166: }
167:
168: public Iterator getImageTypes(int imageIndex)
169: {
170: validateIndex( imageIndex );
171: return null;
172: }
173:
174:
177: public int getNumImages(boolean allowSearch)
178: {
179: try
180: {
181: readImage();
182: }
183: catch(IOException ioe)
184: {
185: return 0;
186: }
187: return file.nImages();
188: }
189:
190:
191:
192: public IIOMetadata getImageMetadata(int imageIndex)
193: {
194: validateIndex( imageIndex );
195: return null;
196: }
197:
198:
199: public IIOMetadata getStreamMetadata()
200: {
201: return null;
202: }
203:
204:
208: public BufferedImage read(int imageIndex, ImageReadParam param)
209: throws IOException, IIOException
210: {
211: validateIndex( imageIndex );
212: GIFFile f = file.getImage( imageIndex );
213: int width = f.getWidth();
214: int height = f.getHeight();
215: SampleModel sm;
216: switch( f.getNColors() )
217: {
218: case 16:
219: sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
220: width, height, 4);
221: break;
222: case 4:
223: sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
224: width, height, 2);
225: break;
226: case 2:
227: sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
228: width, height, 1);
229: break;
230: default:
231: sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE,
232: width, height,
233: new int[] {0xFF});
234: break;
235: }
236: DataBuffer db = new DataBufferByte(f.getRawImage(), width * height, 0);
237: WritableRaster raster = Raster.createWritableRaster(sm, db, null);
238:
239: return new BufferedImage(getPalette( imageIndex ), raster, false, null);
240: }
241: }