What's the best way to load large images | developer.brewmp.com What's the best way to load large images | developer.brewmp.com

Developer

What's the best way to load large images

Forums:

Problem:
I'm on a motorolla T720 which has 400K of heap space.

I want to load a 300+ K image and convert it to BitBlt.

Is this a problem (the specs on the phone don't say what the max size of images that can be loaded is)

Possible options:

1) Is it possible to run CONVERTBMP on an image which is larger than 1/2 the heap space, since CONVERBMP attempts to realloc the image... and there's obviously no place to put it... or am I not getting what's actually happening behind the scenes?

2) Would it make sense (if technically possible) to cut the image into 10 pieces, and load 10, 30K files in, converting them to BitBlt one at a time, and releasing the IIMAGE * after each conversion, thus allowing that space to be used for loading the next image?

Or am I just asking for trouble with the whole endeavor? :)

I'm not sure, but I think that CONVERTBMP needs enough RAM to house the original image and the converted image. The second technique would probably work well enough for you... but what kind of massive image are you loading? You'd do well to investigate replacing it with say, a tile map. If the image contains many redundancies (large areas of solid color, etc), a tilemap would be an excellent way to save space. Also, tilemaps would allow you to use many 4 bit BMPs as opposed to one gigantic 8 or 16 bit BMP. Remember, a 300K image will take several minutes to download when the end user purchases your application, so its in your best interest to reduce the size as much as possible. Average games are usually only 50 to 150k.

I'm not sure, but I think that CONVERTBMP needs enough RAM to house the original image and the converted image. The second technique would probably work well enough for you... but what kind of massive image are you loading? You'd do well to investigate replacing it with say, a tile map. If the image contains many redundancies (large areas of solid color, etc), a tilemap would be an excellent way to save space. Also, tilemaps would allow you to use many 4 bit BMPs as opposed to one gigantic 8 or 16 bit BMP. Remember, a 300K image will take several minutes to download when the end user purchases your application, so its in your best interest to reduce the size as much as possible. Average games are usually only 50 to 150k.

unfortunately, a tile map will not be useful in this application. I have reduced the image to the smallest it can possibly be, but it contains the characters from the game... 10 bodies, and their animation limbs. It's all cut out and positioned to be as space effective as possible, but it's still around 300K. I realize it'll take a while to download... but it'll be worth it! :)

unfortunately, a tile map will not be useful in this application. I have reduced the image to the smallest it can possibly be, but it contains the characters from the game... 10 bodies, and their animation limbs. It's all cut out and positioned to be as space effective as possible, but it's still around 300K. I realize it'll take a while to download... but it'll be worth it! :)

Ahh, I see... well, you might try to cut it into 10 images, one for each body and their respective limbs, or even one image per part (although this might not be as space efficient, depending on the images and color depths). Something to remember when you're working on the T720 is that it has a 12 bit color display, so only 16 shades per color, so cutting it down to say, a 4 bit image for just a character's arm can be very effective. I only use 8 bit color for my title screens, personally.
The other thing you might consider, if you're feeling hardcore (which you might be, considering the 300k resources), would be to write a de/compressor for your data. All my resources in my current project are compressed inside the BAR file using a custom compression routine, so while I have a ton of data, it doesn't use up a quarter as much as it would normally.
Also, just FYI, the T720 claims to have 400k of RAM, but either the spec sheet is wrong, or the phone's OS uses much less RAM than other phones, because it usually has as much free RAM as all the other phones I have with 500k.

Ahh, I see... well, you might try to cut it into 10 images, one for each body and their respective limbs, or even one image per part (although this might not be as space efficient, depending on the images and color depths). Something to remember when you're working on the T720 is that it has a 12 bit color display, so only 16 shades per color, so cutting it down to say, a 4 bit image for just a character's arm can be very effective. I only use 8 bit color for my title screens, personally.
The other thing you might consider, if you're feeling hardcore (which you might be, considering the 300k resources), would be to write a de/compressor for your data. All my resources in my current project are compressed inside the BAR file using a custom compression routine, so while I have a ton of data, it doesn't use up a quarter as much as it would normally.
Also, just FYI, the T720 claims to have 400k of RAM, but either the spec sheet is wrong, or the phone's OS uses much less RAM than other phones, because it usually has as much free RAM as all the other phones I have with 500k.

1) im pretty sure this isnt possible.. can an image filling the entire screen of the t720 even take up 300k? .. ah, i re-read your last post.. cutting up the image would probably end up taking more than 300k (since you add image headers to all the images).. but you have to give somewhere ;)
what i did in my app in the initialization was read in each image with loadresdata, call convertBmp on it, and if the realloc flag is true (which i think it usually is on the actual device), free the original data, keeping only the converted data. of course, the drawback with this is that it only works with bitmaps ;) .. this is essentially what your #2 is.
I think the IImage controls retain the original and converted data, which is why they take up much more heap space.
the other thing is.. do you really need access to all of the images all of the time? for example if you have a game, perhaps some images will only be used on certain levels, so they dont need to be in memory on the levels they dont exist.
-Tyndal

1) im pretty sure this isnt possible.. can an image filling the entire screen of the t720 even take up 300k? .. ah, i re-read your last post.. cutting up the image would probably end up taking more than 300k (since you add image headers to all the images).. but you have to give somewhere ;)
what i did in my app in the initialization was read in each image with loadresdata, call convertBmp on it, and if the realloc flag is true (which i think it usually is on the actual device), free the original data, keeping only the converted data. of course, the drawback with this is that it only works with bitmaps ;) .. this is essentially what your #2 is.
I think the IImage controls retain the original and converted data, which is why they take up much more heap space.
the other thing is.. do you really need access to all of the images all of the time? for example if you have a game, perhaps some images will only be used on certain levels, so they dont need to be in memory on the levels they dont exist.
-Tyndal

thank you both... my biggest concern was about pushing the overall heap envelope. I'm not 100% clear on what else shares that space... I mean... does the phone's background operations (listning for incoming calls, etc.) take up any memory? I notice in the emulator that I never start out at 400, it's always 388 or some such. I don't know if that's the background stuff I'm seeing, or if the emulator just isn't displaying the memory use exactly right.
As for my image cutting, I got it all figured out, so, as long as that emulator memory display is accurate, I'm golden.
How good is BREW at finding and filling holes in memory? If my approach of loading images and releasing them as the realloc boolean shows true, is to work, the released IImage * which are the original RESOURCE files (that I'm freeing) need to dependably be refilled with the next image, or I AM going to run out of space in a jiffy! I suppose the important thing is to load them in size order with the largest first, so that I'm sure that enough of a block of memory is free for the next one to load.

thank you both... my biggest concern was about pushing the overall heap envelope. I'm not 100% clear on what else shares that space... I mean... does the phone's background operations (listning for incoming calls, etc.) take up any memory? I notice in the emulator that I never start out at 400, it's always 388 or some such. I don't know if that's the background stuff I'm seeing, or if the emulator just isn't displaying the memory use exactly right.
As for my image cutting, I got it all figured out, so, as long as that emulator memory display is accurate, I'm golden.
How good is BREW at finding and filling holes in memory? If my approach of loading images and releasing them as the realloc boolean shows true, is to work, the released IImage * which are the original RESOURCE files (that I'm freeing) need to dependably be refilled with the next image, or I AM going to run out of space in a jiffy! I suppose the important thing is to load them in size order with the largest first, so that I'm sure that enough of a block of memory is free for the next one to load.

yeah, and youlll also want to make sure that you are error checking mallocs and such, if they dont pass, you need to warn the user somehow (im pretty sure this is a requirement for true brew testing) ... probably just display an error message saying something like "please exit all other apps and try running the app again" or something.
-Tyndal

yeah, and youlll also want to make sure that you are error checking mallocs and such, if they dont pass, you need to warn the user somehow (im pretty sure this is a requirement for true brew testing) ... probably just display an error message saying something like "please exit all other apps and try running the app again" or something.
-Tyndal

Ah, the T720 - I had a heap (no pun intended) of trouble porting one of our games to this phone as the main character had a huge amount of animations. As others have suggested, splitting your image up into multiple images is the only way to go. As per initial heap usage - you get, at runtime, your full 400k, minus the size of your .mod, minus (I think) about 40k for BREW itself. At one point I was facing a 100k (!) deficit, but was saved by stripping out as much wasted, transparent space from the images themselves as I could (and generating compensatory "offsetting" information so that I could show any particular frame of an animation in the correct place onscreen) - the resulting savings when the now-smaller images were converted to device-dependent bitmaps were suprisingly large, and without this technique the game would probably have been impossible to port (I had experimented with the idea of swapping seldom-used animations out of memory and loading & decompressing required ones on the fly, but it led very quickly to severe heap fragmentation and many amusing bugs and crashes).
Anyway, good luck with it! :)
Edit:
About BREW's ability to find and fill holes in memory - our game contains 128 24x24 tiles, which would take up about 128k when converted to ready-to-blit format. So what I did was use the "swapping in and out of memory" technique described above - if there are more than 40 tiles in memory and we need to display a currently unloaded one, we delete the least used one, decompress the required one to a windows bitmap, and run CONVERTBMP on it (a remarkably fast process - thank you, BREW! :)). So far, BREW has not failed to place the newly-created device-dependent bitmap in the region of memory occupied by the just unloaded tile. Of course, if all of the tiles were different sizes/ took up different amounts of memory, I doubt it would perform so well and we would be in a lot of trouble, but I'd say that BREW's memory management techniques are at least reasonably sophisticated.
Edit2:
tyndal wrote:yeah, and youlll also want to make sure that you are error checking mallocs and such, if they dont pass, you need to warn the user somehow (im pretty sure this is a requirement for true brew testing) ... probably just display an error message saying something like "please exit all other apps and try running the app again" or something.
-Tyndal
Wasn't this requirement recently waived? Something to do with the programmers not being provided with tools necessary to test there own apps under low memory conditions, so it was deemed an "unfair" test...? I seem to recall hearing something like that :)

Ah, the T720 - I had a heap (no pun intended) of trouble porting one of our games to this phone as the main character had a huge amount of animations. As others have suggested, splitting your image up into multiple images is the only way to go. As per initial heap usage - you get, at runtime, your full 400k, minus the size of your .mod, minus (I think) about 40k for BREW itself. At one point I was facing a 100k (!) deficit, but was saved by stripping out as much wasted, transparent space from the images themselves as I could (and generating compensatory "offsetting" information so that I could show any particular frame of an animation in the correct place onscreen) - the resulting savings when the now-smaller images were converted to device-dependent bitmaps were suprisingly large, and without this technique the game would probably have been impossible to port (I had experimented with the idea of swapping seldom-used animations out of memory and loading & decompressing required ones on the fly, but it led very quickly to severe heap fragmentation and many amusing bugs and crashes).
Anyway, good luck with it! :)
Edit:
About BREW's ability to find and fill holes in memory - our game contains 128 24x24 tiles, which would take up about 128k when converted to ready-to-blit format. So what I did was use the "swapping in and out of memory" technique described above - if there are more than 40 tiles in memory and we need to display a currently unloaded one, we delete the least used one, decompress the required one to a windows bitmap, and run CONVERTBMP on it (a remarkably fast process - thank you, BREW! :)). So far, BREW has not failed to place the newly-created device-dependent bitmap in the region of memory occupied by the just unloaded tile. Of course, if all of the tiles were different sizes/ took up different amounts of memory, I doubt it would perform so well and we would be in a lot of trouble, but I'd say that BREW's memory management techniques are at least reasonably sophisticated.
Edit2:
tyndal wrote:yeah, and youlll also want to make sure that you are error checking mallocs and such, if they dont pass, you need to warn the user somehow (im pretty sure this is a requirement for true brew testing) ... probably just display an error message saying something like "please exit all other apps and try running the app again" or something.
-Tyndal
Wasn't this requirement recently waived? Something to do with the programmers not being provided with tools necessary to test there own apps under low memory conditions, so it was deemed an "unfair" test...? I seem to recall hearing something like that :)

great advice... thanks again.

great advice... thanks again.