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