Initial release of Maemo 5 port of gnuplot
[gnuplot] / pm3d / contrib / pm3dConvertToImage.awk
1 # pm3dConvertToImage.awk
2 # Written by Petr Mikulik, mikulik@physics.muni.cz
3 # Code of pm3dImage contributed by Dick Crawford
4 # Version: 8. 7. 2002
5 #
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.
11 #
12 # Usage:
13 #    gnuplot>set out "|awk -f pm3dConvertToImage.awk >image.ps"
14 # or
15 #    your_shell>awk -f pm3dConvertToImage.awk <map.ps >image.ps
16 #
17 # Distribution policy: this script belongs to the distribution of pm3d and
18 # gnuplot programs.
19 #
20 # Notes:
21 #    - no use of run length encoding etc --- you are welcome to contribute
22 #      an awk implementation
23 #
24 # History of changes:
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.
31 #
32 # License: public domain.
33
34
35 BEGIN {
36 err = "/dev/stderr"
37
38 if (ARGC!=1) {
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
47   error = -1
48   exit(1)
49 }
50
51 # Setup of main variables.
52 inside_pm3d_map = 0
53 pm3d_images = 0
54
55 # The following global variables will be used:
56 error=0
57 pm3dline=0
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
61 }
62
63
64 ########################################
65 # Add definition of pm3dImage to the dictionary
66 $1=="/BoxFill" && $NF=="def" {
67 print
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"
84 print "  } def"
85 next
86 }
87
88 ########################################
89 # Start pm3d map region.
90
91 !inside_pm3d_map && $1 == "%pm3d_map_begin" {
92 inside_pm3d_map = 1
93 pm3d_images++
94 # initialize variables for the image description
95 pm3dline = 0
96 scans = 1
97 row[scans] = ""
98 x2 = -29999.123; y2 = -29999.123
99 next
100 }
101
102
103 ########################################
104 # Outside pm3d map region.
105
106 !inside_pm3d_map {
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.
112     $2 = "{Stroke"
113     print
114 } else print
115 next
116 }
117
118
119 ########################################
120 # End of pm3d map region: write all.
121
122 $1 == "%pm3d_map_end" {
123 inside_pm3d_map = 0
124
125 if (pm3dline==0) { # empty map
126     pm3d_images--;
127     next;
128 }
129
130 if (scans_in_x) { grid_y = scan_pts; grid_x = scans; }
131   else  { grid_x = scan_pts; grid_y = scans; }
132
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
135
136 # write image header
137 print "%pm3d_image_begin"
138
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; }
141
142 #ORIGINAL:
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))
145
146 if (scans_in_x)
147     print "[ " x1 " " y1 " 90 " scaley " -" scalex " " grid_y " " grid_x " ] pm3dImage"
148 else
149     print "[ " x1 " " y1 " 0 " scalex " " scaley " " grid_x " " grid_y " ] pm3dImage"
150
151 if (scan_pts*scans != pm3dline) {
152   print "ERROR: pm3d image is not grid, exiting." >err
153   error=1
154   exit(8)
155 }
156
157 # write the substituted image stuff
158 for (i=1; i<=scans; i++) 
159   print row[i];
160
161 # write the tail of the image environment
162 print "%pm3d_image_end"
163
164 next
165 }
166
167
168 ########################################
169 # Read in the pm3d map/image data.
170
171 {
172 if (NF!=12 || toupper($2)!="G" || $5!="N") {
173         print "ERROR: Wrong (non-pm3d map) data on line " NR ", exiting." >err
174         error=1
175         exit(8)
176 }
177
178 pm3dline++;
179
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;
183 } else {
184         x2last=x2; y2last=y2;   # remember previous point
185         x2=$3; y2=$4;           # remember the current point
186 }
187
188 if (pm3dline==2) { # determine whether data are scans in x or in y
189     if (y1==y2) { # y=const, scan in x
190         scans_in_x = 0;
191         if (x1==x2) { 
192             print "ERROR: First two points are identical?! Exiting." >err
193             error=1
194             exit(5)
195         }
196     } else { # x=const, scan in y
197         if (x1!=x2) {
198                 print "ERROR: Map is obviously not rectangular, exiting." >err
199                 error=1
200                 exit(5)
201         }
202         scans_in_x = 1;
203     }
204 }
205
206 if ( pm3dline>2 && ((!scans_in_x && y2!=y2last) || (scans_in_x && x2!=x2last)) ) {
207         if (scans==1) scan_pts = pm3dline-1
208         scans++
209         row[scans] = ""
210 }
211
212 # now remember the intensity
213 row[scans] = row[scans] sprintf( "%02X", $1*255 );
214 next
215 } # reading map/image data
216
217
218
219 ########################################
220 # The end.
221
222 END {
223 if (error == 0 && inside_pm3d_map) {
224     print "ERROR: Corrupted pm3d block:  \"%pm3d_map_end\"  not found." >err
225     error=1
226 }
227 if (error==0) {
228     if (pm3d_images==0) 
229         print "No pm3d image found in the input file." >err
230     else
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
235         }
236 }
237
238
239 # eof pm3dConvertToImage.awk