%!PS % An ACROBAT FLATE COMPRESSION READER UTILITY % =========================================== % by Don Lancaster % Copyright c 2002 by Don Lancaster & Synergetics, Box 809, Thatcher, AZ, 85552 % (928) 428-4073 Email: don@tinaja.com Website: http://www.tinaja.com % Consulting services available http://www.tinaja.com/info01.html % Linking welcome. Reposting expressly forbidden. % All commercial rights and all electronic media rights ~fully~ reserved. % Linking usually welcome. Reposting expressly forbidden. Version 1.5 % Describes http://www.tinaja.com/psutils/flatvue1.psl, a simple PostScript % utility that decodes Flate compression for viewing and analysis. % IMPORTANT NOTE: Don Lancaster's file gonzo.ps is required for this program. % After obvious location mods, uncomment ONE of the following two lines: (C:\\windows\\desktop\\gonzo\\gonzo.ps) run % use internal gonzo % (A:\\gonzo.ps) run % use external gonzo % NOTE THAT ALL PS FILENAME STRINGS !!!DEMAND!!! DOUBLE REVERSE SLASHES. % GONZO20A Guru Gonzo PostScript power tools (Interim release) % Includes gonzo justification and layout utilities. % Copyright c 1990, 1996, 2001 by Don Lancaster and Synergetics, Box 809, % Thatcher Arizona, 5552 (928) 428-4073 don@tinaja.com support % via http://www.tinaja.com All commercial rights and all electronic % media rights **FULLY** reserved. Reposting is expressly forbidden. %%%%%%%%%%% links menu directory %%%%%%%%%%%% % This code locks pdfmark commands out of a PostScript printer. /pdfmark where {pop}{userdict /pdfmark /cleartomark load put} ifelse % /surl "start url" marks the beginning of a text sequence to be urled. % It also paints the text blue... /surl {mark /blue cvx 0.33 /setgray cvx % change text to blue /currentpoint cvx % remember box start /urly /exch cvx /store cvx /urlx /exch cvx /store cvx ] cvx % complete deferred command printlist exch 3 index exch put % stuff into gonzo printlist exch 1 add exch % increment gonzo list count } def % /eurl "end url" unmarks the end of a text sequence and sets up % the pdfmark needed to define the Acrobat web link. /eurl {mark % start deferred proc exch % position url string % /black cvx 0 /setgray cvx % turn blue marker off % maintextcolor /setrgbcolor cvx % reset to main text color??? /aqua cvx /black cvx /makeurl cvx % defer call of url builder ] cvx % complete deferred proc printlist exch 3 index exch % stuff into gonzo printlist put exch 1 add exch % increment gonzo list count } def % /makeurl generates the pdfmark, receiving a {(urlstring) makeurl}. % Note that it is not called until formatted printlist time... /urlover 0.2 def % fraction of hot area over bounds /makeurl { /cururlname exch store % save the url string mark % start pdfmark currentfont /ScaleMatrix get 3 get /fsize exch store % guess height /Rect [ urlx fsize urlover mul sub % set box left x urly fsize urlover mul sub % set box left y currentpoint exch fsize urlover mul add exch fsize add ] /Border [ 0 0 0] % [0 0 0 ] = none; [0 0 2] = debug /Color [ .7 0 0 ] /Action <> /Subtype /Link /ANN % annotation type pdfmark % call pdf operators } def % /makeurlx generates the box specific pdfmark, receiving % a {(urlstring) makeurl}. % Note that it is not called until formatted printlist time... /makeurlx { /cururlnamex exch store % save the url string mark % start pdfmark /Rect [ xpos % set box left x ypos 0.9 sub % set box left y xpos 2.8 add % box right x ypos 0.9 sub 2.8 add % box right y ] /Border [ 0 0 0] % [0 0 0 ] = none; [0 0 2] = debug /Color [ .7 0 0 ] /Action <> /Subtype /Link /ANN % annotation type pdfmark % call pdf operators } def /maintextcolor {0 0 0 } def % text link specific data -- use dictionary instead below /tinaja {(http://www.tinaja.com) eurl} def /cubic01 {(http://www.tinaja.com/cubic01.asp) eurl} def /hack62 {(http://www.tinaja.com/glib/hack62.pdf) eurl} def /post01 {(http://www.tinaja.com/post01.asp) eurl} def /increment {(http://www.tinaja.com/text/bezgen3.html) eurl} def /interpolate {(http://members.bellatlantic.net/~vze2vrva/design.html) eurl } def /info01 {(http://www.tinaja.com/info01.asp) eurl} def /bezmath {(http://www.tinaja.com/text/bezmath.html) eurl } def /table {(http://www.tinaja.com/psutils/imtable.psl) eurl } def /maildon {(mailto:don@tinaja.com) eurl} def % dictionary method << %zzzzz /flatvue1 (http://www.tinaja.com/psutils/flatvue1.psl) /pdfrefman (http://partners.adobe.com/asn/developer/acrosdk/docs.html) /psrefman (http://partners.adobe.com/asn/developer/technotes/postscript.html) /tilley (http://www.tilleyfoundation.com) /mnglobal (http://www.mnglobal.com/energy/pg2.htm) /keely (http://www.keelynet.com) /evolve (http://www.evolvedtechnology.com) /hack64 (http://www.tinaja.com/glib/hack64.pdf) /hackar3 (http://www.tinaja.com/glib/hackar3.pdf) /resbn58 (http://www.tinaja.com/glib/resbn58.pdf) /bppt (http://www.batterypoweronline.com) /muse112 (http://www.tinaja.com/glib/muse112.pdf) /muse113 (http://www.tinaja.com/glib/muse113.pdf) /energfun (http://www.tinaja.com/glib/energfun.pdf) /bashpseu (http://www.tinaja.com/glib/bashpseu.pdf) /adobe (http://www.adobe.com) /netscape (http://www.netscape.com) /gallypsl (http://www.tinaja.com/galley1.psl) /gallypdf (http://www.tinaja.com/galley1.pdf) /atn5150 (http://partners.adobe.com/asn/developer/acrosdk/docs/createpdfapi/pdfmarkReference.pdf) /nutour (http://www.tinaja.com/bargains/nutour02.pdf) /nutoursource (http://www.tinaja.com/bargains/nutour02.psl) /bwhistle (http://www.tinaja.com/glib/bwhistle.pdf) /gonzo1 (http://www.tinaja.com/post01.asp#gonzo) /acrob01 (http://www.tinaja.com/acrob01.asp) /barg01 (http://www.tinaja.com/barg01.asp) /weblib01 (http://www.tinaja.com/weblib01.asp) /gurgrm01 (http://www.tinaja.com/gurgrm01.asp) /z1 (http://www.tinaja.com/bargains/thumb/albradz2.jpg) /z2 (http://www.tinaja.com/bargains/sbtesteq.asp) /z3 (http://www.tinaja.com/images/bargs/albrad02.jpg) /z4 (http://www.tinaja.com/bargains/thumb/tutenaz2.jpg) /z5 (http://www.tinaja.com/bargains/sbphone.asp) /z6 (http://www.tinaja.com/images/bargs/tutena02.jpg) /sourceme (http://www.tinaja.com/glib/gallery.psl) /sourceme2 (http://www.tinaja.com/glib/autourl.psl) >> {mark exch /eurl cvx ] cvx def} forall %%%%%%%%%%%%%%%% New colorizer patches %%%%%%%%%%%%%%%%%% /boxgrays 0.899 def /grayshade boxgrays def /mastergray boxgrays def /staytint {0.33 setgray} def /staytint1 {0.25 setgray} def /showadgrays true def /red {0 settint} def /Zmacro {staytint /ypos ypos 2 add def 72 300 div setlinewidth xpos ypos moveto txtwide 0 rlineto stroke /ypos ypos -2 add def tintoff} def % hair rule /amacro {(zy0) stringmacro /ypos ypos ypara add def 0.33 setgray } def % start drop cap /bmacro {(iFy1) stringmacro /ypos ypos ypara add def black} def % finish drop cap % Gonzo character colorizer /blueon {mark /blue cvx 0.33 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /blueoff {mark /beige cvx 0 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton {mark 0.33 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1 {mark 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1b {mark beige cvx % try for aqua after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1a {mark /aqua cvx % try for aqua after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1p {mark /burple cvx % try for aqua after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1r {mark /red cvx % try for aqua after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1b {mark /beige cvx % try for beige after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tintoff {mark 0 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def %%%%%%%%%%%%%% COMPACT VERSION OF COLORIZER II %%%%%%%%%%%%%%%%%%%%%% /settint {dup /currenttint exch store 5.999 mul dup floor cvi /&cbar exch store dup floor sub /&cwt exch store [ {/setgray [ /dup cvx 0.3 &cwt 0.59 mul add /ge cvx [1 /exch cvx &cwt 0.59 mul 0.30 add /sub cvx 1 &cwt sub 0.59 mul 0.11 add /div cvx /dup cvx 1 &cwt sub /mul cvx &cwt /add cvx /exch cvx ] cvx [ &cwt 0.59 mul 0.3 add /div cvx /dup cvx &cwt /mul cvx 0] cvx /ifelse cvx /setrgbcolor cvx] cvx /def cvx} {/setgray [/dup cvx 0.59 1 &cwt sub 0.3 mul add /ge cvx [1 &cwt sub 0.3 mul 0.59 add /sub cvx &cwt 0.3 mul 0.11 add /div cvx /dup cvx &cwt /mul cvx 1 &cwt sub /add cvx /exch cvx 1 /exch cvx] cvx [1 &cwt sub 0.3 mul 0.59 add /div cvx /dup cvx 1 &cwt sub /mul cvx /exch cvx 0] cvx /ifelse cvx /setrgbcolor cvx] cvx /def cvx} {/setgray [/dup cvx 0.59 &cwt 0.11 mul add /ge cvx [&cwt 0.11 mul 0.59 add /sub cvx 1 &cwt sub 0.11 mul 0.30 add /div cvx /dup cvx 1 &cwt sub /mul cvx &cwt /add cvx 1 /exch cvx] cvx [0 /exch cvx &cwt 0.11 mul 0.59 add /div cvx /dup cvx &cwt /mul cvx] cvx /ifelse cvx /setrgbcolor cvx] cvx /def cvx} {/setgray [/dup cvx 0.59 1 &cwt sub mul 0.11 add /ge cvx [1 &cwt sub 0.59 mul 0.11 add /sub cvx &cwt 0.59 mul 0.30 add /div cvx /dup cvx &cwt /mul cvx 1 &cwt sub /add cvx 1] cvx [0 /exch cvx 1 &cwt sub 0.59 mul 0.11 add /div cvx /dup cvx 1 &cwt sub /mul cvx /exch cvx] cvx /ifelse cvx /setrgbcolor cvx] cvx /def cvx} {/setgray [/dup cvx 0.11 &cwt 0.30 mul add /ge cvx[&cwt 0.30 mul 0.11 add /sub cvx 1 &cwt sub 0.30 mul 0.59 add /div cvx /dup cvx 1 &cwt sub /mul cvx &cwt /add cvx /exch cvx 1] cvx [ &cwt 0.30 mul 0.11 add /div cvx /dup cvx &cwt /mul cvx /exch cvx 0 /exch cvx ] cvx /ifelse cvx /setrgbcolor cvx ] cvx /def cvx} {/setgray [ /dup cvx 0.30 1 &cwt sub 0.11 mul add /ge cvx[ 1 /exch cvx 1 &cwt sub 0.11 mul 0.30 add /sub cvx &cwt 0.11 mul 0.59 add /div cvx /dup cvx &cwt /mul cvx 1 &cwt sub /add cvx ] cvx [ 1 &cwt sub 0.11 mul 0.30 add /div cvx /dup cvx 1 &cwt sub /mul cvx 0 /exch cvx] cvx /ifelse cvx /setrgbcolor cvx ] cvx /def cvx} ] &cbar get exec exec} bind def /beige {0.10 settint} def % examples of convenience operators /aqua {0.52 settint} def /blue {0.67 settint} def /lime {0.44 settint} def /burple {0.75 settint} def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /guru { gonzo begin ps.util.1 begin printerror nuisance begin} def % guru % activate gonzo utilities 50 50 10 setgrid % create grid % 56 61 showgrid /setpagefonts { /cstretch 0.015 def /sstretch 0.015 def /font0 /StoneSans-Bold 1.6 gonzofont /font1 /StoneSans 0.95 gonzofont /font4 /StoneSans 0.85 gonzofont /font3 /StoneSans-Bold 0.85 gonzofont /font6 /StoneSans-Bold 0.85 gonzofont /font8 /StoneSans-Bold [0.65 0 0 0.65 0 0.4] gonzofont /txtwide 36 store /yinc 1.2 store /kern 0.1 store /pm 1.5 store /tabs [7 -2] store aqua 0.33 setgray font1 black font2 /amacro { mark /aqua cvx 0.33 /setgray cvx ] cvx printlist exch 3 index exch % stuff into gonzo printlist put exch 1 add exch } def /bmacro { mark /black cvx ] cvx printlist exch 3 index exch % stuff into gonzo printlist put exch 1 add exch } def /shiftin {xpos /xposhold exch store /xpos xpos 3 add store} def /shiftout {/xpos xposhold store} def /texttop 51 store /textleft 3 store /fmacro % try and fake | {mark /gsave cvx /currentpoint cvx /moveto cvx 0.1 /setlinewidth cvx 0 0.65 /rlineto cvx /stroke cvx /grestore cvx ] cvx printlist exch 3 index exch put % stuff into gonzo printlist exch 1 add exch % increment gonzo list count } def } def setpagefonts % -2 50.5 (optional header here \274) cl aqua 0.33 setgray font0 20 47.3 0.7 add (An Acrobat Flate Compression) cc 20 45.3 0.7 add (PostScript Viewer Utility) cc black font2 %% Set document opening conventions. Note DOCVIEW limited. [/CropBox [0 0 520 620] % set the wierd size /PAGES pdfmark [ {Catalog} << /ViewerPreferences << /FitWindow true /CenterWindow true >> /PageLayout /OneColumn % continous /Pagemode /UseNone % no thumbs /View [/XYZ null null 1 ] % force 100% >> /PUT pdfmark textleft 43 (|3Don Lancaster Synergetics, Box 809, Thatcher, AZ 85552 copyright c2002 as |/surl |6GuruGram|1|/gurgrm01 |6#08 |/surl http://www.tinaja.com|/tinaja |/surl don@tinaja.com|/maildon (928) 428-4073 |h |a|0M|b|1|jost newer |/surl |6Acrobat|1|/acrob01 PDF distribution files have their object streams individually compressed by using |/tinton1 |6Flate Compression|1|/tintoff . Flate is an open source improved variant of LZW compression that is both more efficient and royalty free. Being able to read these obtuse objects in plaintext can be quite useful for program analysis, feature extraction, and new software design. |h The Flate Compression operation is detailed in the |/surl |6PDF Reference Manual|1|/pdfrefman and the |/surl |6PostScript Reference Manual|1|/psrefman from |/surl |6Adobe Systems|1|/adobe . |h One obvious approach is to print your entire .PDF file to disk as |/surl |6PostScript|1|/post01 and then redistill the new file with compression turned off. However, this can sometimes cause a reorganization or worse. One that might eliminate or change the very object you are attempting to view. |h I've posted a simple |/surl |6FLATVUE1.PSL|1|/flatvue1 raw PS Flate Compression viewer utility to my |/surl |6Guru's Lair|1|/tinaja website as file |/surl |6http://www.tinaja.com/psutils/flatvue1.psl|1|/flatvue1 . |h You normally would use this utility by bringing it up in Wordpad or another WP or editor, studying the tutorial comments, changing the requested data, and sending the modified file to Acrobat Distiller. Distiller in turn produces a log file that contains both the compressed and freetext forms of your target object. |h For instance, a typical output might look like\274 |3|/shiftin |h|/burple |/staytint1 |k|k|k|k|k|kFlate compression... |h \(H‰loËnÂ0ZE¿ ÿ0Ëv“‡%q"!*^T©**¢¨@&Ä"l“ºrsrSP+ßqœ¦,P~yÎõÌÜ«DÅißÕ²±`ÒvçÉ$Z••!7ªR l> øî¢u§¥ùycˆa7CB± ¢·ò& @m”Õ*žz„ä9úT­úBÅšNB´2ò¢äu ÅAÙòþR5VJk*T]#}KÝ"ÍOúd`KbB[P"Ò RÎ\~ÇHG]Zo7ônLÙ´çÒÈf+=4 9+æyr&YLsHÀTŽðY¿`¡P¹...\) |h|1|/shiftout |/aqua |/black ) cl black beige 0.35 setgray 21 -2.5 (|3\320|j1|j\320) cc aqua showpage %%%%%%%%% 222222222 %% start page two 50 50 10 setgrid % create grid setpagefonts /tabs [16.5] store textleft texttop (|3|/shiftin |h|/burple |/staytint1 |k|k|k|k|kReads as... |h /DocumentSetup<> DP /Layer<> BDC 0 0.4039 1 rg 0 0 0 RG 0 i 1 w 4 M 0 j 0 J []0 d /RelativeColorimetric ri /R2 gs 543.7773 557 m 80.4443 557 l 80.4443 601.4443 l 543.7773 601.4443 l 543.7773 557 l h B 0 0.8745 0.1961 rg /R3 gs 368.2227 437 m 256 437 l 256 712.5557 l 368.2227 712.5557 l 368.2227 437 l h B 0.9216 0 0.0196 rg /R4 gs 440.4443 497 m 190.4443 497 l 190.4443 634.7778 l 440.4443 634.7778 l 440.4443 497 l h B EMC |h|1|/shiftout |/aqua |/black Your usual starting point is to copy a PDF file to a location that your Acrobat Distiller can reach. Such as\274 |3|/shiftin |h|/burple |/staytint1 /sourcefilename (C:\\\\\\\\WINDOWS\\\\\\\\Desktop\\\\\\\\gurugrams\\\\\\\\alphatrans\\\\\\\\threerects.pdf) def |h|1|/shiftout |/aqua |/black A read file object called |/tinton1 |6/workfile|1|/tintoff can then be created. Note that |/tinton1 |6double|1|/tintoff reverse slashes are needed inside a PostScript string every time you mean a single slash! ) cl black beige 0.35 setgray 21 -2.5 (|3-|j2|j-) cc aqua showpage %% start page three 50 50 10 setgrid % create grid setpagefonts /tabs [16.5] store textleft texttop (|1You then should pull your PDF file up into Wordpad or another editor and shop around for three crucial values: |3|/shiftin |h |/tinton1 |6/fileposloc|1|/tintoff is the start of the object holding your target Flate code. Which you read from the cross reference at the end of the .PDF file. Object six start will be on the sixth line down etc\274 |h |/tinton1 |6/fileheaderoffset|1|/tintoff is the byte count at which the Flate compression actually starts. Which you read by counting or guessing at the number of header characters. You want the |/tinton1 |6actual|1|/tintoff file start |/tinton1 |6without|1|/tintoff any preceding linefeeds or carriage returns. |h |/tinton1 |6/flatelengthstr|1|/tintoff is the actual character count in the compressed Flate file. Which you read from the header of your target file. It may be an actual number or may refer to another object such as |/tinton1 |67 0 R obj|1|/tintoff If an object, go to object 7 or wherever and read the value. |h|1|/shiftout |/aqua |/black Once you find these values, you reposition your file start using\274 |3|/shiftin |h|/burple |/staytint1 workfile fileposloc fileheaderoffset add setfileposition |h|1|/shiftout |/aqua |/black You then read the actual Flate compressed data by using\274 |3|/shiftin |h|/burple |/staytint1 workfile flatelengthstr readstring pop |h|1|/shiftout |/aqua |/black The sneaky line that does all the nasty decoding work is\274 |3|/shiftin |h|/burple |/staytint1 /FlateDecode filter reportstring readstring |h|1|/shiftout |/aqua |/black Note that the logfile opening parenthesis |/tinton1 |6must|1|/tintoff be on the |/tinton1 |6same|1|/tintoff line as the first compressed Flate character! Error messages will result unless you have the |/tinton1 |6exact|1|/tintoff Flate start and the |/tinton1 |6exact|1|/tintoff length. Once properly decoded, you then pretty print both the compressed file and its expanded result to the Distiller log file. |h Note that a |/tinton1 |6"WARNING: Empty Job. No PDF file produced"|1|/tintoff message is normal and expected since your intended results appear in the log file. Your log file results can then be textfile viewed or exported by the usual cut-and-paste. |h This example only works for Flate files and decompressed outputs less than 65K long. As set by the length limit of a |/surl |6PostScript|1|/post01 string. More general code can be written to handle any length by repeated direct writing to disk files. |h Consulting services available per |/surl |6http://www.tinaja.com/info01.asp|1|/info01 . ) cl black beige 0.35 setgray 21 -2.5 (|3-|j3|j-) cc aqua showpage %%%%%%%%%%%%%%%%%%%% % EOF