I try to implement a wrapper around this jpeg decoder library (original by Arnaud Bouchez). The library is DAMN fast but it does not support all jpegs!
For very large jpg files it fails (as expected) with a EOutOfResources exception.
So I try to silently skip those files. It works, but when I close the app, FastMM indicates a memory leak.
function FastJpgDecode(FileName: string; OUT ErrorType: string): TBitmap;
var Img: PJpegDecode;
res: TJpegDecodeError;
Stream: TMemoryStream;
begin
Result:= NIL;
Stream:= TMemoryStream.Create;
TRY
if Length(FileName) > MAX_PATH then { TMemoryStream does not support long paths }
begin
ErrorType:= 'File name too long!';
Exit;
end;
Stream.LoadFromFile(FileName);
Stream.Position:= 0;
res:= JpegDecode(Stream.Memory, Stream.Size, Img);
case res of
JPEG_SUCCESS:
begin
try
Result:= Img.ToBitmap; // This will raise an EOutOfResources for large files!
except
on EOutOfResources do
ErrorType:= 'JPEG_OUTOFMEM!';
end;
end;
JPEG_EOF : ErrorType:= 'JPEG_EOF!';
JPEG_OUTOFMEM : ErrorType:= 'JPEG_OUTOFMEM!';
JPEG_CPUNOTSUPPORTED : ErrorType:= 'JPEG_CPUNOTSUPPORTED!';
JPEG_BADFILE : ErrorType:= 'JPEG_BADFILE!';
JPEG_FORMATNOTSUPPORTED : ErrorType:= 'JPEG_FORMATNOTSUPPORTED!'; // Not all jpegs are supported. In this case we fall back to WIC or the standard LoadGraph loader (WIC).
end;
FINALLY
Img.Free;
Stream.Free;
END;
end;
function TJpegDecode.ToBitmap: TBitmap;
begin
if @self=nil
then result := nil
else
begin
result := TBitmap.Create;
try
if not ToBitmap(result) // This will raise an EOutOfResources for large files!
then FreeAndNil(result);
except
FreeAndNil(Result);
raise;
end;
end;
end;
A memory block has been leaked. The size is: 36
This block was allocated by thread 0xD0C, and the stack trace (return addresses) at the time was: 407246 40830F 408ADE 43231B [Unknown function at __dbk_fcall_wrapper] 407246 40A532 53C353 [Unknown function at TMethodImplementationIntercept] 6E006F [Unknown function at TMethodImplementationIntercept] 7765648F [RtlNtStatusToDosError] 77656494 [RtlNtStatusToDosError] 767A7BEA [Unknown function at IsNLSDefinedString]
The block is currently used for an object of class: EOutOfResources The allocation number is: 4181
Current memory dump of 256 bytes starting at pointer address 7EEEA6C0: 74 7F............ t D . ü $ ú ......
A memory block has been leaked. The size is: 132
This block was allocated by thread 0xD0C, and the stack trace (return addresses) at the time was: 407246 40A2E7 40A518 53C341 [Unknown function at TMethodImplementationIntercept] 6E006F [Unknown function at TMethodImplementationIntercept] 7765648F [RtlNtStatusToDosError] 77656494 [RtlNtStatusToDosError] 767A7BEA [Unknown function at IsNLSDefinedString] 7677F0BA [VirtualQueryEx] 7677F177 [VirtualQuery] 898FD9 [GetFrameBasedStackTrace]The block is currently used for an object of class: UnicodeString
The allocation number is: 4180
Current memory dump of 256 bytes starting at pointer address 7EFA24F0: B0 04 02 00 01 00 00 00......... . . . . . . . : . . . Not . . enough storage . . i . s . . a . v . a . i . l . a . b . l . e . . t . o . . p . r . o . c . e . s . s . . t . h . i . s . . c . o . m . m . a . n . d ............
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):
21 - 36 bytes: EOutOfResources x 1 117 - 132 bytes: UnicodeString x 1
Why does it leak memory there?