home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 January / PCO0198.ISO / 1&1 / java.z / java_301 / sun / awt / image / GifImageDecoder.class (.txt) < prev    next >
Encoding:
Java Class File  |  1996-10-20  |  5.3 KB  |  207 lines

  1. package sun.awt.image;
  2.  
  3. import java.awt.image.ImageConsumer;
  4. import java.awt.image.IndexColorModel;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.util.Hashtable;
  8.  
  9. public class GifImageDecoder extends ImageDecoder {
  10.    private final boolean verbose = false;
  11.    private static final int IMAGESEP = 44;
  12.    private static final int EXBLOCK = 33;
  13.    private static final int EX_GRAPHICS_CONTROL = 249;
  14.    private static final int EX_COMMENT = 254;
  15.    private static final int EX_APPLICATION = 255;
  16.    private static final int TERMINATOR = 59;
  17.    private static final int INTERLACEMASK = 64;
  18.    private static final int COLORMAPMASK = 128;
  19.    PixelStore8 store;
  20.    int num_colors;
  21.    byte[] colormap;
  22.    IndexColorModel model;
  23.    Hashtable props = new Hashtable();
  24.    private static final int normalflags = 30;
  25.    private static final int interlaceflags = 29;
  26.  
  27.    public GifImageDecoder(InputStreamImageSource src, InputStream is) {
  28.       super(src, is);
  29.    }
  30.  
  31.    public synchronized boolean catchupConsumer(InputStreamImageSource src, ImageConsumer ic) {
  32.       return this.store == null || this.store.replay(src, ic);
  33.    }
  34.  
  35.    public synchronized void makeStore(int width, int height) {
  36.       this.store = new PixelStore8(width, height);
  37.    }
  38.  
  39.    private static void error(String s1) throws ImageFormatException {
  40.       throw new ImageFormatException(s1);
  41.    }
  42.  
  43.    boolean readBytes(byte[] buf, int off, int len) {
  44.       while(len > 0) {
  45.          int n;
  46.          try {
  47.             n = super.input.read(buf, off, len);
  48.          } catch (IOException var5) {
  49.             n = -1;
  50.          }
  51.  
  52.          if (n < 0) {
  53.             return false;
  54.          }
  55.  
  56.          off += n;
  57.          len -= n;
  58.       }
  59.  
  60.       return true;
  61.    }
  62.  
  63.    public void produceImage() throws IOException, ImageFormatException {
  64.       int trans_pixel = -1;
  65.  
  66.       try {
  67.          this.readHeader();
  68.  
  69.          label248:
  70.          while(true) {
  71.             switch (super.input.read()) {
  72.                case 59:
  73.                   return;
  74.                case 44:
  75.                   try {
  76.                      this.model = new IndexColorModel(8, this.num_colors, this.colormap, 0, false, trans_pixel);
  77.                      this.colormap = null;
  78.                      if (this.readImage()) {
  79.                         this.store.imageComplete();
  80.                         if (this.store.getBitState() != 2) {
  81.                            super.source.setPixelStore(this.store);
  82.                         }
  83.  
  84.                         super.source.imageComplete(3);
  85.                         return;
  86.                      }
  87.                   } catch (ArrayIndexOutOfBoundsException var19) {
  88.                   }
  89.  
  90.                   return;
  91.                case -1:
  92.                   return;
  93.                case 33:
  94.                   int code;
  95.                   switch (code = super.input.read()) {
  96.                      case 255:
  97.                      case 254:
  98.                      default:
  99.                         String comment = "";
  100.  
  101.                         while(true) {
  102.                            int n = super.input.read();
  103.                            if (n == 0) {
  104.                               if (code == 254) {
  105.                                  this.props.put("comment", comment);
  106.                               }
  107.                               continue label248;
  108.                            }
  109.  
  110.                            byte[] buf = new byte[n];
  111.                            if (!this.readBytes(buf, 0, n)) {
  112.                               return;
  113.                            }
  114.  
  115.                            if (code == 254) {
  116.                               comment = comment + new String(buf, 0);
  117.                            }
  118.                         }
  119.                      case 249:
  120.                         byte[] buf = new byte[6];
  121.                         if (!this.readBytes(buf, 0, 6)) {
  122.                            return;
  123.                         }
  124.  
  125.                         if (buf[0] != 4 || buf[5] != 0) {
  126.                            return;
  127.                         }
  128.  
  129.                         trans_pixel = buf[4] & 255;
  130.                         continue;
  131.                   }
  132.                default:
  133.                   return;
  134.             }
  135.          }
  136.       } finally {
  137.          try {
  138.             super.input.close();
  139.          } catch (IOException var18) {
  140.          }
  141.  
  142.       }
  143.    }
  144.  
  145.    private void readHeader() throws IOException, ImageFormatException {
  146.       byte[] buf = new byte[13];
  147.       if (!this.readBytes(buf, 0, 13)) {
  148.          throw new IOException();
  149.       } else {
  150.          if (buf[0] != 71 || buf[1] != 73 || buf[2] != 70) {
  151.             error("not a GIF file.");
  152.          }
  153.  
  154.          int ch = buf[10] & 255;
  155.          if ((ch & 128) == 0) {
  156.             error("no global colormap in GIF file.");
  157.          }
  158.  
  159.          this.num_colors = 1 << (ch & 7) + 1;
  160.          if (buf[12] != 0) {
  161.             error("corrupt GIF file (no null).");
  162.          }
  163.  
  164.          this.colormap = new byte[this.num_colors * 3];
  165.          if (!this.readBytes(this.colormap, 0, this.num_colors * 3)) {
  166.             throw new IOException();
  167.          }
  168.       }
  169.    }
  170.  
  171.    private native boolean parseImage(int var1, int var2, boolean var3, int var4, byte[] var5, byte[] var6);
  172.  
  173.    private int sendPixels(int y, int width, byte[] rasline) {
  174.       int count = super.source.setPixels(0, y, width, 1, this.model, rasline, 0, width);
  175.       if (this.store.setPixels(0, y, width, 1, rasline, 0, width)) {
  176.          ++count;
  177.       }
  178.  
  179.       return count;
  180.    }
  181.  
  182.    private boolean readImage() throws IOException {
  183.       long tm = 0L;
  184.       byte[] block = new byte[259];
  185.       if (!this.readBytes(block, 0, 10)) {
  186.          throw new IOException();
  187.       } else {
  188.          int width = block[4] & 255 | block[5] << 8;
  189.          int height = block[6] & 255 | block[7] << 8;
  190.          boolean interlace = (block[8] & 64) != 0;
  191.          int initCodeSize = block[9] & 255;
  192.          super.source.setDimensions(width, height);
  193.          this.makeStore(width, height);
  194.          super.source.setProperties(this.props);
  195.          this.store.setProperties(this.props);
  196.          super.source.setColorModel(this.model);
  197.          this.store.setColorModel(this.model);
  198.          int hints = interlace ? 29 : 30;
  199.          super.source.setHints(hints);
  200.          this.store.setHints(hints);
  201.          byte[] rasline = new byte[width];
  202.          boolean ret = this.parseImage(width, height, interlace, initCodeSize, block, rasline);
  203.          return ret;
  204.       }
  205.    }
  206. }
  207.