11 |
|
my $mult = 179.0; # Multiplier. Default W/sr/m2 -> cd/m2 |
12 |
|
my $label = 'cd/m2'; # Units shown in legend |
13 |
|
my $scale = 1000; # Top of the scale |
14 |
< |
my $matchscale = 1; # Adjust top of scale to match given label |
14 |
> |
my $scaledigits = 3; # Number of maximum digits for numbers in legend |
15 |
|
my $decades = 0; # Default is linear mapping |
16 |
|
my $pal = 'def'; # Palette |
17 |
|
my $redv = "${pal}_red(v)"; # Mapping functions for R,G,B |
22 |
|
my $cpict = ''; |
23 |
|
my $legwidth = 100; # Legend width and height |
24 |
|
my $legheight = 200; |
25 |
+ |
my $haszero = 1; # print 0 in scale for falsecolor images only |
26 |
|
my $docont = ''; # Contours: -cl and -cb |
27 |
|
my $doposter = 0; # Posterization: -cp |
27 |
– |
my $loff = 0; # Offset to align with values |
28 |
|
my $doextrem = 0; # Don't mark extrema |
29 |
|
my $needfile = 0; |
30 |
|
my $showpal = 0; # Show availabel colour palettes |
43 |
|
} elsif (m/-s/) { # Scale |
44 |
|
$scale = shift; |
45 |
|
if ($scale =~ m/[aA].*/) { |
46 |
– |
$matchscale = 0; |
46 |
|
$needfile = 1; |
47 |
< |
} else { |
48 |
< |
$matchscale = 1; |
49 |
< |
} |
47 |
> |
} |
48 |
> |
} elsif (m/-d/) { # Number of maximum digits for numbers in legend |
49 |
> |
$scaledigits = shift; |
50 |
|
} elsif (m/-l$/) { # Label |
51 |
|
$label = shift; |
52 |
|
} elsif (m/-log/) { # Logarithmic mapping |
78 |
|
# Switches |
79 |
|
} elsif (m/-cl/) { # Contour lines |
80 |
|
$docont = 'a'; |
81 |
< |
$loff = 0.48; |
81 |
> |
$haszero = 0; |
82 |
|
} elsif (m/-cb/) { # Contour bands |
83 |
|
$docont = 'b'; |
84 |
< |
$loff = 0.52; |
84 |
> |
$haszero = 0; |
85 |
|
} elsif (m/-cp/) { # Posterize |
86 |
|
$doposter = 1; |
87 |
+ |
$haszero = 0; |
88 |
|
} elsif (m/-palettes/) { # Show all available palettes |
89 |
|
$scale = 45824; # 256 * 179 |
90 |
|
$showpal = 1; |
91 |
|
} elsif (m/-e/) { |
92 |
|
$doextrem = 1; |
93 |
|
$needfile = 1; |
94 |
– |
|
94 |
|
# Oops! Illegal option |
95 |
|
} else { |
96 |
|
die("bad option \"$_\"\n"); |
101 |
|
# Legend is too small to be legible. Don't bother doing one. |
102 |
|
$legwidth = 0; |
103 |
|
$legheight = 0; |
105 |
– |
$loff = 0; |
106 |
– |
$matchscale = 0; |
104 |
|
} |
105 |
|
|
106 |
|
# Temporary directory. Will be removed upon successful program exit. |
130 |
|
# 3.94282 6 |
131 |
|
my $LogLmax = $histo[0]; |
132 |
|
$scale = $mult / 179 * 10**$LogLmax; |
133 |
< |
} elsif ($matchscale) { |
134 |
< |
# Adjust scale so legend reflects -s setting |
135 |
< |
if ($decades > 0) { |
136 |
< |
$scale *= 10**($decades/(2.*$ndivs)); |
137 |
< |
} else { |
138 |
< |
$scale *= $ndivs/($ndivs - .5); |
139 |
< |
} |
133 |
> |
} |
134 |
> |
|
135 |
> |
if ($docont ne '') { |
136 |
> |
# -cl -> $docont = a |
137 |
> |
# -cb -> $docont = b |
138 |
> |
my $newv = join( "(v-1/ndivs)*ndivs/(ndivs-1)", split("v", $redv) ); |
139 |
> |
$redv = $newv; |
140 |
> |
$newv = join( "(v-1/ndivs)*ndivs/(ndivs-1)", split("v", $bluv) ); |
141 |
> |
$bluv = $newv; |
142 |
> |
$newv = join( "(v-1/ndivs)*ndivs/(ndivs-1)", split("v", $grnv) ); |
143 |
> |
$grnv = $newv; |
144 |
> |
} elsif ($doposter == 1) { |
145 |
> |
# -cp -> $doposter = 1 |
146 |
> |
my $newv = join( "seg2(v)", split("v", $redv) ); |
147 |
> |
$redv = $newv; |
148 |
> |
$newv = join( "seg2(v)", split("v", $bluv) ); |
149 |
> |
$bluv = $newv; |
150 |
> |
$newv = join( "seg2(v)", split("v", $grnv) ); |
151 |
> |
$grnv = $newv; |
152 |
|
} |
153 |
|
|
154 |
|
my $pc0 = "$td/pc0.cal"; |
166 |
|
btwn(a,x,b) : if(a-x,-1,b-x); |
167 |
|
clip(x) : if(x-1,1,if(x,x,0)); |
168 |
|
frac(x) : x - floor(x); |
169 |
< |
boundary(a,b) : neq(floor(ndivs*a+.5),floor(ndivs*b+.5)); |
169 |
> |
boundary(a,b) : neq(floor(ndivs*a),floor(ndivs*b)); |
170 |
|
|
171 |
|
spec_red(x) = 1.6*x - .6; |
172 |
|
spec_grn(x) = if(x-.375, 1.6-1.6*x, 8/3*x); |
173 |
|
spec_blu(x) = 1 - 8/3*x; |
174 |
|
|
175 |
< |
pm3d_red(x) = sqrt(x) ^ gamma; |
176 |
< |
pm3d_grn(x) = (x*x*x) ^ gamma; |
175 |
> |
pm3d_red(x) = sqrt(clip(x)) ^ gamma; |
176 |
> |
pm3d_grn(x) = clip(x*x*x) ^ gamma; |
177 |
|
pm3d_blu(x) = clip(sin(2*PI*clip(x))) ^ gamma; |
178 |
|
|
179 |
|
hot_red(x) = clip(3*x) ^ gamma; |
208 |
|
2.432735e-05,1.212949e-05,0.006659406,0.02539); |
209 |
|
def_blu(x):interp_arr(x/0.0454545+1,def_blup); |
210 |
|
|
211 |
< |
isconta = if(btwn(0,v,1),or(boundary(vleft,vright),boundary(vabove,vbelow)),-1); |
212 |
< |
iscontb = if(btwn(0,v,1),btwn(.4,frac(ndivs*v),.6),-1); |
211 |
> |
isconta = if(btwn(1/ndivs/2,v,1+1/ndivs/2),or(boundary(vleft,vright),boundary(vabove,vbelow)),-1); |
212 |
> |
iscontb = if(btwn(1/ndivs/2,v,1+1/ndivs/2),-btwn(.1,frac(ndivs*v),.9),-1); |
213 |
|
|
214 |
+ |
seg(x)=(floor(v*ndivs)+.5)/ndivs; |
215 |
+ |
seg2(x)=(seg(x)-1/ndivs)*ndivs/(ndivs-1); |
216 |
+ |
|
217 |
|
ra = 0; |
218 |
|
ga = 0; |
219 |
|
ba = 0; |
240 |
|
|
241 |
|
map(x) = x; |
242 |
|
|
243 |
+ |
|
244 |
|
ra = ri(nfiles); |
245 |
|
ga = gi(nfiles); |
246 |
|
ba = bi(nfiles); |
272 |
|
# -cl -> $docont = a |
273 |
|
# -cb -> $docont = b |
274 |
|
$pc0args .= qq[ -e "in=iscont$docont"]; |
262 |
– |
} elsif ($doposter == 1) { |
263 |
– |
# -cp -> $doposter = 1 |
264 |
– |
$pc0args .= qq[ -e "ro=${pal}_red(seg(v));go=${pal}_grn(seg(v));bo=${pal}_blu(seg(v))"]; |
265 |
– |
$pc0args .= q[ -e "seg(x)=(floor(v*ndivs)+.5)/ndivs"]; |
275 |
|
} |
276 |
|
|
277 |
|
if ($cpict eq '') { |
291 |
|
# Labels in the legend |
292 |
|
my $slabpic = "$td/slab.hdr"; |
293 |
|
my $cmd; |
285 |
– |
|
294 |
|
if ($legwidth > 0) { |
295 |
|
# Legend: Create the text labels |
296 |
< |
my $sheight = floor($legheight / $ndivs + 0.5); |
297 |
< |
$legheight = $sheight * $ndivs; |
298 |
< |
$loff = floor($loff * $sheight + 0.5); |
299 |
< |
my $text = "$label"; |
300 |
< |
for (my $i=0; $i<$ndivs; $i++) { |
301 |
< |
my $imap = ($ndivs - 0.5 - $i) / $ndivs; |
296 |
> |
my $sheight = floor($legheight / $ndivs ); |
297 |
> |
my $theight = floor($legwidth/(8/1.67)); |
298 |
> |
my $stheight = $sheight <= $theight ? $sheight : $theight; |
299 |
> |
my $vlegheight = $sheight * $ndivs * (1+1.5/$ndivs); |
300 |
> |
my $text = "$label\n"; |
301 |
> |
my $tslabpic = "$td/slabT.hdr"; |
302 |
> |
open PSIGN, "| psign -s -.15 -cf 1 1 1 -cb 0 0 0 -h $stheight > $tslabpic"; |
303 |
> |
print PSIGN "$text"; |
304 |
> |
close PSIGN; |
305 |
> |
my $loop = $ndivs+$haszero; |
306 |
> |
my $hlegheight = $sheight * ($loop) + $sheight * .5; |
307 |
> |
my $pcompost = qq[pcompos -b 0 0 0 =-0 $tslabpic 0 $hlegheight ]; |
308 |
> |
for (my $i=0; $i<$loop; $i++) { |
309 |
> |
my $imap = ($ndivs - $i) / $ndivs; |
310 |
|
my $value = $scale; |
311 |
|
if ($decades > 0) { |
312 |
|
$value *= 10**(($imap - 1) * $decades); |
313 |
|
} else { |
314 |
|
$value *= $imap; |
315 |
|
} |
300 |
– |
|
316 |
|
# Have no more than 3 decimal places |
317 |
< |
$value =~ s/(\.[0-9]{3})[0-9]*/$1/; |
318 |
< |
$text .= "\n$value"; |
317 |
> |
$value =~ s/(\.[0-9]{$scaledigits})[0-9]*/$1/; |
318 |
> |
$text = "$value\n"; |
319 |
> |
$tslabpic = "$td/slab$i.hdr"; |
320 |
> |
open PSIGN, "| psign -s -.15 -cf 1 1 1 -cb 0 0 0 -h $stheight > $tslabpic"; |
321 |
> |
print PSIGN "$text"; |
322 |
> |
close PSIGN; |
323 |
> |
$hlegheight = $sheight * ($loop - $i - 1) + $sheight * .5; |
324 |
> |
$pcompost .= qq[=-0 $tslabpic 0 $hlegheight ]; |
325 |
|
} |
326 |
< |
open PSIGN, "| psign -s -.15 -cf 1 1 1 -cb 0 0 0 -h $sheight > $slabpic"; |
327 |
< |
print PSIGN "$text\n"; |
307 |
< |
close PSIGN; |
326 |
> |
$pcompost .= qq[ > $slabpic]; |
327 |
> |
system $pcompost; |
328 |
|
|
329 |
|
# Legend: Create the background colours |
330 |
|
$cmd = qq[pcomb $pc0args]; |
331 |
< |
$cmd .= q[ -e "v=(y+.5)/yres;vleft=v;vright=v"]; |
332 |
< |
$cmd .= q[ -e "vbelow=(y-.5)/yres;vabove=(y+1.5)/yres"]; |
333 |
< |
$cmd .= qq[ -x $legwidth -y $legheight > $scolpic]; |
331 |
> |
$cmd .= qq[ -e "v=(y+.5-$sheight)/(yres/(1+1.5/$ndivs));;vleft=v;vright=v"]; |
332 |
> |
$cmd .= qq[ -e "vbelow=(y-.5-$sheight)/(yres/(1+1.5/$ndivs));vabove=(y+1.5-$sheight)/(yres/(1+1.5/$ndivs))"]; |
333 |
> |
$cmd .= qq[ -e "ra=0;ga=0;ba=0;"]; |
334 |
> |
$cmd .= qq[ -x $legwidth -y $vlegheight > $scolpic]; |
335 |
|
system $cmd; |
336 |
|
} else { |
337 |
|
# Create dummy colour scale and legend labels so we don't |
349 |
|
$cmd = qq[pcomb -e "lo=1-gi(1)" $slabpic > $slabinvpic]; |
350 |
|
system $cmd; |
351 |
|
|
331 |
– |
my $loff1 = $loff - 1; |
352 |
|
|
353 |
+ |
my $sh0 = -floor($legheight / $ndivs / 2); |
354 |
+ |
if ($haszero < 1) { |
355 |
+ |
$sh0 = -floor($legheight / ($ndivs)*1.5); |
356 |
+ |
} |
357 |
+ |
|
358 |
|
# Command line without extrema |
334 |
– |
$cmd = qq[pcomb $pc0args $pc1args "$picture"]; |
335 |
– |
$cmd .= qq[ "$cpict"] if ($cpict); |
336 |
– |
$cmd .= qq[ | pcompos $scolpic 0 0 +t .1 $slabinvpic 2 $loff1]; |
337 |
– |
$cmd .= qq[ -t .5 $slabpic 0 $loff - $legwidth 0]; |
359 |
|
|
360 |
+ |
$cmd = qq[pcomb $pc0args $pc1args "$picture"]; |
361 |
+ |
$cmd .= qq[ "$cpict"] if ($cpict); |
362 |
+ |
$cmd .= qq[ | pcompos -b 0 0 0 $scolpic 0 $sh0 +t .1 $slabinvpic 2 -1 ]; |
363 |
+ |
$cmd .= qq[ -t .5 $slabpic 0 0 - $legwidth 0]; |
364 |
+ |
|
365 |
|
if ($doextrem == 1) { |
366 |
|
# Get min/max image luminance |
367 |
|
my $cmd1 = 'pextrem -o ' . $picture; |
379 |
|
# Weighted average of R,G,B |
380 |
|
my $minpos = "$lxmin $ymin"; |
381 |
|
my $minval = ($rmin * .27 + $gmin * .67 + $bmin * .06) * $mult; |
382 |
< |
$minval =~ s/(\.[0-9]{3})[0-9]*/$1/; |
382 |
> |
$minval =~ s/(\.[0-9]{$scaledigits})[0-9]*/$1/; |
383 |
|
my $maxval = ($rmax * .27 + $gmax * .67 + $bmax * .06) * $mult; |
384 |
< |
$maxval =~ s/(\.[0-9]{3})[0-9]*/$1/; |
384 |
> |
$maxval =~ s/(\.[0-9]{$scaledigits})[0-9]*/$1/; |
385 |
|
|
386 |
|
# Create the labels for min/max intensity |
387 |
|
my $minvpic = "$td/minv.hdr"; |
392 |
|
# Add extrema labels to command line |
393 |
|
$cmd .= qq[ $minvpic $minpos $maxvpic $lxmax $ymax]; |
394 |
|
} |
395 |
+ |
|
396 |
+ |
|
397 |
+ |
|
398 |
|
|
399 |
|
# Process image and combine with legend |
400 |
|
system "$cmd"; |