<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    gembin

    OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

    HBase, Hadoop, ZooKeeper, Cassandra

    Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

    There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

    About Me

     

    GifDecoder.java源碼(處理GIF圖片)

     
     

    import java.net.*;
    import java.io.*;
    import java.util.*;
    import java.awt.*;
    import java.awt.image.*;

    public class GifDecoder {

     /**
      * File read status: No errors.
      */
     public static final int STATUS_OK = 0;

     /**
      * File read status: Error decoding file (may be partially decoded)
      */
     public static final int STATUS_FORMAT_ERROR = 1;

     /**
      * File read status: Unable to open source.
      */
     public static final int STATUS_OPEN_ERROR = 2;

     protected BufferedInputStream in;
     protected int status;

     protected int width; // full image width
     protected int height; // full image height
     protected boolean gctFlag; // global color table used
     protected int gctSize; // size of global color table
     protected int loopCount = 1; // iterations; 0 = repeat forever

     protected int[] gct; // global color table
     protected int[] lct; // local color table
     protected int[] act; // active color table

     protected int bgIndex; // background color index
     protected int bgColor; // background color
     protected int lastBgColor; // previous bg color
     protected int pixelAspect; // pixel aspect ratio

     protected boolean lctFlag; // local color table flag
     protected boolean interlace; // interlace flag
     protected int lctSize; // local color table size

     protected int ix, iy, iw, ih; // current image rectangle
     protected Rectangle lastRect; // last image rect
     protected BufferedImage image; // current frame
     protected BufferedImage lastImage; // previous frame

     protected byte[] block = new byte[256]; // current data block
     protected int blockSize = 0; // block size

     // last graphic control extension info
     protected int dispose = 0;
     // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
     protected int lastDispose = 0;
     protected boolean transparency = false; // use transparent color
     protected int delay = 0; // delay in milliseconds
     protected int transIndex; // transparent color index

     protected static final int MaxStackSize = 4096;
     // max decoder pixel stack size

     // LZW decoder working arrays
     protected short[] prefix;
     protected byte[] suffix;
     protected byte[] pixelStack;
     protected byte[] pixels;

     protected ArrayList frames; // frames read from current file
     protected int frameCount;

     static class GifFrame {
      public GifFrame(BufferedImage im, int del) {
       image = im;
       delay = del;
      }
      public BufferedImage image;
      public int delay;
     }

     /**
      * Gets display duration for specified frame.
      *
      * @param n int index of frame
      * @return delay in milliseconds
      */
     public int getDelay(int n) {
      //
      delay = -1;
      if ((n >= 0) && (n < frameCount)) {
       delay = ((GifFrame) frames.get(n)).delay;
      }
      return delay;
     }

     /**
      * Gets the number of frames read from file.
      * @return frame count
      */
     public int getFrameCount() {
      return frameCount;
     }

     /**
      * Gets the first (or only) image read.
      *
      * @return BufferedImage containing first frame, or null if none.
      */
     public BufferedImage getImage() {
      return getFrame(0);
     }

     /**
      * Gets the "Netscape" iteration count, if any.
      * A count of 0 means repeat indefinitiely.
      *
      * @return iteration count if one was specified, else 1.
      */
     public int getLoopCount() {
      return loopCount;
     }

     /**
      * Creates new frame image from current data (and previous
      * frames as specified by their disposition codes).
      */
     protected void setPixels() {
      // expose destination image's pixels as int array
      int[] dest =
       ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

      // fill in starting image contents based on last image's dispose code
      if (lastDispose > 0) {
       if (lastDispose == 3) {
        // use image before last
        int n = frameCount - 2;
        if (n > 0) {
         lastImage = getFrame(n - 1);
        } else {
         lastImage = null;
        }
       }

       if (lastImage != null) {
        int[] prev =
         ((DataBufferInt) lastImage.getRaster().getDataBuffer()).getData();
        System.arraycopy(prev, 0, dest, 0, width * height);
        // copy pixels

        if (lastDispose == 2) {
         // fill last image rect area with background color
         Graphics2D g = image.createGraphics();
         Color c = null;
         if (transparency) {
          c = new Color(0, 0, 0, 0);  // assume background is transparent
         } else {
          c = new Color(lastBgColor); // use given background color
         }
         g.setColor(c);
         g.setComposite(AlphaComposite.Src); // replace area
         g.fill(lastRect);
         g.dispose();
        }
       }
      }

      // copy each source line to the appropriate place in the destination
      int pass = 1;
      int inc = 8;
      int iline = 0;
      for (int i = 0; i < ih; i++) {
       int line = i;
       if (interlace) {
        if (iline >= ih) {
         pass++;
         switch (pass) {
          case 2 :
           iline = 4;
           break;
          case 3 :
           iline = 2;
           inc = 4;
           break;
          case 4 :
           iline = 1;
           inc = 2;
         }
        }
        line = iline;
        iline += inc;
       }
       line += iy;
       if (line < height) {
        int k = line * width;
        int dx = k + ix; // start of line in dest
        int dlim = dx + iw; // end of dest line
        if ((k + width) < dlim) {
         dlim = k + width; // past dest edge
        }
        int sx = i * iw; // start of line in source
        while (dx < dlim) {
         // map color and insert in destination
         int index = ((int) pixels[sx++]) & 0xff;
         int c = act[index];
         if (c != 0) {
          dest[dx] = c;
         }
         dx++;
        }
       }
      }
     }

     /**
      * Gets the image contents of frame n.
      *
      * @return BufferedImage representation of frame, or null if n is invalid.
      */
     public BufferedImage getFrame(int n) {
      BufferedImage im = null;
      if ((n >= 0) && (n < frameCount)) {
       im = ((GifFrame) frames.get(n)).image;
      }
      return im;
     }

     /**
      * Gets image size.
      *
      * @return GIF image dimensions
      */
     public Dimension getFrameSize() {
      return new Dimension(width, height);
     }

     /**
      * Reads GIF image from stream
      *
      * @param BufferedInputStream containing GIF file.
      * @return read status code (0 = no errors)
      */
     public int read(BufferedInputStream is) {
      init();
      if (is != null) {
       in = is;
       readHeader();
       if (!err()) {
        readContents();
        if (frameCount < 0) {
         status = STATUS_FORMAT_ERROR;
        }
       }
      } else {
       status = STATUS_OPEN_ERROR;
      }
      try {
       is.close();
      } catch (IOException e) {
      }
      return status;
     }

     /**
      * Reads GIF image from stream
      *
      * @param InputStream containing GIF file.
      * @return read status code (0 = no errors)
      */
     public int read(InputStream is) {
      init();
      if (is != null) {
       if (!(is instanceof BufferedInputStream))
        is = new BufferedInputStream(is);
       in = (BufferedInputStream) is;
       readHeader();
       if (!err()) {
        readContents();
        if (frameCount < 0) {
         status = STATUS_FORMAT_ERROR;
        }
       }
      } else {
       status = STATUS_OPEN_ERROR;
      }
      try {
       is.close();
      } catch (IOException e) {
      }
      return status;
     }

     /**
      * Reads GIF file from specified file/URL source  
      * (URL assumed if name contains ":/" or "file:")
      *
      * @param name String containing source
      * @return read status code (0 = no errors)
      */
     public int read(String name) {
      status = STATUS_OK;
      try {
       name = name.trim().toLowerCase();
       if ((name.indexOf("file:") >= 0) ||
        (name.indexOf(":/") > 0)) {
        URL url = new URL(name);
        in = new BufferedInputStream(url.openStream());
       } else {
        in = new BufferedInputStream(new FileInputStream(name));
       }
       status = read(in);
      } catch (IOException e) {
       status = STATUS_OPEN_ERROR;
      }

      return status;
     }

     /**
      * Decodes LZW image data into pixel array.
      * Adapted from John Cristy's ImageMagick.
      */
     protected void decodeImageData() {
      int NullCode = -1;
      int npix = iw * ih;
      int available, 
       clear,
       code_mask,
       code_size,
       end_of_information,
       in_code,
       old_code,
       bits,
       code,
       count,
       i,
       datum,
       data_size,
       first,
       top,
       bi,
       pi;

      if ((pixels == null) || (pixels.length < npix)) {
       pixels = new byte[npix]; // allocate new pixel array
      }
      if (prefix == null) prefix = new short[MaxStackSize];
      if (suffix == null) suffix = new byte[MaxStackSize];
      if (pixelStack == null) pixelStack = new byte[MaxStackSize + 1];

      //  Initialize GIF data stream decoder.

      data_size = read();
      clear = 1 << data_size;
      end_of_information = clear + 1;
      available = clear + 2;
      old_code = NullCode;
      code_size = data_size + 1;
      code_mask = (1 << code_size) - 1;
      for (code = 0; code < clear; code++) {
       prefix[code] = 0;
       suffix[code] = (byte) code;
      }

      //  Decode GIF pixel stream.

      datum = bits = count = first = top = pi = bi = 0;

      for (i = 0; i < npix;) {
       if (top == 0) {
        if (bits < code_size) {
         //  Load bytes until there are enough bits for a code.
         if (count == 0) {
          // Read a new data block.
          count = readBlock();
          if (count <= 0)
           break;
          bi = 0;
         }
         datum += (((int) block[bi]) & 0xff) << bits;
         bits += 8;
         bi++;
         count--;
         continue;
        }

        //  Get the next code.

        code = datum & code_mask;
        datum >>= code_size;
        bits -= code_size;

        //  Interpret the code

        if ((code > available) || (code == end_of_information))
         break;
        if (code == clear) {
         //  Reset decoder.
         code_size = data_size + 1;
         code_mask = (1 << code_size) - 1;
         available = clear + 2;
         old_code = NullCode;
         continue;
        }
        if (old_code == NullCode) {
         pixelStack[top++] = suffix[code];
         old_code = code;
         first = code;
         continue;
        }
        in_code = code;
        if (code == available) {
         pixelStack[top++] = (byte) first;
         code = old_code;
        }
        while (code > clear) {
         pixelStack[top++] = suffix[code];
         code = prefix[code];
        }
        first = ((int) suffix[code]) & 0xff;

        //  Add a new string to the string table,

        if (available >= MaxStackSize)
         break;
        pixelStack[top++] = (byte) first;
        prefix[available] = (short) old_code;
        suffix[available] = (byte) first;
        available++;
        if (((available & code_mask) == 0)
         && (available < MaxStackSize)) {
         code_size++;
         code_mask += available;
        }
        old_code = in_code;
       }

       //  Pop a pixel off the pixel stack.

       top--;
       pixels[pi++] = pixelStack[top];
       i++;
      }

      for (i = pi; i < npix; i++) {
       pixels[i] = 0; // clear missing pixels
      }

     }

     /**
      * Returns true if an error was encountered during reading/decoding
      */
     protected boolean err() {
      return status != STATUS_OK;
     }

     /**
      * Initializes or re-initializes reader
      */
     protected void init() {
      status = STATUS_OK;
      frameCount = 0;
      frames = new ArrayList();
      gct = null;
      lct = null;
     }

     /**
      * Reads a single byte from the input stream.
      */
     protected int read() {
      int curByte = 0;
      try {
       curByte = in.read();
      } catch (IOException e) {
       status = STATUS_FORMAT_ERROR;
      }
      return curByte;
     }

     /**
      * Reads next variable length block from input.
      *
      * @return number of bytes stored in "buffer"
      */
     protected int readBlock() {
      blockSize = read();
      int n = 0;
      if (blockSize > 0) {
       try {
        int count = 0;
        while (n < blockSize) {
         count = in.read(block, n, blockSize - n);
         if (count == -1) 
          break;
         n += count;
        }
       } catch (IOException e) {
       }

       if (n < blockSize) {
        status = STATUS_FORMAT_ERROR;
       }
      }
      return n;
     }

     /**
      * Reads color table as 256 RGB integer values
      *
      * @param ncolors int number of colors to read
      * @return int array containing 256 colors (packed ARGB with full alpha)
      */
     protected int[] readColorTable(int ncolors) {
      int nbytes = 3 * ncolors;
      int[] tab = null;
      byte[] c = new byte[nbytes];
      int n = 0;
      try {
       n = in.read(c);
      } catch (IOException e) {
      }
      if (n < nbytes) {
       status = STATUS_FORMAT_ERROR;
      } else {
       tab = new int[256]; // max size to avoid bounds checks
       int i = 0;
       int j = 0;
       while (i < ncolors) {
        int r = ((int) c[j++]) & 0xff;
        int g = ((int) c[j++]) & 0xff;
        int b = ((int) c[j++]) & 0xff;
        tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
       }
      }
      return tab;
     }

     /**
      * Main file parser.  Reads GIF content blocks.
      */
     protected void readContents() {
      // read GIF file content blocks
      boolean done = false;
      while (!(done || err())) {
       int code = read();
       switch (code) {

        case 0x2C : // image separator
         readImage();
         break;

        case 0x21 : // extension
         code = read();
         switch (code) {
          case 0xf9 : // graphics control extension
           readGraphicControlExt();
           break;

          case 0xff : // application extension
           readBlock();
           String app = "";
           for (int i = 0; i < 11; i++) {
            app += (char) block[i];
           }
           if (app.equals("NETSCAPE2.0")) {
            readNetscapeExt();
           }
           else
            skip(); // don't care
           break;

          default : // uninteresting extension
           skip();
         }
         break;

        case 0x3b : // terminator
         done = true;
         break;

        case 0x00 : // bad byte, but keep going and see what happens
         break;

        default :
         status = STATUS_FORMAT_ERROR;
       }
      }
     }

     /**
      * Reads Graphics Control Extension values
      */
     protected void readGraphicControlExt() {
      read(); // block size
      int packed = read(); // packed fields
      dispose = (packed & 0x1c) >> 2; // disposal method
      if (dispose == 0) {
       dispose = 1; // elect to keep old image if discretionary
      }
      transparency = (packed & 1) != 0;
      delay = readShort() * 10; // delay in milliseconds
      transIndex = read(); // transparent color index
      read(); // block terminator
     }

     /**
      * Reads GIF file header information.
      */
     protected void readHeader() {
      String id = "";
      for (int i = 0; i < 6; i++) {
       id += (char) read();
      }
      if (!id.startsWith("GIF")) {
       status = STATUS_FORMAT_ERROR;
       return;
      }

      readLSD();
      if (gctFlag && !err()) {
       gct = readColorTable(gctSize);
       bgColor = gct[bgIndex];
      }
     }

     /**
      * Reads next frame image
      */
     protected void readImage() {
      ix = readShort(); // (sub)image position & size
      iy = readShort();
      iw = readShort();
      ih = readShort();

      int packed = read();
      lctFlag = (packed & 0x80) != 0; // 1 - local color table flag
      interlace = (packed & 0x40) != 0; // 2 - interlace flag
      // 3 - sort flag
      // 4-5 - reserved
      lctSize = 2 << (packed & 7); // 6-8 - local color table size

      if (lctFlag) {
       lct = readColorTable(lctSize); // read table
       act = lct; // make local table active
      } else {
       act = gct; // make global table active
       if (bgIndex == transIndex)
        bgColor = 0;
      }
      int save = 0;
      if (transparency) {
       save = act[transIndex];
       act[transIndex] = 0; // set transparent color if specified
      }

      if (act == null) {
       status = STATUS_FORMAT_ERROR; // no color table defined
      }

      if (err()) return;

      decodeImageData(); // decode pixel data
      skip();

      if (err()) return;

      frameCount++;

      // create new image to receive frame data
      image =
       new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);

      setPixels(); // transfer pixel data to image

      frames.add(new GifFrame(image, delay)); // add image to frame list

      if (transparency) {
       act[transIndex] = save;
      }
      resetFrame();

     }

     /**
      * Reads Logical Screen Descriptor
      */
     protected void readLSD() {

      // logical screen size
      width = readShort();
      height = readShort();

      // packed fields
      int packed = read();
      gctFlag = (packed & 0x80) != 0; // 1   : global color table flag
      // 2-4 : color resolution
      // 5   : gct sort flag
      gctSize = 2 << (packed & 7); // 6-8 : gct size

      bgIndex = read(); // background color index
      pixelAspect = read(); // pixel aspect ratio
     }

     /**
      * Reads Netscape extenstion to obtain iteration count
      */
     protected void readNetscapeExt() {
      do {
       readBlock();
       if (block[0] == 1) {
        // loop count sub-block
        int b1 = ((int) block[1]) & 0xff;
        int b2 = ((int) block[2]) & 0xff;
        loopCount = (b2 << 8) | b1;
       }
      } while ((blockSize > 0) && !err());
     }

     /**
      * Reads next 16-bit value, LSB first
      */
     protected int readShort() {
      // read 16-bit value, LSB first
      return read() | (read() << 8);
     }

     /**
      * Resets frame state for reading next image.
      */
     protected void resetFrame() {
      lastDispose = dispose;
      lastRect = new Rectangle(ix, iy, iw, ih);
      lastImage = image;
      lastBgColor = bgColor;
      int dispose = 0;
      boolean transparency = false;
      int delay = 0;
      lct = null;
     }


     protected void skip() {
      do {
       readBlock();
      } while ((blockSize > 0) && !err());
     }
    }

    posted on 2007-09-21 11:15 gembin 閱讀(5404) 評論(2)  編輯  收藏

    評論

    # re: GifDecoder.java源碼(處理GIF圖片) 2007-09-22 00:13 千里冰封

    果然很牛,不錯  回復  更多評論   

    # re: GifDecoder.java源碼(處理GIF圖片)[未登錄] 2013-10-22 12:00 xxx

    @千里冰封
    傻逼  回復  更多評論   


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     

    導航

    統(tǒng)計

    常用鏈接

    留言簿(6)

    隨筆分類(440)

    隨筆檔案(378)

    文章檔案(6)

    新聞檔案(1)

    相冊

    收藏夾(9)

    Adobe

    Android

    AS3

    Blog-Links

    Build

    Design Pattern

    Eclipse

    Favorite Links

    Flickr

    Game Dev

    HBase

    Identity Management

    IT resources

    JEE

    Language

    OpenID

    OSGi

    SOA

    Version Control

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    free counters
    主站蜘蛛池模板: 亚洲人成色99999在线观看| 国产亚洲精品a在线观看| 国产精品无码免费播放| www.免费在线观看| 91黑丝国产线观看免费| 国产精品色拉拉免费看| 成人免费无码视频在线网站| 毛片网站免费在线观看| 永久黄网站色视频免费直播| 午夜小视频免费观看| 国产免费AV片无码永久免费| 成人亚洲综合天堂| 中文字幕亚洲一区二区va在线| 亚洲日韩中文无码久久| 亚洲成AV人片在线观看| 亚洲精品福利在线观看| 亚洲精品第一国产综合野| 亚洲色一区二区三区四区| 国产亚洲精品成人久久网站| 一级白嫩美女毛片免费| 免费人成在线观看视频高潮| 最近免费中文字幕大全高清大全1| 麻豆视频免费观看| 国产成人精品免费直播| 亚洲日韩涩涩成人午夜私人影院| 久久亚洲国产欧洲精品一| 中文字幕亚洲综合久久| 亚洲熟女乱色一区二区三区| 久久精品国产亚洲AV| 中文字幕手机在线免费看电影| 91精品啪在线观看国产线免费| 久久精品女人天堂AV免费观看| 全部免费毛片在线| 亚洲国产精品久久66| 亚洲最大天堂无码精品区| 九九免费观看全部免费视频| 日韩电影免费在线观看| 成人免费无码大片A毛片抽搐| 亚洲无码日韩精品第一页| 亚洲美女免费视频| 国产天堂亚洲精品|