Fast JPEG decoder using SSE/SSE2
This LGPL-distributed unit allows very fast JPEG image decoding, using SSE/SSE2 pure assembly code. It is much faster than the standard jpeg.pas unit.
It's based on the great Dr. Manhattan's source code, from http://sourceforge.net/projects/jpegdec
Most of the hack was to include the SSE/SSE2 assembly code into a true Delphi unit. Conversion was made difficult because the Delphi compiler doesn't allow to align code or data at 16 bytes boundaries, which is required by the SSE/SSE2 operations. This is a well known limitation of the Delphi compiler. See http://qc.embarcadero.com/wc/qcmain.aspx?d=1116
A solution was found by copying the whole used tables into memory-allocated buffer, and by creating the TBL_64 table by code. See JpegDecode() function for the hack.
Some modifications was made to the original code, in order to use these tables from memory, and to allow floating point usage (by adding the emms operation) after decode.
Since we use Win32 VirtualAlloc API for memory allocation (which is always 16 bytes aligned and set to zero, as expected by the code), the TJpegDecode object instance has a not-common creator, as the JpegDecode() function: don't try allocate any TJpegDecode object on the stack or via Delphi heap, but use this JpegDecode() function to allocate a PJpegDecode pointer, which will be freed by its Free method.
There is no TPicture descendent implementation yet, since it should be more usefull to use a resulting TBitmap in your code.
Direct access to the picture bitmap without creating any TBitmap resource is allowed via the TJpegDecode.DrawTo() methods: so you can use very big pictures, without any resource limitations (under Win 2K or XP, allocating big TBitmap instances raises errors)
Decoding is not thread safe by now; if you really need it, please ask.
There is no save method in this unit: it's a fast decoder, not an encoder.
Tested under Delphi 7 and 2009. Should need at least Delphi 7, for the SSE2 instruction set in the asm part.
function JpegDecode(Buffer: pointer; BufferLen: integer): TBitmap; overload;
function JpegDecode(Buffer: pointer; BufferLen: cardinal; var pImg: PJpegDecode): TJpegDecodeError; overload;
procedure JpegDraw(Buffer: pointer; BufferLen: integer; Canvas: TCanvas; X,Y: integer); var pImg: PJpegDecode; begin if JpegDecode(Buffer,BufferLen,pImg)=JPEG_SUCCESS then try pImg^.DrawTo(Canvas,X,Y); finally pImg^.Free; end; end;