tn5250j/src/org/tn5250j/tools/encoder AbstractImageEncoder.java,NONE,1.1 EncodeComponent.java,NONE,1.1 Encoder.java,NONE,1.1 EncoderException.java,NONE,1.1 PNGEncoder.java,NONE,1.1

[email protected]
Newsgroups gmane.comp.java.tn5250j.cvs
Message-ID <[email protected]>
Update of /cvsroot/tn5250j/tn5250j/src/org/tn5250j/tools/encoder
In directory sc8-pr-cvs1:/tmp/cvs-serv20030/src/org/tn5250j/tools/encoder

Added Files:
	AbstractImageEncoder.java EncodeComponent.java Encoder.java 
	EncoderException.java PNGEncoder.java 
Log Message:
Fixed Connect.java, Fixed Gui5250.java, Added SendScreenToImage-Feature.

--- NEW FILE: AbstractImageEncoder.java ---
/**
 * Title: tn5250J
 * Copyright:   Copyright (c) 2001,202,2003
 * Company:
 * @author  Kenneth J. Pouncey
 * @version 0.4
 *
 * Description:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA
 *
 */
package org.tn5250j.tools.encoder;

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.io.OutputStream;

/**
 * This is the base class for encoding a component to a stream file.
 */
public abstract class AbstractImageEncoder implements Encoder {

   protected Image img = null;
   protected OutputStream ofile = null;

   public void encode(Image image, OutputStream os) throws IOException, EncoderException {
      img = image;
      ofile = os;
      saveImage();
   }

   public void encode(Component component, OutputStream os) throws IOException, EncoderException {
      encode(snapshot(component), os);
   }

   public static Image snapshot(Component component) {
      Image img = component.createImage(component.getSize().width,
                             component.getSize().height);
      if (img != null) {
      Graphics igc = img.getGraphics();
      //Gotta set the clip, or else paint throws an exception
      igc.setClip(0, 0, component.getSize().width,
         component.getSize().height);
         component.paint(igc);
      }
      return img;
   }

   public abstract void saveImage() throws IOException, EncoderException;

   public byte createByte(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0) {
      byte bits = 0;
      if (b0 == 1) bits = (byte) (bits | 1);
      if (b1 == 1) bits = (byte) (bits | 2);
      if (b2 == 1) bits = (byte) (bits | 4);
      if (b3 == 1) bits = (byte) (bits | 8);
      if (b4 == 1) bits = (byte) (bits | 16);
      if (b5 == 1) bits = (byte) (bits | 32);
      if (b6 == 1) bits = (byte) (bits | 64);
      if (b7 == 1) bits = (byte) (bits | 128);
      return bits;
   }

   public static byte byteFromInt(int value) {
      return ((byte) (value & 255));
   }

   public static byte[] bytesFromLong(long value) {
      byte[] buf = new byte[4];
      buf[0] = ((byte) ((value >> 24) & 255));
      buf[1] = ((byte) ((value >> 16) & 255));
      buf[2] = ((byte) ((value >> 8) & 255));
      buf[3] = ((byte) ((value) & 255));
      return buf;
   }

   public static byte byteFromChar(char ochar) {
      int temp = (int) ochar;
      byte bits = 0;

      int curpos = 0;
      for (int i = 0; i <=7; i++) {
        if ((temp & ((byte) Math.pow(2, i))) != 0) {
            bits = (byte) (bits | ((byte) Math.pow(2, i)));
        }
      }
      return bits;
   }

   /**
   * Compress the given color into one 8 bit representation.
   * @param clr integer representation of rgb value (lowest byte is blue,
   *            second lowest byte is green, third lowest byte is red)
   * @return color compressed into 8-bit representation
   */
   public byte compressColor(int clr) {
      return compressColor((clr >> 16) & 255, (clr >> 8) & 255, clr & 255);
   }

   /**
   * Compress the given color into one 8 bit representation.
   * @param red value of the red portion of the color
   * @param green value of the green portion of the color
   * @param blue value of the blue portion of the color
   * @return color compressed into 8-bit representation
   */
   public byte compressColor(int red, int green, int blue) {
      // take 3 most significatnt bits of red, 3 most significant bits of
      // green and 2 most significant bits of blue to form 8-bit compression
      // of color values

      return (byte) ((red & 224) | ((green >> 3) & 28) | ((blue >> 6) & 3));
   }

   protected void error(String msg) throws EncoderException {
      throw new EncoderException(msg);
   }

}


--- NEW FILE: EncodeComponent.java ---
/**
 * Title: tn5250J
 * Copyright:   Copyright (c) 2001,202,2003
 * Company:
 * @author  Kenneth J. Pouncey
 * @version 0.4
 *
 * Description:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA
 *
 */
package org.tn5250j.tools.encoder;

import java.awt.Component;
import java.io.OutputStream;
import java.io.IOException;
import java.io.File;

/**
 * Used to encode components into different image file formats. ie .GIF and .PNG
 */
public class EncodeComponent {

   /** specifies PNG encoding */
   public static final Encoding PNG = new Encoding("PNG",
      "Portable Network Graphics",
      "org.tn5250j.tools.encoder.PNGEncoder",
      " PNG Load Error");

   public static final Encoding ENCODINGS[] = {
      PNG
   };

   /**
    * Invoke this methods on Java components to encode their image into the
    * specified format
    * @param component component to encode
    * @param encoding type of encoding to use (Currently GIF or PNG)
    * @param output stream to which to write the encoding
    */
   public static void encode(Encoding encoding, Component component, OutputStream output) throws IOException, EncoderException {
      Encoder encoder = encoding.getEncoder();
      if (encoder == null) {
   	   throw new EncoderException("Graphics Encoder could not be loaded.");
      }
      encoder.encode(component, output);
   }

   /**
    * Invoke this methods on Java components to encode their image into the
    * specified format
    * @param component component to encode
    * @param encoding type of encoding to use (GIF, PNG, JPEG, EPS, PS, PDF,
    * or PCL)
    * @param file file to which to write the encoding
    */
   public static void encode(Encoding encoding, Component component, File file) throws IOException, EncoderException {
      OutputStream os = new java.io.FileOutputStream(file);
      encode(encoding, component, os);
      os.close();
   }

      /**
      * Class used to enumerate valid encodings
      */
      public static class Encoding {
         private String shortName;
         private String longName;
         private String encoderClass;
         private String failureMessage;

         private Encoder encoder;

          /**
           * Constructs and new image encoder.
           */
         public Encoding(String short_name, String long_name,
                     String encoder_class, String failure_message) {
            this.shortName = short_name;
            this.longName = long_name;
            this.encoderClass = encoder_class;
            this.failureMessage = failure_message;
         }

         /**
          * Return the short brief name of the supported encoding type
          */
         public String getShortName() {
            return shortName;
         }

         /**
          * Return the long name of the supported encoding type
          */
         public String getLongName() {
            return longName;
         }

          /**
           * Returns a string representation bassed on the long and short name of the
           * Encoder.
           */
         public String toString() {
            return getLongName() + " (" + getShortName() + ")";
         }

         /**
          * Message to return about possible reasons for encoder load
          * failure (i.e. getEncoder() returns null)
          */
         public String getFailureMessage() {
            String locale_message = "There was a failure loading encoder." ;
            if (locale_message == null) {
               locale_message = failureMessage;
            }
            return locale_message;
         }

         /**
          * Return an encoder for this encoding type.
          * @return returns null if it cannot locate or load the encoder
          */
         public Encoder getEncoder() {
            if (encoder == null) {
               // encoder null so attempt to load it
               Class encoder_class = null;
               try {
                  encoder_class = Class.forName(encoderClass);
               }
               catch (ClassNotFoundException cnfe) {
               }

               if (encoder_class != null) {
                  try {
                     encoder = (Encoder) encoder_class.newInstance();
                  }
                  catch (InstantiationException ie) {
                  }
                  catch (IllegalAccessException iae) {
                  }
               }
            }
            return encoder;
         }

      } // End of Encoding inner class

}

--- NEW FILE: Encoder.java ---
/**
 * Title: tn5250J
 * Copyright:   Copyright (c) 2001,202,2003
 * Company:
 * @author  Kenneth J. Pouncey
 * @version 0.4
 *
 * Description:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA
 *
 */
package org.tn5250j.tools.encoder;

import java.awt.Component;
import java.io.OutputStream;
import java.io.IOException;

/**
 * Interface that defines an encoder
 */
public interface Encoder {
   /**
    * Encode the specified component on the specified stream
    */
   public void encode(Component component, OutputStream stream) throws IOException, EncoderException;

}


--- NEW FILE: EncoderException.java ---
/**
 * Title: tn5250J
 * Copyright:   Copyright (c) 2001,202,2003
 * Company:
 * @author  Kenneth J. Pouncey
 * @version 0.4
 *
 * Description:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA
 *
 */
package org.tn5250j.tools.encoder;

/**
 * This class is an exception that is raised by Encode or one of it's
 * subclasses.  It may also be subclassed for exceptions thrown by subclasses
 * of Encode. It represents any problem encountered while encoding an image.
 * The message is used to state the type of error.
*/
public class EncoderException extends Exception {
   /**
    * Creates an exception with the given message.
    */
   public EncoderException(String msg) {
       super(msg);
   }

}

--- NEW FILE: PNGEncoder.java ---
/**
 * Title: tn5250J
 * Copyright:   Copyright (c) 2001,202,2003
 * Company:
 * @author  Kenneth J. Pouncey
 * @version 0.4
 *
 * Description:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA
 *
 */
package org.tn5250j.tools.encoder;

import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import java.io.IOException;
import java.util.zip.Deflater;

/**
 * This class encodes a Png file from an Image to an OutputStream.  No color
 * depths except 8 and 16 bpp are supported.  No additional Png blocks except
 * those absolutely necessary for Png encoding are included.
 */
public class PNGEncoder extends AbstractImageEncoder {

public PNGEncoder() {
}

   public void saveImage() throws IOException, EncoderException {
      if (img == null)
      error("PNG encoding error: Image is NULL.");

      PixelGrabber pg = new PixelGrabber(img, 0,0,img.getWidth(null), img.getHeight(null), false);
      try {
         pg.grabPixels();
      }
      catch (InterruptedException e) {
        error("PNG encoding error: Unable to retrieve pixels from image.");
      }

      ColorModel cmodel = pg.getColorModel();
      int pixels = cmodel.getPixelSize();
      int numcolors = (int) Math.pow(2,pixels);
      if ((pixels != 8) && (pixels != 16) && (pixels != 24) && (pixels !=32)) {
         error("PNG encoding error: PNG method must have 8 or 16 bit colors.");
      }

      int[] pixelarray = null;
      byte[] pixelarray8 = null;
      if (pixels >= 16) {
         pixelarray = (int[]) pg.getPixels();
      }
      else {
         pixelarray8 = (byte[]) pg.getPixels();
      }

      ofile.write(byteFromInt(137));
      ofile.write(byteFromInt(80));
      ofile.write(byteFromInt(78));
      ofile.write(byteFromInt(71));
      ofile.write(byteFromInt(13));
      ofile.write(byteFromInt(10));
      ofile.write(byteFromInt(26));
      ofile.write(byteFromInt(10));

      // IHDR

      long crc = start_crc();

      // length

      ofile.write(bytesFromLong(13));
      ofile.write(byteFromChar('I'));
      ofile.write(byteFromChar('H'));
      ofile.write(byteFromChar('D'));
      ofile.write(byteFromChar('R'));

      crc = update_crc(crc, byteFromChar('I'));
      crc = update_crc(crc, byteFromChar('H'));
      crc = update_crc(crc, byteFromChar('D'));
      crc = update_crc(crc, byteFromChar('R'));

      int width = img.getWidth(null);
      int height = img.getHeight(null);
      crc = update_crc(crc, bytesFromLong(width));
      crc = update_crc(crc, bytesFromLong(height));
      crc = update_crc(crc, byteFromInt(8));

      if (pixels >= 16)
         crc = update_crc(crc, byteFromInt(2));
      else
         crc = update_crc(crc, byteFromInt(3));

      crc = update_crc(crc, byteFromInt(0));
      crc = update_crc(crc, byteFromInt(0));
      crc = update_crc(crc, byteFromInt(0));

      ofile.write(bytesFromLong(width));
      ofile.write(bytesFromLong(height));
      ofile.write(byteFromInt(8));

      if (pixels >= 16) {
         ofile.write(byteFromInt(2)); // Color type
      }
      else {
         ofile.write(byteFromInt(3)); // Color type
      }

      ofile.write(byteFromInt(0)); // Compression type
      ofile.write(byteFromInt(0)); // Filter method
      ofile.write(byteFromInt(0)); // Interlace method
      ofile.write(bytesFromLong(end_crc(crc)));

      // PLTE

      if (pixels == 8) {
         crc = start_crc();

         ofile.write(bytesFromLong(numcolors * 3));
         ofile.write(byteFromChar('P'));
         ofile.write(byteFromChar('L'));
         ofile.write(byteFromChar('T'));
         ofile.write(byteFromChar('E'));

         crc = update_crc(crc, byteFromChar('P'));
         crc = update_crc(crc, byteFromChar('L'));
         crc = update_crc(crc, byteFromChar('T'));
         crc = update_crc(crc, byteFromChar('E'));

         for(int i = 0; i < numcolors; i++) {
            byte red = byteFromInt(cmodel.getRed(i));
            byte green = byteFromInt(cmodel.getGreen(i));
            byte blue = byteFromInt(cmodel.getBlue(i));
            crc = update_crc(crc, red);
            crc = update_crc(crc, green);
            crc = update_crc(crc, blue);

            ofile.write(red);
            ofile.write(green);
            ofile.write(blue);
         }
         ofile.write(bytesFromLong(end_crc(crc)));
      }

      // IDAT
      byte[] outarray = null;
      if (pixels == 8)
        outarray = new byte[(pixelarray8.length) + height];
      else
        outarray = new byte[(pixelarray.length * 3) + height];

      for (int i = 0; i < outarray.length; i++) {
        outarray[i] = 0;
      }

      int size = 0;
      if (pixels >= 16)
        size = compress(outarray, pixelarray, cmodel, width, height);
      else
        size = compress(outarray, pixelarray8, width, height);

      crc = start_crc();

      ofile.write(bytesFromLong(size));
      ofile.write(byteFromChar('I'));
      ofile.write(byteFromChar('D'));
      ofile.write(byteFromChar('A'));
      ofile.write(byteFromChar('T'));

      crc = update_crc(crc, byteFromChar('I'));
      crc = update_crc(crc, byteFromChar('D'));
      crc = update_crc(crc, byteFromChar('A'));
      crc = update_crc(crc, byteFromChar('T'));

      ofile.write(outarray, 0, size);

      for (int i = 0; i < (size); i++) {
        crc = update_crc(crc, outarray[i]);
      }

      ofile.write(bytesFromLong(end_crc(crc)));

      // IEND
      crc = start_crc();

      ofile.write(bytesFromLong(0));
      ofile.write(byteFromChar('I'));
      ofile.write(byteFromChar('E'));
      ofile.write(byteFromChar('N'));
      ofile.write(byteFromChar('D'));

      crc = update_crc(crc, byteFromChar('I'));
      crc = update_crc(crc, byteFromChar('E'));
      crc = update_crc(crc, byteFromChar('N'));
      crc = update_crc(crc, byteFromChar('D'));

      ofile.write(bytesFromLong(end_crc(crc)));

   }

   public int compress(byte[] outarray, int[] pixelarray, ColorModel cmodel, int width, int height) throws EncoderException {

       Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION);

       byte[] inarray = new byte[(pixelarray.length * 3) + height];
       for (int i = 0; i < height; i++) {
           inarray[i * ((width * 3) + 1)] = byteFromInt(0);
           for (int j = 0; j < (width * 3); j+= 3) {
               inarray[(i * ((width * 3) + 1)) + j + 1] = (byte) cmodel.getRed(pixelarray[(i * width) + (int)Math.floor(j / 3)]);
               inarray[(i * ((width * 3) + 1)) + j + 2] = (byte) cmodel.getGreen(pixelarray[(i * width) + (int)Math.floor(j / 3)]);
               inarray[(i * ((width * 3) + 1)) + j + 3] = (byte) cmodel.getBlue(pixelarray[(i * width) + (int)Math.floor(j / 3)]);
           }
       }

       deflater.setInput(inarray, 0,inarray.length);
       deflater.finish();
       deflater.deflate(outarray);

       if (!deflater.finished()) {
           error("PNG encoding error: Deflater could not compress image data.");
       }
       byte[] temp = bytesFromLong(deflater.getAdler());

       return (deflater.getTotalOut());

   }

   public int compress(byte[] outarray, byte[] pixelarray, int width, int height) throws EncoderException {
       Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION);

       byte[] inarray = new byte[pixelarray.length + height];
       for (int i = 0; i < height; i++) {
           inarray[i * (width + 1)] = byteFromInt(0);
           for (int j = 0; j < width; j++) {
               inarray[(i * (width + 1)) + j + 1] = pixelarray[(i * width) + j];
           }
       }

       deflater.setInput(inarray, 0,inarray.length);
       deflater.finish();
       deflater.deflate(outarray);

       if (!deflater.finished()) {
           error("PNG encoding error: Deflater could not compress image data.");
       }

       return (deflater.getTotalOut());

   }

   long crc_table[] = null;

   void make_crc_table() {
      crc_table = new long[256];
      long c;
      int n;
      int k;
      for (n = 0; n < 256; n++) {
         c = n;
         for (k = 0; k < 8; k++) {
            if ((c & 1) != 0)
                c = 0xedb88320L ^ (c >> 1);
            else
                c = c >> 1;

         }
         crc_table[n] = c;

      }
   }

   long start_crc() {
      return 0xffffffffL;
   }
   long end_crc(long crc) {
      return crc ^ 0xffffffffL;
   }

   long update_crc(long crc, byte[] buf) {

      long c = crc;
      for (int i = 0; i < buf.length; i++) {
         c = update_crc(c,buf[i]);
      }

      return c;
   }

   long update_crc(long crc, byte buf) {
      if (crc_table == null)
         make_crc_table();
      return crc_table[(int) ((crc ^ buf) & 0xff)] ^ (crc >> 8);
   }

}





-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive?  Does it
help you create better code?  SHARE THE LOVE, and help us help
YOU!  Click Here: http://sourceforge.net/donate/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.