Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

I'm trying to process a bitmap file on the SE47 and am having alignment problems.

By using GCCPACKED on the struct I can grab the bitmap header information

typedef struct GCCPACKED _MY_BMPINFO{
.
.
MY_BMPINFO;

However the app crashes when trying to access the data in the pixel and palette arrays.

uint8* pBuf; //raw bitmap data
uint32* palette = (uint32*)(pBuf+54) //pointer to the palette array
uint8* pPixels = (pBuf+offset) //pointer to pixels

uint8 index = *pPixels++;
uint32 rgbquad = palette

    ; //crash
    rgbquad = NTOHL(rgbquad);
    *pRow = (uint8)IBITMAP_RGBToNative(pDeviceBmp, rgbquad);

    I've read the posts that the ARM compiler will allow this type of data access by defining the pointers to the arrays with __packed,
    using GCCPACKED/gcc on these pointers does not help.

    Any ideas?

    The palette pointer is unaligned. (You are adding 54 to pBuf, and 54 is not divisible by 4.) When you use pointer arithmetic like that, the compiler assumes you are doing aligned memory accesses, rather than assuming the accesses are unaligned. (It can't tell at compile time, and the performance hit of unaligned accesses is generally undesirable.)
    You will have to read a byte at a time and piece together the the rgbquads yourself. You could also allocate an aligned buffer of rgbquads and memcpy the whole palette. Either way, you are going to have to copy it if you want to access it efficiently later.

    The palette pointer is unaligned. (You are adding 54 to pBuf, and 54 is not divisible by 4.) When you use pointer arithmetic like that, the compiler assumes you are doing aligned memory accesses, rather than assuming the accesses are unaligned. (It can't tell at compile time, and the performance hit of unaligned accesses is generally undesirable.)
    You will have to read a byte at a time and piece together the the rgbquads yourself. You could also allocate an aligned buffer of rgbquads and memcpy the whole palette. Either way, you are going to have to copy it if you want to access it efficiently later.

    thanks mark, that got it working.

    thanks mark, that got it working.

    Here's a question:
    Is it safe to assume that a poniter returned by MALLOC will ALWAYS be divisible by 4 ?
    i.e.
    void * p = MALLOC(size);
    if((uunt32)p % 4 != 0)
    {
    // SHOULD NEVER GET HERE

    Here's a question:
    Is it safe to assume that a poniter returned by MALLOC will ALWAYS be divisible by 4 ?
    i.e.
    void * p = MALLOC(size);
    if((uunt32)p % 4 != 0)
    {
    // SHOULD NEVER GET HERE

    gcc should align to BIGGEST_ALIGNMENT, but its often a broken definition, use the lesser of BIGGEST_ALIGNMENT or 2 * BITS_PER_WORD
    usually malloc isn't guaranteed to be aligned to anything other than the fundamental machine type
    to be correct and safe, wrap malloc in an aligned allocater

    gcc should align to BIGGEST_ALIGNMENT, but its often a broken definition, use the lesser of BIGGEST_ALIGNMENT or 2 * BITS_PER_WORD
    usually malloc isn't guaranteed to be aligned to anything other than the fundamental machine type
    to be correct and safe, wrap malloc in an aligned allocater

    The implementation of BREW's MALLOC() function doesn't have anything to do with GCC. To answer the question, you can assume it's allingned for the platform. To date, this has always been 4-byte alignment.

    The implementation of BREW's MALLOC() function doesn't have anything to do with GCC. To answer the question, you can assume it's allingned for the platform. To date, this has always been 4-byte alignment.

    i was talking about malloc, and not MALLOC and my suggestion on the best approach which is not to rely on what the API maker gives you and wrap, given the inconsistencies, that way you can alter the alignment as required and its guaranteed to work

    i was talking about malloc, and not MALLOC and my suggestion on the best approach which is not to rely on what the API maker gives you and wrap, given the inconsistencies, that way you can alter the alignment as required and its guaranteed to work

    Thanks guys, I ask cos im looking into memory management solutions. Specifically implementing a "private heap" so I grap heap at start-up and from then on re-route my MALLOC and FREE calls to use my custom memory calls which will use the private heap.
    [I want to do this primarily so its easy to clean up the memory if an error occurs at run-time]
    In your opinions is this a feasible thing / good idea to do on BREW handsets ?

    Thanks guys, I ask cos im looking into memory management solutions. Specifically implementing a "private heap" so I grap heap at start-up and from then on re-route my MALLOC and FREE calls to use my custom memory calls which will use the private heap.
    [I want to do this primarily so its easy to clean up the memory if an error occurs at run-time]
    In your opinions is this a feasible thing / good idea to do on BREW handsets ?