home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / browser / ns405lyc / nav40.z / java40.jar / sun / awt / image / GifImageDecoder.class (.txt) < prev    next >
Encoding:
Java Class File  |  1998-03-24  |  6.6 KB  |  491 lines

  1. package sun.awt.image;
  2.  
  3. import java.awt.image.ColorModel;
  4. import java.awt.image.ImageConsumer;
  5. import java.awt.image.IndexColorModel;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.util.Hashtable;
  9.  
  10. public class GifImageDecoder extends ImageDecoder {
  11.    private static final boolean verbose = false;
  12.    private static final int IMAGESEP = 44;
  13.    private static final int EXBLOCK = 33;
  14.    private static final int EX_GRAPHICS_CONTROL = 249;
  15.    private static final int EX_COMMENT = 254;
  16.    private static final int EX_APPLICATION = 255;
  17.    private static final int TERMINATOR = 59;
  18.    private static final int TRANSPARENCYMASK = 1;
  19.    private static final int INTERLACEMASK = 64;
  20.    private static final int COLORMAPMASK = 128;
  21.    private static final int DISPOSAL_NONE = 0;
  22.    private static final int DISPOSAL_SAVE = 1;
  23.    private static final int DISPOSAL_BGCOLOR = 2;
  24.    private static final int DISPOSAL_PREVIOUS = 3;
  25.    private static IndexColorModel trans_model;
  26.    PixelStore8 store;
  27.    boolean cancatchup = true;
  28.    int num_global_colors;
  29.    byte[] global_colormap;
  30.    int trans_pixel = -1;
  31.    IndexColorModel global_model;
  32.    Hashtable props = new Hashtable();
  33.    byte[] saved_image;
  34.    IndexColorModel saved_model;
  35.    int disposal_method;
  36.    int global_width;
  37.    int global_height;
  38.    int global_bgpixel;
  39.    boolean firstframe = true;
  40.    int nloops = -1;
  41.    int delay = -1;
  42.    private static final int normalflags = 30;
  43.    private static final int interlaceflags = 29;
  44.    private short[] prefix = new short[4096];
  45.    private byte[] suffix = new byte[4096];
  46.    private byte[] outCode = new byte[4097];
  47.  
  48.    public GifImageDecoder(InputStreamImageSource var1, InputStream var2) {
  49.       super(var1, var2);
  50.    }
  51.  
  52.    public synchronized boolean catchupConsumer(InputStreamImageSource var1, ImageConsumer var2) {
  53.       return this.cancatchup && (this.store == null || this.store.replay(var1, var2));
  54.    }
  55.  
  56.    public synchronized void makeStore(int var1, int var2) {
  57.       if (this.cancatchup) {
  58.          this.store = new PixelStore8(var1, var2);
  59.       }
  60.  
  61.    }
  62.  
  63.    private static void error(String var0) throws ImageFormatException {
  64.       throw new ImageFormatException(var0);
  65.    }
  66.  
  67.    private int readBytes(byte[] var1, int var2, int var3) {
  68.       while(true) {
  69.          if (var3 > 0) {
  70.             try {
  71.                int var4 = super.input.read(var1, var2, var3);
  72.                if (var4 >= 0) {
  73.                   var2 += var4;
  74.                   var3 -= var4;
  75.                   continue;
  76.                }
  77.             } catch (IOException var5) {
  78.             }
  79.          }
  80.  
  81.          return var3;
  82.       }
  83.    }
  84.  
  85.    private static final int ExtractByte(byte[] var0, int var1) {
  86.       return var0[var1] & 255;
  87.    }
  88.  
  89.    private static final int ExtractWord(byte[] var0, int var1) {
  90.       return var0[var1] & 255 | (var0[var1 + 1] & 255) << 8;
  91.    }
  92.  
  93.    public void produceImage() throws IOException, ImageFormatException {
  94.       try {
  95.          this.readHeader();
  96.          int var3 = 0;
  97.          int var4 = 0;
  98.  
  99.          label357:
  100.          while(true) {
  101.             switch (super.input.read()) {
  102.                case -1:
  103.                default:
  104.                   if (var4 == 0) {
  105.                      return;
  106.                   }
  107.                   break;
  108.                case 33:
  109.                   int var5;
  110.                   String var7;
  111.                   boolean var26;
  112.                   switch (var5 = super.input.read()) {
  113.                      case -1:
  114.                         return;
  115.                      case 249:
  116.                         byte[] var6 = new byte[6];
  117.                         if (this.readBytes(var6, 0, 6) != 0) {
  118.                            return;
  119.                         }
  120.  
  121.                         if (var6[0] != 4 || var6[5] != 0) {
  122.                            return;
  123.                         }
  124.  
  125.                         this.delay = ExtractWord(var6, 2) * 10;
  126.                         if (this.delay > 0) {
  127.                            this.cancatchup = false;
  128.                            this.store = null;
  129.                            ImageFetcher.startingAnimation();
  130.                         }
  131.  
  132.                         this.disposal_method = var6[1] >> 2 & 7;
  133.                         if ((var6[1] & 1) != 0) {
  134.                            this.trans_pixel = ExtractByte(var6, 4);
  135.                         } else {
  136.                            this.trans_pixel = -1;
  137.                         }
  138.                         continue;
  139.                      case 254:
  140.                      case 255:
  141.                      default:
  142.                         var26 = false;
  143.                         var7 = "";
  144.                   }
  145.  
  146.                   while(true) {
  147.                      int var8 = super.input.read();
  148.                      if (var8 <= 0) {
  149.                         if (var5 == 254) {
  150.                            this.props.put("comment", var7);
  151.                         }
  152.  
  153.                         if (var26) {
  154.                            super.input.mark(1000000);
  155.                            this.cancatchup = false;
  156.                            this.store = null;
  157.                            ImageFetcher.startingAnimation();
  158.                         }
  159.                         continue label357;
  160.                      }
  161.  
  162.                      byte[] var9 = new byte[var8];
  163.                      if (this.readBytes(var9, 0, var8) != 0) {
  164.                         return;
  165.                      }
  166.  
  167.                      if (var5 == 254) {
  168.                         var7 = var7 + new String(var9, 0);
  169.                      } else if (var5 == 255) {
  170.                         if (var26) {
  171.                            if (var8 == 3 && var9[0] == 1) {
  172.                               this.nloops = ExtractWord(var9, 1);
  173.                            } else {
  174.                               var26 = false;
  175.                            }
  176.                         }
  177.  
  178.                         if ("NETSCAPE2.0".equals(new String(var9, 0))) {
  179.                            var26 = true;
  180.                         }
  181.                      }
  182.                   }
  183.                case 44:
  184.                   try {
  185.                      if (!this.readImage(var3 == 0)) {
  186.                         this.cancatchup = false;
  187.                         return;
  188.                      }
  189.                   } catch (Exception var23) {
  190.                      return;
  191.                   }
  192.  
  193.                   ++var4;
  194.                   ++var3;
  195.                   this.firstframe = false;
  196.                   continue;
  197.                case 59:
  198.             }
  199.  
  200.             if (this.nloops == 0 || this.nloops-- >= 0) {
  201.                try {
  202.                   super.input.reset();
  203.                   this.saved_image = null;
  204.                   this.saved_model = null;
  205.                   this.firstframe = true;
  206.                   var4 = 0;
  207.                   continue;
  208.                } catch (IOException var24) {
  209.                }
  210.             }
  211.  
  212.             if (this.store != null) {
  213.                this.store.imageComplete();
  214.                if (this.store.getBitState() != 2) {
  215.                   super.source.setPixelStore(this.store);
  216.                }
  217.             }
  218.  
  219.             super.source.imageComplete(3);
  220.             return;
  221.          }
  222.       } finally {
  223.          try {
  224.             super.input.close();
  225.          } catch (IOException var22) {
  226.          }
  227.  
  228.       }
  229.    }
  230.  
  231.    private void readHeader() throws IOException, ImageFormatException {
  232.       byte[] var1 = new byte[13];
  233.       if (this.readBytes(var1, 0, 13) != 0) {
  234.          throw new IOException();
  235.       } else {
  236.          if (var1[0] != 71 || var1[1] != 73 || var1[2] != 70) {
  237.             error("not a GIF file.");
  238.          }
  239.  
  240.          this.global_width = ExtractWord(var1, 6);
  241.          this.global_height = ExtractWord(var1, 8);
  242.          int var2 = ExtractByte(var1, 10);
  243.          if ((var2 & 128) == 0) {
  244.             error("no global colormap in GIF file.");
  245.          }
  246.  
  247.          this.num_global_colors = 1 << (var2 & 7) + 1;
  248.          this.global_bgpixel = ExtractByte(var1, 11);
  249.          if (var1[12] != 0) {
  250.             this.props.put("aspectratio", String.valueOf((double)(ExtractByte(var1, 12) + 15) / (double)64.0F));
  251.          }
  252.  
  253.          this.global_colormap = new byte[this.num_global_colors * 3];
  254.          if (this.readBytes(this.global_colormap, 0, this.num_global_colors * 3) != 0) {
  255.             throw new IOException();
  256.          }
  257.       }
  258.    }
  259.  
  260.    private native boolean parseImage(int var1, int var2, int var3, int var4, boolean var5, int var6, byte[] var7, byte[] var8, IndexColorModel var9);
  261.  
  262.    private int sendPixels(int var1, int var2, int var3, int var4, byte[] var5, ColorModel var6) {
  263.       if (var2 < 0) {
  264.          var4 += var2;
  265.          var2 = 0;
  266.       }
  267.  
  268.       if (var2 + var4 > this.global_height) {
  269.          var4 = this.global_height - var2;
  270.       }
  271.  
  272.       if (var4 <= 0) {
  273.          return 1;
  274.       } else {
  275.          int var7;
  276.          int var9;
  277.          if (var1 < 0) {
  278.             var7 = -var1;
  279.             var3 += var1;
  280.             var9 = 0;
  281.          } else {
  282.             var7 = 0;
  283.             var9 = var1;
  284.          }
  285.  
  286.          if (var9 + var3 > this.global_width) {
  287.             var3 = this.global_width - var9;
  288.          }
  289.  
  290.          if (var3 <= 0) {
  291.             return 1;
  292.          } else {
  293.             int var8 = var7 + var3;
  294.             int var10 = var2 * this.global_width + var9;
  295.             if (this.trans_pixel >= 0 && !this.firstframe) {
  296.                if (this.saved_image == null || this.saved_model != var6) {
  297.                   int var16 = -1;
  298.                   int var17 = 1;
  299.  
  300.                   for(int var13 = var7; var13 < var8; ++var10) {
  301.                      byte var14 = var5[var13];
  302.                      if ((var14 & 255) == this.trans_pixel) {
  303.                         if (var16 >= 0) {
  304.                            var17 = super.source.setPixels(var1 + var16, var2, var13 - var16, var4, var6, var5, var16, 0);
  305.                            if (var17 == 0) {
  306.                               break;
  307.                            }
  308.                         }
  309.  
  310.                         var16 = -1;
  311.                      } else {
  312.                         if (var16 < 0) {
  313.                            var16 = var13;
  314.                         }
  315.  
  316.                         if (this.disposal_method == 1) {
  317.                            this.saved_image[var10] = var14;
  318.                         }
  319.                      }
  320.  
  321.                      ++var13;
  322.                   }
  323.  
  324.                   if (var16 >= 0) {
  325.                      var17 = super.source.setPixels(var1 + var16, var2, var8 - var16, var4, var6, var5, var16, 0);
  326.                   }
  327.  
  328.                   return var17;
  329.                }
  330.  
  331.                for(int var11 = var7; var11 < var8; ++var10) {
  332.                   byte var12 = var5[var11];
  333.                   if ((var12 & 255) == this.trans_pixel) {
  334.                      var5[var11] = this.saved_image[var10];
  335.                   } else if (this.disposal_method == 1) {
  336.                      this.saved_image[var10] = var12;
  337.                   }
  338.  
  339.                   ++var11;
  340.                }
  341.             } else if (this.disposal_method == 1) {
  342.                System.arraycopy(var5, var7, this.saved_image, var10, var3);
  343.             }
  344.  
  345.             int var15 = super.source.setPixels(var9, var2, var3, var4, var6, var5, var7, 0);
  346.             if (this.store != null && this.store.setPixels(var9, var2, var3, var4, var5, var7, 0)) {
  347.                ++var15;
  348.             }
  349.  
  350.             return var15;
  351.          }
  352.       }
  353.    }
  354.  
  355.    private boolean readImage(boolean var1) throws IOException {
  356.       long var2 = 0L;
  357.       byte[] var4 = new byte[259];
  358.       if (this.readBytes(var4, 0, 10) != 0) {
  359.          throw new IOException();
  360.       } else {
  361.          int var5 = ExtractWord(var4, 0);
  362.          int var6 = ExtractWord(var4, 2);
  363.          int var7 = ExtractWord(var4, 4);
  364.          int var8 = ExtractWord(var4, 6);
  365.          boolean var9 = (var4[8] & 64) != 0;
  366.          IndexColorModel var10 = this.global_model;
  367.          if ((var4[8] & 128) != 0) {
  368.             int var11 = 1 << (var4[8] & 7) + 1;
  369.             byte[] var12 = new byte[var11 * 3];
  370.             var12[0] = var4[9];
  371.             if (this.readBytes(var12, 1, var11 * 3 - 1) != 0) {
  372.                throw new IOException();
  373.             }
  374.  
  375.             if (this.readBytes(var4, 9, 1) != 0) {
  376.                throw new IOException();
  377.             }
  378.  
  379.             var10 = new IndexColorModel(8, var11, var12, 0, false, this.trans_pixel);
  380.          } else if (var10 == null || this.trans_pixel != var10.getTransparentPixel()) {
  381.             var10 = new IndexColorModel(8, this.num_global_colors, this.global_colormap, 0, false, this.trans_pixel);
  382.             this.global_model = var10;
  383.          }
  384.  
  385.          if (var1) {
  386.             this.makeStore(this.global_width, this.global_height);
  387.             if (this.store != null) {
  388.                this.store.setProperties(this.props);
  389.                this.store.setColorModel(var10);
  390.             }
  391.  
  392.             super.source.setDimensions(this.global_width, this.global_height);
  393.             super.source.setProperties(this.props);
  394.             super.source.setColorModel(var10);
  395.          } else if (this.store != null && var10 != this.store.getColorModel()) {
  396.             this.cancatchup = false;
  397.             this.store = null;
  398.          }
  399.  
  400.          if (this.disposal_method == 1 && this.saved_image == null) {
  401.             this.saved_image = new byte[this.global_width * this.global_height];
  402.          }
  403.  
  404.          int var17 = var9 ? 29 : 30;
  405.          super.source.setHints(var17);
  406.          if (this.store != null) {
  407.             this.store.setHints(var17);
  408.          }
  409.  
  410.          byte[] var18 = new byte[var7];
  411.          boolean var13 = this.parseImage(var5, var6, var7, var8, var9, ExtractByte(var4, 9), var4, var18, var10);
  412.          if (var13) {
  413.             super.source.imageComplete(2);
  414.             if (this.delay > 0) {
  415.                try {
  416.                   Thread.sleep((long)this.delay);
  417.                } catch (InterruptedException var16) {
  418.                   return false;
  419.                }
  420.             }
  421.  
  422.             if (var5 < 0) {
  423.                var7 += var5;
  424.                var5 = 0;
  425.             }
  426.  
  427.             if (var5 + var7 > this.global_width) {
  428.                var7 = this.global_width - var5;
  429.             }
  430.  
  431.             if (var7 <= 0) {
  432.                this.disposal_method = 0;
  433.             } else {
  434.                if (var6 < 0) {
  435.                   var8 += var6;
  436.                   var6 = 0;
  437.                }
  438.  
  439.                if (var6 + var8 > this.global_height) {
  440.                   var8 = this.global_height - var6;
  441.                }
  442.  
  443.                if (var8 <= 0) {
  444.                   this.disposal_method = 0;
  445.                }
  446.             }
  447.  
  448.             switch (this.disposal_method) {
  449.                case 1:
  450.                   this.saved_model = var10;
  451.                   break;
  452.                case 2:
  453.                   byte var14;
  454.                   if (var10.getTransparentPixel() < 0) {
  455.                      this.cancatchup = false;
  456.                      this.store = null;
  457.                      var10 = trans_model;
  458.                      if (var10 == null) {
  459.                         var10 = new IndexColorModel(8, 1, new byte[4], 0, true);
  460.                         trans_model = var10;
  461.                      }
  462.  
  463.                      var14 = 0;
  464.                   } else {
  465.                      var14 = (byte)var10.getTransparentPixel();
  466.                   }
  467.  
  468.                   for(int var15 = 0; var15 < var7; ++var15) {
  469.                      var18[var15] = var14;
  470.                   }
  471.  
  472.                   super.source.setPixels(var5, var6, var7, var8, var10, var18, 0, 0);
  473.                   if (this.store != null) {
  474.                      this.store.setPixels(var5, var6, var7, var8, var18, 0, 0);
  475.                   }
  476.                   break;
  477.                case 3:
  478.                   if (this.saved_image != null) {
  479.                      super.source.setPixels(var5, var6, var7, var8, this.saved_model, this.saved_image, var6 * this.global_width + var5, this.global_width);
  480.                      if (this.store != null) {
  481.                         this.store.setPixels(var5, var6, var7, var8, this.saved_image, var6 * this.global_width + var5, this.global_width);
  482.                      }
  483.                   }
  484.             }
  485.          }
  486.  
  487.          return var13;
  488.       }
  489.    }
  490. }
  491.