fpexif: Fix some errors with various test images.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6090 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2017-12-06 22:12:10 +00:00
parent d4e1105bb9
commit 824c594816
10 changed files with 249 additions and 62 deletions

View File

@ -59,6 +59,11 @@
<Debugging> <Debugging>
<UseExternalDbgSyms Value="True"/> <UseExternalDbgSyms Value="True"/>
</Debugging> </Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking> </Linking>
</CompilerOptions> </CompilerOptions>
<Debugging> <Debugging>

View File

@ -89,37 +89,6 @@ object MainForm: TMainForm
ClientHeight = 691 ClientHeight = 691
ClientWidth = 647 ClientWidth = 647
TabOrder = 2 TabOrder = 2
object TagListView: TListView
Left = 0
Height = 668
Top = 23
Width = 647
Align = alClient
AutoSort = False
Columns = <
item
Caption = 'Group'
Width = 120
end
item
Caption = 'Property'
Width = 220
end
item
AutoSize = True
Caption = 'Value'
Width = 44
end>
HideSelection = False
ReadOnly = True
RowSelect = True
SortColumn = 0
SortType = stText
TabOrder = 0
ViewStyle = vsReport
OnCompare = TagListViewCompare
OnSelectItem = TagListViewSelectItem
end
object Panel3: TPanel object Panel3: TPanel
Left = 0 Left = 0
Height = 23 Height = 23
@ -131,7 +100,7 @@ object MainForm: TMainForm
BorderWidth = 4 BorderWidth = 4
ClientHeight = 23 ClientHeight = 23
ClientWidth = 647 ClientWidth = 647
TabOrder = 1 TabOrder = 0
object FilenameInfo: TLabel object FilenameInfo: TLabel
Left = 4 Left = 4
Height = 15 Height = 15
@ -141,6 +110,112 @@ object MainForm: TMainForm
ParentColor = False ParentColor = False
end end
end end
object PageControl1: TPageControl
Left = 0
Height = 573
Top = 23
Width = 647
ActivePage = PgImage
Align = alClient
TabIndex = 1
TabOrder = 1
OnChange = PageControl1Change
object PgMetadata: TTabSheet
Caption = 'Meta data'
ClientHeight = 640
ClientWidth = 639
object TagListView: TListView
Left = 0
Height = 640
Top = 0
Width = 639
Align = alClient
AutoSort = False
Columns = <
item
Caption = 'Group'
Width = 120
end
item
Caption = 'Property'
Width = 220
end
item
AutoSize = True
Caption = 'Value'
Width = 44
end>
HideSelection = False
ReadOnly = True
RowSelect = True
SortColumn = 0
SortType = stText
TabOrder = 0
ViewStyle = vsReport
OnCompare = TagListViewCompare
OnSelectItem = TagListViewSelectItem
end
end
object PgImage: TTabSheet
Caption = 'Image'
ClientHeight = 545
ClientWidth = 639
object Image: TImage
Left = 0
Height = 517
Top = 0
Width = 639
Align = alClient
Center = True
Proportional = True
Stretch = True
StretchOutEnabled = False
end
object Panel1: TPanel
Left = 0
Height = 28
Top = 517
Width = 639
Align = alBottom
AutoSize = True
BevelOuter = bvNone
ClientHeight = 28
ClientWidth = 639
TabOrder = 0
Visible = False
object CheckBox1: TCheckBox
AnchorSideLeft.Control = Panel1
AnchorSideTop.Control = Panel1
AnchorSideTop.Side = asrCenter
Left = 0
Height = 19
Top = 5
Width = 127
BorderSpacing.Top = 4
BorderSpacing.Bottom = 4
Caption = 'Decode MakerNotes'
TabOrder = 0
end
end
end
end
object Messages: TMemo
Left = 0
Height = 90
Top = 596
Width = 647
Align = alBottom
TabOrder = 2
end
object Splitter3: TSplitter
Cursor = crVSplit
Left = 0
Height = 5
Top = 686
Width = 647
Align = alBottom
ResizeAnchor = akBottom
end
end end
object StatusBar1: TStatusBar object StatusBar1: TStatusBar
Left = 0 Left = 0

View File

@ -14,12 +14,20 @@ type
{ TMainForm } { TMainForm }
TMainForm = class(TForm) TMainForm = class(TForm)
CheckBox1: TCheckBox;
FilenameInfo: TLabel; FilenameInfo: TLabel;
Image: TImage;
Messages: TMemo;
PageControl1: TPageControl;
Panel1: TPanel;
Panel2: TPanel; Panel2: TPanel;
Panel3: TPanel; Panel3: TPanel;
PreviewImage: TImage; PreviewImage: TImage;
ImageList: TImageList; ImageList: TImageList;
Splitter3: TSplitter;
StatusBar1: TStatusBar; StatusBar1: TStatusBar;
PgMetadata: TTabSheet;
PgImage: TTabSheet;
TagListView: TListView; TagListView: TListView;
ShellPanel: TPanel; ShellPanel: TPanel;
ShellListView: TShellListView; ShellListView: TShellListView;
@ -28,6 +36,7 @@ type
Splitter2: TSplitter; Splitter2: TSplitter;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject); procedure FormDestroy(Sender: TObject);
procedure PageControl1Change(Sender: TObject);
procedure ShellListViewSelectItem(Sender: TObject; Item: TListItem; procedure ShellListViewSelectItem(Sender: TObject; Item: TListItem;
Selected: Boolean); Selected: Boolean);
procedure ShellTreeViewGetImageIndex(Sender: TObject; Node: TTreeNode); procedure ShellTreeViewGetImageIndex(Sender: TObject; Node: TTreeNode);
@ -38,6 +47,7 @@ type
Selected: Boolean); Selected: Boolean);
private private
FImgInfo: TImgInfo; FImgInfo: TImgInfo;
FImageLoaded: Boolean;
procedure LoadFile(const AFileName: String); procedure LoadFile(const AFileName: String);
procedure LoadFromIni; procedure LoadFromIni;
procedure SaveToIni; procedure SaveToIni;
@ -94,6 +104,9 @@ var
i: Integer; i: Integer;
ms: TMemoryStream; ms: TMemoryStream;
begin begin
FImageLoaded := false;
Image.Picture.Clear;
TagListView.Items.BeginUpdate; TagListView.Items.BeginUpdate;
try try
TagListView.Clear; TagListView.Clear;
@ -102,9 +115,12 @@ begin
try try
try try
FImgInfo.LoadFromFile(AFileName); FImgInfo.LoadFromFile(AFileName);
Messages.Hide;
except except
on E:EFpExif do on E:EFpExif do begin
MessageDlg(E.Message, mtError, [mbOK], 0); Messages.Lines.Text := E.Message;
Messages.Show;
end;
end; end;
if FImgInfo.HasExif then begin if FImgInfo.HasExif then begin
FImgInfo.ExifData.ExportOptions := FImgInfo.ExifData.ExportOptions + [eoTruncateBinary]; FImgInfo.ExifData.ExportOptions := FImgInfo.ExifData.ExportOptions + [eoTruncateBinary];
@ -136,12 +152,24 @@ begin
finally finally
ms.Free; ms.Free;
end; end;
end else
PreviewImage.Picture.Clear;
if FImgInfo.HasWarnings then begin
Messages.Lines.Text := FImgInfo.Warnings;
Messages.Show;
end;
if PageControl1.ActivePage = PgImage then begin
Image.Picture.LoadfromFile(AFileName);
FImageLoaded := true;
end; end;
if FImgInfo.HasWarnings then
MessageDlg(FImgInfo.Warnings, mtWarning, [mbOK], 0);
except except
FreeAndNil(FImgInfo); on E:Exception do begin
raise; FreeAndNil(FImgInfo);
Messages.Lines.Text := E.Message;
Messages.Show;
end;
end; end;
UpdateCaption; UpdateCaption;
finally finally
@ -191,6 +219,17 @@ begin
end; end;
end; end;
procedure TMainForm.PageControl1Change(Sender: TObject);
begin
if FImgInfo = nil then
exit;
if not FImageLoaded then begin
Image.Picture.LoadfromFile(FImgInfo.FileName);
FImageLoaded := true;
end;
end;
procedure TMainForm.SaveToIni; procedure TMainForm.SaveToIni;
var var
ini: TCustomIniFile; ini: TCustomIniFile;

View File

@ -336,20 +336,22 @@ begin
ifdRec.DataCount := FixEndian32(ifdRec.DataCount); ifdRec.DataCount := FixEndian32(ifdRec.DataCount);
// ifRec.DataValue will be converted later. // ifRec.DataValue will be converted later.
byteCount := Integer(ifdRec.DataCount) * TagElementSize[ifdRec.DataType]; byteCount := Integer(ifdRec.DataCount) * TagElementSize[ifdRec.DataType];
SetLength(data, bytecount); if byteCount > 0 then begin
if byteCount <= 4 then SetLength(data, bytecount);
Move(ifdRec.DataValue, data[0], byteCount) if byteCount <= 4 then
else begin Move(ifdRec.DataValue, data[0], byteCount)
AStream.Position := FStartPosition + FixEndian32(ifdRec.DataValue); else begin
AStream.Read(data[0], byteCount); AStream.Position := FStartPosition + FixEndian32(ifdRec.DataValue);
end; AStream.Read(data[0], byteCount);
AddTag(AStream, ifdRec, data, AParent); end;
AddTag(AStream, ifdRec, data, AParent);
if ifdRec.DataType = ord(ttIFD) then begin if ifdRec.DataType = ord(ttIFD) then begin
newPos := FStartPosition + FixEndian32(ifdRec.DataValue); newPos := FStartPosition + FixEndian32(ifdRec.DataValue);
if newPos < AStream.Size then begin if newPos < AStream.Size then begin
AStream.Position := newPos; AStream.Position := newPos;
ReadIFD(AStream, ifdRec.TagID shl 16); ReadIFD(AStream, ifdRec.TagID shl 16);
end;
end; end;
end; end;

View File

@ -330,7 +330,8 @@ begin
AIdentifier := block.Identifier; AIdentifier := block.Identifier;
AName := block.Name; AName := block.Name;
SetLength(AData, Length(block.Data)); SetLength(AData, Length(block.Data));
Move(block.Data[0], AData[0], Length(AData)); if Length(block.Data) > 0 then
Move(block.Data[0], AData[0], Length(AData));
end; end;
function TIptcData.GetImageResourceBlockCount: Integer; function TIptcData.GetImageResourceBlockCount: Integer;
@ -580,7 +581,9 @@ procedure TIptcDateTag.SetAsString(const AValue: String);
var var
d: TDateTime; d: TDateTime;
fmt: String; fmt: String;
{$IFNDEF FPC}
fs: TFormatSettings; fs: TFormatSettings;
{$ENDIF}
begin begin
fmt := GetFormat; fmt := GetFormat;
if fmt = IPTC_DATE_FORMAT then if fmt = IPTC_DATE_FORMAT then
@ -642,7 +645,9 @@ procedure TIptcTimeTag.SetAsString(const AValue: String);
var var
t: TDateTime; t: TDateTime;
fmt: String; fmt: String;
{$IFNDEF FPC}
fs: TFormatSettings; fs: TFormatSettings;
{$ENDIF}
begin begin
fmt := GetFormat; fmt := GetFormat;
if fmt = IPTC_TIME_FORMAT then if fmt = IPTC_TIME_FORMAT then

View File

@ -118,7 +118,9 @@ var
tagID: TTagID; tagID: TTagID;
s: String; s: String;
w: Word; w: Word;
{$IFNDEF FPC}
sa: ansistring; sa: ansistring;
{$ENDIF}
begin begin
Result := nil; Result := nil;
@ -253,6 +255,9 @@ begin
AName := s; AName := s;
end; end;
lSize := BEToN(ReadDWord(AStream)); lSize := BEToN(ReadDWord(AStream));
if lSize = 0 then
exit;
SetLength(AData, lSize); SetLength(AData, lSize);
AStream.Read(AData[0], lSize); AStream.Read(AData[0], lSize);
end; end;

View File

@ -81,6 +81,9 @@ begin
// Put binary data into a word array and fix endianness // Put binary data into a word array and fix endianness
n := Length(AData) div TagElementSize[ord(tagDef.TagType)]; n := Length(AData) div TagElementSize[ord(tagDef.TagType)];
if n = 0 then
exit;
if FBigEndian then if FBigEndian then
for i:=0 to n-1 do AData[i] := BEtoN(AData[i]) for i:=0 to n-1 do AData[i] := BEtoN(AData[i])
else else
@ -94,58 +97,101 @@ begin
1: // Exposure Info 1 1: // Exposure Info 1
with FImgInfo.ExifData do begin with FImgInfo.ExifData do begin
AddMakerNoteTag(1, 1, 'Macro mode', w[1], rsCanonMacroLkup); AddMakerNoteTag(1, 1, 'Macro mode', w[1], rsCanonMacroLkup);
if n = 2 then exit;
AddMakerNoteTag(1, 2, 'Self-timer', w[2]/10, '%2:.1f s'); AddMakerNoteTag(1, 2, 'Self-timer', w[2]/10, '%2:.1f s');
if n = 3 then exit;
AddMakerNoteTag(1, 3, 'Quality', w[3], rsCanonQualityLkup); AddMakerNoteTag(1, 3, 'Quality', w[3], rsCanonQualityLkup);
if n = 4 then exit;
AddMakerNoteTag(1, 4, 'Flash mode', w[4], rsCanonFlashLkup); AddMakerNoteTag(1, 4, 'Flash mode', w[4], rsCanonFlashLkup);
if n = 5 then exit;
AddMakerNoteTag(1, 5, 'Drive mode', w[5], rsSingleContinuous); AddMakerNoteTag(1, 5, 'Drive mode', w[5], rsSingleContinuous);
if n = 7 then exit;
AddMakerNoteTag(1, 7, 'Focus mode', w[7], rsCanonFocusLkup); AddMakerNoteTag(1, 7, 'Focus mode', w[7], rsCanonFocusLkup);
if n = 9 then exit;
AddMakerNoteTag(1, 9, 'Record mode', w[9], rsCanonRecLkup); AddMakerNoteTag(1, 9, 'Record mode', w[9], rsCanonRecLkup);
if n = 10 then exit;
AddMakerNoteTag(1,10, 'Image size', w[10], rsCanonSizeLkup); AddMakerNoteTag(1,10, 'Image size', w[10], rsCanonSizeLkup);
if n = 11 then exit;
AddMakerNoteTag(1,11, 'Easy shoot', w[11], rsCanonEasyLkup); AddMakerNoteTag(1,11, 'Easy shoot', w[11], rsCanonEasyLkup);
if n = 12 then exit;
AddMakerNoteTag(1,12, 'Digital zoom', w[12], rsCanonZoomLkup); AddMakerNoteTag(1,12, 'Digital zoom', w[12], rsCanonZoomLkup);
if n = 13 then exit;
AddMakerNoteTag(1,13, 'Contrast', w[13], rsCanonGenLkup); AddMakerNoteTag(1,13, 'Contrast', w[13], rsCanonGenLkup);
if n = 14 then exit;
AddMakerNoteTag(1,14, 'Saturation', w[14], rsCanonGenLkup); AddMakerNoteTag(1,14, 'Saturation', w[14], rsCanonGenLkup);
if n = 15 then exit;
AddMakerNoteTag(1,15, 'Sharpness', w[15], rsCanonGenLkup); AddMakerNoteTag(1,15, 'Sharpness', w[15], rsCanonGenLkup);
if n = 16 then exit;
AddMakerNoteTag(1,16, 'CCD ISO', w[16], rsCanonISOLkup); AddMakerNoteTag(1,16, 'CCD ISO', w[16], rsCanonISOLkup);
if n = 17 then exit;
AddMakerNoteTag(1,17, 'Metering mode', w[17], rsCanonMeterLkup); AddMakerNoteTag(1,17, 'Metering mode', w[17], rsCanonMeterLkup);
if n = 18 then exit;
AddMakerNoteTag(1,18, 'Focus type', w[18], rsCanonFocTypeLkup); AddMakerNoteTag(1,18, 'Focus type', w[18], rsCanonFocTypeLkup);
AddMakerNoteTag(1,19, 'AFPoint', w[19], rsCanonAFLkup); if n = 19 then exit;
AddMakerNoteTag(1,19, 'AFPoint', w[19], rsCanonAFLkup);
if n = 20 then exit;
AddMakerNoteTag(1,20, 'Exposure mode', w[20], rsCanonExposeLkup); AddMakerNoteTag(1,20, 'Exposure mode', w[20], rsCanonExposeLkup);
if n = 24 then exit;
AddMakerNoteTag(1,24, 'Long focal', w[24]); AddMakerNoteTag(1,24, 'Long focal', w[24]);
if n = 25 then exit;
AddMakerNoteTag(1,25, 'Short focal', w[25]); AddMakerNoteTag(1,25, 'Short focal', w[25]);
if n = 26 then exit;
AddMakerNoteTag(1,26, 'Focal units', w[26]); AddMakerNoteTag(1,26, 'Focal units', w[26]);
if n = 28 then exit;
AddMakerNoteTag(1,28, 'Flash activity', w[28], rsCanonFlashActLkup); AddMakerNoteTag(1,28, 'Flash activity', w[28], rsCanonFlashActLkup);
if n = 29 then exit;
AddMakerNoteTag(1,29, 'Flash details', w[29]); AddMakerNoteTag(1,29, 'Flash details', w[29]);
if n = 32 then exit;
AddMakerNoteTag(1,32, 'Focus mode', w[32], rsSingleContinuous); AddMakerNoteTag(1,32, 'Focus mode', w[32], rsSingleContinuous);
AddMakerNoteTag(1,33, 'AESetting', w[33], rsCanonAELkup); if n = 33 then exit;
AddMakerNoteTag(1,33, 'AESetting', w[33], rsCanonAELkup);
if n = 34 then exit;
AddMakerNoteTag(1,34, 'Image stabilization', w[34], rsSingleContinuous); AddMakerNoteTag(1,34, 'Image stabilization', w[34], rsSingleContinuous);
end; end;
2: // Focal length 2: // Focal length
with FImgInfo.ExifData do begin with FImgInfo.ExifData do begin
AddMakerNoteTag(2, 0, 'FocalType', w[0], rsCanonFocalTypeLkup); AddMakerNoteTag(2, 0, 'FocalType', w[0], rsCanonFocalTypeLkup);
if n = 1 then exit;
AddMakerNoteTag(2, 1, 'FocalLength', w[1]); AddMakerNoteTag(2, 1, 'FocalLength', w[1]);
end; end;
4: // ExposureInfo2 4: // ExposureInfo2
with FImgInfo.ExifData do begin with FImgInfo.ExifData do begin
if n = 7 then exit;
AddMakerNoteTag(4, 7, 'WhiteBalance', w[7], rsCanonWhiteBalLkup); AddMakerNoteTag(4, 7, 'WhiteBalance', w[7], rsCanonWhiteBalLkup);
if n = 8 then exit;
AddMakerNoteTag(4, 8, 'Slow shutter', w[8], rsCanonSloShuttLkup); AddMakerNoteTag(4, 8, 'Slow shutter', w[8], rsCanonSloShuttLkup);
if n = 9 then exit;
AddMakerNoteTag(4, 9, 'SequenceNumber', w[9]); AddMakerNoteTag(4, 9, 'SequenceNumber', w[9]);
if n = 11 then exit;
AddMakerNoteTag(4,11, 'OpticalZoomStep', w[11]); AddMakerNoteTag(4,11, 'OpticalZoomStep', w[11]);
if n = 12 then exit;
AddMakerNoteTag(4,12, 'Camera temperature', w[12]); AddMakerNoteTag(4,12, 'Camera temperature', w[12]);
AddMakerNoteTag(4,14, 'AFPoint', w[14]); if n = 14 then exit;
AddMakerNoteTag(4,14, 'AFPoint', w[14]);
if n = 15 then exit;
AddMakerNoteTag(4,15, 'FlashBias', w[15], rsCanonBiasLkup); AddMakerNoteTag(4,15, 'FlashBias', w[15], rsCanonBiasLkup);
if n = 19 then exit;
AddMakerNoteTag(4,19, 'Distance', w[19]); AddMakerNoteTag(4,19, 'Distance', w[19]);
if n = 21 then exit;
AddMakerNoteTag(4,21, 'FNumber', w[21]); AddMakerNoteTag(4,21, 'FNumber', w[21]);
if n = 22 then exit;
AddMakerNoteTag(4,22, 'Exposure time', w[22]); AddMakerNoteTag(4,22, 'Exposure time', w[22]);
if n = 23 then exit;
AddMakerNoteTag(4,23, 'Measured EV2', w[23]); AddMakerNoteTag(4,23, 'Measured EV2', w[23]);
if n = 24 then exit;
AddMakerNoteTag(4,24, 'Bulb duration', w[24]); AddMakerNoteTag(4,24, 'Bulb duration', w[24]);
if n = 26 then exit;
AddMakerNoteTag(4,26, 'Camera type', w[26], rsCanonCamTypeLkup); AddMakerNoteTag(4,26, 'Camera type', w[26], rsCanonCamTypeLkup);
if n = 27 then exit;
AddMakerNoteTag(4,27, 'Auto rotation', w[27], rsCanonAutoRotLkup); AddMakerNoteTag(4,27, 'Auto rotation', w[27], rsCanonAutoRotLkup);
if n = 28 then exit;
AddMakerNoteTag(4,28, 'NDFilter', w[28], rsCanonGenLkup); AddMakerNoteTag(4,28, 'NDFilter', w[28], rsCanonGenLkup);
end; end;
5: // Panorma 5: // Panorma
with FImgInfo.ExifData do begin with FImgInfo.ExifData do begin
if n = 2 then exit;
AddMakerNoteTag(5, 2, 'Panorama frame number', w[2]); AddMakerNoteTag(5, 2, 'Panorama frame number', w[2]);
if n = 5 then exit;
AddMakerNoteTag(5, 5, 'Panorama direction', w[5], rsCanonPanDirLkup); AddMakerNoteTag(5, 5, 'Panorama direction', w[5], rsCanonPanDirLkup);
end; end;
end; end;

View File

@ -639,7 +639,9 @@ const
var var
jfifSegment: TJpegJFIFSegment; jfifSegment: TJpegJFIFSegment;
writer: TBasicMetadataWriter; writer: TBasicMetadataWriter;
{$IFNDEF FPC}
sa: ansistring; sa: ansistring;
{$ENDIF}
begin begin
// Write Start-of-image segment (SOI) // Write Start-of-image segment (SOI)
AStream.WriteBuffer(SOI_MARKER, SizeOf(SOI_MARKER)); AStream.WriteBuffer(SOI_MARKER, SizeOf(SOI_MARKER));

View File

@ -818,9 +818,10 @@ var
len: Integer; len: Integer;
begin begin
len := Length(AValue); len := Length(AValue);
FCount := len div TagElementSize[ord(FType)];
SetLength(FRawData, len); SetLength(FRawData, len);
Move(AValue[0], FRawData[0], len); if len > 0 then
Move(AValue[0], FRawData[0], len);
FCount := len div TagElementSize[ord(FType)];
end; end;
procedure TTag.SetTruncBinary(const AValue: Boolean); procedure TTag.SetTruncBinary(const AValue: Boolean);
@ -1225,11 +1226,13 @@ var
r: TExifRational; r: TExifRational;
begin begin
Result := GetRational(AIndex, r); Result := GetRational(AIndex, r);
if Result then begin if Result and (r.Denominator <> 0) then
begin
AValue := r.Numerator / r.Denominator; AValue := r.Numerator / r.Denominator;
if IsInt(AValue) then if IsInt(AValue) then
AValue := Round(AValue); AValue := Round(AValue);
end; end else
Result := false;
end; end;
function TFloatTag.GetRational(AIndex: Integer; out AValue: TExifRational): Boolean; function TFloatTag.GetRational(AIndex: Integer; out AValue: TExifRational): Boolean;
@ -1457,6 +1460,9 @@ begin
// Not sure what Delphi does when a unicodestring is put into FValue. // Not sure what Delphi does when a unicodestring is put into FValue.
Result := ''; Result := '';
if Length(FRawData) = 0 then
exit;
SetLength(sa, Length(FRawData)); SetLength(sa, Length(FRawData));
Move(FRawData[0], sa[1], Length(FRawData)); Move(FRawData[0], sa[1], Length(FRawData));
while (sa <> '') and (sa[Length(sa)] = #0) do while (sa <> '') and (sa[Length(sa)] = #0) do
@ -1472,9 +1478,10 @@ procedure TStringTag.SetAsString(const AValue: String);
var var
sa: Ansistring; sa: Ansistring;
begin begin
if AValue = '' then if AValue = '' then begin
SetLength(FRawData, 0) SetLength(FRawData, 0);
else FCount := 0;
end else
begin begin
sa := ansistring(AValue); sa := ansistring(AValue);
FCount := Length(sa); FCount := Length(sa);

View File

@ -28,6 +28,7 @@ Some examples in which fpexif can be applied:
in foreign countries) in foreign countries)
- adding GPS information to scanned photographs - adding GPS information to scanned photographs
- remember exposure settings of difficult photos - remember exposure settings of difficult photos
- extract thumbnails for a super-fast thumbnail viewer
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------