Gif file Encoder : GIF « 2D Graphics GUI « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Collections Data Structure
8. Database SQL JDBC
9. Design Pattern
10. Development Class
11. Email
12. Event
13. File Input Output
14. Game
15. Hibernate
16. J2EE
17. J2ME
18. JDK 6
19. JSP
20. JSTL
21. Language Basics
22. Network Protocol
23. PDF RTF
24. Regular Expressions
25. Security
26. Servlets
27. Spring
28. Swing Components
29. Swing JFC
30. SWT JFace Eclipse
31. Threads
32. Tiny Application
33. Velocity
34. Web Services SOA
35. XML
Microsoft Office Word 2007 Tutorial
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java » 2D Graphics GUI » GIFScreenshots 
Gif file Encoder

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;

/**
 * Class GifDecoder - Decodes a GIF file into one or more frames. <br>
 
 * <pre>
 *  Example:
 *     GifDecoder d = new GifDecoder();
 *     d.read(&quot;sample.gif&quot;);
 *     int n = d.getFrameCount();
 *     for (int i = 0; i &lt; n; i++) {
 *        BufferedImage frame = d.getFrame(i);  // frame i
 *        int t = d.getDelay(i);  // display duration of frame in milliseconds
 *        // do something with frame
 *     }
 * </pre>
 
 * No copyright asserted on the source code of this class. May be used for any
 * purpose, however, refer to the Unisys LZW patent for any additional
 * restrictions. Please forward any corrections to kweiner@fmsware.com.
 
 @author Kevin Weiner, FM Software; LZW decoder adapted from John Cristy's
 *         ImageMagick.
 @version 1.03 November 2003
 
 */

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 = ((GifFrameframes.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 = ((DataBufferIntimage.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 = ((DataBufferIntlastImage.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(0000)// 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 = ((intpixels[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 = ((GifFrameframes.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 = (BufferedInputStreamis;
      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 = << data_size;
    end_of_information = clear + 1;
    available = clear + 2;
    old_code = NullCode;
    code_size = data_size + 1;
    code_mask = (<< code_size1;
    for (code = 0; code < clear; code++) {
      prefix[code0;
      suffix[code(bytecode;
    }

    // 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 += (((intblock[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 = (<< code_size1;
          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++(bytefirst;
          code = old_code;
        }
        while (code > clear) {
          pixelStack[top++= suffix[code];
          code = prefix[code];
        }
        first = ((intsuffix[code]) 0xff;

        // Add a new string to the string table,

        if (available >= MaxStackSize)
          break;
        pixelStack[top++(bytefirst;
        prefix[available(shortold_code;
        suffix[available(bytefirst;
        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[i0// 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 = * 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 = ((intc[j++]) 0xff;
        int g = ((intc[j++]) 0xff;
        int b = ((intc[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 += (charblock[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 += (charread();
    }
    if (!id.startsWith("GIF")) {
      status = STATUS_FORMAT_ERROR;
      return;
    }

    readLSD();
    if (gctFlag && !err()) {
      gct = readColorTable(gctSize);
     &