home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / desvs7nu / src / ximagesource.java < prev    next >
Encoding:
Java Source  |  1996-08-14  |  8.7 KB  |  308 lines

  1. /*
  2.  * Copyright (c) 1996 by Jan Andersson, Torpa Konsult AB.
  3.  *
  4.  * Permission to use, copy, and distribute this software for
  5.  * NON-COMMERCIAL purposes and without fee is hereby granted
  6.  * provided that this copyright notice appears in all copies.
  7.  *
  8.  */
  9.  
  10. import java.awt.Color;
  11. import java.awt.image.ImageConsumer;
  12. import java.awt.image.ImageProducer;
  13. import java.awt.image.ColorModel;
  14. import java.awt.image.IndexColorModel;
  15. import java.util.Hashtable;
  16. import java.io.InputStream;
  17. import java.io.StringBufferInputStream;
  18.  
  19. /**
  20.  * This class is an implementation of the ImageProducer interface that
  21.  * uses a X11 bitmap (xbm) array, X11 pixmap (xpm) array or an input
  22.  * stream to a xbm/xpm file to produce pixel values for an Image.
  23.  *
  24.  * Here is a few examples: which creates an image from a xbm-file: "foo.xbm".
  25.  * The forground is set to blue and the Component background is used.
  26.  * <pre>
  27.  *     // create image from inline xbm data using transparent color. 
  28.  *     // I.e no background specied.
  29.  *     static private int[] arrow = {
  30.  *        0x3f, 0x0f, 0x0f, 0x1f, 0x39, 0x71, 0xe0, 0xc0
  31.  *     };
  32.  *     Image image = createImage(
  33.  *          new XImageSource(8, 8, arrow, Color.black, nil, true));
  34.  *
  35.  *     // create image from xpm-file "foo.xpm"
  36.  *     FileInputStream is = new FileInputStream("foo.xpm");
  37.  *     Image image = createImage(new XImageSource(is));
  38.  * 
  39.  * </pre>
  40.  *
  41.  * @see ImageProducer
  42.  *
  43.  * @version    1.1 96/02/20
  44.  * @author     Jan Andersson, Torpa Konsult AB. (janne@torpa.se)
  45.  */
  46. public class XImageSource implements ImageProducer {
  47.    int width;
  48.    int height;
  49.    byte pixels[];
  50.    
  51.    ColorModel colorModel;
  52.    private boolean error = false;
  53.    private ImageConsumer theConsumer;
  54.    
  55.    /**
  56.     * Constructs an ImageProducer object from an X11 style bitmap (xbm)
  57.     * to produce data for an Image object.
  58.     * @param w width
  59.     * @param h height
  60.     * @param bits bitmap in xbm format
  61.     * @param fg foreground color
  62.     * @param bg background color (if trans is false)
  63.     * @param trans transparent if true
  64.     */
  65.    public XImageSource(int w, int h, int[] bits,
  66.              Color fg, Color bg, boolean trans) {
  67.       xbmInitialize(w, h, bits, fg, bg, trans);
  68.    }
  69.  
  70.    /**
  71.     * Constructs an ImageProducer object from an X11 style bitmap (xbm)
  72.     * input stream to produce data for an Image object.
  73.     * @param is input stream to xbm data
  74.     * @param fg foreground color
  75.     * @param bg background color (if trans is false)
  76.     * @param trans transparent if true
  77.     */
  78.    public XImageSource(InputStream is,
  79.                Color fg, Color bg, boolean trans) {
  80.       // Use XbmParser to parse input stream
  81.       XbmParser parser = new XbmParser(is);
  82.       if (parser.parse()) 
  83.      xbmInitialize(parser.getWidth(), parser.getHeight(),
  84.             parser.getBitmap(), fg, bg, trans);
  85.       else
  86.      error = true;
  87.    }
  88.  
  89.    /**
  90.     * Constructs an ImageProducer object from an X11 style pixmap (xpm)
  91.     * consisting of an array of strings.
  92.     * @param data string array in xpm format.
  93.     */
  94.    public XImageSource(String[] data) {
  95.  
  96.       // create string buffer from data array
  97.       StringBuffer strBuf = new StringBuffer(1024);
  98.       for (int i=0; i<data.length; i++) 
  99.      strBuf.append("\"" + data[i] + "\"\n");
  100.       
  101.       // create an input stream from the string buffer
  102.       StringBufferInputStream is =
  103.      new StringBufferInputStream(strBuf.toString());
  104.  
  105.       // Use XpmParser to parse input stream
  106.       XpmParser parser = new XpmParser(is);
  107.       if (parser.parse()) 
  108.      xpmInitialize(parser.getWidth(), parser.getHeight(),
  109.                parser.getPixmap(), parser.getColorTable());
  110.       else
  111.      error = true;
  112.    }
  113.    /**
  114.     * Constructs an ImageProducer object from an X11 style pixmap (xpm)
  115.     * input stream to produce data for an Image object.
  116.     * @param is input stream to xpm data
  117.     */
  118.    public XImageSource(InputStream is) {
  119.       // Use XpmParser to parse input stream
  120.       XpmParser parser = new XpmParser(is);
  121.       if (parser.parse()) 
  122.      xpmInitialize(parser.getWidth(), parser.getHeight(),
  123.                parser.getPixmap(), parser.getColorTable());
  124.       else
  125.      error = true;
  126.    }
  127.    
  128.    /**
  129.     * Initialize pixels from the xbm bitmap, using the provided colors
  130.     * as foreground/background
  131.     */
  132.    private void xbmInitialize(int w, int h, int[] bits,
  133.                   Color fg, Color bg,
  134.                   boolean trans) {
  135.       width = w;
  136.       height = h;
  137.  
  138.       // create color map
  139.       byte colormap[] = new byte[6];
  140.       int transIndex = -1;
  141.       // color component 0 is for background
  142.       if (trans) {
  143.      // color component 0: transparent
  144.      transIndex = 0;
  145.      colormap[0] = 0;
  146.      colormap[1] = 0;
  147.      colormap[2] = 0;
  148.       }
  149.       else {
  150.      // color component 0: background
  151.      colormap[0] = (byte) bg.getRed();
  152.      colormap[1] = (byte) bg.getGreen();
  153.      colormap[2] = (byte) bg.getBlue();
  154.       }
  155.       // color component 1: foreground
  156.       colormap[3] = (byte) fg.getRed();
  157.       colormap[4] = (byte) fg.getGreen();
  158.       colormap[5] = (byte) fg.getBlue();
  159.  
  160.       // create color model
  161.       colorModel = new IndexColorModel(8, 2, colormap, 0, false, transIndex);
  162.        
  163.       // allocate pixels
  164.       pixels = new byte[width*height];
  165.       
  166.       // loop for xbm bitmap and create pixels
  167.       int index = 0;
  168.       int byteIndex = 0;
  169.       int jMax = width/8;
  170.       try {
  171.      for (int i=0; i<height; i++) {
  172.         for (int j=0; j<jMax; j++) {
  173.            byte bitByte = (byte) bits[byteIndex];
  174.            for (int k=0; k<8; k++) {
  175.           int pixel = bitByte & (1 << k);
  176.           pixels[index] = (pixel != 0) ? (byte) 1 : (byte) 0;
  177.           index++;
  178.            }
  179.            byteIndex++;
  180.         }
  181.      }
  182.       }
  183.       catch (Exception e) {
  184.      error = true;        // error
  185.       }
  186.    }
  187.  
  188.    /**
  189.     * Initialize pixels from the xpm pixmap.
  190.     */
  191.    private void xpmInitialize(int w, int h, byte[] pixels,
  192.                   Color[] colorTable) {
  193.       width = w;
  194.       height = h;
  195.       this.pixels = pixels;
  196.  
  197.       // create color map
  198.       int nColors = colorTable.length;
  199.       int cmSize = 3 * nColors;
  200.       byte colormap[] = new byte[cmSize];
  201.  
  202.       // init color map
  203.       int transIndex = -1;
  204.       for (int i=0; i<nColors; i++) {
  205.      if (colorTable[i] == null) {
  206.         // transparent color
  207.         transIndex = i;
  208.      }
  209.      else {
  210.         colormap[3*i] = (byte) colorTable[i].getRed();
  211.         colormap[3*i+1] = (byte) colorTable[i].getGreen();
  212.         colormap[3*i+2] = (byte) colorTable[i].getBlue();
  213.      }
  214.       }
  215.       
  216.       // create color model
  217.       colorModel = new IndexColorModel(8, nColors, colormap,
  218.                        0, false, transIndex);
  219.    }
  220.  
  221.    /**
  222.     * Adds an ImageConsumer to the list of consumers interested in
  223.     * data for this image.
  224.     * @see ImageConsumer
  225.     */
  226.    public synchronized void addConsumer(ImageConsumer ic) {
  227.       theConsumer = ic;
  228.       produce();
  229.       theConsumer = null;
  230.    }
  231.    
  232.    /**
  233.     * Determine if an ImageConsumer is on the list of consumers currently
  234.     * interested in data for this image.
  235.     * @return true if the ImageConsumer is on the list; false otherwise
  236.     * @see ImageConsumer
  237.     */
  238.    public synchronized boolean isConsumer(ImageConsumer ic) {
  239.       return (ic == theConsumer);
  240.    }
  241.  
  242.    /**
  243.     * Remove an ImageConsumer from the list of consumers interested in
  244.     * data for this image.
  245.     * @see ImageConsumer
  246.     */
  247.    public synchronized void removeConsumer(ImageConsumer ic) {
  248.       if (theConsumer == ic) {
  249.      theConsumer = null;
  250.       }
  251.    }
  252.    
  253.    /**
  254.     * Adds an ImageConsumer to the list of consumers interested in
  255.     * data for this image, and immediately start delivery of the
  256.     * image data through the ImageConsumer interface.
  257.     * @see ImageConsumer
  258.     */
  259.    public void startProduction(ImageConsumer ic) {
  260.       addConsumer(ic);
  261.    }
  262.  
  263.    /**
  264.     * Requests that a given ImageConsumer have the image data delivered
  265.     * one more time in top-down, left-right order.
  266.     * @see ImageConsumer
  267.     */
  268.    public void requestTopDownLeftRightResend(ImageConsumer ic) {
  269.       // Not needed.  The data is always in TDLR format.
  270.    }
  271.  
  272.    /*
  273.     * Produce Image data.
  274.     * I.e set the data for the Image, using the ImageConsumer interface.
  275.     */
  276.    private void produce() {
  277.       if (theConsumer != null) {
  278.      theConsumer.setDimensions(width, height);
  279.       }
  280.       if (theConsumer != null) {
  281.      theConsumer.setProperties(new Hashtable());
  282.       }
  283.       if (theConsumer != null) {
  284.      theConsumer.setColorModel(colorModel);
  285.       }
  286.       if (theConsumer != null) {
  287.      theConsumer.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
  288.                   ImageConsumer.COMPLETESCANLINES |
  289.                   ImageConsumer.SINGLEPASS |
  290.                   ImageConsumer.SINGLEFRAME);
  291.       }
  292.       if (theConsumer != null) {
  293.      theConsumer.setPixels(0, 0, width, height,
  294.                    colorModel,
  295.                    pixels, 0, width);
  296.       }
  297.       if (theConsumer != null) {
  298.      if (!error) {
  299.         theConsumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
  300.      }
  301.      else {
  302.         theConsumer.imageComplete(ImageConsumer.IMAGEERROR);
  303.      }
  304.       }
  305.    }
  306. }
  307.  
  308.