2
STEREO.C a module to view 3D images.
3
Written in Borland 'C++' by Paul de Leeuw.
4
From an idea in "New Scientist" 9 October 1993 pages 26 - 29.
7
11 June 94 - Modified to reuse existing Fractint arrays TW
8
11 July 94 - Added depth parameter PDL
9
14 July 94 - Added grayscale option and did general cleanup TW
10
19 July 94 - Fixed negative depth PDL
11
19 July 94 - Added calibration bars, get_min_max() TW
12
24 Sep 94 - Added image save/restore, color cycle, and save TW
13
28 Sep 94 - Added image map TW
14
20 Mar 95 - Fixed endless loop bug with bad depth values TW
15
23 Mar 95 - Allow arbitrary dimension image maps TW
17
(TW is Tim Wegner, PDL is Paul de Leeuw)
23
/* see Fractint.c for a description of the "include" hierarchy */
28
char stereomapname[FILE_MAX_DIR+1] = {""};
29
int AutoStereo_depth = 100;
30
double AutoStereo_width = 10;
31
char grayflag = 0; /* flag to use gray value rather than color
33
char calibrate = 1; /* add calibration bars to image */
36
/* this structure permits variables to be temporarily static and visible
37
to routines in this file without permanently hogging memory */
39
static struct static_vars
63
#define AVGCT (pv->avgct)
64
#define DEPTH (pv->depth)
65
#define BARHEIGHT (pv->barheight)
66
#define GROUND (pv->ground)
67
#define MAXCC (pv->maxcc)
68
#define MAXC (pv->maxc)
69
#define MINC (pv->minc)
70
#define REVERSE (pv->reverse)
72
#define WIDTH (pv->width)
78
#define XCEN (pv->xcen)
79
#define YCEN (pv->ycen)
82
The getdepth() function allows using the grayscale value of the color
83
as DEPTH, rather than the color number. Maybe I got a little too
84
sophisticated trying to avoid a divide, so the comment tells what all
85
the multiplies and shifts are trying to do. The result should be from
89
typedef BYTE (*DACBOX)[256][3];
90
#define dac (*((DACBOX)(pv->savedac)))
92
static int getdepth(int xd, int yd)
95
pal = getcolor(xd, yd);
98
/* effectively (30*R + 59*G + 11*B)/100 scaled 0 to 255 */
99
pal = ((int) dac[pal][0] * 77 +
100
(int) dac[pal][1] * 151 +
101
(int) dac[pal][2] * 28);
108
Get min and max DEPTH value in picture
111
static int get_min_max(void)
116
for(yd = 0; yd < ydots; yd++)
121
showtempmsg("Getting min and max");
122
for(xd = 0; xd < xdots; xd++)
124
ldepth = getdepth(xd,yd);
135
void toggle_bars(int *bars, int barwidth, int far *colour)
138
find_special_colors();
140
for (i = XCEN; i < (XCEN) + barwidth; i++)
141
for (j = YCEN; j < (YCEN) + BARHEIGHT; j++)
145
putcolor(i + (int)(AVG), j , color_bright);
146
putcolor(i - (int)(AVG), j , color_bright);
150
putcolor(i + (int)(AVG), j, colour[ct++]);
151
putcolor(i - (int)(AVG), j, colour[ct++]);
157
int outline_stereo(BYTE * pixels, int linelen)
164
same = (int far *)MK_FP(extraseg,0);
165
colour = &same[ydots];
167
for (x = 0; x < xdots; ++x)
169
for (x = 0; x < xdots; ++x)
172
SEP = GROUND - (int) (DEPTH * (getdepth(x, Y) - MINC) / MAXCC);
174
SEP = GROUND - (int) (DEPTH * (MAXCC - (getdepth(x, Y) - MINC)) / MAXCC);
175
SEP = (int)((SEP * 10.0) / WIDTH); /* adjust for media WIDTH */
177
/* get average value under calibration bars */
178
if(X1 <= x && x <= X2 && Y1 <= Y && Y <= Y2)
183
i = x - (SEP + (SEP & Y & 1)) / 2;
185
if (0 <= i && j < xdots)
187
/* there are cases where next never terminates so we timeout */
189
for (s = same[i]; s != i && s != j && ct++ < xdots; s = same[i])
203
for (x = xdots - 1; x >= 0; x--)
206
/* colour[x] = rand()%colors; */
207
colour[x] = (int)pixels[x%linelen];
209
colour[x] = colour[same[x]];
210
putcolor(x, Y, colour[x]);
217
/**************************************************************************
218
Convert current image into Auto Stereo Picture
219
**************************************************************************/
221
int do_AutoStereo(void)
223
struct static_vars v;
224
BYTE savedacbox[256*3];
225
int oldhelpmode, ret=0;
227
int bars, ct, kbdchar, barwidth;
229
unsigned char *buf = (unsigned char *)decoderline;
230
/* following two lines re-use existing arrays in Fractint */
233
same = (int far *)MK_FP(extraseg,0);
234
colour = &same[ydots];
236
pv = &v; /* set static vars to stack structure */
237
pv->savedac = savedacbox;
239
/* Use the current time to randomize the random number sequence. */
241
srand((unsigned int)ltime);
243
oldhelpmode = helpmode;
245
savegraphics(); /* save graphics image */
246
memcpy(savedacbox, dacbox, 256 * 3); /* save colors */
248
if(xdots > OLDMAXPIXELS)
251
{"Stereo not allowed with resolution > 2048 pixels wide"};
258
/* empircally determined adjustment to make WIDTH scale correctly */
259
WIDTH = AutoStereo_width*.67;
263
if(AutoStereo_depth < 0)
267
DEPTH = ((long) xdots * (long) AutoStereo_depth) / 4000L;
268
DEPTH = labs(DEPTH) + 1;
275
MAXCC = MAXC - MINC + 1;
277
barwidth = 1 + xdots / 200;
278
BARHEIGHT = 1 + ydots / 20;
285
/* box to average for calibration bars */
286
X1 = XCEN - xdots/16;
287
X2 = XCEN + xdots/16;
288
Y1 = YCEN - BARHEIGHT/2;
289
Y2 = YCEN + BARHEIGHT/2;
294
outln = outline_stereo;
312
buf[i] = (unsigned char)(rand()%colors);
313
outline_stereo(buf,xdots);
317
find_special_colors();
321
for (i = XCEN; i < XCEN + barwidth; i++)
322
for (j = YCEN; j < YCEN + BARHEIGHT; j++)
324
colour[ct++] = getcolor(i + (int)(AVG), j);
325
colour[ct++] = getcolor(i - (int)(AVG), j);
331
toggle_bars(&bars, barwidth, colour);
335
while(keypressed()==0); /* to trap F1 key */
339
case ENTER: /* toggle bars */
341
toggle_bars(&bars, barwidth, colour);
346
rotate((kbdchar == 'c') ? 0 : ((kbdchar == '+') ? 1 : -1));
350
diskisactive = 1; /* flag for disk-video routines */
351
savetodisk(savename);
355
if(kbdchar == 27) /* if ESC avoid returning to menu */
365
helpmode = oldhelpmode;
367
memcpy(dacbox, savedacbox, 256 * 3);