1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include "cdl.h"
/* ANIMATE -- Example task to demonstrate rapid display of rasters such as
* would be done in an animation sequence, or in an acquisition system
* which needs to display guider images repeatedly (the actual inspiration
* for this demo.
*
* Examples:
* Display a scrolling test pattern:
* % animate
*
* Usage:
* animate [-nx N] [-ny N] [-fbconfig N]
*
* Note that your choice of frame buffer is important since if it's
* larger than the image size you're spending a lot of overhead in writing
* blank pixels around the actual image. When writing a true subraster of
* the image/frame buffer, the routine first reads back the pixels in the
* affected rows, edits the pixels in the subraster columns and then writes
* back the entire row. If the subraster width is the same size as the
* frame buffer width it does a straight write which will speed up the dis-
* play since you avoid the readback overhead. It may be worth defining a
* custom frame buffer the size of your image to speed things up.
*/
#define DIAGONAL 0 /* test pattern flags */
#define VERTICAL 1
#define HORIZONTAL 2
#define max(a,b) (a > b ? a : b) /* Utility macros */
#define min(a,b) (a < b ? a : b)
CDLPtr cdl;
uchar *pix = NULL;
main (argc, argv)
int argc;
char *argv[];
{
register int i, frame=1;
int nx=256, ny=256, fbconfig=0;
int status=0, fb_w, fb_h, nf, lx, ly;
uchar *line;
/* Handle command line args. */
if (argc > 1) {
for (i=1; i < argc; i++) {
if (strcmp (argv[i], "-nx") == 0)
nx = atoi (argv[++i]);
else if (strcmp (argv[i], "-ny") == 0)
ny = atoi (argv[++i]);
else if (strcmp (argv[i], "-fbconfig") == 0)
fbconfig = atoi (argv[++i]);
}
}
/* Open the package and a connection to the server. */
if (!(cdl = cdl_open ((char *)getenv("IMTDEV"))) )
exit (-1);
/* Make a test pattern. */
pix = (uchar *) malloc (nx * ny);
makeTestPattern (pix, nx, ny, DIAGONAL);
/* Now select a frame buffer large enough for the image. The
* fbconfig number is passed in the WCS packet, but the display
* calls below will compute the correct WCS for the image and
* transmit that prior to display, all we're doing here is
* setting up the FB to be used.
*/
if (fbconfig == 0)
cdl_selectFB (cdl, nx, ny, &fbconfig, &fb_w, &fb_h, &nf, 1);
else
cdl_lookupFBSize (cdl, fbconfig, &fb_w, &fb_h, &nf);
/* For the WCS we assume a simple linear transform where the image is
* Y-flipped, the (x,y) translation is computed so it is correct
* for an frame buffer >= than the image size. The Z-transform is
* fixed since we're using a test pattern with known values.
*/
cdl_setWCS (cdl, "test pattern", "", 1., 0., 0., -1.,
(float) (nx / 2) - (fb_w / 2) + 1, /* X translation */
(float) (fb_h / 2) + (ny / 2), /* Y translation */
0.0, 200.0, CDL_LINEAR); /* Z transform */
/* Select and clear the initial frame prior to display. */
cdl_setFrame (cdl, frame);
cdl_clearFrame (cdl);
/* Now display the pixels. We'll compute the image placement
* ourselves and write the image as a raw subraster of the frame
* buffer in the center of the display.
*/
lx = (fb_w / 2) - (nx / 2);
ly = fb_h - ((fb_h / 2) + (ny / 2));
status = cdl_writeSubRaster (cdl, lx, ly, nx, ny, pix);
/* Now animate the image. */
line = (uchar *) malloc (nx);
while (1) {
/* Shift the image down one line, roll the botton line to the
* top and redisplay the subraster/
*/
memcpy (pix, line, nx);
memmove (pix+nx, pix, (ny-1)*nx);
memcpy (line, pix+((ny-1)*nx), nx);
status = cdl_writeSubRaster (cdl, lx, ly, nx, ny, pix);
}
cdl_close (cdl); /* close the package */
free ((unsigned char *) pix); /* free the raster */
exit (status);
}
/* Make a test pattern. */
makeTestPattern (raster, nx, ny, pattern)
uchar *raster;
int nx, ny, pattern;
{
register uchar pix;
register int i, j;
register float scale;
for (i = 0; i < nx; i++) {
for (j = 0; j < ny; j++) {
switch (pattern) {
case DIAGONAL: /* Diagonal ramp */
scale = 200. / (float)(ny) / 2.;
pix = (uchar) max(2, (min(200,(scale*i + scale*j))));
break;
case VERTICAL: /* Vertical ramp */
scale = 200. / (float)(ny);
pix = (uchar) max(2, (min(200,(scale * i))));
break;
case HORIZONTAL: /* Horizontal ramp */
scale = 200. / (float)(nx);
pix = (uchar) max(2, (min(200,(scale * j))));
break;
}
raster[i * nx + j] = pix;
}
}
}
|