<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) 評(píng)論(2)  編輯  收藏

    評(píng)論

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

    果然很牛,不錯(cuò)  回復(fù)  更多評(píng)論   

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

    @千里冰封
    傻逼  回復(fù)  更多評(píng)論   


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


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(6)

    隨筆分類(440)

    隨筆檔案(378)

    文章檔案(6)

    新聞檔案(1)

    相冊(cè)

    收藏夾(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

    最新隨筆

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    free counters
    主站蜘蛛池模板: 亚洲人成网www| 视频一区二区三区免费观看| 狠狠综合亚洲综合亚洲色| 本道天堂成在人线av无码免费| 无码日韩精品一区二区免费暖暖 | 在线观看成人免费| a级亚洲片精品久久久久久久| 又粗又硬又黄又爽的免费视频 | 亚洲精品乱码久久久久蜜桃 | 无码国产精品久久一区免费| 亚洲视频在线观看网站| 一级毛片**免费看试看20分钟| 国产美女精品视频免费观看| 亚洲成AV人片在WWW| 亚洲А∨精品天堂在线| 丰满妇女做a级毛片免费观看| 国产高清不卡免费在线| 亚洲日韩国产精品乱-久| 日韩精品视频免费在线观看| 免费无码AV一区二区| 亚洲国产精品无码专区在线观看| 久久精品无码专区免费青青| 亚洲白嫩在线观看| 日韩在线免费电影| 最近的2019免费中文字幕| 亚洲视频在线一区二区三区| 青苹果乐园免费高清在线| 老外毛片免费视频播放| 亚洲色成人网站WWW永久| 久草免费在线观看视频| 国产亚洲精品AAAA片APP| 亚洲综合无码AV一区二区| 亚欧色视频在线观看免费| 亚洲国产精品成人综合色在线| 免费人成在线观看视频播放| 可以免费观看的毛片| 亚洲精品无AMM毛片| 亚洲人成色77777| 免费毛片在线看片免费丝瓜视频 | 亚洲色av性色在线观无码| 国产免费观看a大片的网站|