Home Help Search Login Register


J2meForums  |  General Category  |  Game programming (Moderators: mikkom, shendley)  |  Topic: Give me all your tricks for minimizing jar file size « previous next »
Pages: 1 ... 3 4 [5] 6 7 ... 12 Print
Author

Give me all your tricks for minimizing jar file size

 (Read 67442 times)
Atem
Member
**
Posts: 61



View Profile
Re:Give me all your tricks for minimizing jar file size
« Reply #60 on: June 16, 2005, 09:55:25 pm »

i am creating memory images with uncompressed idat. I've tested it on nokia6630 and se630.
it is working.
i would recommend using them. it opens up creating procedural images of any type. like rotating images, zooming images, perspective images, warping images etc. as far as your phones memory handles them.


i go for it :-)
Logged
Glen
Guest


Email
Re:Give me all your tricks for minimizing jar file size
« Reply #61 on: June 17, 2005, 02:04:08 am »

I've been messing with this for a few days, and I've come to the conclusion, you DONT need to compress the IDAT chunk at all. This will obviously speed up the loading of images, as the IDAT chunk can be created using raw uncompressed data. The code will then not have to go through the wasted compress / decompress cycle.

If works on all the phones I've tried, but I need to test on other phones to make sure they work ok.

If someone wants the png to try I can mail it to them. I'm not sure how to add attachments here.

glen at acepocket dot com

I'll stick a little demo together and put up a link to the jad / jar when I get a chance.

Glen.
Logged
Claymore
Global Moderator
J2me god
*****
Posts: 4935


Quantity != Quality


View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #62 on: June 17, 2005, 02:09:27 am »

That's certainly very interesting to know!

Should hopefully bring about some interesting techniques for handling images.
Logged

pascal
Global Moderator
J2me god
*****
Posts: 3000



View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #63 on: June 17, 2005, 10:51:01 am »

have you also tried it with multiple images?  cause I'm kinda curious how the compression is within the jar.. it might actually be better then using many different png's   (if you combine the raw png's in a single binary file that is)

interesting Smiley
Logged

----------------------------------------------------
www.rumblex.com - Gaming Community
www.orangepixel.net - Game Development
Glen
Guest


Email
Re:Give me all your tricks for minimizing jar file size
« Reply #64 on: June 17, 2005, 02:44:01 pm »

Hi,

The uncompressed png's when stuck into a jar file come out quite a bit smaller than the same standard png's in the jar file.

I'm currently writing a class file which will dynamically create an image from raw data. I intend to let the community have it to play with. I should have it finished today. I'll post a link when I'm happy with it.

I'm still battling with learning j2me and OO programming in general. I tend to be an unruly C / ASM programmer and j2me and OOP is quite a lesson in writing tidy code. You wouldn't think I'd been coding games for 25 years  Wink

Glen.
Logged
pascal
Global Moderator
J2me god
*****
Posts: 3000



View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #65 on: June 17, 2005, 03:44:05 pm »

make sure too look at the bincompiler (http://www.mobilegd.com/article393.html&mode=flat) as it might be useufull to use with your raw-image code..
Logged

----------------------------------------------------
www.rumblex.com - Gaming Community
www.orangepixel.net - Game Development
Atem
Member
**
Posts: 61



View Profile
Re:Give me all your tricks for minimizing jar file size
« Reply #66 on: June 17, 2005, 04:35:33 pm »

multiple images:

you don't need to put images with the same color palette into a large image. as this is not working on all devices, because the size of the largest possible images is different.

with memory created images, you can save the palette once and create multiple images with the same palette by just saving the idat of the png.

an other interesting options opens up: you can save images as big as you want. without worying about device types. if the image in the binary is too large for the device, the loader can split up the idat and create several images out of it. you can change your sprite-class to accomplish drawing several images instead of one
Logged
Glen
Full Member
***
Posts: 106


I'm not a llama!


View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #67 on: June 17, 2005, 10:05:16 pm »

Hi,

Ok, its complete and appear to work.

Please feel free to comment or improve the code.

// Dynamic PNG Creator
// Author : Glen Cook
// Version : 1.0 Beta
// Date : 17th June 2005
// Company : AcePocket
// Email : glen (at) acepocket (dot) com

// Usage
// width = width of image
// height = height of image
// palette = number of colours in raw palette data
// idata = byte array of 1 byte per pixel indexed image data
// pal = byte array of RGB triplets
// trans = palette index for transparency colour, -1 for no transparency
// flips = 0-Normal 1:X-Flip 2:Y-Flip 3:XY-Flip
// palOffset = offset to start of palette within byte array
// imgOffset = offset to start of image within byte array

import javax.microedition.lcdui.*;

class Png
{
   int[]   crc_table;
   int      dataptr;
   int      crcfrom;
   int      pngsize;
   byte[]   data;
   byte[]   PNG_header={
      -119,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,
      0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x08,0x03,0x00,0x00,0x00};
     
   byte[] PNG_End={0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,-82, 0x42,0x60,-126};

   Image create(int width, int height, int palette, byte[] idata, byte[] pal, int trans, int flips, int palOffset, int imgOffset)
   {
      int i;
     
      pngsize = palette*3 + (width+1)*height + 80;
     
      if(trans>-1) pngsize += 13 + trans;
     
      data = new byte[pngsize];
     
      make_crc_table ();
     
      // Create PNG Header      
      for(i=0;i<PNG_header.length;i++)
         data[i] = PNG_header[i];
     
      data[19] = (byte)width;
      data[23] = (byte)height;
   
      dataptr=29;
     
      writeInt(calc_crc(data, 12, 17));
   
      writeInt(palette*3);
     
      crcfrom=dataptr;
     
      writeHeader("PLTE");
     
      for(i=0;i<palette*3;i++)
         data[dataptr++]=pal[i+palOffset];
     
      writeInt(calc_crc(data, crcfrom, dataptr - crcfrom));
     
      if(trans>-1)
      {
         // Write tRNS Length
         writeInt(trans+1);
         
         // Mark start of CRC check
         crcfrom=dataptr;      
         
         // Write tRNS Chunk text
         writeHeader("tRNS");
         
         // Create Transparency data
         for(i=0;i<trans;i++)
            data[dataptr++]=(byte)0xff;
         
         // Mark the transparent palette
         data[dataptr++]=0;
         
         // Calc CRC on tRNS Block
         writeInt(calc_crc(data, crcfrom, dataptr - crcfrom));
      }
     
      int compsize = (width+1) * height;
     
      // Write IDAT Length
      writeInt(compsize+11);
     
      crcfrom=dataptr;      
     
      // Write IDAT Chunk text
      writeHeader("IDAT");
     
      data[dataptr++]=(byte)0x78;      // PNG compression flags
      data[dataptr++]=(byte)0xda;      // PNG compression flags
      data[dataptr++]=(byte)0x01;      // PNG final block / No compression

      // Write data length (little endian)
      data[dataptr++]=(byte)(compsize & 0xff);      
      data[dataptr++]=(byte)((compsize>>>8) & 0xff);
     
      // Write inverse length
      data[dataptr]=(byte)(~data[dataptr-2]);
      dataptr++;
      data[dataptr]=(byte)(~data[dataptr-2]);  
      dataptr++;
     
      int adlerstart = dataptr;
     
      switch(flips)
      {
         case 0:

            i=imgOffset;            
            for(int y=0;y<height;y++)
            {
               data[dataptr++]=0;      // No Filter flag for each line

               for(int x=0;x<width;x++)
                  data[dataptr++]=idata[i++];
            }
            break;
           
         case 1:            
           
            for(int y=0;y<height;y++)
            {
               i=(y+1)*width-1+imgOffset;
               data[dataptr++]=0;      // No Filter flag for each line
               for(int x=0;x<width;x++)
                  data[dataptr++]=idata[i--];
            }
            break;
           
         case 2:            
           
            for(int y=0;y<height;y++)
            {
               i=(height-y-1)*width+imgOffset;
               data[dataptr++]=0;      // No Filter flag for each line
               for(int x=0;x<width;x++)
                  data[dataptr++]=idata[i++];
            }
            break;  
           
         case 3:            
           
            for(int y=0;y<height;y++)
            {
               i=(height-y)*width-1+imgOffset;
               data[dataptr++]=0;      // No Filter flag for each line
               for(int x=0;x<width;x++)
                  data[dataptr++]=idata[i--];
            }
            break;      
      }
     
      int adler1=1;
      int adler2=0;

      for(i=0;i<compsize;i++)
      {
         adler1=adler1+((int)data[adlerstart+i]&0xff);
         adler2=adler1+adler2;
         adler1%=65521;
         adler2%=65521;
      }
     
      data[dataptr++]=(byte)((adler2>>8)&0xff);
      data[dataptr++]=(byte)(adler2&0xff);
      data[dataptr++]=(byte)((adler1>>8)&0xff);
      data[dataptr++]=(byte)(adler1&0xff);  
     
      writeInt(calc_crc(data, crcfrom, dataptr - crcfrom));
     
      // Finish off the PNG with the IEND chunk
      for(i=0;i<PNG_End.length;i++)
         data[dataptr++] = PNG_End[i];
     
      return Image.createImage (data,0, dataptr);
   }
   
   void writeInt(long crc)
   {
      data[dataptr++]=(byte)((crc>>>24)&255);
      data[dataptr++]=(byte)((crc>>>16)&255);      
      data[dataptr++]=(byte)((crc>>>8)&255);      
      data[dataptr++]=(byte)(crc&255);
   }
   
   void writeHeader(String t)
   {
      for(int i=0;i<4;i++)
         data[dataptr++]=(byte)t.charAt (i);
   }  
 
   void make_crc_table ()
   {
      crc_table = new int[256];
     
      for (int n = 0; n < 256; n++)
      {
         int c = n;
         for (int k = 8;  --k >= 0; )
         {
            if ((c & 1) != 0)
               c = 0xedb88320 ^ (c >>> 1);
            else
               c = c >>> 1;
         }        
         crc_table[n] = c;
      }
   }
   
   long calc_crc (byte[] buf, int off, int len)
   {
      int c = ~0;
      while (--len >= 0)
      c = crc_table[(c ^ buf[off++]) & 0xff] ^ (c >>> 8);
     
      return (long) ~c & 0xffffffffL;
   }  
}
« Last Edit: June 18, 2005, 03:50:05 pm by Glen » Logged
Glen
Full Member
***
Posts: 106


I'm not a llama!


View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #68 on: June 18, 2005, 03:23:02 pm »

The code above seems to be working fine.

I recommend moving the create_crc_table into a constructor and then setting data to null before returning from the function.

No comments yet though, has anyone tried it yet?

Glen.
Logged
pascal
Global Moderator
J2me god
*****
Posts: 3000



View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #69 on: June 18, 2005, 04:07:52 pm »

haven't tried it yet (no project code to try it in at the moment) .. will try it once I have some actual code around it Smiley
Logged

----------------------------------------------------
www.rumblex.com - Gaming Community
www.orangepixel.net - Game Development
Wex Viator
Full Member
***
Posts: 157


Rather mad


View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #70 on: June 19, 2005, 05:24:44 pm »

Maybe this compression lark should be made into a competition! Given a standard set of game-type images (splash screen / menus / avatars / maps / icons) see who can get it down as small as possible. Tongue

There's also the uncompression / rebuilding speed-factor though. Which is very important.

The game we're currently developing is weighing in at 140K! It's very graphical... even with a lot of the tips that have been mentioned here getting it below 100K might be tough.

I'm currently putting together a number of different crush-methods, if I find something incredible then I'll let you guys know. For now, here's some possible interesting data on just-PNGs-in-a-JAR testing:

Individual compressed PNGs: Jar size is 17.2K
Individual uncompressed  PNGs: Jar size is 16.7K
Binaray-type file using compressed PNGs: Jar size is 11.2K
Binaray-type file using uncompressed PNGs: Jar size is 7.62K

The PNGs I'm compressing are 19 frames of a character avatar. These values basically just enforce what's been said/debated already, but facts are always nice Wink.

Something I'm pondering is when saving the frames, it might well be better to just save the changes from the previous frame. This would hopefully result in a lot of zero-bytes where no change has occured... anyone tried anything like this? This wouldn't help with images that are very different, or varying in size, but for animations...

Another thing that comes to mind is loading in different palettes to make the same data appear totally different. Something some modders (like myself) did in GTA1 to include multiple car skins in one car file:



Note: these aren't mine, but good examples of how altering the palette can give more effects than just changing blue to red, so long as it's done right. Figured it's worth mentioning.
Logged

loppy
Senior. Member
****
Posts: 351


Clarity Games


View Profile
Re:Give me all your tricks for minimizing jar file size
« Reply #71 on: June 20, 2005, 12:55:59 am »

Is there any such concept in J2ME as palettes?  It would be great to be able to manipulate the colours of a canvas and would give developers a lot of options for reducing the amount of memory needed for graphics  e.g. animation through manipulation of a canvas palette as opposed to using a range of images.  But I would've thought that palettes would've been too device specific to have been implemented in J2ME.
Logged
Claymore
Global Moderator
J2me god
*****
Posts: 4935


Quantity != Quality


View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #72 on: June 20, 2005, 01:12:20 am »

I am assuming you mean palettes like the ones used in GBAs? No, they don't exist in that sense.

Logged

Wex Viator
Full Member
***
Posts: 157


Rather mad


View Profile WWW
Re:Give me all your tricks for minimizing jar file size
« Reply #73 on: June 20, 2005, 01:49:05 pm »

Unfourtunately you can only manipulate the palette at the creation time of the image, not directly on the fly. Same goes for any of the image data.
Logged

tsmith
New user
*
Posts: 26


w00t


View Profile
Re:Give me all your tricks for minimizing jar file size
« Reply #74 on: June 21, 2005, 03:45:15 am »

Wow, this discussion has really taken off!

To emphasize what has been said earlier: DEFLATE supports uncompressed streams, and the PNG format supports DEFLATE, so any PNG-conformant phone (which means all J2ME phones) can read PNGs with uncompressed streams via the Image.createImage(byte [], int, int) method.

I used this technique in a game that is currently on deck on 80+ handsets, so I can assure you that no phones have any trouble with it Smiley

A tip when writing your PNG generating code: write a command line version as well (i.e. as a regular java app) and check its output with pngcheck. Pngcheck is very good for debugging PNGs.

Cheers,
Tim
Logged
Pages: 1 ... 3 4 [5] 6 7 ... 12 Print 
J2meForums  |  General Category  |  Game programming (Moderators: mikkom, shendley)  |  Topic: Give me all your tricks for minimizing jar file size « 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!