SE47-specific CONVERRTBMP() attempt | developer.brewmp.com SE47-specific CONVERRTBMP() attempt | developer.brewmp.com

Developer

SE47-specific CONVERRTBMP() attempt

Forums:

Hello...

I've been trying to roll my own CONVERTBMP() specific to the SE47 for several days, and I'm not getting very far. Below is the code (sorry about the formatting) that I currently have. It's based off of someone else's routine (sorry, the thread escapes me) with my own reverse engineering applied to it. It works ~10% of the time in the emulator, and it instantly crashes the SE47. Perhaps the solution will come quicker if more pairs of eyes are looking at it. :) If a generic solution (2.x+ or even 1.1+) could be found, then that's obviously better as it would solve some of the same problems for other handsets.

static void * CONVERTBMP_SE47(AppData * pAppData,
BMPHeader * pSrcBuffer,
AEEImageInfo * pii,
boolean * pbRealloc)
{
/* validate the arguments */
DEBUG_ASSERT(pAppData);
DEBUG_ASSERT(pSrcBuffer);
DEBUG_ASSERT((pSrcBuffer->m_nNumBits == 4) || (pSrcBuffer->m_nNumBits == 8));
DEBUG_ASSERT(pii);
DEBUG_ASSERT(pbRealloc);
DBGPRINTF("CONVERTBMP_SE47()");

{
IDIB * pDIB;
UBYTE8 * pSourcePixelPtr;
IBitmap * pScreenBitmap;
IBitmap * pNewBitmap;

IDISPLAY_GetDeviceBitmap(pAppData->m_sApplet.m_pIDisplay, &pScreenBitmap);
IBITMAP_CreateCompatibleBitmap(pScreenBitmap, &pNewBitmap, (uint16)pSrcBuffer->m_nPixelWidth, (uint16)pSrcBuffer->m_nPixelHeight);
IBITMAP_QueryInterface(pNewBitmap, AEECLSID_DIB, (void **)&pDIB);

pSourcePixelPtr = (UBYTE8 *)((UBYTE8 *)pSrcBuffer + sizeof(BMPHeader));

pDIB->pRGB = (unsigned long *)pSourcePixelPtr;

if (pSrcBuffer->m_nNumBits == 4)
{
pSourcePixelPtr += (sizeof(BMP4BytePalette) * 16);
}
else
{
pSourcePixelPtr += (sizeof(BMP4BytePalette) * 256);
}

pDIB->pBmp = pSourcePixelPtr;
// pDIB->ncTransparent = 0x0000F81F;
pDIB->cx = pSrcBuffer->m_nPixelWidth;
pDIB->cy = pSrcBuffer->m_nPixelHeight;
pDIB->nPitch = pSrcBuffer->m_nPixelWidth << 1;
pDIB->cntRGB = 1 << pSrcBuffer->m_nNumBits;
pDIB->nDepth = (unsigned char)pSrcBuffer->m_nNumBits;
// pDIB->nColorScheme = IDIB_COLORSCHEME_565;

IBITMAP_BltIn(pNewBitmap,
0, 0,
pSrcBuffer->m_nPixelWidth, pSrcBuffer->m_nPixelHeight,
IDIB_TO_IBITMAP(pDIB),
0, 0,
AEE_RO_COPY);

IBITMAP_Release((IBitmap *)pDIB);
IBITMAP_Release(pScreenBitmap);

return(pNewBitmap);
}

BMPHeader is my own structure that's just the standard BMP header. (Yes, I am packing the structure for both the emu and ARM.)

Thank you.

-- Bob
One Man Band

Quote:IBITMAP_QueryInterface(pNewBitmap, AEECLSID_DIB, (void **)&pDIB);
Check the return value of QueryInterface(). Device compatible bitmaps on the SE47 might not be DIB-compatible, in which case this will fail, pDIB will be NULL, and your app will crash when you dereference it.
What you probably want to do is create a DIB with IDISPLAY_CreateDIBitmap().

Quote:IBITMAP_QueryInterface(pNewBitmap, AEECLSID_DIB, (void **)&pDIB);
Check the return value of QueryInterface(). Device compatible bitmaps on the SE47 might not be DIB-compatible, in which case this will fail, pDIB will be NULL, and your app will crash when you dereference it.
What you probably want to do is create a DIB with IDISPLAY_CreateDIBitmap().

Also, it's important to never modify the fields of an IDIB unless it came from CreateDIBitmap(). It's okay to change pixel values through the pBmp field, but otherwise, conside the structure read only.

Also, it's important to never modify the fields of an IDIB unless it came from CreateDIBitmap(). It's okay to change pixel values through the pBmp field, but otherwise, conside the structure read only.

Here's a brief high level pseudo-code version how I would do it...
GetDeviceBitmap
GetDeviceDIB
CreateNewBitmap the size of the input image
GetDIB of new bitmap
for each pixel in input bitmap
convert pixel RGBToNative
store pixel in DIB of new bitmap, accessible through IDIB->pBmp
advance one pixel in source and destination by DIB->nPitch
next
That should be it. There's no need at all to manipulate any of the DIBI data. BREW can created the DIB and everything for you.

Here's a brief high level pseudo-code version how I would do it...
GetDeviceBitmap
GetDeviceDIB
CreateNewBitmap the size of the input image
GetDIB of new bitmap
for each pixel in input bitmap
convert pixel RGBToNative
store pixel in DIB of new bitmap, accessible through IDIB->pBmp
advance one pixel in source and destination by DIB->nPitch
next
That should be it. There's no need at all to manipulate any of the DIBI data. BREW can created the DIB and everything for you.

I didn't look into the device spec sheet, What is the native bitformat of SE47? In your case pDIB->nDepth should have the value. Since you are getting device bitmap, you shouldn't modify this value, as this will contain native device bitformat value. When you create compatible device bitmap, IDIB structure will already contain correct info. All you need to do is to initialize pBmp pointer with correctly formatted data.
Sometime device dependent bitmap may not support (most of the time it does) IDIB interface. You should check
IBITMAP_QueryInterface(pNewBitmap, AEECLSID_DIB, (void **)&pDIB);
as markb suggested.
Since you are in BREW 2.0 or above, and if you don't want to deal with device bitmap, use IDisplay_CreateCompatiblebitmap to create a device independent bitmap(DIB) and do you writing on that bitmap. You can get IDIB pointer out of device independent bitmap.
At the end do IDISPLAY_BitBlt.

I didn't look into the device spec sheet, What is the native bitformat of SE47? In your case pDIB->nDepth should have the value. Since you are getting device bitmap, you shouldn't modify this value, as this will contain native device bitformat value. When you create compatible device bitmap, IDIB structure will already contain correct info. All you need to do is to initialize pBmp pointer with correctly formatted data.
Sometime device dependent bitmap may not support (most of the time it does) IDIB interface. You should check
IBITMAP_QueryInterface(pNewBitmap, AEECLSID_DIB, (void **)&pDIB);
as markb suggested.
Since you are in BREW 2.0 or above, and if you don't want to deal with device bitmap, use IDisplay_CreateCompatiblebitmap to create a device independent bitmap(DIB) and do you writing on that bitmap. You can get IDIB pointer out of device independent bitmap.
At the end do IDISPLAY_BitBlt.

Hi gang...
The Query() doesn't fail, and the device pixel format is 16-bit (565).
I did try Dragon's looping method first, but as I said, that behavior was worse that what I currently have implemented.
I will try other methods as suggested to see how far I can go with that.
-- Bob

Hi gang...
The Query() doesn't fail, and the device pixel format is 16-bit (565).
I did try Dragon's looping method first, but as I said, that behavior was worse that what I currently have implemented.
I will try other methods as suggested to see how far I can go with that.
-- Bob

In the meantime, though:
ruben wrote:Since you are in BREW 2.0 or above, and if you don't want to deal with device bitmap, use IDisplay_CreateCompatiblebitmap to create a device independent bitmap(DIB) and do you writing on that bitmap. You can get IDIB pointer out of device independent bitmap.
Is what you're describing different than what I'm doing in the code above (sans the DIB jiggery-pokery)?
Also, for everyone, are all the bitmap and DIB creation approaching the memory use that the native CONVERTBMP() requires?
Is it correct to release the DIB at the end?
-- Bob

In the meantime, though:
ruben wrote:Since you are in BREW 2.0 or above, and if you don't want to deal with device bitmap, use IDisplay_CreateCompatiblebitmap to create a device independent bitmap(DIB) and do you writing on that bitmap. You can get IDIB pointer out of device independent bitmap.
Is what you're describing different than what I'm doing in the code above (sans the DIB jiggery-pokery)?
Also, for everyone, are all the bitmap and DIB creation approaching the memory use that the native CONVERTBMP() requires?
Is it correct to release the DIB at the end?
-- Bob

A typo, for device independent bitmap, you need to use IDISPLAY_CreateDIBitmap.
Sorry for confusion.

A typo, for device independent bitmap, you need to use IDISPLAY_CreateDIBitmap.
Sorry for confusion.

Has anyone been able to create an SE47 specific version of CONVERTBMP? Since this is a known bug, it sure would be great if the good folks at QCOM were to post the source code for the standard work-around for this problem.
All the solution attempts I have seen on this thread use BREW 2.0 calls. Is it even possible to do any of this in BREW 1.1? Are there any BREW 1.1 workarounds for the CONVERTBMP problem?
Also, does the same problem occur if we use the IImage interface instead? In other words, does IImage call CONVERTBMP "under the hood" so that it has the same problem even if we don't call CONVERTBMP explicitly in our own code.
Finally, is any good soul out there willing to post the code for a working solution to the device-specific CONVERTBMP problem? Just thought I'd ask...
Thanks

Has anyone been able to create an SE47 specific version of CONVERTBMP? Since this is a known bug, it sure would be great if the good folks at QCOM were to post the source code for the standard work-around for this problem.
All the solution attempts I have seen on this thread use BREW 2.0 calls. Is it even possible to do any of this in BREW 1.1? Are there any BREW 1.1 workarounds for the CONVERTBMP problem?
Also, does the same problem occur if we use the IImage interface instead? In other words, does IImage call CONVERTBMP "under the hood" so that it has the same problem even if we don't call CONVERTBMP explicitly in our own code.
Finally, is any good soul out there willing to post the code for a working solution to the device-specific CONVERTBMP problem? Just thought I'd ask...
Thanks

Yes, I have written my own CONVERTBMP implementations to build against both Brew 2.x and Brew 1.1 SDKs for the SE47. It is possible and it's not really that hard and I've laid out the pseudo-code above. As for releasing my source, sorry but that I will not do, mostly because it is a hack that relies on undocumented BREW features to work in the 1.1 build.
But for a Brew 2.0 usable version, this is really one of the most trivial programming exercises I can think of, particularly given the pseudo-code I listed above. Things don't get much easier than doing a table-look-up in a loop.

Yes, I have written my own CONVERTBMP implementations to build against both Brew 2.x and Brew 1.1 SDKs for the SE47. It is possible and it's not really that hard and I've laid out the pseudo-code above. As for releasing my source, sorry but that I will not do, mostly because it is a hack that relies on undocumented BREW features to work in the 1.1 build.
But for a Brew 2.0 usable version, this is really one of the most trivial programming exercises I can think of, particularly given the pseudo-code I listed above. Things don't get much easier than doing a table-look-up in a loop.

Unfortunately I need a BREW 1.1 solution. So let me ask this to anyone out there who has a BREW 1.1 solution: would any of you be willing to license your solution to me a reasonable price? You would provide me with a .o file (say se47utils.o) that I can link in with my code. Just tell me the format for the function I must call (e.g, CONVERTBMP_SE47(void *src, AEEImageInfo *info, boolean *reallocFlag) ). If anyone has a working solution that youcan license to me at a reasonable price, then you could make some quick $ and I can avoid having to figure this out myself.
Any takers? Feel free to send me a private message.

Unfortunately I need a BREW 1.1 solution. So let me ask this to anyone out there who has a BREW 1.1 solution: would any of you be willing to license your solution to me a reasonable price? You would provide me with a .o file (say se47utils.o) that I can link in with my code. Just tell me the format for the function I must call (e.g, CONVERTBMP_SE47(void *src, AEEImageInfo *info, boolean *reallocFlag) ). If anyone has a working solution that youcan license to me at a reasonable price, then you could make some quick $ and I can avoid having to figure this out myself.
Any takers? Feel free to send me a private message.

hi Bob
In your code of convertBMP_SE47, can i know the description of DEBUG_ASSERT
function wat it is doing basically. :confused:
thanks
dost

hi Bob
In your code of convertBMP_SE47, can i know the description of DEBUG_ASSERT
function wat it is doing basically. :confused:
thanks
dost

thanks Dragon,
i followed the algorithm u worte previously and successfully tested the code on SE47 and found that it actually does it's work :) well, and saves the memory as well.

thanks Dragon,
i followed the algorithm u worte previously and successfully tested the code on SE47 and found that it actually does it's work :) well, and saves the memory as well.

One Man Band wrote:I did try Dragon's looping method first, but as I said, that behavior was worse that what I currently have implemented.
I too am seeing this phenomenon. Creating a bitmap and manually blitting the pixels into it is absorbing just as much memory as CONVERTBMP() does. Don't suppose somebody would like to be more specific about this?
I get the device bitmap via IDISPLAY_GetDeviceBitmap() and then pass the result of that to IBITMAP_CreateCompatibleBitmap(). The end result is a structure that eats roughly twice the memory as any other handset would, which is exactly no help at all.

One Man Band wrote:I did try Dragon's looping method first, but as I said, that behavior was worse that what I currently have implemented.
I too am seeing this phenomenon. Creating a bitmap and manually blitting the pixels into it is absorbing just as much memory as CONVERTBMP() does. Don't suppose somebody would like to be more specific about this?
I get the device bitmap via IDISPLAY_GetDeviceBitmap() and then pass the result of that to IBITMAP_CreateCompatibleBitmap(). The end result is a structure that eats roughly twice the memory as any other handset would, which is exactly no help at all.

CreateCompatibleBitmap() is just as broken as CONVERTBMP() Both function use the same core routines, which have a bug.
You will have to write them yourself if you want to get rid of the problem or you could license the replacement module that I wrote.

CreateCompatibleBitmap() is just as broken as CONVERTBMP() Both function use the same core routines, which have a bug.
You will have to write them yourself if you want to get rid of the problem or you could license the replacement module that I wrote.

Quote:CreateCompatibleBitmap() is just as broken as CONVERTBMP() Both function use the same core routines, which have a bug.
You will have to write them yourself if you want to get rid of the problem or you could license the replacement module that I wrote.
Yeah, I can say the exact same thing here as well (including the part about licensing my own solution). :)
Dante, it's really easier than you think.
-- Bob
One Man Band

Quote:CreateCompatibleBitmap() is just as broken as CONVERTBMP() Both function use the same core routines, which have a bug.
You will have to write them yourself if you want to get rid of the problem or you could license the replacement module that I wrote.
Yeah, I can say the exact same thing here as well (including the part about licensing my own solution). :)
Dante, it's really easier than you think.
-- Bob
One Man Band

Licensing the solution is likely not an option, but I'd have to check with the boss ;)
So the long and short of it is, I need to investigate the device's native format and create the DDB myself, yes? I'm sure it's easy enough, but sometimes one requires "the magic words" to tie it all together.

Licensing the solution is likely not an option, but I'd have to check with the boss ;)
So the long and short of it is, I need to investigate the device's native format and create the DDB myself, yes? I'm sure it's easy enough, but sometimes one requires "the magic words" to tie it all together.

I have a semi-similar problem with the SE47.
Does anyone know how to get around the IBTIMAP_CreateCompatibleBitmap problem?
My app uses a lot of images which it rotates through a LRU cache on the device since it is unable to hold all the images on the device at any one time. Since there are so many images I am using PNG images to help reduce the cache size.
Of course the IIMAGE interface uses a lot of memory, so I have been loading the PNGs using IIMAGE to decode them, and then when they are ready I create a compatible bitmap and draw the IIMAGE to the bitmap and then free the IIMAGE which saves a lot of memory.
Only on the SE47 CreateCompatibleBitmap allocates more memory than the IIMAGE does....
If I create a DIB I can't set it as the Display destination and draw the IIMAGE to it.
IBitmap* pDeviceBmp;
IDISPLAY_GetDeviceBitmap(pIDisplay, &pDeviceBmp);
IBITMAP_CreateCompatibleBitmap(pDeviceBmp, &m_pBitmap, m_aei.cx, m_aei.cy);
IBITMAP_Release(pDeviceBmp);
if(m_pBitmap)
{
IDISPLAY_SetDestination(pIDisplay, m_pBitmap);
IIMAGE_Draw(imgPtr, 0, 0);
IIMAGE_Release(imgPtr);
IDISPLAY_SetDestination(pIDisplay, NULL);
NativeColor nc = IBITMAP_RGBToNative(m_pBitmap, MAKE_RGB(255,0,255));
IBITMAP_SetTransparencyColor(m_pBitmap, nc);

I have a semi-similar problem with the SE47.
Does anyone know how to get around the IBTIMAP_CreateCompatibleBitmap problem?
My app uses a lot of images which it rotates through a LRU cache on the device since it is unable to hold all the images on the device at any one time. Since there are so many images I am using PNG images to help reduce the cache size.
Of course the IIMAGE interface uses a lot of memory, so I have been loading the PNGs using IIMAGE to decode them, and then when they are ready I create a compatible bitmap and draw the IIMAGE to the bitmap and then free the IIMAGE which saves a lot of memory.
Only on the SE47 CreateCompatibleBitmap allocates more memory than the IIMAGE does....
If I create a DIB I can't set it as the Display destination and draw the IIMAGE to it.
IBitmap* pDeviceBmp;
IDISPLAY_GetDeviceBitmap(pIDisplay, &pDeviceBmp);
IBITMAP_CreateCompatibleBitmap(pDeviceBmp, &m_pBitmap, m_aei.cx, m_aei.cy);
IBITMAP_Release(pDeviceBmp);
if(m_pBitmap)
{
IDISPLAY_SetDestination(pIDisplay, m_pBitmap);
IIMAGE_Draw(imgPtr, 0, 0);
IIMAGE_Release(imgPtr);
IDISPLAY_SetDestination(pIDisplay, NULL);
NativeColor nc = IBITMAP_RGBToNative(m_pBitmap, MAKE_RGB(255,0,255));
IBITMAP_SetTransparencyColor(m_pBitmap, nc);

In SE47 device black color is transparency color and not magenta color.
Hence use black color instead of magenta color.
Following is sample code. Please check this in device and give me your responses as soon as possible.
IBitmap *pIBitmap;
AEEBitmapInfo imageInfo;
//First Clear Screen.
IDISPLAY_ClearScreen(pMe->a.m_pIDisplay);
//Load Image from Resource file (i.e. BAR file).
pIBitmap=ISHELL_LoadResBitmap(pMe->a.m_pIShell, RES_DATA,(short)IDB_IMAGE1);
//Get dimension of image.
IBITMAP_GetInfo(pIBitmap, &imageInfo, sizeof(AEEBitmapInfo));
//Set BLACK color as transparency color of the image.
IBITMAP_SetTransparencyColor(pIBitmap,IBITMAP_RGBToNative(pIBitmap,MAKE_RGB(0,0,0)));
//Display image on screen.
IDISPLAY_BitBlt(pMe->a.m_pIDisplay, 0, 0, imageInfo.cx, imageInfo.cy, pIBitmap, 0, 0, AEE_RO_TRANSPARENT);
//Update screen.
IDISPLAY_UpdateEx(pMe->a.m_pIDisplay, FALSE);

In SE47 device black color is transparency color and not magenta color.
Hence use black color instead of magenta color.
Following is sample code. Please check this in device and give me your responses as soon as possible.
IBitmap *pIBitmap;
AEEBitmapInfo imageInfo;
//First Clear Screen.
IDISPLAY_ClearScreen(pMe->a.m_pIDisplay);
//Load Image from Resource file (i.e. BAR file).
pIBitmap=ISHELL_LoadResBitmap(pMe->a.m_pIShell, RES_DATA,(short)IDB_IMAGE1);
//Get dimension of image.
IBITMAP_GetInfo(pIBitmap, &imageInfo, sizeof(AEEBitmapInfo));
//Set BLACK color as transparency color of the image.
IBITMAP_SetTransparencyColor(pIBitmap,IBITMAP_RGBToNative(pIBitmap,MAKE_RGB(0,0,0)));
//Display image on screen.
IDISPLAY_BitBlt(pMe->a.m_pIDisplay, 0, 0, imageInfo.cx, imageInfo.cy, pIBitmap, 0, 0, AEE_RO_TRANSPARENT);
//Update screen.
IDISPLAY_UpdateEx(pMe->a.m_pIDisplay, FALSE);

That is not correct. You can easily use magenta as the transparent color. You simply have to tell the system about it.

That is not correct. You can easily use magenta as the transparent color. You simply have to tell the system about it.

Dragon wrote:Here's a brief high level pseudo-code version how I would do it...
GetDeviceBitmap
GetDeviceDIB
CreateNewBitmap the size of the input image
GetDIB of new bitmap
for each pixel in input bitmap
convert pixel RGBToNative
store pixel in DIB of new bitmap, accessible through IDIB->pBmp
advance one pixel in source and destination by DIB->nPitch
next
That should be it. There's no need at all to manipulate any of the DIBI data. BREW can created the DIB and everything for you.
Awesome advice... but where is the CreateNewBitmap function? I've tried creating a DIB and then IDIB_TO_BITMAP... but then none of the drawing routines work.

Dragon wrote:Here's a brief high level pseudo-code version how I would do it...
GetDeviceBitmap
GetDeviceDIB
CreateNewBitmap the size of the input image
GetDIB of new bitmap
for each pixel in input bitmap
convert pixel RGBToNative
store pixel in DIB of new bitmap, accessible through IDIB->pBmp
advance one pixel in source and destination by DIB->nPitch
next
That should be it. There's no need at all to manipulate any of the DIBI data. BREW can created the DIB and everything for you.
Awesome advice... but where is the CreateNewBitmap function? I've tried creating a DIB and then IDIB_TO_BITMAP... but then none of the drawing routines work.

There is no such function. You will have to do that yourself. Since it's a standard BMP format, it is documented in every book about Windows graphics programming and all over the web. Just google for BMP file format and you're ready to go.

There is no such function. You will have to do that yourself. Since it's a standard BMP format, it is documented in every book about Windows graphics programming and all over the web. Just google for BMP file format and you're ready to go.

CreateCompatibleBitmap isn't a good idea for creating the new bitmap?

CreateCompatibleBitmap isn't a good idea for creating the new bitmap?

This function is broken for the SE47. It will 'work' but it allocates twice as much memory as it should, which leads to low memory conditions if your app uses a lot of images
From the first post
>>CreateCompatibleBitmap() is just as broken as CONVERTBMP() Both function use >>the same core routines, which have a bug.
>>
>>You will have to write them yourself if you want to get rid of the problem or you >>could license the replacement module that I wrote.

This function is broken for the SE47. It will 'work' but it allocates twice as much memory as it should, which leads to low memory conditions if your app uses a lot of images
From the first post
>>CreateCompatibleBitmap() is just as broken as CONVERTBMP() Both function use >>the same core routines, which have a bug.
>>
>>You will have to write them yourself if you want to get rid of the problem or you >>could license the replacement module that I wrote.