File: photoshop_paths.config

package info (click to toggle)
libimage-exiftool-perl 11.16-1%2Bdeb10u1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 24,024 kB
  • sloc: perl: 245,177; xml: 120; makefile: 9
file content (198 lines) | stat: -rw-r--r-- 8,078 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#------------------------------------------------------------------------------
# File:         photoshop_paths.config
#
# Description:  This config file generates user-defined tags for Photoshop
#               paths, and may be used to extract path names and/or Bezier knot
#               anchor points, or copy path information from one file to
#               another.
#
#               The anchor points may be extracted along with the path names by
#               setting the "Anchor" user parameter (ie. "-userparam anchor"),
#               or by themselves with "AnchorOnly".
#
#               An "AllPaths" shortcut tag is also provided represent all
#               Photoshop path tags.  This shortcut must be used when copying
#               because these tags are marked as "Protected" so they won't be
#               copied by default (also see the notes below).
#
#               Path anchor points are converted to pixel coordinates by the
#               Composite PathPixXXX tags, and an "AllPathPix" shortcut is
#               provided to represent these tags.
#
#               Finally, a Composite PathCount tag is provided to return the
#               number of paths in an image, and a TotalPathPoints tag counts
#               the total number of path anchor points.
#
# Notes:     1) Print conversion must be disabled to be able to copy the paths
#               (via either the -n option, or by adding a "#" to the tag name,
#               eg. "-tagsfromfile SRC -allpaths#").
#
#            2) When copying the paths, OriginPathInfo must also be copied
#               (otherwise Photoshop may give a "program error" and refuse to
#               load the image).
#
# Usage:
#
#   1) Extract Photoshop path names:
# 
#      exiftool -config photoshop_paths.config -allpaths FILE
#
#   2) Extract Photoshop path names and anchor points:
# 
#      exiftool -config photoshop_paths.config -userparam anchor -allpaths FILE
#
#   3) Extract Photoshop path anchor points only:
# 
#      exiftool -config photoshop_paths.config -userparam anchoronly -allpaths FILE
#
#   4) Copy all Photoshop paths from one file (SRC) to another (DST):
#      (note that OriginPathInfo must also be copied when copying all paths)
#
#      exiftool -config photoshop_paths.config -tagsfromfile SRC -allpaths# -originpathinfo DST
#
#   5) Extract path names and anchor points in pixel coordinates:
#
#      exiftool -config photoshop_paths.config -allpathpix FILE
#
# Requires:     ExifTool version 9.95 or later
#
# Notes:        A "-" before a set of Bezier path points indicates a closed subpath,
#               and a "+ indicates the start of an open subpath.
#
# Revisions:    2015/05/07 - P. Harvey Created
#               2016/09/14 - PH Added feature to allow extracting anchor points
#               2017/01/24 - PH Added PathCount and PathPix Composite tags
#               2017/02/02 - PH Added support for copying OriginPathInfo
#               2017/02/22 - PH Fixed problem printing some paths
#               2017/03/19 - PH Added "-" or "+" at the start of closed or open
#                               subpath respectively
#               2017/06/03 - PH Added TotalPathPoints
#               2017/07/17 - PH Added UniquePathPoints
#
# References:   http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,1621.0.html
#               http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3910.0.html
#               http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,6647.0.html
#------------------------------------------------------------------------------

# Print Photoshop path name and/or anchor points
# Inputs: 0) reference to Photoshop path data, 1) ExifTool object reference
#         2-3) optional image width/height to convert anchor points to pixels
# Returns: String with name and/or Bezier knot anchor points
sub PrintPath($$;$$)
{
    my ($val, $et, $w, $h) = @_;
    my ($pos, $name, @rtn);
    my $len = length($$val) - 26;

    # recover exiftool-added path name if it exists
    if ($$val =~ m{.*/#(.{0,255})#/$}s) {
        $name = $1;
        $len -= length($1) + 4;
    } else {
        $name = '<none>';
    }
    my $anchorOnly = $et->Options(UserParam => 'AnchorOnly');
    push @rtn, $name unless $anchorOnly;

    # loop through path points and extract anchor points if specified
    if ($anchorOnly or $et->Options(UserParam => 'Anchor') or defined $w) {
        SetByteOrder('MM');
        for ($pos=0; $pos<=$len; $pos+=26) {
            my $type = Get16u($val, $pos);
            $type == 0 and push(@rtn, '-'), next;
            $type == 3 and push(@rtn, '+'), next;
            # Bezier knot records are types 1, 2, 4 and 5
            next unless {1=>1,2=>1,4=>1,5=>1}->{$type};
            # the anchor point is at offset 10 in the Bezier knot record
            # (fixed-point values with 24-bits after the decimal point)
            my $y = Get32s($val, $pos+10) / 0x1000000;  # (vertical component first)
            my $x = Get32s($val, $pos+14) / 0x1000000;
            if (defined $w and defined $h) {
                push @rtn, sprintf('(%g,%g)', $x * $w, $y * $h);
            } else {
                push @rtn, sprintf('(%g,%g)', $x, $y);
            }
        }
    }
    return join ' ', @rtn;
}

%Image::ExifTool::Shortcuts::UserDefined = (
    # create "AllPaths" shortcut for all Photoshop path tags
    AllPaths => [
        map { sprintf "Path%x", $_ } (0x7d0 .. 0xbb5),
    ],
    AllPathPix => [
        map { sprintf "PathPix%x", $_ } (0x7d0 .. 0xbb5),
    ],
);

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Photoshop::Main' => {
        0xbb8 => {
            Name => 'OriginPathInfo',
            Flags => [ qw(Writable Protected Binary SetResourceName) ],
        },
        # generate tags for each of the 998 possible Photoshop paths
        map { $_ => {
            Name => sprintf('Path%x', $_),
            Description => sprintf('Path %x', $_),
            Flags => [ qw(Writable Protected Binary ConvertBinary SetResourceName) ],
            PrintConv => \&PrintPath,
        } } (0x7d0 .. 0xbb5),
    },
    'Image::ExifTool::Composite' => {
        PathCount => {
            Desire => {
                map { $_-0x7d0 => sprintf('Path%x', $_) } (0x7d0 .. 0xbb5),
            },
            ValueConv => sub {
                my ($val, $self) = @_;
                my $count = 0;
                my $pts = 0;
                my $uniq = 0;
                my %uniq;
                foreach (@$val) {
                    next unless defined $_;
                    ++$count;
                    # determine the total number of path anchor points
                    my $len = length($$_) - 26;
                    for ($pos=0; $pos<=$len; $pos+=26) {
                        SetByteOrder('MM');
                        my $type = Get16u($_, $pos);
                        last if $type == 0x2f23; # (start of path name added by ExifTool)
                        next unless {1=>1,2=>1,4=>1,5=>1}->{$type};
                        my $pt = substr($$_, $pos+10, 8);
                        $uniq{$pt} or ++$uniq, $uniq{$pt} = 1;
                        ++$pts;
                    }
                }
                $$self{TotalPathPoints} = $pts;
                $$self{UniquePathPoints} = $uniq;
                return $count;
            },
        },
        UniquePathPoints => {
            Require => 'PathCount',
            ValueConv => '$$self{UniquePathPoints}',
        },
        TotalPathPoints => {
            Require => 'PathCount',
            ValueConv => '$$self{TotalPathPoints}',
        },
        map { sprintf('PathPix%x', $_) => {
            Require => {
                0 => 'ImageWidth',
                1 => 'ImageHeight',
                2 => sprintf('Path%x', $_),
            },
            Description => sprintf('Path Pix %x', $_),
            ValueConv => sub {
                my ($val, $et) = @_;
                PrintPath($$val[2], $et, $$val[0], $$val[1]);
            },
        } } (0x7d0 .. 0xbb5),
    },
);

1;  #end