Home Help Search Login Register


J2meForums  |  General Category  |  Programming (Moderators: mikkom, shendley)  |  Topic: Finally I got a PNG encoder for midp... « previous next »
Pages: [1] Print
Author

Finally I got a PNG encoder for midp...

 (Read 968 times)
Akscorp
New user
*
Posts: 16



View Profile
Finally I got a PNG encoder for midp...
« on: February 21, 2007, 02:04:27 pm »

I got a PNG encoder for mobiles. Thought wud share with you ppl:
Code:
/*
* Minimal PNG encoder to create MIDP images from RGBA arrays.
*
* Copyright 2006 Christian Froeschlin
*
* www.chrfr.de
*
*/

import java.io.*;
import javax.microedition.lcdui.Image;

public class PNG
{
 
  public static Image toImage(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue)
  {
    try   
    {
      byte[] png = toPNG(width, height, alpha, red, green, blue);
      return Image.createImage(png, 0, png.length);
    }
    catch (IOException e)
    {
      return null;
    }
  }
 
  public static byte[] toPNG(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue) throws IOException
  {
    byte[] signature = new byte[] {(byte) 137, (byte) 80, (byte) 78, (byte) 71, (byte) 13, (byte) 10, (byte) 26, (byte) 10};
    byte[] header = createHeaderChunk(width, height);
    byte[] data = createDataChunk(width, height, alpha, red, green, blue);
    byte[] trailer = createTrailerChunk();
   
    ByteArrayOutputStream png = new ByteArrayOutputStream(signature.length + header.length + data.length + trailer.length);
    png.write(signature);
    png.write(header);
    png.write(data);
    png.write(trailer);
    return png.toByteArray();
  }

  public static byte[] createHeaderChunk(int width, int height) throws IOException
  {
    ByteArrayOutputStream baos = new ByteArrayOutputStream(13);
    DataOutputStream chunk = new DataOutputStream(baos);
    chunk.writeInt(width);
    chunk.writeInt(height);
    chunk.writeByte(8); // Bitdepth
    chunk.writeByte(6); // Colortype ARGB
    chunk.writeByte(0); // Compression
    chunk.writeByte(0); // Filter
    chunk.writeByte(0); // Interlace   
    return toChunk("IHDR", baos.toByteArray());
  }

  public static byte[] createDataChunk(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue) throws IOException
  {
    int source = 0;
    int dest = 0;
    byte[] raw = new byte[4*(width*height) + height];
    for (int y = 0; y < height; y++)
    {
      raw[dest++] = 0; // No filter
      for (int x = 0; x < width; x++)
      {
        raw[dest++] = red[source];
        raw[dest++] = green[source];
        raw[dest++] = blue[source];
        raw[dest++] = alpha[source++];
      }
    }
    return toChunk("IDAT", toZLIB(raw));
  }

  public static byte[] createTrailerChunk() throws IOException
  {
    return toChunk("IEND", new byte[] {});
  }
 
  public static byte[] toChunk(String id, byte[] raw) throws IOException
  {
    ByteArrayOutputStream baos = new ByteArrayOutputStream(raw.length + 12);
    DataOutputStream chunk = new DataOutputStream(baos);
   
    chunk.writeInt(raw.length);
   
    byte[] bid = new byte[4];
    for (int i = 0; i < 4; i++)
    {
      bid[i] = (byte) id.charAt(i);
    }
   
    chunk.write(bid);
       
    chunk.write(raw);
   
    int crc = 0xFFFFFFFF;
    crc = updateCRC(crc, bid); 
    crc = updateCRC(crc, raw);   
    chunk.writeInt(~crc);
   
    return baos.toByteArray();
  }

  static int[] crcTable = null;
 
  public static void createCRCTable()
  {
    crcTable = new int[256];
   
    for (int i = 0; i < 256; i++)
    {
      int c = i;
      for (int k = 0; k < 8; k++)
      {
        c = ((c & 1) > 0) ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
      }
      crcTable[i] = c;
    }
  }
 
  public static int updateCRC(int crc, byte[] raw)
  {
    if (crcTable == null)
    {
      createCRCTable();
    }
   
    for (int i = 0; i < raw.length; i++)
    {
      crc = crcTable[(crc ^ raw[i]) & 0xFF] ^ (crc >>> 8);     
    }
   
    return crc;
  }
 
  // Creates a single zlib block contain a single
  // uncompressed deflate block. Must be < 64K!
  public static byte[] toZLIB(byte[] raw) throws IOException
  {   
    byte tmp;
    ByteArrayOutputStream baos = new ByteArrayOutputStream(raw.length + 5 + 6);
    DataOutputStream zlib = new DataOutputStream(baos);
    tmp = (byte) (8 + (7 << 16));
    zlib.writeByte(tmp);      // Compression + Flags
    zlib.writeByte((31 - ((tmp << 8) % 31)) % 31); // FCHECK (compr/dict 0)
   
    //Uncompressed deflate block
    zlib.writeByte((byte) 1);    //Final flag set, Compression type 0
    char length = (char) raw.length;
    zlib.writeChar(length);  //Length
    zlib.writeChar(~length); //Length 1st complement
    zlib.write(raw);         //Data
   
    // zlib block check sum
    zlib.writeInt(calcADLER32(raw));
    return baos.toByteArray();
  }

  // Unverified (the Java PNG loader did not complain at any value)
  public static int calcADLER32(byte[] raw)
  {
    int s1 = 1;
    int s2 = 0;
    for (int i = 0; i < raw.length; i++)
    {
      s1 = (s1 + raw[i]) % 65521;
      s2 = (s2 + s1) % 65521;     
    }
    return (s2 << 16) + s1;
  }
}


Only one problem it can save only png's upto 64KB.  Angry
Logged
Pages: [1] Print 
J2meForums  |  General Category  |  Programming (Moderators: mikkom, shendley)  |  Topic: Finally I got a PNG encoder for midp... « previous next »
Jump to:  


Login with username, password and session length

Powered by MySQL Powered by PHP J2meForums | Powered by SMF 1.0.8.
© 2001-2005, Lewis Media. All Rights Reserved.
Valid XHTML 1.0! Valid CSS!