You've already forked lazarus-ccr
fpexif: Delphi support for XMP metadata.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9012 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -10,11 +10,9 @@ object MainForm: TMainForm
|
||||
Font.Height = -11
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
OldCreateOrder = True
|
||||
ShowHint = True
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object Splitter2: TSplitter
|
||||
Left = 274
|
||||
@ -181,7 +179,7 @@ object MainForm: TMainForm
|
||||
Top = 21
|
||||
Width = 647
|
||||
Height = 550
|
||||
ActivePage = PgMetadata
|
||||
ActivePage = PgXMP
|
||||
Align = alClient
|
||||
TabOrder = 1
|
||||
OnChange = PageControl1Change
|
||||
@ -241,6 +239,87 @@ object MainForm: TMainForm
|
||||
end
|
||||
end
|
||||
end
|
||||
object PgXMP: TTabSheet
|
||||
Caption = 'XMP'
|
||||
ImageIndex = 2
|
||||
object Splitter4: TSplitter
|
||||
Left = 0
|
||||
Top = 150
|
||||
Width = 639
|
||||
Height = 3
|
||||
Cursor = crVSplit
|
||||
Align = alTop
|
||||
end
|
||||
object XMPListView: TListView
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 639
|
||||
Height = 150
|
||||
Align = alTop
|
||||
Columns = <
|
||||
item
|
||||
Caption = 'Description'
|
||||
Width = 200
|
||||
end
|
||||
item
|
||||
Caption = 'Value'
|
||||
Width = 200
|
||||
end>
|
||||
TabOrder = 0
|
||||
ViewStyle = vsReport
|
||||
end
|
||||
object XMPSynEdit: TMemo
|
||||
Left = 0
|
||||
Top = 153
|
||||
Width = 639
|
||||
Height = 335
|
||||
Align = alClient
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Courier New'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
TabOrder = 1
|
||||
end
|
||||
object Panel6: TPanel
|
||||
Left = 0
|
||||
Top = 488
|
||||
Width = 639
|
||||
Height = 34
|
||||
Align = alBottom
|
||||
BevelOuter = bvNone
|
||||
TabOrder = 2
|
||||
object cbProcessXMP: TCheckBox
|
||||
Left = 8
|
||||
Top = 8
|
||||
Width = 129
|
||||
Height = 17
|
||||
Caption = 'Load && display XMP'
|
||||
Checked = True
|
||||
State = cbChecked
|
||||
TabOrder = 0
|
||||
end
|
||||
object btnApplyChangesXMP: TButton
|
||||
Left = 143
|
||||
Top = 7
|
||||
Width = 98
|
||||
Height = 25
|
||||
Caption = 'Apply changes'
|
||||
TabOrder = 1
|
||||
OnClick = btnApplyChangesXMPClick
|
||||
end
|
||||
object btnSaveXMP: TButton
|
||||
Left = 247
|
||||
Top = 7
|
||||
Width = 75
|
||||
Height = 25
|
||||
Caption = 'Save'
|
||||
TabOrder = 2
|
||||
OnClick = btnSaveXMPClick
|
||||
end
|
||||
end
|
||||
end
|
||||
object PgImage: TTabSheet
|
||||
Caption = 'Image'
|
||||
object Image: TImage
|
||||
|
@ -1,8 +1,8 @@
|
||||
unit mdvMain;
|
||||
|
||||
{$IFDEF FPC}
|
||||
!!! THIS PROGRAM IS INTENDED FOR DELPHI ONLY
|
||||
{$ENDIF}
|
||||
!!! THIS PROGRAM IS INTENDED FOR DELPHI ONLY !!!
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
@ -44,6 +44,14 @@ type
|
||||
Splitter2: TSplitter;
|
||||
DriveComboBox1: TDriveComboBox;
|
||||
Panel5: TPanel;
|
||||
PgXMP: TTabSheet;
|
||||
XMPListView: TListView;
|
||||
Splitter4: TSplitter;
|
||||
XMPSynEdit: TMemo;
|
||||
Panel6: TPanel;
|
||||
cbProcessXMP: TCheckBox;
|
||||
btnApplyChangesXMP: TButton;
|
||||
btnSaveXMP: TButton;
|
||||
procedure BtnChangeDateClick(Sender: TObject);
|
||||
procedure CbShowTagIDsChange(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
@ -63,6 +71,8 @@ type
|
||||
procedure ShellListViewChange(Sender: TObject);
|
||||
procedure DriveComboBox1Change(Sender: TObject);
|
||||
procedure Panel5Resize(Sender: TObject);
|
||||
procedure btnApplyChangesXMPClick(Sender: TObject);
|
||||
procedure btnSaveXMPClick(Sender: TObject);
|
||||
private
|
||||
FFileName: String;
|
||||
FImgInfo: TImgInfo;
|
||||
@ -70,6 +80,7 @@ type
|
||||
FImageOrientation: TExifOrientation;
|
||||
procedure LoadFile(const AFileName: String);
|
||||
procedure LoadFromIni;
|
||||
procedure LoadXMPTags;
|
||||
procedure SaveToIni;
|
||||
procedure UpdateCaption;
|
||||
|
||||
@ -194,6 +205,24 @@ begin
|
||||
//ShellListView.Parent.DoubleBuffered := true;
|
||||
end;
|
||||
|
||||
procedure TMainForm.btnApplyChangesXMPClick(Sender: TObject);
|
||||
var
|
||||
ms: TMemoryStream;
|
||||
begin
|
||||
if Assigned(FImgInfo) and FImgInfo.HasXMP then
|
||||
begin
|
||||
ms := TMemoryStream.Create;
|
||||
try
|
||||
XMPSynEdit.Lines.SaveToStream(ms);
|
||||
ms.Position := 0;
|
||||
FImgInfo.XMPData.LoadFromStream(ms);
|
||||
LoadXMPTags;
|
||||
finally
|
||||
ms.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.BtnChangeDateClick(Sender: TObject);
|
||||
var
|
||||
lTag: TTag;
|
||||
@ -225,6 +254,19 @@ begin
|
||||
FImgInfo.SaveToFile(fn);
|
||||
end;
|
||||
|
||||
procedure TMainForm.btnSaveXMPClick(Sender: TObject);
|
||||
var
|
||||
fn: String;
|
||||
begin
|
||||
if Assigned(FImgInfo) then
|
||||
begin
|
||||
fn := FImgInfo.FileName;
|
||||
fn := ChangeFileExt(fn, '') + '_modified' + ExtractFileExt(fn);
|
||||
FImgInfo.SaveToFile(fn);
|
||||
ShowMessage('Modified image saved as ' + fn);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.CbShowTagIDsChange(Sender: TObject);
|
||||
var
|
||||
c: TListColumn;
|
||||
@ -290,6 +332,10 @@ begin
|
||||
FImgInfo.MetadataKinds := FImgInfo.MetadataKinds + [mdkExif] - [mdkExifNoMakerNotes]
|
||||
else
|
||||
FImgInfo.MetadataKinds := FImgInfo.MetadataKinds - [mdkExif] + [mdkExifNoMakerNotes];
|
||||
if CbProcessXMP.Checked then
|
||||
FImgInfo.MetadataKinds := FImgInfo.MetaDataKinds + [mdkXMP]
|
||||
else
|
||||
FImgInfo.MetadataKinds := FImgInfo.MetaDataKinds - [mdkXMP];
|
||||
FImgInfo.LoadFromFile(AFileName);
|
||||
Messages.Hide;
|
||||
except
|
||||
@ -332,6 +378,22 @@ begin
|
||||
end else
|
||||
DateTimePanel.Hide;
|
||||
|
||||
if FImgInfo.HasXMP then begin
|
||||
ms := TMemoryStream.Create;
|
||||
try
|
||||
FImgInfo.XMPData.SaveToStream(ms);
|
||||
ms.Position := 0;
|
||||
XMPSynEdit.Lines.LoadFromStream(ms);
|
||||
LoadXMPTags;
|
||||
finally
|
||||
ms.Free;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
XMPListView.Clear;
|
||||
XMPSynEdit.Clear;
|
||||
end;
|
||||
|
||||
if FImgInfo.HasIptc then begin
|
||||
for i := 0 to FImgInfo.IptcData.TagCount-1 do begin
|
||||
lTag := FImgInfo.IptcData.TagByIndex[i];
|
||||
@ -449,6 +511,24 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.LoadXMPTags;
|
||||
var
|
||||
i: Integer;
|
||||
item: TListItem;
|
||||
begin
|
||||
XMPListView.Items.BeginUpdate;
|
||||
try
|
||||
XMPListView.Items.Clear;
|
||||
for i := 0 to FImgInfo.XMPData.TagCount-1 do begin
|
||||
item := XMPListView.Items.Add;
|
||||
item.Caption := FImgInfo.XMPData.TagName[i];
|
||||
item.SubItems.Add(FImgInfo.XMPData.TagByIndex[i]);
|
||||
end;
|
||||
finally
|
||||
XMPListView.Items.EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.PageControl1Change(Sender: TObject);
|
||||
var
|
||||
crs: TCursor;
|
||||
|
@ -141,9 +141,9 @@ object MainForm: TMainForm
|
||||
Height = 539
|
||||
Top = 23
|
||||
Width = 647
|
||||
ActivePage = PgMetadata
|
||||
ActivePage = PgXMP
|
||||
Align = alClient
|
||||
TabIndex = 0
|
||||
TabIndex = 1
|
||||
TabOrder = 1
|
||||
OnChange = PageControlChange
|
||||
object PgMetadata: TTabSheet
|
||||
|
@ -126,7 +126,7 @@ type
|
||||
TAdobeImageResourceBlock = class
|
||||
public
|
||||
Identifier: Word;
|
||||
Name: String;
|
||||
Name: AnsiString;
|
||||
Data: TBytes;
|
||||
end;
|
||||
|
||||
|
@ -13,11 +13,7 @@ uses
|
||||
{$IFDEF FPC}
|
||||
LazUTF8,
|
||||
{$ENDIF}
|
||||
fpeGlobal,
|
||||
{$IFDEF FPC}
|
||||
fpeXmpData,
|
||||
{$ENDIF}
|
||||
fpeExifData, fpeIptcData;
|
||||
fpeGlobal, fpeXmpData, fpeExifData, fpeIptcData;
|
||||
|
||||
type
|
||||
TImgInfo = class;
|
||||
@ -67,9 +63,7 @@ type
|
||||
private
|
||||
FExifData: TExifData;
|
||||
FIptcData: TIptcData;
|
||||
{$IFDEF FPC}
|
||||
FXmpData: TXmpData;
|
||||
{$ENDIF}
|
||||
function GetComment: String;
|
||||
function GetWarnings: String;
|
||||
procedure SetComment(const AValue: String);
|
||||
@ -92,18 +86,14 @@ type
|
||||
|
||||
function CreateExifData(ABigEndian: Boolean = false): TExifData;
|
||||
function CreateIptcData: TIptcData;
|
||||
{$IFDEF FPC}
|
||||
function CreateXmpData: TXmpData;
|
||||
{$ENDIF}
|
||||
|
||||
function HasComment: Boolean;
|
||||
function HasExif: Boolean;
|
||||
function HasIptc: Boolean;
|
||||
function HasThumbnail: Boolean;
|
||||
function HasWarnings: boolean;
|
||||
{$IFDEF FPC}
|
||||
function HasXMP: Boolean;
|
||||
{$ENDIF}
|
||||
|
||||
{ Comment stored in the Jpeg COM segment }
|
||||
property Comment: String read GetComment write SetComment;
|
||||
@ -128,9 +118,7 @@ type
|
||||
|
||||
property ExifData: TExifData read FExifData;
|
||||
property IptcData: TIptcData read FIptcData;
|
||||
{$IFDEF FPC}
|
||||
property XmpData: TXmpData read FXmpData;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
|
||||
@ -138,8 +126,7 @@ implementation
|
||||
|
||||
uses
|
||||
Variants,
|
||||
fpeStrConsts, fpeUtils, fpeExifReadWrite, {$IFDEF FPC}fpeXMPReadWrite,{$ENDIF}
|
||||
fpeIptcReadWrite;
|
||||
fpeStrConsts, fpeUtils, fpeExifReadWrite, fpeXMPReadWrite, fpeIptcReadWrite;
|
||||
|
||||
type
|
||||
TJpegJFIFSegment = packed record
|
||||
@ -276,9 +263,7 @@ begin
|
||||
FWarnings.Free;
|
||||
FExifData.Free;
|
||||
FIptcData.Free;
|
||||
{$IFDEF FPC}
|
||||
FXmpData.Free;
|
||||
{$ENDIF}
|
||||
inherited;
|
||||
end;
|
||||
|
||||
@ -298,7 +283,6 @@ begin
|
||||
Result := FIptcData;
|
||||
end;
|
||||
|
||||
{$IFDEF FPC}
|
||||
function TImgInfo.CreateXmpData: TXmpData;
|
||||
begin
|
||||
FWarnings.Clear;
|
||||
@ -306,7 +290,6 @@ begin
|
||||
FXmpData := TXmpData.Create;
|
||||
Result := FXmpData;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TImgInfo.Error(const AMsg: String);
|
||||
begin
|
||||
@ -381,12 +364,10 @@ begin
|
||||
Result := FWarnings.Count > 0;
|
||||
end;
|
||||
|
||||
{$IFDEF FPC}
|
||||
function TImgInfo.HasXMP: Boolean;
|
||||
begin
|
||||
Result := FXmpData <> nil;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TImgInfo.LoadFromFile(const AFileName: String);
|
||||
var
|
||||
@ -441,7 +422,7 @@ var
|
||||
{$IFDEF FPC}
|
||||
s: RawByteString = '';
|
||||
{$ELSE}
|
||||
s: String;
|
||||
s: AnsiString;
|
||||
{$ENDIF}
|
||||
begin
|
||||
// Write the header segment and all metadata segments stored in TImgInfo
|
||||
@ -588,7 +569,6 @@ begin
|
||||
finally
|
||||
reader.Free;
|
||||
end;
|
||||
{$IFDEF FPC}
|
||||
end else
|
||||
if HasXMPHeader(AStream) and (mdkXMP in FMetadataKinds) then
|
||||
begin
|
||||
@ -602,7 +582,6 @@ begin
|
||||
raise EFpExifReader.Create('Error reading XMP data: ' + E.Message);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
M_IPTC:
|
||||
@ -842,7 +821,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF FPC}
|
||||
// XMP --> Write another APP1 segment
|
||||
if (mdkXMP in FMetadataKinds) and HasXMP then
|
||||
begin
|
||||
@ -853,8 +831,7 @@ begin
|
||||
writer.Free;
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
// Write IPTCSegment (APP13)
|
||||
if (mdkIPTC in FMetadataKinds) and HasIPTC then begin
|
||||
writer := TIptcWriter.Create(Self);
|
||||
|
@ -20,24 +20,28 @@ uses
|
||||
Classes, SysUtils, contnrs,
|
||||
{$IFDEF FPC}
|
||||
laz2_dom, laz2_xmlread,
|
||||
{$ELSE}
|
||||
XMLDoc, XMLIntf,
|
||||
{$ENDIF}
|
||||
fpeGlobal, fpeTags;
|
||||
|
||||
type
|
||||
TXMPData = class
|
||||
private
|
||||
FData: String;
|
||||
FData: AnsiString;
|
||||
{$IFDEF FPC}
|
||||
FDoc: TXMLDocument;
|
||||
{$ELSE}
|
||||
FDoc: IXMLDocument;
|
||||
{$ENDIF}
|
||||
FTags: TStringList;
|
||||
function GetTagByIndex(AIndex: Integer): String;
|
||||
function GetTagByName(ATagName: String): String;
|
||||
function GetTagName(AIndex: Integer): String;
|
||||
function GetTagCount: Integer;
|
||||
protected
|
||||
{$IFDEF FPC}
|
||||
procedure Create_RDFDescription_Tags(ANode: TDOMNode);
|
||||
procedure Create_RDFDescription_Tags(ANode: {$IFDEF FPC}TDOMNode{$ELSE}IXMLNode{$ENDIF});
|
||||
procedure CreateTags;
|
||||
{$ENDIF}
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -69,61 +73,120 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
{$IFDEF FPC}
|
||||
procedure TXMPData.Create_RDFDescription_Tags(ANode: TDOMNode);
|
||||
procedure TXMPData.Create_RDFDescription_Tags(ANode: {$IFDEF FPC}TDOMNode{$ELSE}IXMLNode{$ENDIF});
|
||||
var
|
||||
{$IFDEF FPC}
|
||||
node: TDOMNode;
|
||||
nodeName: String;
|
||||
i: Integer;
|
||||
attr: TDOMNode;
|
||||
{$ELSE}
|
||||
node: IXMLNode;
|
||||
attr: IXMLNode;
|
||||
{$ENDIF}
|
||||
nodeName: String;
|
||||
i, n: Integer;
|
||||
lTagName, lTagValue: String;
|
||||
lTag: TTag;
|
||||
begin
|
||||
while ANode <> nil do begin
|
||||
nodeName := ANode.NodeName;
|
||||
{$IFDEF FPC}
|
||||
for i := 0 to ANode.Attributes.Length-1 do
|
||||
begin
|
||||
attr := ANode.Attributes.Item[i];
|
||||
lTagName := attr.NodeName;
|
||||
lTagValue := attr.NodeValue;
|
||||
lTagValue := attr.nodeValue;
|
||||
FTags.Add(lTagName + '=' + lTagValue);
|
||||
end;
|
||||
if ANode.HasChildNodes then
|
||||
begin
|
||||
node := ANode.FirstChild;
|
||||
while node <> nil do
|
||||
while node <> nil do
|
||||
begin
|
||||
nodeName := node.NodeName;
|
||||
{$IFDEF FPC}
|
||||
lTagValue := node.TextContent;
|
||||
{$ELSE}
|
||||
lTagValue := node.NodeValue;
|
||||
{$ENDIF}
|
||||
if lTagName <> '' then
|
||||
FTags.Add(nodeName + '=' + lTagValue);
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
end;
|
||||
ANode := ANode.NextSibling;
|
||||
{$ELSE}
|
||||
for i := 0 to ANode.AttributeNodes.Count-1 do
|
||||
begin
|
||||
attr := ANode.AttributeNodes[i];
|
||||
lTagName := attr.NodeName;
|
||||
lTagValue := attr.NodeValue;
|
||||
FTags.Add(lTagName + '=' + lTagValue);
|
||||
end;
|
||||
if ANode.HasChildNodes then
|
||||
begin
|
||||
node := ANode.ChildNodes.First;
|
||||
while node <> nil do
|
||||
begin
|
||||
nodeName := node.NodeName;
|
||||
{$IFDEF FPC}
|
||||
lTagValue := node.TextContent;
|
||||
{$ELSE}
|
||||
lTagValue := node.NodeValue;
|
||||
{$ENDIF}
|
||||
if lTagName <> '' then
|
||||
FTags.Add(nodeName + '=' + lTagValue);
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
end;
|
||||
ANode := ANode.NextSibling;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TXMPData.CreateTags;
|
||||
var
|
||||
stream: TStringStream;
|
||||
{$IFDEF FPC}
|
||||
node: TDOMNode;
|
||||
{$ELSE}
|
||||
node: IXMLNode;
|
||||
{$ENDIF}
|
||||
nodeName: String;
|
||||
stream: TStringStream;
|
||||
begin
|
||||
{$IFDEF FPC}
|
||||
FDoc.Free;
|
||||
{$ENDIF}
|
||||
stream := TStringStream.Create(FData);
|
||||
try
|
||||
{$IFDEF FPC}
|
||||
ReadXMLFile(FDoc, stream);
|
||||
{$ELSE}
|
||||
FDoc := TXMLDocument.Create(nil);
|
||||
FDoc.Options := FDoc.Options - [doNodeAutoCreate];
|
||||
FDoc.LoadFromStream(stream, xetUTF_8);
|
||||
{$ENDIF}
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
|
||||
FTags.Clear;
|
||||
try
|
||||
{$IFDEF FPC}
|
||||
node := FDoc.DocumentElement.FindNode('rdf:RDF');
|
||||
if node = nil then exit;
|
||||
node := node.FirstChild;
|
||||
while node <> nil do
|
||||
{$ELSE}
|
||||
|
||||
node := FDoc.DocumentElement;
|
||||
if node.ChildNodes.Count = 0 then
|
||||
exit;
|
||||
node := node.ChildNodes.First;
|
||||
nodename :=node.NodeName;
|
||||
if nodeName <> 'rdf:RDF' then
|
||||
exit;
|
||||
node := node.ChildNodes.First;
|
||||
{$ENDIF}
|
||||
while node <> nil do
|
||||
begin
|
||||
nodeName := node.NodeName;
|
||||
if nodeName = 'rdf:Description' then
|
||||
@ -132,11 +195,12 @@ begin
|
||||
end;
|
||||
except
|
||||
FTags.Clear;
|
||||
{$IFDEF FPC}
|
||||
FreeAndNil(FDoc);
|
||||
{$ENDIF}
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function TXMPData.GetTagByIndex(AIndex: Integer): String;
|
||||
begin
|
||||
@ -161,7 +225,7 @@ end;
|
||||
procedure TXMPData.LoadFromStream(AStream: TStream; ASize: Integer = -1);
|
||||
var
|
||||
p: Int64;
|
||||
i: SizeInt;
|
||||
i: Cardinal;
|
||||
begin
|
||||
if ASize = -1 then
|
||||
ASize := AStream.Size;
|
||||
@ -181,9 +245,7 @@ begin
|
||||
end;
|
||||
|
||||
AStream.Position := p;
|
||||
{$IFDEF FPC}
|
||||
CreateTags;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TXMPData.SaveToStream(AStream: TStream);
|
||||
|
@ -1,12 +1,14 @@
|
||||
unit fpeXMPReadWrite;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$IFDEF FPC}
|
||||
{$mode objfpc}{$H+}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils,
|
||||
fpeGlobal, fpeMetaData;
|
||||
fpeGlobal, fpeUtils, fpeMetaData;
|
||||
|
||||
const
|
||||
XMP_BASE_KEY = 'http://ns.adobe.com/xap/1.0/';
|
||||
@ -27,12 +29,12 @@ implementation
|
||||
function HasXMPHeader(AStream: TStream): Boolean;
|
||||
var
|
||||
p: Int64;
|
||||
hdr: array of ansichar;
|
||||
hdr: array of ansichar;
|
||||
begin
|
||||
p := AStream.Position;
|
||||
SetLength(hdr, Length(XMP_KEY));
|
||||
AStream.Read(hdr[0], Length(XMP_KEY));
|
||||
Result := CompareMem(@hdr[0], @XMP_KEY[1], Length(XMP_KEY));
|
||||
AStream.Read(hdr[0], Length(XMP_KEY));
|
||||
Result := CompareMem(PAnsiChar(hdr), PAnsiChar(AnsiString(XMP_KEY)), Length(XMP_KEY));
|
||||
if not Result then
|
||||
AStream.Position := p;
|
||||
end;
|
||||
@ -66,7 +68,7 @@ begin
|
||||
// Size of the segment
|
||||
ADataSize := NToBE(Word(ADataSize));
|
||||
AStream.WriteBuffer(ADataSize, 2);
|
||||
AStream.WriteBuffer(XMP_KEY, Length(XMP_KEY));
|
||||
AStream.WriteBuffer(AnsiString(XMP_KEY), Length(XMP_KEY));
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -7,7 +7,7 @@
|
||||
<TargetedPlatforms>1</TargetedPlatforms>
|
||||
<AppType>Application</AppType>
|
||||
<FrameworkType>VCL</FrameworkType>
|
||||
<ProjectVersion>18.8</ProjectVersion>
|
||||
<ProjectVersion>19.5</ProjectVersion>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||
@ -18,6 +18,11 @@
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
|
||||
<Base_Win64>true</Base_Win64>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<CfgParent>Base</CfgParent>
|
||||
@ -29,6 +34,12 @@
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
|
||||
<Cfg_1_Win64>true</Cfg_1_Win64>
|
||||
<CfgParent>Cfg_1</CfgParent>
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<CfgParent>Base</CfgParent>
|
||||
@ -40,6 +51,12 @@
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
|
||||
<Cfg_2_Win64>true</Cfg_2_Win64>
|
||||
<CfgParent>Cfg_2</CfgParent>
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base)'!=''">
|
||||
<DCC_E>false</DCC_E>
|
||||
<DCC_F>false</DCC_F>
|
||||
@ -58,6 +75,9 @@
|
||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=0.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=</VerInfo_Keys>
|
||||
<DCC_DcuOutput>output\dcu\Delphi</DCC_DcuOutput>
|
||||
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
|
||||
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
|
||||
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win32)'!=''">
|
||||
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
|
||||
@ -70,6 +90,13 @@
|
||||
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
|
||||
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win64)'!=''">
|
||||
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
|
||||
<BT_BuildType>Debug</BT_BuildType>
|
||||
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1)'!=''">
|
||||
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
||||
<DCC_DebugInformation>0</DCC_DebugInformation>
|
||||
@ -80,6 +107,9 @@
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<AppDPIAwarenessMode>PerMonitor</AppDPIAwarenessMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
|
||||
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||
<DCC_Optimize>false</DCC_Optimize>
|
||||
@ -94,6 +124,9 @@
|
||||
<AppDPIAwarenessMode>PerMonitor</AppDPIAwarenessMode>
|
||||
<BT_BuildType>Debug</BT_BuildType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
|
||||
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<DelphiCompile Include="$(MainSource)">
|
||||
<MainSource>MainSource</MainSource>
|
||||
@ -107,15 +140,11 @@
|
||||
<DCCReference Include="..\..\fpemetadata.pas"/>
|
||||
<DCCReference Include="..\..\fpestrconsts.pas"/>
|
||||
<DCCReference Include="..\..\fpetags.pas"/>
|
||||
<DCCReference Include="..\..\fpeutils.pas"/>
|
||||
<DCCReference Include="..\..\fpeUtils.pas"/>
|
||||
<DCCReference Include="common\fetexifbe.pas"/>
|
||||
<DCCReference Include="common\fetexifle.pas"/>
|
||||
<DCCReference Include="common\fetiptc.pas"/>
|
||||
<DCCReference Include="common\fetutils.pas"/>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
@ -123,6 +152,10 @@
|
||||
<Key>Cfg_1</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||
@ -135,6 +168,7 @@
|
||||
</Delphi.Personality>
|
||||
<Platforms>
|
||||
<Platform value="Win32">True</Platform>
|
||||
<Platform value="Win64">False</Platform>
|
||||
</Platforms>
|
||||
</BorlandProject>
|
||||
<ProjectFileVersion>12</ProjectFileVersion>
|
||||
|
Binary file not shown.
Reference in New Issue
Block a user