<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

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


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


    網站導航:
     

    導航

    統計

    常用鏈接

    留言簿(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
    主站蜘蛛池模板: 思思re热免费精品视频66| 免费看美女被靠到爽| 亚洲日本久久久午夜精品| 日韩免费视频播放| 国产真人无码作爱视频免费| 中文字幕亚洲综合久久| 国内自产少妇自拍区免费| 91在线免费视频| 亚洲人成网站免费播放| 亚洲午夜福利在线观看| 成全视频免费高清| 日韩精品无码免费专区网站| 亚洲精品人成网线在线播放va| 亚洲色婷婷综合久久| 永久免费视频v片www| 污污网站免费观看| 丁香六月婷婷精品免费观看| 亚洲欧洲日产韩国在线| 亚洲自偷自偷偷色无码中文| 免费鲁丝片一级观看| 日本免费一区二区三区| 一个人免费观看www视频| 亚洲久悠悠色悠在线播放| 久久夜色精品国产亚洲AV动态图| 国产精品色午夜免费视频| 蜜臀98精品国产免费观看| www免费黄色网| 国产精品亚洲专区在线播放| 亚洲bt加勒比一区二区| 亚洲精品综合久久| 精品剧情v国产在免费线观看 | 18禁亚洲深夜福利人口| 久久久久亚洲av无码专区| 国产精品亚洲不卡一区二区三区| 成年女人免费碰碰视频| 18禁美女裸体免费网站| 日本高清免费观看| 在线观看人成视频免费无遮挡| 曰批全过程免费视频免费看| 亚洲日韩AV一区二区三区中文| 亚洲精品熟女国产|