%!PS % Dodging and burning utility dodbur1.psl % ======================================================= % by Don Lancaster %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright c 2005, 2010, 2014 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 % All commercial rights and all electronic media rights ~fully~ reserved. % Linking usually welcome. Reposting expressly forbidden. Version 2.1 % This allows portions of a bitmap to be selectively raised or lowered in brightness. % At present, anything within a green=255 mask gets adjusted. % Image must be EXTERNALLY converted to/from .JPG or other non .BMP format. % Any random green=255 pixels MUST be removed before masking! % NOTE THAT ALL PS FILENAME STRINGS !!!DEMAND!!! DOUBLE REVERSE SLASHES. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /sourcefilename (test01.bmp) store % original bitmap file /maskfilename (test01mask.bmp) store % original bitmap file with green=255 mask /targetfilename (test01db.bmp) store % destination file false { /sourcefilename (x2016.bmp) store % original bitmap file /maskfilename (xmask2016.bmp) store % original bitmap file with green=255 mask /targetfilename (xf2016.bmp) store % destination file } if /sourcefilenameprefix (C:\\Users\\MrDon\\Desktop\\gsPlay\\dodbur\\) store % pick a working prefix % /sourcefilenameprefix (C:\\Users\\MrDon\\Desktop\\Do today\\) store /targetfilenameprefix sourcefilenameprefix store % all files in same directory /maskfilenameprefix sourcefilenameprefix store /currentgamma {blackboostarray} store % pick an available correction generated below % /currentgamma {whitecutarray} store /adjdepth 30 store % select amount of brightening or darkening. % ========= % gonzo excerpts /mt {moveto} store /black {0 setgray} store % timing utilities. use stopwatchon and stopwatchoff for simple % one shot timing. For multiple time totals, use resettimer % starttimer stoptimer ... starttimer stoptimer reporttimer /stopwatchoff {stoptimer reporttimer} def % for single shots /stopwatchon {resettimer starttimer} def % for single shots /reporttimer {mytime 1000 div (\nElapsed time: ) print 20 string cvs print ( seconds.\n) print flush} def % to host /resettimer {/mytime 0 def} def % reset timer /starttimer {usertime /mytimenow exch def} def % add to time so far /stoptimer {usertime mytimenow sub /mytime exch mytime add def} def % for multiple timing intervals % mergestr merges the two top stack strings into one top stack string /mergestr {2 copy length exch length add string dup dup 4 3 roll 4 index length exch putinterval 3 1 roll exch 0 exch putinterval} def % [yourarray] makestring converts an array to a string... /makestring {dup length string dup % new string of right size /NullEncode filter % make a file out of string 3 -1 roll {1 index exch write} forall pop } def /random {rand 65536 div 32768 div mul cvi} def % as in -- 6 random -- % no longer used %%%%%%%%% end gonzo excerpts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% generate gamma functions %%%%%%%%%%%%%%%%%%%%%%%%% (\nGenerating Gamma functions...\n\n) print flush %%% One of these needs selected above as currentgamma % lighten blacks... /blackboostarray mark 255 -1 0 {255 div adjdepth mul round cvi} for] store % darken whites... /whitecutarray mark 0 1 255 { 255 div adjdepth mul round cvi neg} for] store % currentgamma == %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% copy create target filename %%%%%%%%%%%%%%%%%%%%%%% (\nVerifying bitmap...\n\n) print /wholesourcefilename sourcefilenameprefix sourcefilename mergestr store /wholemaskfilename sourcefilenameprefix maskfilename mergestr store /wholetargetfilename targetfilenameprefix targetfilename mergestr store /readfile wholesourcefilename (r) file store % establish input read file /maskfile wholemaskfilename (r) file store % establish mask read file /writefile wholetargetfilename (w+) file store % establish output target file /bitsperpixelposition 28 store % BMP header positioning info /datastartposition 10 store /horizontalpixels 18 store /verticalpixels 22 store /backcount 0 store /showtime true store %%%%%%%%% CHECK FOR VALID 24-BIT UNCOMPRESSED BITMAP %%%%%%%%%%%%% % BM check: readfile (XX) readstring pop % error message if file not two chars long (BM) eq {(File has correct "BM" as first two bytes.\n) print } { sourcefilename ( is not in .BMP format; further eval terminated.\n\n\n) mergestr print quit } ifelse % 24 bit check: readfile bitsperpixelposition setfileposition % access 2 {readfile read pop} repeat % get color planes error if not present 1 {256 mul add} repeat % calculate bits per pixel dup /bpp exch store % save for expanded analysis 10 string cvs % make string (24) eq {(File has correct 24-bit color format.\n) print } { sourcefilename ( is not in 24-bit format; further eval terminated.\n\n\n) mergestr print quit } ifelse % Compression mode: 4 {readfile read pop} repeat % get color planes error if not present 3 {256 mul add} repeat % calculate compression mode dup /cmm exch store % save for expanded analysis 10 string cvs % make string (0) eq {(File has correct 0 uncompressed format.\n) print } { sourcefilename ( is not in uncompressed format; further action terminated.\n\n\n) mergestr print quit } ifelse % Bitmap Width: readfile horizontalpixels setfileposition % access 4 {readfile read pop} repeat % get bitmap width bytes error if not present 3 {256 mul add} repeat % calculate data start dup /hres exch def 10 string cvs % make string showtime { (Bitmap width is ) exch mergestr ( pixels.\n) mergestr print flush } if % Bitmap Height: readfile verticalpixels setfileposition % access 4 {readfile read pop} repeat % get bitmap width bytes error if not present 3 {256 mul add} repeat % calculate data start dup /vres exch def 10 string cvs % make string showtime { (Bitmap height is ) exch mergestr ( pixels.\n) mergestr print flush } if % Find padding % .BMP rows MUST end on a 32-bit boundary! Zero, one, two, or three 00 % padding bits are required depending upon the actual width. /padding hres 3 mul cvi 4 mod % find start of next 32-byte block [ 0 3 2 1 ] exch get % TLU correction def (Padding 8-bit bytes per line are ) padding 10 string cvs mergestr ( .\n\n) mergestr print flush (Active storage 8-bit RGB bytes per line are ) hres 3 mul dup cvi /activestore exch store 10 string cvs mergestr ( .\n) mergestr print flush activestore 4 div ceiling cvi 4 mul /totalbytesperline exch store % find data start readfile datastartposition setfileposition % access 4 {readfile read pop} repeat % get data start bytes error if not present 3 {256 mul add} repeat % calculate data start /actualdatastart exch store % define read strings /linestring hres 3 mul string store % read file line buffer %%%%%%%%%%%%%%%%%%%% DUPLICATE SOURCE FILE %%%%%%%%%%%%%%%%%%%%% % Use of a separate target file prevents inadvertently trashing original. (\n\nCopying source file to target file\n) print flush /workstring 10000 string store stopwatchon readfile 0 setfileposition % start with byte zero! {readfile workstring readstring {writefile exch writestring} {writefile exch writestring exit} ifelse } loop % dangerous!!! /totalfilelength writefile fileposition 1 sub store writefile closefile stopwatchoff %% find the green pixels /findgreens { /readfile wholesourcefilename (r) file store % reestablish input read file /writefile wholetargetfilename (r+) file store % re establish output target file actualdatastart 1 add 3 totalfilelength { % dup /curpos exch store triples to 3 seconds maskfile exch setfileposition maskfile read pop % risky but fast? 255 eq {foundgreen }if } for } bind store %% process the green pixels /foundgreen { writefile maskfile fileposition 1 sub setfileposition 3 {writefile read pop 256 div} repeat 3 1 roll setrgbcolor currenthsbcolor 255 mul dup cvi currentgamma exch get add 255 div % adjust pixel brightness sethsbcolor currentrgbcolor 3 -1 roll writefile maskfile fileposition 1 sub setfileposition writefile exch 255 mul cvi write writefile exch 255 mul cvi write writefile exch 255 mul cvi write } bind store stopwatchon findgreens stopwatchoff asdfasdfasdf %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % speedup countdown originally 1.454 seconds 1.453 with rolls gone % EOF