You've already forked lazarus-ccr
fpexif: Add support of XMP meta data (reading).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8201 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -25,13 +25,19 @@
|
|||||||
<Mode0 Name="default"/>
|
<Mode0 Name="default"/>
|
||||||
</Modes>
|
</Modes>
|
||||||
</RunParams>
|
</RunParams>
|
||||||
<RequiredPackages Count="2">
|
<RequiredPackages Count="4">
|
||||||
<Item1>
|
<Item1>
|
||||||
<PackageName Value="fpexif_pkg"/>
|
<PackageName Value="SynEditDsgn"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
<Item2>
|
<Item2>
|
||||||
<PackageName Value="LCL"/>
|
<PackageName Value="SynEdit"/>
|
||||||
</Item2>
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<PackageName Value="fpexif_pkg"/>
|
||||||
|
</Item3>
|
||||||
|
<Item4>
|
||||||
|
<PackageName Value="LCL"/>
|
||||||
|
</Item4>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="3">
|
<Units Count="3">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
@ -70,6 +76,7 @@
|
|||||||
</CodeGeneration>
|
</CodeGeneration>
|
||||||
<Linking>
|
<Linking>
|
||||||
<Debugging>
|
<Debugging>
|
||||||
|
<DebugInfoType Value="dsDwarf2Set"/>
|
||||||
<UseExternalDbgSyms Value="True"/>
|
<UseExternalDbgSyms Value="True"/>
|
||||||
</Debugging>
|
</Debugging>
|
||||||
<Options>
|
<Options>
|
||||||
|
@ -147,7 +147,7 @@ object MainForm: TMainForm
|
|||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
OnChange = PageControl1Change
|
OnChange = PageControl1Change
|
||||||
object PgMetadata: TTabSheet
|
object PgMetadata: TTabSheet
|
||||||
Caption = 'Meta data'
|
Caption = 'EXIF, IPTC'
|
||||||
ClientHeight = 511
|
ClientHeight = 511
|
||||||
ClientWidth = 639
|
ClientWidth = 639
|
||||||
object TagListView: TListView
|
object TagListView: TListView
|
||||||
@ -243,6 +243,539 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
object PgXMP: TTabSheet
|
||||||
|
Caption = 'XMP'
|
||||||
|
ClientHeight = 511
|
||||||
|
ClientWidth = 639
|
||||||
|
inline SynEdit: TSynEdit
|
||||||
|
Left = 0
|
||||||
|
Height = 231
|
||||||
|
Top = 280
|
||||||
|
Width = 639
|
||||||
|
Align = alClient
|
||||||
|
Font.Height = -13
|
||||||
|
Font.Name = 'Courier New'
|
||||||
|
Font.Pitch = fpFixed
|
||||||
|
Font.Quality = fqNonAntialiased
|
||||||
|
ParentColor = False
|
||||||
|
ParentFont = False
|
||||||
|
TabOrder = 0
|
||||||
|
Gutter.Width = 57
|
||||||
|
Gutter.MouseActions = <>
|
||||||
|
RightGutter.Width = 0
|
||||||
|
RightGutter.MouseActions = <>
|
||||||
|
Highlighter = SynXMLSyn
|
||||||
|
Keystrokes = <
|
||||||
|
item
|
||||||
|
Command = ecUp
|
||||||
|
ShortCut = 38
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelUp
|
||||||
|
ShortCut = 8230
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecScrollUp
|
||||||
|
ShortCut = 16422
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecDown
|
||||||
|
ShortCut = 40
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelDown
|
||||||
|
ShortCut = 8232
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecScrollDown
|
||||||
|
ShortCut = 16424
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecLeft
|
||||||
|
ShortCut = 37
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelLeft
|
||||||
|
ShortCut = 8229
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecWordLeft
|
||||||
|
ShortCut = 16421
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelWordLeft
|
||||||
|
ShortCut = 24613
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecRight
|
||||||
|
ShortCut = 39
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelRight
|
||||||
|
ShortCut = 8231
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecWordRight
|
||||||
|
ShortCut = 16423
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelWordRight
|
||||||
|
ShortCut = 24615
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecPageDown
|
||||||
|
ShortCut = 34
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelPageDown
|
||||||
|
ShortCut = 8226
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecPageBottom
|
||||||
|
ShortCut = 16418
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelPageBottom
|
||||||
|
ShortCut = 24610
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecPageUp
|
||||||
|
ShortCut = 33
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelPageUp
|
||||||
|
ShortCut = 8225
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecPageTop
|
||||||
|
ShortCut = 16417
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelPageTop
|
||||||
|
ShortCut = 24609
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecLineStart
|
||||||
|
ShortCut = 36
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelLineStart
|
||||||
|
ShortCut = 8228
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecEditorTop
|
||||||
|
ShortCut = 16420
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelEditorTop
|
||||||
|
ShortCut = 24612
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecLineEnd
|
||||||
|
ShortCut = 35
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelLineEnd
|
||||||
|
ShortCut = 8227
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecEditorBottom
|
||||||
|
ShortCut = 16419
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelEditorBottom
|
||||||
|
ShortCut = 24611
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecToggleMode
|
||||||
|
ShortCut = 45
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecCopy
|
||||||
|
ShortCut = 16429
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecPaste
|
||||||
|
ShortCut = 8237
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecDeleteChar
|
||||||
|
ShortCut = 46
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecCut
|
||||||
|
ShortCut = 8238
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecDeleteLastChar
|
||||||
|
ShortCut = 8
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecDeleteLastChar
|
||||||
|
ShortCut = 8200
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecDeleteLastWord
|
||||||
|
ShortCut = 16392
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecUndo
|
||||||
|
ShortCut = 32776
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecRedo
|
||||||
|
ShortCut = 40968
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecLineBreak
|
||||||
|
ShortCut = 13
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSelectAll
|
||||||
|
ShortCut = 16449
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecCopy
|
||||||
|
ShortCut = 16451
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecBlockIndent
|
||||||
|
ShortCut = 24649
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecLineBreak
|
||||||
|
ShortCut = 16461
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecInsertLine
|
||||||
|
ShortCut = 16462
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecDeleteWord
|
||||||
|
ShortCut = 16468
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecBlockUnindent
|
||||||
|
ShortCut = 24661
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecPaste
|
||||||
|
ShortCut = 16470
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecCut
|
||||||
|
ShortCut = 16472
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecDeleteLine
|
||||||
|
ShortCut = 16473
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecDeleteEOL
|
||||||
|
ShortCut = 24665
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecUndo
|
||||||
|
ShortCut = 16474
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecRedo
|
||||||
|
ShortCut = 24666
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker0
|
||||||
|
ShortCut = 16432
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker1
|
||||||
|
ShortCut = 16433
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker2
|
||||||
|
ShortCut = 16434
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker3
|
||||||
|
ShortCut = 16435
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker4
|
||||||
|
ShortCut = 16436
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker5
|
||||||
|
ShortCut = 16437
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker6
|
||||||
|
ShortCut = 16438
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker7
|
||||||
|
ShortCut = 16439
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker8
|
||||||
|
ShortCut = 16440
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecGotoMarker9
|
||||||
|
ShortCut = 16441
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker0
|
||||||
|
ShortCut = 24624
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker1
|
||||||
|
ShortCut = 24625
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker2
|
||||||
|
ShortCut = 24626
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker3
|
||||||
|
ShortCut = 24627
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker4
|
||||||
|
ShortCut = 24628
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker5
|
||||||
|
ShortCut = 24629
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker6
|
||||||
|
ShortCut = 24630
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker7
|
||||||
|
ShortCut = 24631
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker8
|
||||||
|
ShortCut = 24632
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecSetMarker9
|
||||||
|
ShortCut = 24633
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel1
|
||||||
|
ShortCut = 41009
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel2
|
||||||
|
ShortCut = 41010
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel3
|
||||||
|
ShortCut = 41011
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel4
|
||||||
|
ShortCut = 41012
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel5
|
||||||
|
ShortCut = 41013
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel6
|
||||||
|
ShortCut = 41014
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel7
|
||||||
|
ShortCut = 41015
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel8
|
||||||
|
ShortCut = 41016
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel9
|
||||||
|
ShortCut = 41017
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldLevel0
|
||||||
|
ShortCut = 41008
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcFoldCurrent
|
||||||
|
ShortCut = 41005
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcUnFoldCurrent
|
||||||
|
ShortCut = 41003
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = EcToggleMarkupWord
|
||||||
|
ShortCut = 32845
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecNormalSelect
|
||||||
|
ShortCut = 24654
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColumnSelect
|
||||||
|
ShortCut = 24643
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecLineSelect
|
||||||
|
ShortCut = 24652
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecTab
|
||||||
|
ShortCut = 9
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecShiftTab
|
||||||
|
ShortCut = 8201
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecMatchBracket
|
||||||
|
ShortCut = 24642
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelUp
|
||||||
|
ShortCut = 40998
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelDown
|
||||||
|
ShortCut = 41000
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelLeft
|
||||||
|
ShortCut = 40997
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelRight
|
||||||
|
ShortCut = 40999
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelPageDown
|
||||||
|
ShortCut = 40994
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelPageBottom
|
||||||
|
ShortCut = 57378
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelPageUp
|
||||||
|
ShortCut = 40993
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelPageTop
|
||||||
|
ShortCut = 57377
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelLineStart
|
||||||
|
ShortCut = 40996
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelLineEnd
|
||||||
|
ShortCut = 40995
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelEditorTop
|
||||||
|
ShortCut = 57380
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Command = ecColSelEditorBottom
|
||||||
|
ShortCut = 57379
|
||||||
|
end>
|
||||||
|
MouseActions = <>
|
||||||
|
MouseTextActions = <>
|
||||||
|
MouseSelActions = <>
|
||||||
|
Lines.Strings = (
|
||||||
|
'SynEdit'
|
||||||
|
)
|
||||||
|
VisibleSpecialChars = [vscSpace, vscTabAtLast]
|
||||||
|
SelectedColor.BackPriority = 50
|
||||||
|
SelectedColor.ForePriority = 50
|
||||||
|
SelectedColor.FramePriority = 50
|
||||||
|
SelectedColor.BoldPriority = 50
|
||||||
|
SelectedColor.ItalicPriority = 50
|
||||||
|
SelectedColor.UnderlinePriority = 50
|
||||||
|
SelectedColor.StrikeOutPriority = 50
|
||||||
|
BracketHighlightStyle = sbhsBoth
|
||||||
|
BracketMatchColor.Background = clNone
|
||||||
|
BracketMatchColor.Foreground = clNone
|
||||||
|
BracketMatchColor.Style = [fsBold]
|
||||||
|
FoldedCodeColor.Background = clNone
|
||||||
|
FoldedCodeColor.Foreground = clGray
|
||||||
|
FoldedCodeColor.FrameColor = clGray
|
||||||
|
MouseLinkColor.Background = clNone
|
||||||
|
MouseLinkColor.Foreground = clBlue
|
||||||
|
LineHighlightColor.Background = clNone
|
||||||
|
LineHighlightColor.Foreground = clNone
|
||||||
|
inline SynLeftGutterPartList1: TSynGutterPartList
|
||||||
|
object SynGutterMarks1: TSynGutterMarks
|
||||||
|
Width = 24
|
||||||
|
MouseActions = <>
|
||||||
|
end
|
||||||
|
object SynGutterLineNumber1: TSynGutterLineNumber
|
||||||
|
Width = 17
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clBtnFace
|
||||||
|
MarkupInfo.Foreground = clNone
|
||||||
|
DigitCount = 2
|
||||||
|
ShowOnlyLineNumbersMultiplesOf = 1
|
||||||
|
ZeroStart = False
|
||||||
|
LeadingZeros = False
|
||||||
|
end
|
||||||
|
object SynGutterChanges1: TSynGutterChanges
|
||||||
|
Width = 4
|
||||||
|
MouseActions = <>
|
||||||
|
ModifiedColor = 59900
|
||||||
|
SavedColor = clGreen
|
||||||
|
end
|
||||||
|
object SynGutterSeparator1: TSynGutterSeparator
|
||||||
|
Width = 2
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clWhite
|
||||||
|
MarkupInfo.Foreground = clGray
|
||||||
|
end
|
||||||
|
object SynGutterCodeFolding1: TSynGutterCodeFolding
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clNone
|
||||||
|
MarkupInfo.Foreground = clGray
|
||||||
|
MouseActionsExpanded = <>
|
||||||
|
MouseActionsCollapsed = <>
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object XMPListView: TListView
|
||||||
|
Left = 0
|
||||||
|
Height = 275
|
||||||
|
Top = 0
|
||||||
|
Width = 639
|
||||||
|
Align = alTop
|
||||||
|
AutoWidthLastColumn = True
|
||||||
|
Columns = <
|
||||||
|
item
|
||||||
|
Caption = 'Description'
|
||||||
|
Width = 200
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Caption = 'Value'
|
||||||
|
Width = 435
|
||||||
|
end>
|
||||||
|
TabOrder = 1
|
||||||
|
ViewStyle = vsReport
|
||||||
|
end
|
||||||
|
object Splitter4: TSplitter
|
||||||
|
Cursor = crVSplit
|
||||||
|
Left = 0
|
||||||
|
Height = 5
|
||||||
|
Top = 275
|
||||||
|
Width = 639
|
||||||
|
Align = alTop
|
||||||
|
ResizeAnchor = akTop
|
||||||
|
end
|
||||||
|
end
|
||||||
object PgImage: TTabSheet
|
object PgImage: TTabSheet
|
||||||
Caption = 'Image'
|
Caption = 'Image'
|
||||||
ClientHeight = 511
|
ClientHeight = 511
|
||||||
@ -385,4 +918,11 @@ object MainForm: TMainForm
|
|||||||
1FDF9F1F363F97D9C744ECB29398DFDF7A8BC172
|
1FDF9F1F363F97D9C744ECB29398DFDF7A8BC172
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
object SynXMLSyn: TSynXMLSyn
|
||||||
|
DefaultFilter = 'XML Document (*.xml,*.xsd,*.xsl,*.xslt,*.dtd)|*.xml;*.xsd;*.xsl;*.xslt;*.dtd'
|
||||||
|
Enabled = False
|
||||||
|
WantBracesParsed = False
|
||||||
|
Left = 480
|
||||||
|
Top = 145
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -5,9 +5,9 @@ unit mdvMain;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ShellCtrls,
|
Classes, SysUtils, FileUtil, SynEdit, SynHighlighterXML, Forms, Controls,
|
||||||
ExtCtrls, ComCtrls, StdCtrls,
|
Graphics, Dialogs, ShellCtrls, ExtCtrls, ComCtrls, StdCtrls, fpeGlobal,
|
||||||
fpeGlobal, fpeMetadata;
|
fpeMetadata;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ type
|
|||||||
Image: TImage;
|
Image: TImage;
|
||||||
Label1: TLabel;
|
Label1: TLabel;
|
||||||
LblChangeDate: TLabel;
|
LblChangeDate: TLabel;
|
||||||
|
XMPListView: TListView;
|
||||||
Messages: TMemo;
|
Messages: TMemo;
|
||||||
PageControl1: TPageControl;
|
PageControl1: TPageControl;
|
||||||
Panel1: TPanel;
|
Panel1: TPanel;
|
||||||
@ -33,9 +34,13 @@ type
|
|||||||
PreviewImage: TImage;
|
PreviewImage: TImage;
|
||||||
ImageList: TImageList;
|
ImageList: TImageList;
|
||||||
Splitter3: TSplitter;
|
Splitter3: TSplitter;
|
||||||
|
Splitter4: TSplitter;
|
||||||
StatusBar1: TStatusBar;
|
StatusBar1: TStatusBar;
|
||||||
PgMetadata: TTabSheet;
|
PgMetadata: TTabSheet;
|
||||||
PgImage: TTabSheet;
|
PgImage: TTabSheet;
|
||||||
|
PgXMP: TTabSheet;
|
||||||
|
SynEdit: TSynEdit;
|
||||||
|
SynXMLSyn: TSynXMLSyn;
|
||||||
TagListView: TListView;
|
TagListView: TListView;
|
||||||
ShellPanel: TPanel;
|
ShellPanel: TPanel;
|
||||||
ShellListView: TShellListView;
|
ShellListView: TShellListView;
|
||||||
@ -182,7 +187,8 @@ begin
|
|||||||
ShellListView.SmallImages := ImageList;
|
ShellListView.SmallImages := ImageList;
|
||||||
ShellTreeView.Images := ImageList;
|
ShellTreeView.Images := ImageList;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
//ShellListView.Parent.DoubleBuffered := true;
|
|
||||||
|
// XMPListView.ControlStyle:= XMPListView.Controlstyle + [csOpaque];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.BtnChangeDateClick(Sender: TObject);
|
procedure TMainForm.BtnChangeDateClick(Sender: TObject);
|
||||||
@ -248,6 +254,7 @@ end;
|
|||||||
procedure TMainForm.LoadFile(const AFileName: String);
|
procedure TMainForm.LoadFile(const AFileName: String);
|
||||||
var
|
var
|
||||||
lTag: TTag;
|
lTag: TTag;
|
||||||
|
xmpTag: String;
|
||||||
item: TListItem;
|
item: TListItem;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
ms: TMemoryStream;
|
ms: TMemoryStream;
|
||||||
@ -315,6 +322,21 @@ begin
|
|||||||
end else
|
end else
|
||||||
DateTimePanel.Hide;
|
DateTimePanel.Hide;
|
||||||
|
|
||||||
|
if FImgInfo.HasXMP then begin
|
||||||
|
ms := TMemoryStream.Create;
|
||||||
|
FImgInfo.XMPData.SaveToStream(ms);
|
||||||
|
ms.Position := 0;
|
||||||
|
SynEdit.Lines.LoadFromStream(ms);
|
||||||
|
|
||||||
|
XMPListView.Clear;
|
||||||
|
for i := 0 to FImgInfo.XMPData.TagCount-1 do begin
|
||||||
|
xmpTag := FImgInfo.XMPData.TagByIndex[i];
|
||||||
|
item := XMPListView.Items.Add;
|
||||||
|
item.Caption := Copy(xmptag, 1, pos('=', xmptag)-1);
|
||||||
|
item.SubItems.Add(copy(xmptag, pos('=', xmptag)+1));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
if FImgInfo.HasIptc then begin
|
if FImgInfo.HasIptc then begin
|
||||||
for i := 0 to FImgInfo.IptcData.TagCount-1 do begin
|
for i := 0 to FImgInfo.IptcData.TagCount-1 do begin
|
||||||
lTag := FImgInfo.IptcData.TagByIndex[i];
|
lTag := FImgInfo.IptcData.TagByIndex[i];
|
||||||
|
@ -63,7 +63,7 @@ type
|
|||||||
procedure ReadIFD(AStream: TStream; AParent: TTagID); override;
|
procedure ReadIFD(AStream: TStream; AParent: TTagID); override;
|
||||||
public
|
public
|
||||||
constructor Create(AImgInfo: TImgInfo); override;
|
constructor Create(AImgInfo: TImgInfo); override;
|
||||||
function ReadExifHeader(AStream: TStream): Boolean;
|
class function ReadExifHeader(AStream: TStream): Boolean;
|
||||||
procedure ReadFromStream(AStream: TStream; AImgFormat: TImgFormat); override;
|
procedure ReadFromStream(AStream: TStream; AImgFormat: TImgFormat); override;
|
||||||
function ReadTiffHeader(AStream: TStream; out ABigEndian: Boolean): Boolean;
|
function ReadTiffHeader(AStream: TStream; out ABigEndian: Boolean): Boolean;
|
||||||
property BigEndian: Boolean read FBigEndian;
|
property BigEndian: Boolean read FBigEndian;
|
||||||
@ -485,14 +485,19 @@ end;
|
|||||||
// Reads the header of the APP1 jpeg segment ("EXIF segment")
|
// Reads the header of the APP1 jpeg segment ("EXIF segment")
|
||||||
// Note that the segment marker and the segment size already have been read.
|
// Note that the segment marker and the segment size already have been read.
|
||||||
// The function returns FALSE if the header is not valid.
|
// The function returns FALSE if the header is not valid.
|
||||||
// Call ReadFromStream immediately afterwards
|
// In this case, the stream position is reset to where it started.
|
||||||
|
// Otherwise ReadFromStream can be called immediately afterwards.
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
function TExifReader.ReadExifHeader(AStream: TStream): Boolean;
|
class function TExifReader.ReadExifHeader(AStream: TStream): Boolean;
|
||||||
var
|
var
|
||||||
hdr: array[0..5] of ansichar;
|
hdr: array[0..5] of ansichar;
|
||||||
|
p: Int64;
|
||||||
begin
|
begin
|
||||||
|
p := AStream.Position;
|
||||||
AStream.Read({%H-}hdr[0], SizeOf(hdr));
|
AStream.Read({%H-}hdr[0], SizeOf(hdr));
|
||||||
Result := CompareMem(@hdr[0], @EXIF_SIGNATURE[0], SizeOf(hdr));
|
Result := CompareMem(@hdr[0], @EXIF_SIGNATURE[0], SizeOf(hdr));
|
||||||
|
if not Result then
|
||||||
|
AStream.Position := p;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -16,13 +16,14 @@ type
|
|||||||
TMetaDataKind = (
|
TMetaDataKind = (
|
||||||
mdkExif, // Complete Exif (incl MakerNotes)
|
mdkExif, // Complete Exif (incl MakerNotes)
|
||||||
mdkExifNoMakerNotes, // Exif without MakerNotes (instead of mdkExif)
|
mdkExifNoMakerNotes, // Exif without MakerNotes (instead of mdkExif)
|
||||||
|
mdkXMP, // XMP
|
||||||
mdkIPTC, // IPTC
|
mdkIPTC, // IPTC
|
||||||
mdkComment // Comment segment
|
mdkComment // Comment segment
|
||||||
);
|
);
|
||||||
TMetaDataKinds = set of TMetaDataKind;
|
TMetaDataKinds = set of TMetaDataKind;
|
||||||
|
|
||||||
const
|
const
|
||||||
mdkAll = [mdkExif, mdkIPTC, mdkComment];
|
mdkAll = [mdkExif, mdkXMP, mdkIPTC, mdkComment];
|
||||||
|
|
||||||
type
|
type
|
||||||
{$IFNDEF FPC}
|
{$IFNDEF FPC}
|
||||||
|
@ -14,7 +14,7 @@ uses
|
|||||||
LazUTF8,
|
LazUTF8,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
fpeGlobal,
|
fpeGlobal,
|
||||||
fpeExifData, fpeIptcData;
|
fpeExifData, fpeIptcData, fpeXmpData;
|
||||||
|
|
||||||
type
|
type
|
||||||
TImgInfo = class;
|
TImgInfo = class;
|
||||||
@ -64,6 +64,7 @@ type
|
|||||||
private
|
private
|
||||||
FExifData: TExifData;
|
FExifData: TExifData;
|
||||||
FIptcData: TIptcData;
|
FIptcData: TIptcData;
|
||||||
|
FXmpData: TXmpData;
|
||||||
function GetComment: String;
|
function GetComment: String;
|
||||||
function GetWarnings: String;
|
function GetWarnings: String;
|
||||||
procedure SetComment(const AValue: String);
|
procedure SetComment(const AValue: String);
|
||||||
@ -86,12 +87,14 @@ type
|
|||||||
|
|
||||||
function CreateExifData(ABigEndian: Boolean = false): TExifData;
|
function CreateExifData(ABigEndian: Boolean = false): TExifData;
|
||||||
function CreateIptcData: TIptcData;
|
function CreateIptcData: TIptcData;
|
||||||
|
function CreateXmpData: TXmpData;
|
||||||
|
|
||||||
function HasComment: Boolean;
|
function HasComment: Boolean;
|
||||||
function HasExif: Boolean;
|
function HasExif: Boolean;
|
||||||
function HasIptc: Boolean;
|
function HasIptc: Boolean;
|
||||||
function HasThumbnail: Boolean;
|
function HasThumbnail: Boolean;
|
||||||
function HasWarnings: boolean;
|
function HasWarnings: boolean;
|
||||||
|
function HasXMP: Boolean;
|
||||||
|
|
||||||
{ Comment stored in the Jpeg COM segment }
|
{ Comment stored in the Jpeg COM segment }
|
||||||
property Comment: String read GetComment write SetComment;
|
property Comment: String read GetComment write SetComment;
|
||||||
@ -115,7 +118,8 @@ type
|
|||||||
property WriteJFIFandEXIF: Boolean read FWriteJFIFandEXIF write FWriteJFIFandEXIF;
|
property WriteJFIFandEXIF: Boolean read FWriteJFIFandEXIF write FWriteJFIFandEXIF;
|
||||||
|
|
||||||
property ExifData: TExifData read FExifData;
|
property ExifData: TExifData read FExifData;
|
||||||
property IptcData: TIptcData read FIptcData; // to do: rename to IptcData
|
property IptcData: TIptcData read FIptcData;
|
||||||
|
property XmpData: TXmpData read FXmpData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -260,6 +264,7 @@ begin
|
|||||||
FWarnings.Free;
|
FWarnings.Free;
|
||||||
FExifData.Free;
|
FExifData.Free;
|
||||||
FIptcData.Free;
|
FIptcData.Free;
|
||||||
|
FXmpData.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -279,6 +284,14 @@ begin
|
|||||||
Result := FIptcData;
|
Result := FIptcData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TImgInfo.CreateXmpData: TXmpData;
|
||||||
|
begin
|
||||||
|
FWarnings.Clear;
|
||||||
|
FXmpData.Free;
|
||||||
|
FXmpData := TXmpData.Create;
|
||||||
|
Result := FXmpData;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TImgInfo.Error(const AMsg: String);
|
procedure TImgInfo.Error(const AMsg: String);
|
||||||
begin
|
begin
|
||||||
raise EFpExif.Create(AMsg);
|
raise EFpExif.Create(AMsg);
|
||||||
@ -352,6 +365,11 @@ begin
|
|||||||
Result := FWarnings.Count > 0;
|
Result := FWarnings.Count > 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TImgInfo.HasXMP: Boolean;
|
||||||
|
begin
|
||||||
|
Result := FXmpData <> nil;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TImgInfo.LoadFromFile(const AFileName: String);
|
procedure TImgInfo.LoadFromFile(const AFileName: String);
|
||||||
var
|
var
|
||||||
stream: TStream;
|
stream: TStream;
|
||||||
@ -527,11 +545,12 @@ begin
|
|||||||
p := AStream.Position;
|
p := AStream.Position;
|
||||||
case marker of
|
case marker of
|
||||||
M_EXIF:
|
M_EXIF:
|
||||||
if FMetaDataKinds * [mdkExif, mdkExifNoMakerNotes] <> [] then begin
|
if FMetaDataKinds * [mdkExif, mdkExifNoMakerNotes, mdkXMP] <> [] then begin
|
||||||
|
if TExifReader.ReadExifHeader(AStream) then
|
||||||
|
begin
|
||||||
reader := TExifReader.Create(self);
|
reader := TExifReader.Create(self);
|
||||||
try
|
try
|
||||||
if TExifReader(reader).ReadExifHeader(AStream) and
|
if TExifReader(reader).ReadTiffHeader(AStream, bigEndian) then
|
||||||
TExifReader(reader).ReadTiffHeader(AStream, bigEndian) then
|
|
||||||
begin
|
begin
|
||||||
FExifData := CreateExifData(bigEndian);
|
FExifData := CreateExifData(bigEndian);
|
||||||
try
|
try
|
||||||
@ -544,6 +563,17 @@ begin
|
|||||||
finally
|
finally
|
||||||
reader.Free;
|
reader.Free;
|
||||||
end;
|
end;
|
||||||
|
end else
|
||||||
|
if HasXMPHeader(AStream) then
|
||||||
|
begin
|
||||||
|
FXmpData := CreateXMPData;
|
||||||
|
try
|
||||||
|
FXmpData.ReadFromStream(AStream, size - Length(XMP_KEY));
|
||||||
|
except
|
||||||
|
FreeAndNil(FXmpData);
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
M_IPTC:
|
M_IPTC:
|
||||||
if (mdkIPTC in FMetadataKinds) then begin
|
if (mdkIPTC in FMetadataKinds) then begin
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<CONFIG>
|
<CONFIG>
|
||||||
<Package Version="4">
|
<Package Version="5">
|
||||||
<Name Value="fpexif_pkg"/>
|
<Name Value="fpexif_pkg"/>
|
||||||
<Author Value="Werner Pamler"/>
|
<Author Value="Werner Pamler"/>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<Description Value="Library for displaying and editing of meta data (EXIF, IPTC) in images."/>
|
<Description Value="Library for displaying and editing of meta data (EXIF, IPTC) in images."/>
|
||||||
<License Value="LGPL with linking exception (like Lazarus)"/>
|
<License Value="LGPL with linking exception (like Lazarus)"/>
|
||||||
<Version Minor="1"/>
|
<Version Minor="1"/>
|
||||||
<Files Count="20">
|
<Files Count="21">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="fpeglobal.pas"/>
|
<Filename Value="fpeglobal.pas"/>
|
||||||
<UnitName Value="fpeGlobal"/>
|
<UnitName Value="fpeGlobal"/>
|
||||||
@ -83,17 +83,22 @@
|
|||||||
</Item17>
|
</Item17>
|
||||||
<Item18>
|
<Item18>
|
||||||
<Filename Value="fpemakernotesanyo.pas"/>
|
<Filename Value="fpemakernotesanyo.pas"/>
|
||||||
<UnitName Value="fpemakernotesanyo"/>
|
<UnitName Value="fpeMakerNoteSanyo"/>
|
||||||
</Item18>
|
</Item18>
|
||||||
<Item19>
|
<Item19>
|
||||||
<Filename Value="fpemakernotecasio.pas"/>
|
<Filename Value="fpemakernotecasio.pas"/>
|
||||||
<UnitName Value="fpemakernotecasio"/>
|
<UnitName Value="fpeMakerNoteCasio"/>
|
||||||
</Item19>
|
</Item19>
|
||||||
<Item20>
|
<Item20>
|
||||||
<Filename Value="fpemakernotecanon.pas"/>
|
<Filename Value="fpemakernotecanon.pas"/>
|
||||||
<UnitName Value="fpeMakerNoteCanon"/>
|
<UnitName Value="fpeMakerNoteCanon"/>
|
||||||
</Item20>
|
</Item20>
|
||||||
|
<Item21>
|
||||||
|
<Filename Value="fpexmpdata.pas"/>
|
||||||
|
<UnitName Value="fpeXMPData"/>
|
||||||
|
</Item21>
|
||||||
</Files>
|
</Files>
|
||||||
|
<CompatibilityMode Value="True"/>
|
||||||
<i18n>
|
<i18n>
|
||||||
<EnableI18N Value="True"/>
|
<EnableI18N Value="True"/>
|
||||||
<OutDir Value="languages"/>
|
<OutDir Value="languages"/>
|
||||||
|
@ -12,7 +12,7 @@ uses
|
|||||||
fpeIptcReadWrite, fpeExifData, fpeIptcData, fpeStrConsts, fpeMakerNote,
|
fpeIptcReadWrite, fpeExifData, fpeIptcData, fpeStrConsts, fpeMakerNote,
|
||||||
fpeMakerNoteNikon, fpeMakerNoteMinolta, fpeMakerNoteOlympus,
|
fpeMakerNoteNikon, fpeMakerNoteMinolta, fpeMakerNoteOlympus,
|
||||||
fpeMakerNoteEpson, fpeMakerNoteFuji, fpeMakerNoteSanyo, fpeMakerNoteCasio,
|
fpeMakerNoteEpson, fpeMakerNoteFuji, fpeMakerNoteSanyo, fpeMakerNoteCasio,
|
||||||
fpeMakerNoteCanon;
|
fpeMakerNoteCanon, fpeXMPData;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
187
components/fpexif/fpexmpdata.pas
Normal file
187
components/fpexif/fpexmpdata.pas
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
unit fpeXMPData;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, contnrs,
|
||||||
|
{$IFDEF FPC}
|
||||||
|
laz2_dom, laz2_xmlread,
|
||||||
|
{$ENDIF}
|
||||||
|
fpeGlobal, fpeTags;
|
||||||
|
|
||||||
|
const
|
||||||
|
XMP_BASE_KEY = 'http://ns.adobe.com/xap/1.0/';
|
||||||
|
XMP_KEY = XMP_BASE_KEY + #0;
|
||||||
|
|
||||||
|
type
|
||||||
|
TXMPData = class
|
||||||
|
private
|
||||||
|
FData: String;
|
||||||
|
FDoc: TXMLDocument;
|
||||||
|
FTags: TStringList;
|
||||||
|
// FTags: TTagList;
|
||||||
|
function GetTagByIndex(AIndex: Integer): String;
|
||||||
|
function GetTagByName(ATagName: String): String;
|
||||||
|
function GetTagCount: Integer;
|
||||||
|
protected
|
||||||
|
{$IFDEF FPC}
|
||||||
|
procedure Create_RDFDescription_Tags(ANode: TDOMNode);
|
||||||
|
procedure CreateTags;
|
||||||
|
{$ENDIF}
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure ReadFromStream(AStream: TStream; ASize: Integer = -1);
|
||||||
|
procedure SaveToStream(AStream: TStream);
|
||||||
|
property TagByIndex[AIndex: Integer]: String read GetTagByIndex;
|
||||||
|
property TagByName[ATagName: String]: String read GetTagByName;
|
||||||
|
property TagCount: Integer read GetTagCount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function HasXMPHeader(AStream: TStream): Boolean;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function HasXMPHeader(AStream: TStream): Boolean;
|
||||||
|
var
|
||||||
|
p: Int64;
|
||||||
|
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));
|
||||||
|
if not Result then
|
||||||
|
AStream.Position := p;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TXMPData }
|
||||||
|
|
||||||
|
constructor TXMPData.Create;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
FTags := TStringList.Create; //TTagList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TXMPData.Destroy;
|
||||||
|
begin
|
||||||
|
{$IFDEF FPC}
|
||||||
|
FDoc.Free;
|
||||||
|
{$ENDIF}
|
||||||
|
FTags.Free;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$IFDEF FPC}
|
||||||
|
procedure TXMPData.Create_RDFDescription_Tags(ANode: TDOMNode);
|
||||||
|
var
|
||||||
|
node: TDOMNode;
|
||||||
|
nodeName: String;
|
||||||
|
i: Integer;
|
||||||
|
attr: TDOMNode;
|
||||||
|
tagName, tagValue: String;
|
||||||
|
lTag: TTag;
|
||||||
|
begin
|
||||||
|
while ANode <> nil do begin
|
||||||
|
nodeName := ANode.NodeName;
|
||||||
|
for i := 0 to ANode.Attributes.Length-1 do
|
||||||
|
begin
|
||||||
|
attr := ANode.Attributes.Item[i];
|
||||||
|
tagName := attr.NodeName;
|
||||||
|
tagValue := attr.NodeValue;
|
||||||
|
FTags.Add(tagName + '=' + tagValue);
|
||||||
|
end;
|
||||||
|
if ANode.HasChildNodes then
|
||||||
|
begin
|
||||||
|
node := ANode.FirstChild;
|
||||||
|
while node <> nil do
|
||||||
|
begin
|
||||||
|
nodeName := node.NodeName;
|
||||||
|
tagValue := node.TextContent;
|
||||||
|
if tagName <> '' then
|
||||||
|
FTags.Add(nodeName + '=' + tagValue);
|
||||||
|
node := node.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ANode := ANode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TXMPData.CreateTags;
|
||||||
|
var
|
||||||
|
stream: TStringStream;
|
||||||
|
node: TDOMNode;
|
||||||
|
nodeName: String;
|
||||||
|
begin
|
||||||
|
FDoc.Free;
|
||||||
|
stream := TStringStream.Create(FData);
|
||||||
|
try
|
||||||
|
ReadXMLFile(FDoc, stream);
|
||||||
|
finally
|
||||||
|
stream.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FTags.Clear;
|
||||||
|
try
|
||||||
|
node := FDoc.DocumentElement.FindNode('rdf:RDF');
|
||||||
|
if node = nil then exit;
|
||||||
|
node := node.FirstChild;
|
||||||
|
while node <> nil do
|
||||||
|
begin
|
||||||
|
nodeName := node.NodeName;
|
||||||
|
if nodeName = 'rdf:Description' then
|
||||||
|
Create_RDFDescription_Tags(node);
|
||||||
|
node := node.NextSibling;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
FTags.Clear;
|
||||||
|
FreeAndNil(FDoc);
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
function TXMPData.GetTagByIndex(AIndex: Integer): String;
|
||||||
|
begin
|
||||||
|
Result := FTags[AIndex];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TXMPData.GetTagByName(ATagName: String): String;
|
||||||
|
begin
|
||||||
|
Result := FTags.Values[ATagName];;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TXMPData.GetTagCount: Integer;
|
||||||
|
begin
|
||||||
|
Result := FTags.Count;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TXMPData.ReadFromStream(AStream: TStream; ASize: Integer = -1);
|
||||||
|
var
|
||||||
|
p: Int64;
|
||||||
|
begin
|
||||||
|
if ASize = -1 then
|
||||||
|
ASize := AStream.Size;
|
||||||
|
SetLength(FData, ASize);
|
||||||
|
p := AStream.Position;
|
||||||
|
AStream.Read(FData[1], ASize);
|
||||||
|
|
||||||
|
AStream.Position := p;
|
||||||
|
{$IFDEF FPC}
|
||||||
|
CreateTags;
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TXMPData.SaveToStream(AStream: TStream);
|
||||||
|
begin
|
||||||
|
if FData <> '' then
|
||||||
|
AStream.Write(FData[1], Length(FData));
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
Reference in New Issue
Block a user