1 # pm3dConvertToImage.awk
2 # Written by Petr Mikulik, mikulik@physics.muni.cz
3 # Code of pm3dImage contributed by Dick Crawford
6 # This awk script tries to compress maps in a postscript file created by pm3d
7 # or gnuplot with pm3d splotting mode. If the input data formed a rectangular
8 # equidistant map (matrix), then its postscript representation is converted
9 # into an image operator with 256 levels (of gray or colour). This conversion
10 # makes the image 20 times smaller.
13 # gnuplot>set out "|awk -f pm3dConvertToImage.awk >image.ps"
15 # your_shell>awk -f pm3dConvertToImage.awk <map.ps >image.ps
17 # Distribution policy: this script belongs to the distribution of pm3d and
21 # - no use of run length encoding etc --- you are welcome to contribute
22 # an awk implementation
25 # - 8. 7. 2002 Petr Mikulik: Don't fail on empty map. Treat properly both
26 # cases of scans_in_x.
27 # - 4. 7. 2002 Petr Mikulik: Fix for compressing several images in one file.
28 # - 3. 10. 2001 Petr Mikulik: Replaced "stroke" by "Stroke" in the "/g"
29 # definition - fixes conversion of colour images.
30 # - 16. 5. 2000 Petr Mikulik and Dick Crawford: The first version.
32 # License: public domain.
39 print "pm3dConvertToImage.awk --- (c) Petr Mikulik, Brno. Version 8. 7. 2002" >err
40 print "Compression of matrix-like pm3d .ps files into 256 levels image. See also" >err
41 print "header of this script for more info." >err
42 print "Usage:\n\t[stdout | ] awk -f pm3dConvertToImage.awk [<inp_file.ps] >out_file.ps" >err
43 print "Example for gnuplot:" >err
44 print "\tset out \"|awk -f pm3dConvertToImage.awk >smaller.ps\"" >err
45 print "Hint: the region to be converted is between %pm3d_map_begin and %pm3d_map_end" >err
46 print "keywords. Rename them to avoid converting specified region." >err
51 # Setup of main variables.
55 # The following global variables will be used:
58 scans=0; scan_pts=0; scans_in_x=0
59 x1=0; y1 = 0; cell_x=0; cell_y=0
60 x2=0; y2 = 0; x2last=0; y2last=0
64 ########################################
65 # Add definition of pm3dImage to the dictionary
66 $1=="/BoxFill" && $NF=="def" {
68 print "/Stroke {stroke} def"
69 print "/pm3dImage {/I exch def gsave % saves the input array"
70 print " /ps 1 string def"
71 # print " Color not {/g {setgray} def} if % avoid stroke in the usual def of /g"
72 print " /Stroke {} def % avoid stroke in the usual def"
73 print " I 0 get I 1 get translate I 2 get rotate % translate & rotate"
74 print " /XCell I 3 get I 5 get div def % pixel width"
75 print " /YCell I 4 get I 6 get div def % pixel height"
76 print " 0 1 I 6 get 1 sub { % loop over rows"
77 print " /Y exch YCell mul def % save y-coordinate"
78 print " 0 1 I 5 get 1 sub { % loop over columns"
79 print " XCell mul Y moveto XCell 0 rlineto 0 YCell rlineto"
80 print " XCell neg 0 rlineto closepath % outline pixel"
81 print " currentfile ps readhexstring pop % read hex value"
82 print " 0 get cvi 255 div g % convert to [0,1]"
83 print " fill } for } for grestore % fill pixel & close loops"
88 ########################################
89 # Start pm3d map region.
91 !inside_pm3d_map && $1 == "%pm3d_map_begin" {
94 # initialize variables for the image description
98 x2 = -29999.123; y2 = -29999.123
103 ########################################
104 # Outside pm3d map region.
107 if ($1 == "%%Creator:")
108 print $0 ", compressed by pm3dConvertToImage.awk"
109 else if ($1 == "/g" && $2 == "{stroke") {
110 # Replace "/g {stroke ...}" by "/g {Stroke ...}" (stroke cannot be used
111 # in the pm3dImage region.
119 ########################################
120 # End of pm3d map region: write all.
122 $1 == "%pm3d_map_end" {
125 if (pm3dline==0) { # empty map
130 if (scans_in_x) { grid_y = scan_pts; grid_x = scans; }
131 else { grid_x = scan_pts; grid_y = scans; }
133 print "Info on pm3d image region number " pm3d_images ": grid " grid_x " x " grid_y >err
134 print "\tpoints: " pm3dline " scans: " scans " start point: " x1","y1 " end point: " x2","y2 >err
137 print "%pm3d_image_begin"
139 if (x1 > x2) { x1+=cell_x; x2+=cell_x; } # align offset of the image corner by the cell dimension
140 if (y1 > y2) { y1+=cell_y; y2+=cell_y; }
143 scalex = (grid_x <= 1) ? cell_x : (x2-x1)*(grid_x/(grid_x-1))
144 scaley = (grid_y <= 1) ? cell_y : (y2-y1)*(grid_y/(grid_y-1))
147 print "[ " x1 " " y1 " 90 " scaley " -" scalex " " grid_y " " grid_x " ] pm3dImage"
149 print "[ " x1 " " y1 " 0 " scalex " " scaley " " grid_x " " grid_y " ] pm3dImage"
151 if (scan_pts*scans != pm3dline) {
152 print "ERROR: pm3d image is not grid, exiting." >err
157 # write the substituted image stuff
158 for (i=1; i<=scans; i++)
161 # write the tail of the image environment
162 print "%pm3d_image_end"
168 ########################################
169 # Read in the pm3d map/image data.
172 if (NF!=12 || toupper($2)!="G" || $5!="N") {
173 print "ERROR: Wrong (non-pm3d map) data on line " NR ", exiting." >err
180 if (pm3dline==1) { # first point of the map
181 x1=$3; y1=$4; cell_x=$8;
182 x2=x1; y2=y1; cell_y=$9;
184 x2last=x2; y2last=y2; # remember previous point
185 x2=$3; y2=$4; # remember the current point
188 if (pm3dline==2) { # determine whether data are scans in x or in y
189 if (y1==y2) { # y=const, scan in x
192 print "ERROR: First two points are identical?! Exiting." >err
196 } else { # x=const, scan in y
198 print "ERROR: Map is obviously not rectangular, exiting." >err
206 if ( pm3dline>2 && ((!scans_in_x && y2!=y2last) || (scans_in_x && x2!=x2last)) ) {
207 if (scans==1) scan_pts = pm3dline-1
212 # now remember the intensity
213 row[scans] = row[scans] sprintf( "%02X", $1*255 );
215 } # reading map/image data
219 ########################################
223 if (error == 0 && inside_pm3d_map) {
224 print "ERROR: Corrupted pm3d block: \"%pm3d_map_end\" not found." >err
229 print "No pm3d image found in the input file." >err
231 print "There were " pm3d_images " pm3d image(s) found in the input file." >err
232 } else if (error>0) {
233 print "An ERROR has been reported. This file is INCORRECT."
234 print "An ERROR has been reported. Output file is INCORRECT." >err
239 # eof pm3dConvertToImage.awk