Page 1 of 1

Java applet w/ large data sets

Posted: 2007-05-07 09:23pm
by Pu-239
I'm writing a java applet (for fun, will post link when it's reasonably done, it's yet another network painting thing), and I'm running into the memory size limits allocated to java applets (by default 64 megs or so). The applet is supposed to be an editor for images. The problem is when one loads large images (2400x1800), I hit the memory limit after the user creates and uses about 2-3 fully filled layers. I've already implemented some kind of tiling mechanism to only use RAM for parts of the layers that are actually drawn on, but that only prolongs the inevitable.

Is there any way to allow more data to be stored w/o sending it back to the server, other than having the user change applet settings or using signed applets? I'm not sure I can page to disk using a temporary file for unused tiles due to applet securtiy restrictions. Also, will signed applets get around the RAM restriction, or only the disk access one?

Posted: 2007-05-07 09:38pm
by Starglider
It's browser dependent but basically no, the only way to avoid the problem is to get the user to change their browser's Java settings. Are you making this an applet as a personal challenge or is there some other reason why it can't run as a local app?

Posted: 2007-05-07 09:49pm
by Pu-239
Friends who are going to use it don't want it running as a local app for various reasons (too lazy to download, hassle on public computers, some people have restrictions on running random apps from the internet, etc).

Posted: 2007-05-07 10:21pm
by Starglider
If the images are low complexity (i.e. drawings) then fast simple compression (i.e. run length encoding) should massively reduce the layer size without slowing things down much. If you're compositing photographic images, that won't help, so I guess your only option (if you're stuck with the memory limit) is to reduce the pixel depth. Make sure you're not using 32-bit buffers if you're not actually using the alpha channel, and consider dropping to 16-bit colour.

Posted: 2007-05-07 10:31pm
by Beowulf
Another idea is to make a vector based image editor as opposed to a raster based one. There's relatively little point in editing a raster image that's multimegapixel in size if you aren't editing photos anyway.

Posted: 2007-05-07 11:20pm
by Pu-239
Hrm, well, it looks like it'd be acceptable to have the user change memory limits. Still, any reduction in memory footprint is good.
Starglider wrote:If the images are low complexity (i.e. drawings) then fast simple compression (i.e. run length encoding) should massively reduce the layer size without slowing things down much. If you're compositing photographic images, that won't help, so I guess your only option (if you're stuck with the memory limit) is to reduce the pixel depth. Make sure you're not using 32-bit buffers if you're not actually using the alpha channel, and consider dropping to 16-bit colour.
I'm unfortunately actually using the alpha channel, so 16 bit doesn't seem to be an option. Compressing the unused tiles using a fast algorithm does seem to be a good idea, which I'll probably use if I find 256MB to be insufficient, or if someone complains about needing to run it on an older machine. It is a better solution than telling someone to change their settings, although I lose the guarantee that the applet will run out of heap space and crash (i.e., in the unlikely event all the tiles on several layers are flagged as in-use and decompressed in quick succession before the tile compressing routine has a chance to act). For some reason was under the impression images in use had to be uncompressed, forgot I implemented some kind of tiling mechanism already. Thanks!
Beowulf wrote: Another idea is to make a vector based image editor as opposed to a raster based one. There's relatively little point in editing a raster image that's multimegapixel in size if you aren't editing photos anyway.
Well, the idea is multiple people are editing the same canvas and there should be enough space so each person's artwork doesn't clobber each other. In addition, it would be somewhat annoying/difficult to implement smearing/blurring/etc on a vector image.

Posted: 2007-05-07 11:47pm
by Starglider
Pu-239 wrote:I'm unfortunately actually using the alpha channel, so 16 bit doesn't seem to be an option.
Can you get away with 1-5-5-5 binary alpha, or are you doing per-pixel alpha blending? Can you store the alpha blend operations (only) as gradient-filled vector shapes? I actually wrote a little image manipulation app that worked that way back in 1998 - it was more convenient to manipulate than trying to paint the alpha channel with bitmap oriented tools.
For some reason was under the impression images in use had to be uncompressed, forgot I implemented some kind of tiling mechanism already. Thanks!
If you're still using the Java imaging API to perform these ops you might have to dump it and write your own compositer rendering to a BufferedImage output (make sure double buffering is turned off on the output canvas if you're using Swing - it has a nasty tendency to waste memory on double buffering things that don't need to be double buffered).

Posted: 2007-05-09 06:33am
by Pu-239
Starglider wrote:
Pu-239 wrote:I'm unfortunately actually using the alpha channel, so 16 bit doesn't seem to be an option.
Can you get away with 1-5-5-5 binary alpha, or are you doing per-pixel alpha blending? Can you store the alpha blend operations (only) as gradient-filled vector shapes? I actually wrote a little image manipulation app that worked that way back in 1998 - it was more convenient to manipulate than trying to paint the alpha channel with bitmap oriented tools.
For some reason was under the impression images in use had to be uncompressed, forgot I implemented some kind of tiling mechanism already. Thanks!
If you're still using the Java imaging API to perform these ops you might have to dump it and write your own compositer rendering to a BufferedImage output (make sure double buffering is turned off on the output canvas if you're using Swing - it has a nasty tendency to waste memory on double buffering things that don't need to be double buffered).
Well, it's a drawing app, so yeah, need to use alpha blending. Cost/benefit of implementing a seperate raster for alpha + one for color doesn't seem worth it (already then at 16+8=24bpp- vector just isn't as smooth (and would be a pain to work w/ if the user wants to smear the drawing, etc etc (Yes, I could store the user's drawing procedures, but then the performance of having to redraw the vector graphics when layers are disabled/swapped/etc comes into play- it'd have to be stored as a bitmap in RAM I think for sufficient performance).

Not going to reimplement BufferedImage, since I think the tiling should be sufficient- I'm wrapping the arrays of BufferedImage tiles in the layer class to abstract it away though, so it would be doable if there was a need (i.e. having the option to page to disk if user accepted signed applet). I'll try to see what disabling doublebuffering will give me - also should get significant memory savings if I kill the offscreen buffer and render directly from layers to panel, although I am concerned about performance.