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: }