Seems to be a popular topic because I have a similar unit for fpspreadsheet (
https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/fpspreadsheet/source/common/fpsimages.pas). Only later I noticed that the format checks are already available in each fpc installation: The folder packages/fcl-image/src contains the units needed by the fcl graphics routines, including the reader and writer units for all graphics format. Each file format has dedicated reader and writer units with corresponding classes. It is an elemental requirement for each reader that it must be able to detect the graphics format from the file (or stream) header, without relying on a file extension. The reader method for this purpose is called "CheckContents", works on the image stream and returns true if the typical signature of the file format is found. When the reader unit of a file format is added to the uses clause of your application the unit is registered in an internal image handler list along with related data, among them the name of the graphic format. TFPCustomImage, the elemental image class of fcl-image, has a method FindHandlerFromStream which scans over all registered image handlers and calls the CheckContents method of each reader class. This way TFPCustomImage can determine the graphics format from the stream header.
Luckily all this is accessible to us, and knowing this (after some study in the fcl-image source) your program shrinks to a few lines. All you have to do is to add the reader units of all formats that you want to check to the uses clause:
uses
...
fpImage,
// what follows are the reader units available in fcl-image
fpReadBMP, fpReadGIF, fpReadPNG, fpReadPSD, fpReadJPEG, fpReadTIFF, fpReadPCX,
fpReadPNM, fpReadTGA, fpReadXPM, fpReadXWD;
function GetImageType(AStream: TStream): String;
var
handlerData: TIHData;
begin
handlerData := TFPCustomImage.FindHandlerFromStream(AStream);
if handlerData = nil then
Result := 'Format not detected'
else
Result := handlerData.TypeName;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
stream: TFileStream;
begin
stream := TFileStream.Create(FILE_NAME, fmOpenRead);
try
ShowMessage(GetImageType(stream));
finally
stream.Free;
end;
end;
Of course, this cannot replace the detection of audo or video files - for these, your code is still required.