Next version will contain a new function (not method) named IEReadEXIFFromMOV.
It can extract EXIF from MOV created with FujiFilm cameras (the unique I found acceptable documentation) like the one you have sent me.
Here is source code of IEReadEXIFFromMOV:
function IEReadEXIFFromMOV(Stream: TStream; OutParams: TObject): boolean;
var
ms: TMemoryStream;
tp: dword;
sz: int64;
nm: integer;
nullpr: TProgressRec;
abort: boolean;
tempAlphaChannel: TIEMask;
TIFFHeader: TTIFFHeader;
ioparams: TIOParams;
function GetDWord():dword;
begin
Stream.Read(result, sizeof(dword));
result := IESwapDWord(result);
end;
function DWordToStr(dw:dword):string;
var
i: integer;
begin
result := '';
for i := 3 downto 0 do
result := result + chr(dw shr (i * 8) and $FF);
end;
function FindTag(tag:string):boolean;
begin
result := false;
while Stream.Position < Stream.Size do
begin
sz := GetDWord(); // get atom size
tp := GetDWord(); // get atom type
if sz = 0 then
sz := Stream.Size - Stream.Position
else if sz = 1 then
begin
// 64 bit size
sz := GetDWord();
sz := sz or (GetDWord() shl 32);
end;
if DWordToStr(tp) = tag then
begin
result := true;
break;
end;
Stream.Seek(sz - 8, soCurrent);
end;
end;
begin
result := false;
if FindTag('moov') and FindTag('udta') and FindTag('MVTG') then
begin
ms := TMemoryStream.Create();
try
Stream.Seek(16, soCurrent);
ms.CopyFrom(Stream, sz - 8);
abort := false;
with nullpr do
begin
Aborting := @abort;
fOnProgress := nil;
Sender := nil;
end;
tempAlphaChannel := nil;
TIFFHeader.Id := $4949;
TIFFHeader.Ver := 42;
TIFFHeader.PosIFD := 0;
ms.Position := 0;
ioparams := OutParams as TIOParams;
TIFFReadStream(nil, ms, nm, ioparams, nullpr, true, tempAlphaChannel, true, true, false, true, @TIFFHeader);
result := true;
finally
ms.Free();
end;
end;
end;
However you have to modify also TIFFReadStream (in tiffilt.pas) to accept an extra optional parameter.
TIFFReadStream must be defined as:
procedure TIFFReadStream(Bitmap:TIEBitmap; Stream:TStream; var numi:integer; IOParams:TIOParams; var Progress:TProgressRec; Preview:boolean; var AlphaChannel:TIEMask; TranslateBase:boolean; IgnoreAlpha:boolean; IsExifThumb:boolean; IsEXIFData:boolean; ProvidedHeader: PTIFFHeader = nil);
Modify...
Stream.read(TIFFHeader, sizeof(TTIFFHeader));
...to...
if ProvidedHeader <> nil then
TIFFHeader := ProvidedHeader^
else
Stream.read(TIFFHeader, sizeof(TTIFFHeader));
And finally...
if PosIFD = 0 then
exit;
...to...
if (PosIFD = 0) and (ProvidedHeader = nil) then
exit;
Usage example:
var
fs: TFileStream;
begin
fs := TFileStream.Create('c:\tempworks\DSCF1261.MOV', fmOpenRead);
try
IEReadEXIFFromMOV(fs, ImageEnView1.IO.Params);
memo1.lines.add('EXIF_Make = '+ImageEnView1.io.params.EXIF_Make);
memo1.lines.add('EXIF_Model = '+ImageEnView1.IO.Params.EXIF_Model);
memo1.lines.add('EXIF_DateTime = '+ImageEnView1.IO.Params.EXIF_DateTime);
finally
fs.Free();
end;
end;