1
-- $Id: x20a.adb 11680 2011-03-27 17:57:51Z airwin $
5
-- Copyright (C) 2008 Jerry Bauck
7
-- This file is part of PLplot.
9
-- PLplot is free software; you can redistribute it and/or modify
10
-- it under the terms of the GNU Library General Public License as published
11
-- by the Free Software Foundation; either version 2 of the License, or
12
-- (at your option) any later version.
14
-- PLplot is distributed in the hope that it will be useful,
15
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
16
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
-- GNU Library General Public License for more details.
19
-- You should have received a copy of the GNU Library General Public License
20
-- along with PLplot; if not, write to the Free Software
21
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29
Ada.Numerics.Long_Elementary_Functions,
37
Ada.Numerics.Long_Elementary_Functions,
45
XDIM : constant Integer := 260;
46
YDIM : constant Integer := 220;
47
PLK_Return : constant unsigned := 16#0D#;
49
nosombrero : Integer := 0;
50
nointeractive : Integer := 0;
51
x : Real_Vector(0 .. XDIM - 1);
52
y : Real_Vector(0 .. YDIM - 1);
53
z, r : Real_Matrix(0 .. XDIM - 1, 0 .. YDIM - 1);
54
xi, yi, xe, ye : Long_Float;
55
width, height, num_col : Integer;
56
img_f : Real_Matrix(0 .. 398, 0 .. 485); -- Lena is width 399, height 486.
57
img_min, img_max : Long_Float;
58
Get_Clip_Return : Integer;
61
xmin, xmax, ymin, ymax : Long_Float;
64
stretch : stretch_data;
66
f_name : String(1 .. 200);
67
f_name_length : Integer;
68
Save_Sombrero : Boolean := False;
70
-- Read image from file in binary ppm format.
72
(fname : String; img_f : out Real_Matrix;
73
width, height, num_col : out Integer)
75
type Byte is mod 2 ** 8;
77
package Lena_IO is new Ada.Sequential_IO(Byte);
79
Input_File : Lena_IO.File_Type;
81
-- Naive grayscale binary ppm reading. If you know how to, improve it.
82
-- Mine is naiver than yours.
83
-- lena.pgm has 133 bytes of header followed by 399 * 486 bytes of 8-bit pixels.
84
Lena_IO.Open(Input_File, In_File, fname);
86
for i in 1 .. 133 loop
87
Lena_IO.Read(Input_File, A_Byte);
90
width := 399; -- columns
91
height := 486; -- rows
92
num_col := 255; -- number of colors
94
for j in img_f'range(2) loop
95
for i in img_f'range(1) loop
96
Lena_IO.Read(Input_File, A_Byte);
97
img_f(i, height - j - 1) := Long_Float(A_Byte); -- Flip image up-down.
104
procedure save_plot(fname : String) is
105
cur_strm, new_strm : Integer;
107
plgstrm(cur_strm); -- Get current stream.
108
plmkstrm(new_strm); -- Create a new one.
109
plsdev("psc"); -- New device type. Use a known existing driver.
110
plsfnam(fname); -- Set the file name.
111
plcpstrm(cur_strm, False); -- Copy old stream parameters to new stream.
112
plreplot; -- Do the save.
113
plend1; -- Close new device...
114
plsstrm(cur_strm); -- ...and return to previous one.
118
-- Get selection square interactively.
119
procedure get_clip(xi, xe, yi, ye : in out Long_Float; Return_This : out Integer) is
120
gin : Graphics_Input_Record_Type;
121
xxi : Long_Float := xi;
122
yyi : Long_Float := yi;
123
xxe : Long_Float := xe;
124
yye : Long_Float := ye;
126
start : Integer := 0;
127
st : Boolean := False;
128
sx, sy : Real_Vector(0 .. 4);
130
plxormod(True, st); -- Enter xor mode to draw a selection rectangle.
132
if st then -- Driver has xormod capability. Continue.
138
if gin.button = 1 then
142
-- Suppress warning """sy"" may be referenced before it has a value".
143
pragma Warnings(Off);
144
plline(sx, sy); -- Clear previous rectangle.
156
if (gin.state and Unsigned(16#100#)) /= 0 then
161
plline(sx, sy); -- Clear previous rectangle.
172
plline(sx, sy); -- Draw new rectangle.
175
if gin.button = 3 or gin.keysym = PLK_Return or
176
gin.keysym = unsigned(Character'pos('Q')) then
178
plline(sx, sy); -- Clear previous rectangle.
184
plxormod(False, st); -- Leave xor mod.
203
if gin.keysym = unsigned(Character'pos('Q')) then
208
else -- Driver has no xormod capability; just do nothing.
214
-- Set gray colormap.
215
procedure gray_cmap(num_col : Integer) is
216
r, g, b, pos : Real_Vector(0 .. 1);
230
plscmap1l(RGB, pos, r, g, b, Reverse_Hue_None);
236
tx, ty : out Long_Float;
239
x0, y0, dy : Long_Float;
241
x0 := (s.xmin + s.xmax) * 0.5;
242
y0 := (s.ymin + s.ymax) * 0.5;
243
dy := (s.ymax - s.ymin) * 0.5;
244
tx := x0 + (x0 - x) * (1.0 - s.stretch * cos((y - y0) / dy * pi * 0.5));
249
-- Bugs in plimage():
250
-- -at high magnifications, the left and right edge are ragged. Try
251
-- ./x20c -dev xwin -wplt 0.3,0.3,0.6,0.6 -ori 0.5.
254
-- -if the window is resized after a selection is made on "lena", when
255
-- making a new selection the old one will re-appear.
258
-- Parse and process command line arguments
259
plparseopts(PL_PARSE_FULL);
264
-- View image border pixels.
266
plenv(1.0, Long_Float(XDIM), 1.0, Long_Float(YDIM), 1, 1); -- no plot box
268
-- Build a one pixel square border, for diagnostics.
269
for i in z'range(1) loop
270
z(i, YDIM - 1) := 1.0; -- right
273
for i in z'range(1) loop
274
z(i, 0) := 1.0; -- left
277
for i in z'range(2) loop
278
z(0, i) := 1.0; -- top
281
for i in z'range(2) loop
282
z(XDIM - 1, i) := 1.0; -- botton
285
pllab("...around a blue square."," ","A red border should appear...");
288
1.0, Long_Float(XDIM), 1.0, Long_Float(YDIM), 0.0, 0.0,
289
1.0, Long_Float(XDIM), 1.0, Long_Float(YDIM));
292
-- sombrero-like demo
293
if nosombrero = 0 then
294
plcol0(2); -- Draw a yellow plot box, useful for diagnostics! :(
295
plenv(0.0, 2.0 * pi, 0.0, 3.0 * pi, 1, -1);
297
for i in x'range loop
298
x(i) := Long_Float(i) * 2.0 * pi / Long_Float(XDIM - 1);
301
for i in y'range loop
302
y(i) := Long_Float(i) * 3.0 * pi / Long_Float(YDIM - 1);
305
for i in z'range(1) loop
306
for j in z'range(2) loop
307
r(i, j) := sqrt(x(i) * x(i) + y(j) * y(j)) + 1.0e-3;
308
z(i, j) := sin(r(i, j)) / (r(i, j));
312
pllab("No, an amplitude clipped ""sombrero""", "", "Saturn?");
313
plptex(2.0, 2.0, 3.0, 4.0, 0.0, "Transparent image");
314
plimage(z, 0.0, 2.0 * pi, 0.0, 3.0 * pi, 0.05, 1.0,
315
0.0, 2.0 * pi, 0.0, 3.0 * pi);
318
if Save_Sombrero then
319
Put("Enter a path and name to save the Postscript file or RETURN to not save: ");
320
Get_Line(f_name, f_name_length);
321
if f_name'Length /= 0 then
322
save_plot(f_name(1 .. f_name_length));
327
-- Read the Lena image.
328
-- Note we try two different locations to cover the case where this
329
-- examples is being run from the test_c.sh script.
331
read_img("./lena.pgm", img_f, width, height, num_col);
336
read_img("../lena.pgm", img_f, width, height, num_col);
339
Put_Line("Failed to open lena.pgm. Aborting.");
342
end; -- second exception block
343
end; -- first exception block
345
-- Set gray colormap.
349
plenv(1.0, Long_Float(width), 1.0, Long_Float(height), 1, -1);
351
if nointeractive = 0 then
352
pllab("Set and drag Button 1 to (re)set selection, Button 2 to finish."," ","Lena...");
354
pllab(""," ","Lena...");
357
plimage(img_f, 1.0, Long_Float(width), 1.0, Long_Float(height), 0.0, 0.0, 1.0,
358
Long_Float(width), 1.0, Long_Float(height));
360
-- Selection/expansion demo
361
if nointeractive = 0 then
367
get_clip(xi, xe, yi, ye, Get_Clip_Return); -- get selection rectangle
368
if Get_Clip_Return /= 0 then
372
-- I'm unable to continue, clearing the plot and advancing to the next
373
-- one, without hiting the enter key, or pressing the button... help!
375
-- Forcing the xwin driver to leave locate mode and destroying the
376
-- xhairs (in GetCursorCmd()) solves some problems, but I still have
377
-- to press the enter key or press Button-2 to go to next plot, even
378
-- if a pladv() is not present! Using plbop() solves the problem, but
379
-- it shouldn't be needed!
383
-- plspause(0), pladv(0), plspause(1), also works,
384
-- but the above question remains.
385
-- With this approach, the previous pause state is lost,
386
-- as there is no API call to get its current state.
391
-- Display selection only.
392
plimage(img_f, 1.0, Long_Float(width), 1.0, Long_Float(height), 0.0, 0.0, xi, xe, ye, yi);
396
-- Zoom in selection.
397
plenv(xi, xe, ye, yi, 1, -1);
398
plimage(img_f, 1.0, Long_Float(width), 1.0, Long_Float(height), 0.0, 0.0, xi, xe, ye, yi);
401
-- Base the dynamic range on the image contents.
402
img_min := Matrix_Min(img_f);
403
img_max := Matrix_Max(img_f);
405
-- Draw a saturated version of the original image. Use only the middle 50%
406
-- of the image's full dynamic range.
408
plenv(0.0, Long_Float(width), 0.0, Long_Float(height), 1, -1);
409
pllab("", "", "Reduced dynamic range image example");
410
plimagefr(img_f, 0.0, Long_Float(width), 0.0, Long_Float(height), 0.0, 0.0,
411
img_min + img_max * 0.25, img_max - img_max * 0.25, Null, System.Null_Address);
413
-- Draw a distorted version of the original image, showing its full dynamic range.
414
plenv(0.0, Long_Float(width), 0.0, Long_Float(height), 1, -1);
415
pllab("", "", "Distorted image example");
418
stretch.xmax := Long_Float(width);
420
stretch.ymax := Long_Float(height);
421
stretch.stretch := 0.5;
423
-- In C / C++ the following would work, with plimagefr directly calling
424
-- mypltr. For compatibilty with other language bindings the same effect
425
-- can be achieved by generating the transformed grid first and then
427
-- plimagefr(img_f, width, height, 0., width, 0., height, 0., 0., img_min, img_max, mypltr, (PLPointer) &stretch);
429
declare -- Declare block is based on runtime-determined values of width, height.
430
cgrid2 : aliased Transformation_Data_Type_2
434
for i in 0 .. width loop
435
for j in 0 .. height loop
436
mypltr(Long_Float(i), Long_Float(j), xx, yy, stretch);
437
cgrid2.xg(i, j) := xx;
438
cgrid2.yg(i, j) := yy;
442
plimagefr(img_f, 0.0, Long_Float(width), 0.0, Long_Float(height), 0.0, 0.0, img_min, img_max,
443
pltr2'access, cgrid2'Address);