The memory usage does not come from the JPEG library, but in the way you use it.
If you convert a JPEG into a TBitmap, it will create a bitmap resource, then uncompress the JPEG into the bitmap memory buffer.
You can paint directly from the JPEG content into the screen. Depending on the JPEG implementation, it will use (or not) a temporary TBitmap
.
You are not tied to the JPEG unit supplied by Borland.
For instance, you may try calling directly the StretchDIBits()
windows API from the uncompressed memory buffer, as such (this code is extracted from our SSE JPEG decoder):
procedure TJpegDecode.DrawTo(Canvas: TCanvas; X, Y: integer);
var BMI: TBitmapInfo;
begin
if @self=nil then
exit;
ToBMI(BMI);
StretchDIBits(Canvas.Handle,X,Y,width,height,0,0,width,height,pRGB,
BMI,DIB_RGB_COLORS,SrcCopy);
end;
Creating a huge bitmap is sometimes not possible (at least under Windows XP), because it uses shared GDI resources, whereas using plain RAM and StretchDIBits
will always work, even for huge content. You can create a memory mapped file to handle the binary content, but just allocating the memory at once would suffice (and Windows will use hard drive only if short of RAM). With today's PCs, you should have enough RAM available even for big pictures. (17 MB is not a big deal, even for your 3264x1840 pix).
Then, from this global uncompressed memory buffer containing raw pixel triplets, you can use
a smaller bitmap corresponding to a region of the picture, then work on the region using StretchDIBits(aBitmap.Handle,...
. It will use less GDI resource.
You could also rely for instance on GDI+ drawing, which will draw it without any temporary bitmap. See e.g. this OpenSource unit. From our testing, it's very fast and can be used without any TBitmap
. You could also ask only for a region of the whole picture, and draw it using GDI+ on your bitmap canvas: this will use less RAM. And your exe will be a bit smaller than the default JPEG unit. And you'll be able to display and save not only JPEG, but GIF and TIFF formats.
If you want to minimize even further the memory usage, you'll have to call directly the JPEG library, at lowest-level. It's able to uncompress only a region of the JPEG. So you would be able to minimize used RAM. You may try using the IJL library with Delphi, a bit old, but still working.