% Copyright (C) 2009 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 that % license. Refer to licensing information at http://www.artifex.com/ % or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, % San Rafael, CA 94903, 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 % copyfile { 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 get /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