~ubuntu-branches/ubuntu/trusty/xfractint/trusty

« back to all changes in this revision

Viewing changes to common/stereo.c

  • Committer: Bazaar Package Importer
  • Author(s): Riku Voipio
  • Date: 2010-11-24 21:24:54 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20101124212454-a2vxdh9pk5p5lhlm
Tags: 20.4.10-1
* New upstream version
* enable autobuilding, Closes: #410674, #587959
* update watch file. Closes: #449889
* remove bashism from rules, Closes: #581474

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
5
 
 
6
    Change History:
 
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
 
16
 
 
17
      (TW is Tim Wegner, PDL is Paul de Leeuw)
 
18
*/
 
19
 
 
20
#include <string.h>
 
21
#include <time.h>
 
22
 
 
23
  /* see Fractint.c for a description of the "include"  hierarchy */
 
24
#include "port.h"
 
25
#include "prototyp.h"
 
26
#include "helpdefs.h"
 
27
 
 
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
 
32
                                 * number */
 
33
char calibrate = 1;             /* add calibration bars to image */
 
34
char image_map = 0;
 
35
 
 
36
/* this structure permits variables to be temporarily static and visible
 
37
   to routines in this file without permanently hogging memory */
 
38
 
 
39
static struct static_vars
 
40
{
 
41
   long avg;
 
42
   long avgct;
 
43
   long depth;
 
44
   int barheight;
 
45
   int ground;
 
46
   int maxcc;
 
47
   int maxc;
 
48
   int minc;
 
49
   int reverse;
 
50
   int sep;
 
51
   double width;
 
52
   int x1;
 
53
   int x2;
 
54
   int xcen;
 
55
   int y;
 
56
   int y1;
 
57
   int y2;
 
58
   int ycen;
 
59
   BYTE *savedac;
 
60
} *pv;
 
61
 
 
62
#define AVG         (pv->avg)
 
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)
 
71
#define SEP         (pv->sep)
 
72
#define WIDTH       (pv->width)
 
73
#define X1          (pv->x1)
 
74
#define X2          (pv->x2)
 
75
#define Y           (pv->y)
 
76
#define Y1          (pv->y1)
 
77
#define Y2          (pv->y2)
 
78
#define XCEN        (pv->xcen)
 
79
#define YCEN        (pv->ycen)
 
80
 
 
81
/*
 
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
 
86
   0 to 255.
 
87
*/
 
88
 
 
89
typedef BYTE (*DACBOX)[256][3];
 
90
#define dac   (*((DACBOX)(pv->savedac)))
 
91
 
 
92
static int getdepth(int xd, int yd)
 
93
{
 
94
   int pal;
 
95
   pal = getcolor(xd, yd);
 
96
   if (grayflag)
 
97
   {
 
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);
 
102
      pal >>= 6;
 
103
   }
 
104
   return (pal);
 
105
}
 
106
 
 
107
/*
 
108
   Get min and max DEPTH value in picture
 
109
*/
 
110
 
 
111
static int get_min_max(void)
 
112
{
 
113
   int xd, yd, ldepth;
 
114
   MINC = colors;
 
115
   MAXC = 0;
 
116
   for(yd = 0; yd < ydots; yd++)
 
117
   {
 
118
      if (keypressed())
 
119
         return (1);
 
120
      if(yd == 20)
 
121
         showtempmsg("Getting min and max");
 
122
      for(xd = 0; xd < xdots; xd++)
 
123
      {
 
124
         ldepth = getdepth(xd,yd);
 
125
         if ( ldepth < MINC)
 
126
            MINC = ldepth;
 
127
         if (ldepth > MAXC)
 
128
            MAXC = ldepth;
 
129
      }
 
130
   }
 
131
   cleartempmsg();
 
132
   return(0);
 
133
}
 
134
 
 
135
void toggle_bars(int *bars, int barwidth, int far *colour)
 
136
{
 
137
   int i, j, ct;
 
138
   find_special_colors();
 
139
   ct = 0;
 
140
   for (i = XCEN; i < (XCEN) + barwidth; i++)
 
141
      for (j = YCEN; j < (YCEN) + BARHEIGHT; j++)
 
142
      {
 
143
         if(*bars)
 
144
         {
 
145
            putcolor(i + (int)(AVG), j , color_bright);
 
146
            putcolor(i - (int)(AVG), j , color_bright);
 
147
         }
 
148
         else
 
149
         {
 
150
            putcolor(i + (int)(AVG), j, colour[ct++]);
 
151
            putcolor(i - (int)(AVG), j, colour[ct++]);
 
152
         }
 
153
      }
 
154
   *bars = 1 - *bars;
 
155
}
 
156
 
 
157
int outline_stereo(BYTE * pixels, int linelen)
 
158
{
 
159
   int i, j, x, s;
 
160
   int far *same;
 
161
   int far *colour;
 
162
   if((Y) >= ydots)
 
163
      return(1);
 
164
   same   = (int far *)MK_FP(extraseg,0);
 
165
   colour = &same[ydots];
 
166
 
 
167
   for (x = 0; x < xdots; ++x)
 
168
      same[x] = x;
 
169
   for (x = 0; x < xdots; ++x)
 
170
   {
 
171
      if(REVERSE)
 
172
         SEP = GROUND - (int) (DEPTH * (getdepth(x, Y) - MINC) / MAXCC);
 
173
      else
 
174
         SEP = GROUND - (int) (DEPTH * (MAXCC - (getdepth(x, Y) - MINC)) / MAXCC);
 
175
      SEP =  (int)((SEP * 10.0) / WIDTH);        /* adjust for media WIDTH */
 
176
 
 
177
      /* get average value under calibration bars */
 
178
      if(X1 <= x && x <= X2 && Y1 <= Y && Y <= Y2)
 
179
      {
 
180
         AVG += SEP;
 
181
         (AVGCT)++;
 
182
      }
 
183
      i = x - (SEP + (SEP & Y & 1)) / 2;
 
184
      j = i + SEP;
 
185
      if (0 <= i && j < xdots)
 
186
      {
 
187
         /* there are cases where next never terminates so we timeout */
 
188
         int ct = 0;
 
189
         for (s = same[i]; s != i && s != j && ct++ < xdots; s = same[i])
 
190
         {
 
191
            if (s > j)
 
192
            {
 
193
               same[i] = j;
 
194
               i = j;
 
195
               j = s;
 
196
            }
 
197
            else
 
198
               i = s;
 
199
         }
 
200
         same[i] = j;
 
201
      }
 
202
   }
 
203
   for (x = xdots - 1; x >= 0; x--)
 
204
   {
 
205
      if (same[x] == x)
 
206
         /* colour[x] = rand()%colors; */
 
207
         colour[x] = (int)pixels[x%linelen];
 
208
      else
 
209
         colour[x] = colour[same[x]];
 
210
      putcolor(x, Y, colour[x]);
 
211
   }
 
212
   (Y)++;
 
213
   return(0);
 
214
}
 
215
 
 
216
 
 
217
/**************************************************************************
 
218
        Convert current image into Auto Stereo Picture
 
219
**************************************************************************/
 
220
 
 
221
int do_AutoStereo(void)
 
222
{
 
223
   struct static_vars v;
 
224
   BYTE savedacbox[256*3];
 
225
   int oldhelpmode, ret=0;
 
226
   int i, j, done;
 
227
   int bars, ct, kbdchar, barwidth;
 
228
   time_t ltime;
 
229
   unsigned char *buf = (unsigned char *)decoderline;
 
230
   /* following two lines re-use existing arrays in Fractint */
 
231
   int far *same;
 
232
   int far *colour;
 
233
   same   = (int far *)MK_FP(extraseg,0);
 
234
   colour = &same[ydots];
 
235
 
 
236
   pv = &v;   /* set static vars to stack structure */
 
237
   pv->savedac = savedacbox;
 
238
 
 
239
   /* Use the current time to randomize the random number sequence. */
 
240
   time(&ltime);
 
241
   srand((unsigned int)ltime);
 
242
 
 
243
   oldhelpmode = helpmode;
 
244
   helpmode = RDSKEYS;
 
245
   savegraphics();                      /* save graphics image */
 
246
   memcpy(savedacbox, dacbox, 256 * 3);  /* save colors */
 
247
 
 
248
   if(xdots > OLDMAXPIXELS)
 
249
   {
 
250
      static FCODE msg[] = 
 
251
         {"Stereo not allowed with resolution > 2048 pixels wide"};
 
252
      stopmsg(0,msg);
 
253
      buzzer(1);
 
254
      ret = 1;
 
255
      goto exit_stereo;
 
256
   }
 
257
 
 
258
   /* empircally determined adjustment to make WIDTH scale correctly */
 
259
   WIDTH = AutoStereo_width*.67;
 
260
   if(WIDTH < 1)
 
261
      WIDTH = 1;
 
262
   GROUND = xdots / 8;
 
263
   if(AutoStereo_depth < 0)
 
264
      REVERSE = 1;
 
265
   else
 
266
      REVERSE = 0;
 
267
   DEPTH = ((long) xdots * (long) AutoStereo_depth) / 4000L;
 
268
   DEPTH = labs(DEPTH) + 1;
 
269
   if(get_min_max())
 
270
   {
 
271
      buzzer(1);
 
272
      ret = 1;
 
273
      goto exit_stereo;
 
274
   }
 
275
   MAXCC = MAXC - MINC + 1;
 
276
   AVG = AVGCT = 0L;
 
277
   barwidth  = 1 + xdots / 200;
 
278
   BARHEIGHT = 1 + ydots / 20;
 
279
   XCEN = xdots/2;
 
280
   if(calibrate > 1)
 
281
      YCEN = BARHEIGHT/2;
 
282
   else
 
283
      YCEN = ydots/2;
 
284
 
 
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;
 
290
 
 
291
   Y = 0;
 
292
   if(image_map)
 
293
   {
 
294
      outln = outline_stereo;
 
295
      while((Y) < ydots)
 
296
         if(gifview())
 
297
         {
 
298
            ret = 1;
 
299
            goto exit_stereo;
 
300
         }
 
301
   }
 
302
   else
 
303
   {
 
304
      while(Y < ydots)
 
305
      {
 
306
          if(keypressed())
 
307
          {
 
308
             ret = 1;
 
309
             goto exit_stereo;
 
310
          }
 
311
          for(i=0;i<xdots;i++)
 
312
             buf[i] = (unsigned char)(rand()%colors);
 
313
          outline_stereo(buf,xdots);
 
314
      }
 
315
   }
 
316
 
 
317
   find_special_colors();
 
318
   AVG /= AVGCT;
 
319
   AVG /= 2;
 
320
   ct = 0;
 
321
   for (i = XCEN; i < XCEN + barwidth; i++)
 
322
      for (j = YCEN; j < YCEN + BARHEIGHT; j++)
 
323
      {
 
324
         colour[ct++] = getcolor(i + (int)(AVG), j);
 
325
         colour[ct++] = getcolor(i - (int)(AVG), j);
 
326
      }
 
327
   if(calibrate)
 
328
      bars = 1;
 
329
   else
 
330
      bars = 0;
 
331
   toggle_bars(&bars, barwidth, colour);
 
332
   done = 0;
 
333
   while(done==0)
 
334
   {
 
335
      while(keypressed()==0); /* to trap F1 key */
 
336
      kbdchar = getakey();
 
337
      switch(kbdchar)
 
338
      {
 
339
         case ENTER:   /* toggle bars */
 
340
         case SPACE:
 
341
            toggle_bars(&bars, barwidth, colour);
 
342
            break;
 
343
         case 'c':
 
344
         case '+':
 
345
         case '-':
 
346
            rotate((kbdchar == 'c') ? 0 : ((kbdchar == '+') ? 1 : -1));
 
347
            break;
 
348
         case 's':
 
349
         case 'S':
 
350
            diskisactive = 1;           /* flag for disk-video routines */
 
351
            savetodisk(savename);
 
352
            diskisactive = 0;
 
353
            break;
 
354
         default:
 
355
            if(kbdchar == 27)   /* if ESC avoid returning to menu */
 
356
               kbdchar = 255;
 
357
            ungetakey(kbdchar);
 
358
            buzzer(0);
 
359
            done = 1;
 
360
            break;
 
361
       }
 
362
   }
 
363
 
 
364
   exit_stereo:
 
365
   helpmode = oldhelpmode;
 
366
   restoregraphics();
 
367
   memcpy(dacbox, savedacbox, 256 * 3);
 
368
   spindac(0,1);
 
369
   return (ret);
 
370
}