use
vars
qw($VERSION @ISA $makeMissing)
;
$VERSION
=
'1.37'
;
@ISA
=
qw(Exporter)
;
$makeMissing
=
''
;
sub
LoadLangModules($;$);
sub
WriteLangModule($$;$);
sub
NumbersFirst;
my
%credits
= (
cs
=>
'Jens Duttke and Petr MichE<aacute>lek'
,
de
=>
'Jens Duttke, Herbert Kauer and Jobi'
,
es
=>
'Jens Duttke, Santiago del BrE<iacute>o GonzE<aacute>lez and Emilio Sancha'
,
fi
=>
'Jens Duttke and Jarkko ME<auml>kineva'
,
fr
=>
'Jens Duttke, Bernard Guillotin, Jean Glasser, Jean Piquemal, Harry Nizard, Alphonse Philippe and Philippe Bonnaure (GraphicConverter)'
,
it
=>
'Jens Duttke, Ferdinando Agovino, Emilio Dati and Michele Locati'
,
ja
=>
'Jens Duttke and Kazunari Nishina'
,
ko
=>
'Jens Duttke and Jeong Beom Kim'
,
nl
=>
'Jens Duttke, Peter Moonen, Herman Beld and Peter van der Laan'
,
pl
=>
'Jens Duttke, Przemyslaw Sulek and Kacper Perschke'
,
ru
=>
'Jens Duttke, Sergey Shemetov, Dmitry Yerokhin, Anton Sukhinov and Alexander'
,
sk
=>
'Peter Bagin'
,
sv
=>
'Jens Duttke and BjE<ouml>rn SE<ouml>derstrE<ouml>m'
,
'tr'
=>
'Jens Duttke, Hasan Yildirim and Cihan Ulusoy'
,
zh_cn
=>
'Jens Duttke and Haibing Zhong'
,
zh_tw
=>
'Jens Duttke and MikeF'
,
);
my
%translateLang
= (
ch_s
=>
'zh_cn'
,
ch_cn
=>
'zh_cn'
,
ch_tw
=>
'zh_tw'
,
cz
=>
'cs'
,
jp
=>
'ja'
,
kr
=>
'ko'
,
se
=>
'sv'
,
);
my
$numbersFirst
= 1;
my
$caseInsensitive
;
my
%fakeWriteGroup
= (
Comment
=> 1,
colr
=> 1,
);
sub
Write(;$$%)
{
local
(
$_
,
*PTIFILE
);
my
(
$file
,
$group
,
%opts
) =
@_
;
my
$et
= Image::ExifTool->new;
my
(
$fp
,
$tableName
,
%langInfo
,
@langs
,
$defaultLang
,
@groups
);
@groups
=
split
':'
,
$group
if
$group
;
Image::ExifTool::LoadAllTables();
unless
(
$opts
{NoDesc}) {
$defaultLang
=
$Image::ExifTool::defaultLang
;
LoadLangModules(\
%langInfo
,
$opts
{Lang});
if
(
$opts
{Lang}) {
@langs
=
grep
/^
$opts
{Lang}$/i,
keys
%langInfo
;
}
else
{
@langs
=
sort
keys
%langInfo
;
}
}
if
(
defined
$file
) {
open
PTIFILE,
">$file"
or
return
0;
$fp
= \
*PTIFILE
;
}
else
{
$fp
= \
*STDOUT
;
}
print
$fp
"<?xml version='1.0' encoding='UTF-8'?>\n"
;
print
$fp
"<!-- Generated by Image::ExifTool $Image::ExifTool::VERSION -->\n"
;
print
$fp
"<taginfo>\n\n"
;
foreach
$tableName
(
sort
keys
%allTables
) {
my
$table
= GetTagTable(
$tableName
);
my
$grps
=
$$table
{GROUPS};
my
(
$tagID
,
$didTag
);
$caseInsensitive
= (
$tableName
=~ /::XMP::/);
my
$isBinary
= (
$$table
{PROCESS_PROC} and
$$table
{PROCESS_PROC} eq \
&Image::ExifTool::ProcessBinaryData
);
if
(
$$table
{GROUPS} and
$$table
{GROUPS}{0} eq
'XMP'
) {
Image::ExifTool::XMP::AddFlattenedTags(
$table
);
}
$numbersFirst
= 2;
$numbersFirst
= -1
if
$$table
{VARS} and
$$table
{VARS}{ALPHA_FIRST};
my
@keys
=
sort
NumbersFirst TagTableKeys(
$table
);
$numbersFirst
= 1;
foreach
$tagID
(
@keys
) {
my
@infoArray
= GetTagInfoList(
$table
,
$tagID
);
my
$xmlID
= Image::ExifTool::XMP::FullEscapeXML(
$tagID
);
my
(
$index
,
$fam
);
PTILoop:
for
(
$index
=0;
$index
<
@infoArray
; ++
$index
) {
my
$tagInfo
=
$infoArray
[
$index
];
next
unless
$$tagInfo
{Writable} or not
$$tagInfo
{SubDirectory};
if
(
@groups
) {
my
@tg
=
$et
->GetGroup(
$tagInfo
);
foreach
$group
(
@groups
) {
next
PTILoop
unless
grep
/^
$group
$/i,
@tg
;
}
}
unless
(
$didTag
) {
my
$tname
=
$$table
{SHORT_NAME};
print
$fp
"<table name='${tname}' g0='$$grps{0}' g1='$$grps{1}' g2='$$grps{2}'>\n"
;
unless
(
$opts
{NoDesc}) {
my
$desc
=
$$table
{TABLE_DESC};
unless
(
$desc
) {
(
$desc
=
$tname
) =~ s/::Main$//;
$desc
=~ s/::/ /g;
}
print
$fp
" <desc lang='en'>$desc</desc>\n"
;
foreach
(
@langs
) {
$desc
=
$langInfo
{
$_
}{
$tableName
} or
next
;
$desc
= Image::ExifTool::XMP::EscapeXML(
$desc
);
print
$fp
" <desc lang='${_}'>$desc</desc>\n"
;
}
}
$didTag
= 1;
}
my
$name
=
$$tagInfo
{Name};
my
$ind
=
@infoArray
> 1 ?
" index='${index}'"
:
''
;
my
$format
=
$$tagInfo
{Writable} ||
$$table
{WRITABLE};
my
$writable
=
$format
?
'true'
:
'false'
;
if
(
$writable
eq
'true'
) {
$writable
=
'false'
if
defined
$$tagInfo
{Writable} and not
$$tagInfo
{Writable};
foreach
(
'PrintConv'
,
'ValueConv'
) {
next
unless
$$tagInfo
{
$_
};
next
if
$$tagInfo
{
$_
.
'Inv'
};
next
if
ref
(
$$tagInfo
{
$_
}) =~ /^(HASH|ARRAY)$/;
next
if
$$tagInfo
{WriteAlso};
$writable
=
'false'
;
last
;
}
}
$format
=
$$tagInfo
{Format} ||
$$table
{FORMAT}
if
not
$format
or
$format
eq
'1'
;
$format
=
'struct'
if
$$tagInfo
{Struct};
if
(
defined
$format
) {
$format
=~ s/\[.*\$.*\]//;
$format
=
'undef'
if
$format
eq
'2'
;
}
elsif
(
$isBinary
) {
$format
=
'int8u'
;
}
else
{
$format
=
'?'
;
}
my
$count
=
''
;
if
(
$format
=~ s/\[.*?(\d*)\]$//) {
$count
=
" count='${1}'"
if
length
$1;
}
elsif
(
$$tagInfo
{Count} and
$$tagInfo
{Count} > 1) {
$count
=
" count='$$tagInfo{Count}'"
;
}
my
@groups
=
$et
->GetGroup(
$tagInfo
);
my
$writeGroup
=
$$tagInfo
{WriteGroup} ||
$$table
{WRITE_GROUP};
$groups
[1] =
$writeGroup
if
$writeGroup
and not
$fakeWriteGroup
{
$writeGroup
};
my
$grp
=
''
;
for
(
$fam
=0;
$fam
<3; ++
$fam
) {
$grp
.=
" g$fam='$groups[$fam]'"
if
$groups
[
$fam
] ne
$$grps
{
$fam
};
}
if
(
$opts
{Flags}) {
my
@flags
;
foreach
(
qw(Avoid Binary List Mandatory Unknown)
) {
push
@flags
,
$_
if
$$tagInfo
{
$_
};
}
push
@flags
,
$$tagInfo
{List}
if
$$tagInfo
{List} and
$$tagInfo
{List} =~ /^(Alt|Bag|Seq)$/;
push
@flags
,
'Flattened'
if
defined
$$tagInfo
{Flat};
push
@flags
,
'Unsafe'
if
$$tagInfo
{Protected} and
$$tagInfo
{Protected} & 0x01;
push
@flags
,
'Protected'
if
$$tagInfo
{Protected} and
$$tagInfo
{Protected} & 0x02;
push
@flags
,
'Permanent'
if
$$tagInfo
{Permanent} or
(
$groups
[0] eq
'MakerNotes'
and not
defined
$$tagInfo
{Permanent});
$grp
=
" flags='"
.
join
(',
', sort @flags) . "'
$grp
"
if
@flags
;
$grp
.=
" struct='$$tagInfo{ParentTagInfo}{TagID}'"
if
$$tagInfo
{ParentTagInfo};
}
print
$fp
" <tag id='${xmlID}' name='${name}'$ind type='${format}'$count writable='${writable}'$grp"
;
if
(
$opts
{NoDesc}) {
print
$fp
"/>\n"
;
next
;
}
else
{
print
$fp
">"
;
}
my
$desc
=
$$tagInfo
{Description};
$desc
= Image::ExifTool::MakeDescription(
$name
)
unless
defined
$desc
;
my
$altDescr
=
''
;
my
%langConv
;
foreach
(
@langs
) {
my
$ld
=
$langInfo
{
$_
}{
$name
} or
next
;
if
(
ref
$ld
) {
$langConv
{
$_
} =
$$ld
{PrintConv};
$ld
=
$$ld
{Description} or
next
;
}
next
if
$ld
eq
$desc
;
$ld
= Image::ExifTool::XMP::EscapeXML(
$ld
);
$altDescr
.=
"\n <desc lang='${_}'>$ld</desc>"
;
}
$desc
= Image::ExifTool::XMP::EscapeXML(
$desc
);
unless
(
$opts
{Lang} and
$altDescr
) {
print
$fp
"\n <desc lang='${defaultLang}'>$desc</desc>"
;
}
print
$fp
"$altDescr\n"
;
for
(
my
$i
=0; ; ++
$i
) {
my
$conv
=
$$tagInfo
{PrintConv};
my
$idx
=
''
;
if
(
ref
$conv
eq
'ARRAY'
) {
last
unless
$i
<
@$conv
;
$conv
=
$$conv
[
$i
];
$idx
=
" index='${i}'"
;
}
else
{
last
if
$i
;
}
next
unless
ref
$conv
eq
'HASH'
;
my
@langConv
=
sort
keys
%langConv
;
print
$fp
" <values$idx>\n"
;
my
$key
;
$caseInsensitive
= 0;
if
(
$$conv
{BITMASK}) {
foreach
$key
(
keys
%{
$$conv
{BITMASK}}) {
my
$mask
=
"Bit$key"
;
next
if
not
$mask
or
$$conv
{
$mask
};
$$conv
{
$mask
} =
$$conv
{BITMASK}{
$key
};
}
}
foreach
$key
(
sort
NumbersFirst
keys
%$conv
) {
next
if
$key
eq
'BITMASK'
or
$key
eq
'OTHER'
or
$key
eq
'Notes'
;
my
$val
=
$$conv
{
$key
};
my
$xmlVal
= Image::ExifTool::XMP::EscapeXML(
$val
);
my
$xmlKey
= Image::ExifTool::XMP::FullEscapeXML(
$key
);
print
$fp
" <key id='${xmlKey}'>\n"
;
my
$altConv
=
''
;
foreach
(
@langConv
) {
my
$lv
=
$langConv
{
$_
};
$lv
=
$$lv
[
$i
] or
next
if
ref
$lv
eq
'ARRAY'
;
$lv
=
$$lv
{
$val
};
next
unless
defined
$lv
and
$lv
ne
$val
;
$lv
= Image::ExifTool::XMP::EscapeXML(
$lv
);
$altConv
.=
" <val lang='${_}'>$lv</val>\n"
;
}
unless
(
$opts
{Lang} and
$altConv
) {
print
$fp
" <val lang='${defaultLang}'>$xmlVal</val>\n"
}
print
$fp
"$altConv </key>\n"
;
}
print
$fp
" </values>\n"
;
}
print
$fp
" </tag>\n"
;
}
}
print
$fp
"</table>\n\n"
if
$didTag
;
}
my
$success
= 1;
print
$fp
"</taginfo>\n"
or
$success
= 0;
close
$fp
or
$success
= 0
if
defined
$file
;
return
$success
;
}
sub
EscapePerl
{
my
$str
=
shift
;
$str
=~ s/\\/\\\\/g;
$str
=~ s/
'/\\'
/g;
return
$str
;
}
sub
BuildLangModules($;$)
{
local
(
$_
,
*XFILE
);
my
(
$file
,
$updateFlag
) =
@_
;
my
(
$table
,
$tableName
,
$id
,
$index
,
$valIndex
,
$name
,
$key
,
$lang
,
$defDesc
);
my
(
%langInfo
,
%different
,
%changed
,
$overrideDifferent
);
Image::ExifTool::LoadAllTables();
foreach
$tableName
(
sort
keys
%allTables
) {
my
$table
= GetTagTable(
$tableName
);
next
unless
$$table
{GROUPS} and
$$table
{GROUPS}{0} eq
'XMP'
;
Image::ExifTool::XMP::AddFlattenedTags(
$table
);
}
LoadLangModules(\
%langInfo
);
$updateFlag
= 0
unless
$updateFlag
;
%langInfo
= ()
if
$updateFlag
& 0x04;
$overrideDifferent
= 1
if
$updateFlag
& 0x08;
if
(
defined
$file
) {
open
XFILE,
$file
or
return
-1;
while
(<XFILE>) {
next
unless
/^\s*<(\/?)(\w+)/;
my
$tok
= $2;
if
($1) {
if
(
$tok
eq
'tag'
) {
undef
$id
;
undef
$index
;
undef
$name
;
undef
$defDesc
;
}
elsif
(
$tok
eq
'values'
) {
undef
$key
;
undef
$valIndex
;
}
elsif
(
$tok
eq
'table'
) {
undef
$table
;
undef
$id
;
}
next
;
}
if
(
$tok
eq
'table'
) {
/^\s*<table name=
'([^'
]+)
'[ >]/ or warn('
Bad table'),
next
;
$tableName
=
"Image::ExifTool::$1"
;
next
if
$tableName
=~ /^Image::ExifTool::UserDefined/;
$table
= Image::ExifTool::GetTagTable(
$tableName
);
$table
or
warn
(
"Unknown tag table $tableName\n"
);
next
;
}
next
unless
defined
$table
;
if
(
$tok
eq
'tag'
) {
/^\s*<tag id=
'([^'
]*)
' name='
([^
']+)'
(
index
=
'(\d+)'
)?[ >]/ or
warn
(
'Bad tag'
),
next
;
$id
= Image::ExifTool::XMP::FullUnescapeXML($1);
$name
= $2;
$index
= $4;
if
(
$id
=~ /^0x[\da-fA-F]+$/ and (not
defined
$$table
{VARS} or
not
defined
$$table
{VARS}{HEX_ID} or
$$table
{VARS}{HEX_ID}))
{
$id
=
hex
(
$id
);
}
next
;
}
if
(
$tok
eq
'values'
) {
/^\s*<
values
index
=
'([^'
]*)'>/ or
next
;
$valIndex
= $1;
}
elsif
(
$tok
eq
'key'
) {
defined
$id
or
warn
(
'No ID'
),
next
;
/^\s*<key id=
'([^'
]*)
'>/ or warn('
Bad key'),
next
;
$key
= Image::ExifTool::XMP::FullUnescapeXML($1);
$key
=
hex
(
$key
)
if
$key
=~ /^0x[\da-fA-F]+$/;
}
elsif
(
$tok
eq
'val'
or
$tok
eq
'desc'
) {
/^\s*<
$tok
( lang=
'([-\w]+?)'
)?>(.*)<\/
$tok
>/ or
warn
(
"Bad $tok"
),
next
;
$tok
eq
'desc'
and
defined
$key
and
warn
(
'Out of order "desc"'
),
next
;
my
$lang
= $2 or
next
;
$lang
=~
tr
/-A-Z/_a-z/;
$lang
=
$translateLang
{
$lang
}
if
$translateLang
{
$lang
};
my
$tval
= Image::ExifTool::XMP::UnescapeXML($3);
my
$val
=
ucfirst
$tval
;
$val
=
$tval
if
$tval
=~ /^(cRAW|iTun)/;
my
$cap
= (
$tval
ne
$val
);
if
(
$makeMissing
) {
if
(
$lang
eq
'en'
) {
$lang
=
$makeMissing
;
$val
=
'MISSING'
;
undef
$cap
;
}
}
elsif
(
$val
eq
'MISSING'
) {
next
;
}
my
$isDefault
= (
$lang
eq
$Image::ExifTool::defaultLang
);
unless
(
$langInfo
{
$lang
} or
$isDefault
) {
print
"Creating new language $lang\n"
;
$langInfo
{
$lang
} = { };
}
defined
$name
or
$name
=
'<unknown>'
;
unless
(
defined
$id
) {
next
if
$isDefault
;
next
if
$langInfo
{
$lang
}{
$tableName
} and
$langInfo
{
$lang
}{
$tableName
} eq
$val
;
$langInfo
{
$lang
}{
$tableName
} =
$val
;
$changed
{
$lang
} = 1;
warn
(
"Capitalized '${lang}' val for $name: $val\n"
)
if
$cap
;
next
;
}
my
@infoArray
= GetTagInfoList(
$table
,
$id
);
@infoArray
or
warn
(
"Error loading tag for $tableName ID='${id}'\n"
),
next
;
my
(
$tagInfo
,
$langInfo
);
if
(
defined
$index
) {
$tagInfo
=
$infoArray
[
$index
];
$tagInfo
or
warn
(
'Invalid index'
),
next
;
}
else
{
@infoArray
> 1 and
warn
(
'Missing index'
),
next
;
$tagInfo
=
$infoArray
[0];
}
my
$tagName
=
$$tagInfo
{Name};
if
(
$isDefault
) {
unless
(
$$tagInfo
{Description}) {
$$tagInfo
{Description} = Image::ExifTool::MakeDescription(
$tagName
);
}
$defDesc
=
$$tagInfo
{Description};
$langInfo
=
$tagInfo
;
}
else
{
$langInfo
=
$langInfo
{
$lang
}{
$tagName
};
if
(not
defined
$langInfo
) {
$langInfo
=
$langInfo
{
$lang
}{
$tagName
} = { };
}
elsif
(not
ref
$langInfo
) {
$langInfo
=
$langInfo
{
$lang
}{
$tagName
} = {
Description
=>
$langInfo
};
}
}
if
(
$tok
eq
'desc'
) {
my
$oldVal
=
$$langInfo
{Description};
next
if
defined
$oldVal
and
$oldVal
eq
$val
;
if
(
$makeMissing
) {
next
if
defined
$oldVal
and
$val
eq
'MISSING'
;
}
elsif
(
defined
$oldVal
) {
my
$t
=
"$lang $tagName"
;
unless
(
defined
$different
{
$t
} and
$different
{
$t
} eq
$val
) {
my
$a
=
defined
$different
{
$t
} ?
'ANOTHER '
:
''
;
warn
"${a}Different '${lang}' desc for $tagName: $val (was $$langInfo{Description})\n"
;
next
if
defined
$different
{
$t
};
$different
{
$t
} =
$val
;
}
next
unless
$overrideDifferent
;
}
next
if
$isDefault
;
if
(
defined
$defDesc
and
$defDesc
eq
$val
) {
delete
$$langInfo
{Description};
}
else
{
$$langInfo
{Description} =
$val
;
}
}
else
{
defined
$key
or
warn
(
"No key for $$tagInfo{Name}"
),
next
;
my
$printConv
=
$$tagInfo
{PrintConv};
if
(
ref
$printConv
eq
'ARRAY'
) {
defined
$valIndex
or
warn
(
'No value index'
),
next
;
$printConv
=
$$printConv
[
$valIndex
];
}
ref
$printConv
eq
'HASH'
or
warn
(
'No PrintConv'
),
next
;
my
$convVal
=
$$printConv
{
$key
};
unless
(
defined
$convVal
) {
if
(
$$printConv
{BITMASK} and
$key
=~ /^\d+$/) {
my
$i
;
for
(
$i
=0;
$i
<64; ++
$i
) {
my
$mask
= (0x01 <<
$i
) or
last
;
next
unless
$key
==
$mask
;
$convVal
=
$$printConv
{BITMASK}{
$i
};
}
}
warn
(
"Missing PrintConv entry for $tableName $$tagInfo{Name} $key\n"
) and
next
unless
defined
$convVal
;
}
if
(
$cap
and
$convVal
=~ /^[a-z]/) {
$val
=
lcfirst
$val
;
undef
$cap
;
}
my
$lc
=
$$langInfo
{PrintConv};
$lc
or
$lc
=
$$langInfo
{PrintConv} = { };
$lc
=
$printConv
if
ref
$lc
eq
'ARRAY'
;
my
$oldVal
=
$$lc
{
$convVal
};
next
if
defined
$oldVal
and
$oldVal
eq
$val
;
if
(
$makeMissing
) {
next
if
defined
$oldVal
and
$val
eq
'MISSING'
;
}
elsif
(
defined
$oldVal
and (not
$isDefault
or not
$val
=~/^\d+$/)) {
my
$t
=
"$lang $tagName $convVal"
;
unless
(
defined
$different
{
$t
} and
$different
{
$t
} eq
$val
) {
my
$a
=
defined
$different
{
$t
} ?
'ANOTHER '
:
''
;
warn
"${a}Different '${lang}' val for $tagName '${convVal}': $val (was $oldVal)\n"
;
next
if
defined
$different
{
$t
};
$different
{
$t
} =
$val
;
}
next
unless
$overrideDifferent
;
}
next
if
$isDefault
;
warn
(
"Capitalized '${lang}' val for $tagName: $tval\n"
)
if
$cap
;
$$lc
{
$convVal
} =
$val
;
}
$changed
{
$lang
} = 1;
}
}
close
XFILE;
}
my
$rtnVal
= 0;
foreach
$lang
(
$updateFlag
& 0x02 ?
@Image::ExifTool::langs
:
sort
keys
%changed
) {
next
if
$lang
eq
$Image::ExifTool::defaultLang
;
++
$rtnVal
;
WriteLangModule(
$lang
,
$langInfo
{
$lang
}, not
$updateFlag
& 0x01) or
$rtnVal
= -1,
last
;
}
return
$rtnVal
;
}
sub
WriteLangModule($$;$)
{
local
(
$_
,
*XOUT
);
my
(
$lang
,
$langTags
,
$newVersion
) =
@_
;
my
$err
;
-e
"lib/Image/ExifTool"
or
die
"Must run from directory containing 'lib'\n"
;
my
$out
=
"lib/Image/ExifTool/Lang/$lang.pm"
;
my
$tmp
=
"$out.tmp"
;
open
XOUT,
">$tmp"
or
die
"Error creating $tmp\n"
;
my
$ver
=
"Image::ExifTool::Lang::${lang}::VERSION"
;
no
strict
'refs'
;
if
(
$$ver
) {
$ver
=
$$ver
;
$ver
=
int
(
$ver
* 100 + 1.5) / 100
if
$newVersion
;
}
else
{
$ver
= 1.0;
}
$ver
=
sprintf
(
'%.2f'
,
$ver
);
my
$langName
=
$Image::ExifTool::langName
{
$lang
} ||
$lang
;
$langName
=~ s/\s*\(.*//;
print
XOUT
<<HEADER;
#------------------------------------------------------------------------------
# File: $lang.pm
#
# Description: ExifTool $langName language translations
#
# Notes: This file generated automatically by Image::ExifTool::TagInfoXML
#------------------------------------------------------------------------------
package Image::ExifTool::Lang::$lang;
use strict;
use vars qw(\$VERSION);
\$VERSION = '${ver}';
HEADER
print
XOUT
"\%Image::ExifTool::Lang::${lang}::Translate = (\n"
;
my
$tag
;
foreach
$tag
(
sort
keys
%$langTags
) {
my
$desc
=
$$langTags
{
$tag
};
my
$conv
;
if
(
ref
$desc
) {
$conv
=
$$desc
{PrintConv};
$desc
=
$$desc
{Description};
undef
$desc
if
$desc
and
$desc
eq
$tag
;
if
(
$conv
) {
my
@keys
=
keys
%$conv
;
foreach
(
@keys
) {
delete
$$conv
{
$_
}
if
$_
eq
$$conv
{
$_
};
}
undef
$conv
unless
%$conv
;
}
}
if
(
defined
$desc
) {
$desc
= EscapePerl(
$desc
);
}
else
{
next
unless
$conv
;
}
print
XOUT
" '${tag}' => "
;
unless
(
$conv
) {
print
XOUT
"'${desc}',\n"
;
next
;
}
print
XOUT
"{\n"
;
print
XOUT
" Description => '${desc}',\n"
if
defined
$desc
;
if
(
$conv
) {
print
XOUT
" PrintConv => {\n"
;
foreach
(
sort
keys
%$conv
) {
my
$str
= EscapePerl(
$_
);
my
$val
= EscapePerl(
$$conv
{
$_
});
print
XOUT
" '${str}' => '${val}',\n"
;
}
print
XOUT
" },\n"
;
}
print
XOUT
" },\n"
;
}
my
$ack
;
if
(
$credits
{
$lang
}) {
$ack
=
"Thanks to $credits{$lang} for providing this translation."
;
$ack
=~ s/(.{1,76})( +|$)/$1\n/sg;
$ack
=
"~head1 ACKNOWLEDGEMENTS\n\n$ack\n"
;
}
else
{
$ack
=
''
;
}
my
$footer
=
<<FOOTER;
);
1; # end
__END__
~head1 NAME
Image::ExifTool::Lang::$lang.pm - ExifTool $langName language translations
~head1 DESCRIPTION
This file is used by Image::ExifTool to generate localized tag descriptions
and values.
~head1 AUTHOR
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
$ack~head1 SEE ALSO
L<Image::ExifTool(3pm)|Image::ExifTool>,
L<Image::ExifTool::TagInfoXML(3pm)|Image::ExifTool::TagInfoXML>
~cut
FOOTER
$footer
=~ s/^~/=/mg;
print
XOUT
$footer
or
$err
= 1;
close
XOUT or
$err
= 1;
if
(
$err
or not
rename
(
$tmp
,
$out
)) {
warn
"Error writing $out\n"
;
unlink
$tmp
;
$err
= 1;
}
return
$err
? 0 : 1;
}
sub
LoadLangModules($;$)
{
my
(
$langHash
,
$lang
) =
@_
;
my
@langs
=
$lang
? (
$lang
) :
@Image::ExifTool::langs
;
foreach
$lang
(
@langs
) {
next
if
$lang
eq
$Image::ExifTool::defaultLang
;
eval
"require Image::ExifTool::Lang::$lang"
or
warn
(
"Can't load Lang::$lang\n"
),
next
;
my
$xlat
=
"Image::ExifTool::Lang::${lang}::Translate"
;
no
strict
'refs'
;
%$xlat
or
warn
(
"Missing Info for $lang\n"
),
next
;
$$langHash
{
$lang
} = \
%$xlat
;
}
}
sub
NumbersFirst
{
my
$rtnVal
;
my
(
$bNum
,
$bDec
);
(
$bNum
,
$bDec
) = ($1, $3)
if
$b
=~ /^(-?[0-9]+)(\.(\d*))?$/;
if
(
$a
=~ /^(-?[0-9]+)(\.(\d*))?$/) {
if
(
defined
$bNum
) {
$bNum
+= 1e9
if
$numbersFirst
== 2 and
$bNum
< 0;
my
$aInt
= $1;
$aInt
+= 1e9
if
$numbersFirst
== 2 and
$aInt
< 0;
$rtnVal
=
$aInt
<=>
$bNum
;
unless
(
$rtnVal
) {
my
$aDec
= $3 || 0;
$bDec
or
$bDec
= 0;
$rtnVal
=
$aDec
<=>
$bDec
;
}
}
else
{
$rtnVal
= -
$numbersFirst
;
}
}
elsif
(
defined
$bNum
) {
$rtnVal
=
$numbersFirst
;
}
else
{
my
(
$a2
,
$b2
) = (
$a
,
$b
);
$a2
=~ s/(\d+)/
sprintf
(
"%.3d"
,$1)/eg
if
$a2
=~ /^(APP|DMC-\w+ )?[.0-9 ]*$/ and
length
(
$a2
)<16;
$b2
=~ s/(\d+)/
sprintf
(
"%.3d"
,$1)/eg
if
$b2
=~ /^(APP|DMC-\w+ )?[.0-9 ]*$/ and
length
(
$b2
)<16;
$caseInsensitive
and
$rtnVal
= (
lc
(
$a2
) cmp
lc
(
$b2
));
$rtnVal
or
$rtnVal
= (
$a2
cmp
$b2
);
}
return
$rtnVal
;
}
1;
__END__