×

Discussion Board

Results 1 to 3 of 3
  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    14

    Loading images from byte array on 6130i

    Hello,

    I've previously developed games on Siemens' phones (SL45 ja M50) and I'm used to load my images from binary files. I've developed a special tool (an ant task) that compiles png's to bin. Now, when I try to use the same binary files on Nokia's phones (emulator actually, I'm too afraid to test it on the real hardware , I cannot use the same image files directly but recompress them with special routine (given below). The problem is that Nokia uses thighly packed image format whereas Siemens' format has padding bits on each pixel row so that number of bits is divisible by 8 and therefore can be stored as bytes. Let me illustrate this (9x9 image from Nokia's specs):
    <pre>
    MSB LSB
    Bit#-> 0 1 2 3 4 5 6 7 0
    ------------------------
    + + +|+
    + + + |+ +
    + + + + | + +
    + + + + +| + +
    + + +|+ + + +
    + + | + + + + +
    + +| + + + +
    +|+ + + +|
    + + +|+
    </pre>
    On Nokia's phones this would be (size of array (9*9+7)/8 = 11 bytes):
    <pre>
    byteArray[0] = (byte) 0xC1; // binary 11000001
    byteArray[1] = (byte) 0xF0; // binary 11110000
    byteArray[2] = (byte) 0xFC; // binary 11111100
    byteArray[3] = (byte) 0x7F; // binary 01111111
    byteArray[4] = (byte) 0x3D; // binary 00111101
    byteArray[5] = (byte) 0xDE; // binary 11011110
    byteArray[6] = (byte) 0x7F; // binary 01111111
    byteArray[7] = (byte) 0x1F; // binary 00011111
    byteArray[8] = (byte) 0x87; // binary 10000111
    byteArray[9] = (byte) 0xC1; // binary 11000001
    byteArray[10] = (byte) 0x80; // binary 10000000
    </pre>
    But on Siemens' it would be (size ((9+7)/8)*9 = 18 bytes):
    <pre>
    byteArray[0] = (byte) 0xC1; // binary 11000001
    byteArray[1] = (byte) 0x80; // binary 10000000
    byteArray[2] = (byte) 0xE1; // binary 11100001
    byteArray[3] = (byte) 0x80; // binary 10000000
    byteArray[4] = (byte) 0xF1; // binary 11110001
    byteArray[5] = (byte) 0x80; // binary 10000000
    byteArray[6] = (byte) 0xF9; // binary 11111001
    byteArray[7] = (byte) 0x80; // binary 10000000
    byteArray[8] = (byte) 0xDD; // binary 11011101
    byteArray[9] = (byte) 0x80; // binary 10000000
    byteArray[10] = (byte) 0xCF; // binary 11001111
    byteArray[11] = (byte) 0x80; // binary 10000000
    byteArray[12] = (byte) 0xC7; // binary 11000111
    byteArray[13] = (byte) 0x80; // binary 10000000
    byteArray[14] = (byte) 0xC3; // binary 11000011
    byteArray[15] = (byte) 0x80; // binary 10000000
    byteArray[16] = (byte) 0xC1; // binary 11000001
    byteArray[17] = (byte) 0x80; // binary 10000000
    </pre>
    I know there is a parameter called scanlength in the drawImage method of DirectGraphics, but adjusting it does not fix the problem. I tried

    drawPixels(pixels, null, 0, 16, 0, 0, 9, 9, 0, TYPE_BYTE_1_GRAY)

    instead of

    drawPixels(pixels, null, 0, 9, 0, 0, 9, 9, 0, TYPE_BYTE_1_GRAY)

    but the result is same (at least it looks like it).

    So I wrote a little method that compresses the bits from Siemens' style image data to Nokia's format:
    <pre>
    private void compress(byte[] data, int width, int height)
    {
    if (width == ((width + 7) & ~7))
    return;
    int src = 0;
    int dst = 0;
    int byt = 0;
    int bits = 0;
    int wbytes = width / 8;
    int leftover = width - wbytes * 8;

    for (int y = 0; y < height; y++)
    {
    for (int x = 0; x < wbytes; x++)
    {
    byt <<= 8;
    byt |= (data[src++]) & 0xff;
    bits += 8;
    if (bits > 7)
    {
    data[dst] = (byte) ((byt >> (bits - 8)) 0xff);
    dst++;
    bits -= 8;
    }
    }
    byt <<= leftover;
    byt |= (data[src++] & 0xff) >>> (8 - leftover) ;
    bits += leftover;
    if (bits > 7)
    {
    data[dst] = (byte) ((byt >> (bits-8)) & 0xff);
    dst++;
    bits -= 8;
    }
    }
    if (bits > 0)
    {
    data[dst] = (byte) ((byt >> (bits-8)) & 0xff);
    dst++;
    }
    }
    </pre>
    If there is any other way please tell me! Using this method causes a small performance hit and I would like to avoid it :I

    Thanks!

  2. #2
    Regular Contributor
    Join Date
    Mar 2003
    Location
    UK
    Posts
    229

    RE: Loading images from byte array on 6130i

    Hi,

    If your image data is not directly in a format usable by the Nokia UI, for example TYPE_BYTE_1_GRAY, then you're always going to have to perform a conversion on it before using it I'm afraid. It looks like the Siemens format doesn't correspond to anything in the Nokia UI.

    What I would do it to move the compress routine offline and make it part of your ant task. Use a parameter to get the ant task to generate either Nokia or Siemens format data. Then you can use the Nokia format data directly in your MIDlet, without the performance hit at runtime.

    This does mean you have to provide a different JAR file for the Nokia phones, but then you'd probably have to do this anyway if you are using the phone specific APIs.

    Hope this helps,

    Steve

  3. #3
    Regular Contributor
    Join Date
    Mar 2003
    Posts
    71

    RE: Loading images from byte array on 6130i

    hehehe, that sounds *very* familiar

    and I concur with the first responses suggestion. Infact, i've done *exactly* the same myself :P

    also, Siemens support for 2bpp to include a transparency mask was totally incompatible with nokias format (and their method of implementing transparency - which in my opinion stinks - the mask should have been incorperated into the regular Image, class as it is in the Siemens implementation)

    So, i've created my own wrapper to hold the 2 arrays (data & mask), and replaced all regular usage of java.microedition.lcdui.Image with my custom Image wrapper class.(which has a drawImage(DirectGraphics g) method)

    It didn't break anything fundamental to any of the games i've ported, it just involved quite abit of typing

    now if I were using some decent tools, I could probably write a regular expression to do all the changes automatically.... but thats an entirely different problem, and probably not worth the hassel

    rob,

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×