home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 March / pcp161b.iso / handson / archive / Issue159 / files / java / lib / GIFImage.java < prev    next >
Encoding:
Java Source  |  1999-09-28  |  7.4 KB  |  238 lines

  1. /*
  2. ** The code for this class is based on code from Thomas' Boutell's
  3. ** gd GIF graphics library. The condition upon using the code is that
  4. ** the following notices appear.
  5. **
  6. ** David Griffiths 28th September, 1999.
  7. */
  8.  
  9. /*
  10. ** gd 1.2 is copyright 1994, 1995, Quest Protein Database Center, Cold Spring Harbor Labs.
  11. ** Permission granted to copy and distribute this work provided that this notice remains intact. 
  12. ** Credit for the library must be given to the Quest Protein Database Center, Cold Spring 
  13. ** Harbor Labs, in all derived works. This does not affect your ownership of the derived work 
  14. ** itself, and the intent is to assure proper credit for Quest, not to interfere with your use of gd. 
  15. ** If you have questions, ask. ("Derived works" includes all programs that utilize the library.
  16. ** Credit must be given in user-visible documentation.)
  17. ** gd 1.2 was written by Thomas Boutell and is currently distributed by boutell.com, Inc.
  18. ** If you wish to release modifications to gd, please clear them first by sending email to 
  19. ** boutell@boutell.com; if this is not done, any modified version of the gd library must be clearly
  20. ** labeled as such.
  21. ** The Quest Protein Database Center is funded under Grant P41-RR02188 by the National
  22. ** Institutes of Health.
  23. ** Written by Thomas Boutell (http://sunsite.unc.edu/boutell/index.html), 2/94 - 8/95.
  24. ** The GIF compression code is based on that found in the pbmplus utilities, which in turn is based 
  25. ** on GIFENCOD by David Rowley. See the notice below:
  26. */
  27.  
  28. /*
  29. ** Based on GIFENCOD by David Rowley .A
  30. ** Lempel-Zim compression based on "compress".
  31. **
  32. ** Modified by Marcel Wijkstra
  33. **
  34. ** Copyright (C) 1989 by Jef Poskanzer.
  35. **
  36. ** Permission to use, copy, modify, and distribute this software and its
  37. ** documentation for any purpose and without fee is hereby granted, provided
  38. ** that the above copyright notice appear in all copies and that both that
  39. ** copyright notice and this permission notice appear in supporting
  40. ** documentation.    This software is provided "as is" without express or
  41. ** implied warranty.
  42. **
  43. ** The Graphics Interchange Format(c) is the Copyright property of
  44. ** CompuServe Incorporated.    GIF(sm) is a Service Mark property of
  45. ** CompuServe Incorporated.
  46. */
  47.  
  48. /*
  49. ** The GIF decompression is based on that found in the pbmplus utilities,
  50. ** which in turn is based on GIFDECOD by David Koblas. See the notice below:
  51. */
  52.  
  53. /* +---------------------------------------------------------------------+ */
  54. /* | Copyright 1990, 1991, 1993, David Koblas.    (koblas@netcom.com)      | */
  55. /* |     Permission to use, copy, modify, and distribute this software   | */
  56. /* |     and its documentation for any purpose and without fee is hereby | */
  57. /* |     granted, provided that the above copyright notice appear in all | */
  58. /* |     copies and that both that copyright notice and this permission  | */
  59. /* |     notice appear in supporting documentation.    This software is | */
  60. /* |     provided "as is" without express or implied warranty.           | */
  61. /* +---------------------------------------------------------------------+ */
  62.  
  63. import java.lang.String;
  64. import java.net.MalformedURLException;
  65. import java.net.URL;
  66. import java.awt.*;
  67. import java.awt.event.*;
  68. import java.applet.Applet;
  69. import java.applet.AppletContext;
  70. import java.io.*;
  71. import java.net.*;
  72. import java.awt.image.*;
  73.  
  74.  
  75. public class GIFImage implements Animation {
  76.     int Width, Height;
  77.     boolean interlace = false;
  78.     boolean looping = true;
  79.     GIFGraphics graphics[] = new GIFGraphics[500];
  80.     int frameCount;
  81.     LZWCompressor compressor;
  82.  
  83.     GIFImage(int Width, int Height) {
  84.         this.Width = Width;
  85.         this.Height = Height;
  86.         frameCount = 0;
  87.     }
  88.  
  89.     // Attributes
  90.  
  91.     private int fps = 10;
  92.  
  93.     public void setFPS(int newFps) {
  94.         this.fps = newFps;
  95.     }
  96.  
  97.     public int getFPS() {
  98.         return this.fps;
  99.     }
  100.  
  101.     public int addImage(GIFGraphics gg) {
  102.         graphics[frameCount] = gg;
  103.         return frameCount++;
  104.     }
  105.  
  106.     public void serializeTo(PrintStream pout) {
  107.         encodeGIF(pout, 0, 0, 8);
  108.     }
  109.  
  110.     void encodeGIF(PrintStream pout, int Background, int Transparent, int BitsPerPixel) {
  111.         int InitCodeSize;
  112.  
  113.         if (BitsPerPixel <= 1)
  114.             InitCodeSize = 2;
  115.         else
  116.             InitCodeSize = BitsPerPixel;
  117.  
  118.         serializeHeader(pout, Transparent);
  119.  
  120.         serializeLogicalScreen(pout, Background, BitsPerPixel, InitCodeSize);
  121.  
  122.         serializeData(pout, Transparent, InitCodeSize);
  123.  
  124.         serializeTrailer(pout);
  125.     }
  126.  
  127.     private void serializeHeader(PrintStream pout, int Transparent) {
  128.         pout.print((Transparent < 0 ? "GIF87a" : "GIF89a").substring(0, 6));
  129.     }
  130.  
  131.     private void serializeLogicalScreen(PrintStream pout, int Background,
  132.             int BitsPerPixel, int InitCodeSize) {
  133.         int B, Resolution;
  134.         int ColorMapSize;
  135.  
  136.         ColorMapSize = 1 << BitsPerPixel;
  137.         Resolution = BitsPerPixel;
  138.  
  139.          putWord(pout, Width);
  140.         putWord(pout, Height);
  141.         B = 0x80;                                        // Yes, there is a global colour table
  142.         B |= (Resolution - 1) << 5;    // Colour resolution in bits 6-4
  143.         B |= (BitsPerPixel - 1);    // Log size of global colour table (= 2 ^(n+1))
  144.         pout.write (B);            // Write out packed data
  145.         pout.write (Background);    // Background colour index
  146.         pout.write (0);            // Pixel aspect ratio - 0 = no info given
  147.         serializeGlobalColourTable(pout, ColorMapSize);
  148.     }
  149.  
  150.     private void serializeGlobalColourTable(PrintStream pout, int ColorMapSize) {
  151.          for (int i = 0; i<ColorMapSize; i++) {
  152.             pout.write ((byte)GIFGraphics.Red[i]);
  153.             pout.write ((byte)GIFGraphics.Green[i]);
  154.             pout.write ((byte)GIFGraphics.Blue[i]);
  155.         }
  156.     }
  157.  
  158.     private void serializeData(PrintStream pout, int Transparent,
  159.                                 int InitCodeSize) {
  160.         LZWCompressor compressor = new LZWCompressor(pout, interlace);
  161.  
  162.         // Loop
  163.         if (looping) {
  164.             pout.write ('!');
  165.             pout.write (0xff);
  166.             pout.write (0x0b);
  167.             pout.print ("NETSCAPE2.0");
  168.             pout.write (0x03);
  169.             pout.write (0x01);
  170.             putWord(pout, 0);                                 // Loop count: 0 = infinite
  171.             pout.write (0x00);
  172.         }
  173.  
  174.         for (int j = 0; j < frameCount; j++)
  175.             serializeFrame(pout, compressor, false,
  176.                 100 / getFPS(), Transparent, InitCodeSize, j);
  177.     }
  178.  
  179.     private void serializeFrame(PrintStream pout, LZWCompressor compressor,
  180.                                                                 boolean clearFirst, int delay, int transparent,
  181.                                                                 int InitCodeSize, int frameNo) {
  182.         if (transparent >= 0) {
  183.             pout.write ('!');
  184.             pout.write (0xf9);
  185.             pout.write (4);
  186.  
  187.             if (clearFirst)
  188.                 pout.write (9);
  189.             else
  190.                 pout.write (1);
  191.  
  192.             putWord(pout, delay);
  193.  
  194.             pout.write (transparent);
  195.             pout.write (0);
  196.         }
  197.  
  198.         /*
  199.          * Image descriptor
  200.          */
  201.         pout.write(',');                                                            // Image separator
  202.         putWord(pout, graphics[frameNo].left);        // Image left position
  203.         putWord(pout, graphics[frameNo].top);         // Image top position
  204.         putWord(pout, graphics[frameNo].width);        // Image width
  205.         putWord(pout, graphics[frameNo].height);    // Image height
  206.  
  207.         // Packed fields
  208.         // -- Flags for features like interlace
  209.         if (interlace)
  210.             pout.write (0x40);
  211.         else
  212.             pout.write (0x00);
  213.  
  214.  
  215.         /*
  216.          * Table based image data
  217.          */
  218.         compressor.compress (
  219.             InitCodeSize + 1,
  220.             graphics[frameNo].width,
  221.             graphics[frameNo].height,
  222.             graphics[frameNo].getPixels()
  223.         );    // Image data
  224.  
  225.         pout.write ((byte)0);
  226.     }
  227.  
  228.     private void serializeTrailer(PrintStream pout) {
  229.          pout.write (';');
  230.         pout.flush();
  231.     }
  232.  
  233.     void putWord(PrintStream pout, int w) {
  234.         pout.write ((byte)(w & 0xff));
  235.         pout.write ((byte)((w >> 8) & 0xff));
  236.     }
  237. }
  238.