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
|
% Copyright (C) 2001-2019 Artifex Software, Inc.
% All Rights Reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% Refer to licensing information at http://www.artifex.com or contact
% Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
% CA 94945, U.S.A., +1(415)492-9861, for further information.
%
%
% $Id:$
%
% Extract Input and Output ICC profiles from a PDF file
%
% Input ICC profiles are created with the prefix concatenated with
% the Resource ColorSpace name from the PDF file.
%
% Output ICC profiles are created with the prefix concatenated with
% an incrementing number (the text info is usually too bulky to make
% a reasonable file name).
%
% example usage:
%
% gs -q -dNODISPLAY extractICCprofiles.ps -c "(ICC_) (somefile.pdf) extractICCprofiles quit"
%
% to show only input (ICCBased) colorspace profiles, use -dICCin prior to the '-c'.
% to show only output (OutputIntent) device profiles, use -dICCout prior to the '-c'.
%
% default is -dICCin -dICCout (including one but not both selects only that type)
% Copy one file to another.
% Close the files when finished
/copyfile % <infile> <outfile> copyfile <outfile> <length>
{ 0 mark 32000 string
{ 4 index 1 index readstring
exch 5 index 1 index writestring
length 5 -1 roll add 4 1 roll
not { exit } if
} loop
cleartomark 3 -1 roll closefile
pop closefile
} bind def
/extractICCprofiles { % (prefix) (filename) extractICCprofiles
/DoICCin /ICCin where { pop true } { /ICCout where { pop false } { true } ifelse } ifelse def
/DoICCout /ICCout where { pop true } { /ICCin where { pop false } { true } ifelse } ifelse def
currentglobal true setglobal /CSNameDict 100 dict def setglobal
exch /fnprefix exch def % filename prefix
(r) file runpdfbegin
1 pdfpagecount % stack: first_page# last_page#
DoICCin {
1 exch {
pdfgetpage % get pagedict
/Resources pget {
/ColorSpace knownoget {
{
CSNameDict 2 index known not {
oforce
% stack: CSname CSobject
dup type /arraytype eq {
dup 0 oget /Indexed eq {
1 oget
dup type /arraytype ne { pop { 0 } } if
} if
dup 0 oget /ICCBased eq {
dup PDFfile fileposition exch
1 oget
mark exch { oforce } forall .dicttomark
true resolvestream
% construct a destination file name
fnprefix 4 index 100 string cvs concatstrings
(Found ICC input profile, extracting to: ) print dup = flush
(w) file copyfile
PDFfile exch setfileposition
currentglobal true setglobal CSNameDict 3 index //null put setglobal
} if % CS must be ICCBased
} if % ICCBased must be array
} if % CS Resource Name already known ?
pop pop % done with CSname and object
} forall % enumerate the ColorSpace Resource dict
} if
} if
} for % for each Page
} {
pop pop
} ifelse % DoICCin
% OutputIntent ICC output profiles are at the Catalog level
DoICCout {
/ICCoutcount 1 def
Trailer /Root oget /OutputIntents knownoget {
{ % process all output profiles present
dup /DestOutputProfile knownoget {
PDFfile fileposition exch
mark exch { oforce } forall .dicttomark
true resolvestream
(ICC output profile, extracted to: ) print
fnprefix ICCoutcount 10 string cvs concatstrings
dup = flush
(w) file
copyfile
PDFfile exch setfileposition
dup /OutputCondition knownoget { ( OutputCondition: ) print = } if
dup /OutputConditionIdentifier knownoget { ( OutputConditionIdentifier: ) print = } if
dup /Info knownoget { ( Info: ) print = } if
/ICCoutcount dup load 1 add def
} if
pop % done with this OutputIntent dictionary
} forall
} if % OutputIntents known
} if % DoICCout
} bind def
|