// Example of how to verify JPEG Sentinels (first two bytes and last two // bytes) are OK. This avoids JPEG error #52. If JPEG was truncted, or // neverly completely written to disk, the JPEGSentinelsAreOK function will // return FALSE. // // efg, March 2001, www.efg2.com/Lab unit ScreenJPEGSentinels; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TFormJPGSentinels = class(TForm) ButtonLoadImage: TButton; Image: TImage; OpenDialog: TOpenDialog; LabelFilename: TLabel; procedure ButtonLoadImageClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var FormJPGSentinels: TFormJPGSentinels; implementation {$R *.DFM} USES JPEG; // Avoid JPEG Error #52: // Verify first two bytes of JPEG are $FFD8 (little endian $D8FF) // Verify last two bytes of JPEG are $FFD9 (little endian $D9FF) FUNCTION JPEGSentinelsAreOK(CONST Filename: TFilename): BOOLEAN; VAR FileStream: TFileStream; w1 : WORD; // a "word" is always 2 bytes long w2 : WORD; BEGIN ASSERT(SizeOf(WORD) = 2); RESULT := FileExists(Filename); IF RESULT THEN BEGIN FileStream := TFileStream.Create(Filename, fmOpenRead OR fmShareDenyNone); TRY FileStream.Seek(0, soFromBeginning); // use seek or position FileStream.Read(w1,2); FileStream.Position := FileStream.Size - 2; FileStream.Read(w2,2) FINALLY FileStream.Free END; RESULT := (w1 = $D8FF) AND (w2 = $D9FF); END END; procedure TFormJPGSentinels.ButtonLoadImageClick(Sender: TObject); VAR JPEGImage: TJPEGImage; begin IF OpenDialog.Execute THEN BEGIN IF JPEGSentinelsAreOK(OpenDialog.Filename) THEN BEGIN JPEGImage := TJPEGImage.Create; TRY JPEGImage.LoadFromFile(OpenDialog.Filename); Image.Picture.Graphic := JPEGImage; LabelFilename.Caption := OpenDialog.Filename FINALLY JPEGImage.Free END END ELSE BEGIN Image.Picture.Graphic := NIL; LabelFilename.Caption := 'Invalid JPEG: ' + OpenDialog.Filename END END end; end.