home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gems / graphics / dissolve.c < prev    next >
Text File  |  1992-04-09  |  5KB  |  121 lines

  1. /* A Digital Dissolve Effect
  2. by Mike Morton
  3. from "Graphics Gems", Academic Press, 1990
  4. */
  5.  
  6. /*
  7.  * Code fragment to advance from one element to the next.
  8.  *
  9.  * int reg;                /* current sequence element
  10.  * reg = 1;                /* start in any non-zero state
  11.  * if (reg & 1)                /* is the bottom bit set?
  12.  *     reg = (reg >>1) ^ MASK;        /* yes: toss out 1 bit; XOR in mask
  13.  * else reg = reg >>1;            /* no: toss out 0 bit 
  14.  */
  15.  
  16. int randmasks[32];    /* Gotta fill this in yourself. */
  17.  
  18. dissolve1 (height, width)    /* first version of the dissolve                                 /* algorithm */
  19.     int height, width;    /* number of rows, columns */
  20. {
  21.     int pixels, lastnum;    /* number of pixels; */
  22.                 /* last pixel's number */
  23.     int regwidth;        /* "width" of sequence generator */
  24.     register long mask;    /* mask to XOR with to*/
  25.                     /* create sequence */
  26.     register unsigned long element; 
  27.                     /* one element of random sequence */
  28.     register int row, column;
  29.                     /* row and column numbers for a pixel */
  30.  
  31.       /* Find smallest register which produces enough pixel numbers */
  32.      pixels = height * width; /* compute number of pixels */
  33.                             /* to dissolve */
  34.      lastnum = pixels-1;    /* find last element (they go 0..lastnum) */
  35.      regwidth = bitwidth (lastnum); /* how wide must the */
  36.                     /* register be? */
  37.      mask = randmasks [regwidth];    /* which mask is for that width? */
  38.  
  39.      /* Now cycle through all sequence elements. */
  40.  
  41.       element = 1;    /* 1st element (could be any nonzero) */
  42.  
  43.  
  44.       do {
  45.         row = element / width;    /* how many rows down is this pixel? */
  46.         column = element % width;    /* and how many columns across? */
  47.         if (row < height)    /* is this seq element in the array? */
  48.           copy (row, column);    /* yes: copy the (r,c)'th pixel */
  49.  
  50.         /* Compute the next sequence element */
  51.         if (element & 1)        /* is the low bit set? */
  52.           element = (element >>1)^mask;    /* yes: shift value, */
  53.                         /* XOR in mask */
  54.         else element = (element >>1);    /* no: just shift the value */
  55.      } while (element != 1);        /* loop until we return  */
  56.                         /* to original element */
  57.      copy (0, 0);        /* kludge: the loop doesn't produce (0,0) */
  58. }                        /* end of dissolve1() */
  59.  
  60.  
  61.  
  62. int bitwidth (N)    /* find "bit-width" needed to represent N */
  63.     unsigned int N;    /* number to compute the width of */
  64. {
  65.      int width = 0;    /* initially, no bits needed to represent N */
  66.      while (N != 0) {    /* loop 'til N has been whittled down to 0 */
  67.         N >>= 1;        /* shift N right 1 bit (NB: N is unsigned) */
  68.         width++;        /* and remember how wide N is */
  69.       }            /* end of loop shrinking N down to nothing *
  70.       return (width);    /* return bit positions counted */
  71.  
  72. }                        /* end of bitwidth() */
  73.  
  74.  
  75.  
  76. dissolve2 (height, width)    /* fast version of the dissolve algorithm */
  77.     int height, width;    /* number of rows, columns */
  78. {
  79.     int rwidth, cwidth;    /* bit width for rows, for columns */
  80.     int regwidth;        /* "width" of sequence generator */
  81.     register long mask;    /* mask to XOR with to create sequence */
  82.     register int rowshift;    /* shift distance to get row  */
  83.                             /* from element */
  84.     register int colmask; /* mask to extract column from element */
  85.     register unsigned long element; /* one element of random */                                     /* sequence */
  86.     register int row, column;    /* row and column for one pixel */
  87.  
  88.  
  89.       /* Find the mask to produce all rows and columns. */
  90.  
  91.     rwidth = bitwidth (height); /* how many bits needed for height? */
  92.     cwidth = bitwidth (width);  /* how many bits needed for width? */
  93.     regwidth = rwidth + cwidth; /* how wide must the register be? */
  94.     mask = randmasks [regwidth]; /* which mask is for that width? */
  95.  
  96.  /* Find values to extract row and col numbers from each element. */
  97.     rowshift = cwidth; /* find dist to shift to get top bits (row) */
  98.     colmask = (1<<cwidth)-1;    /* find mask to extract  */
  99.                         /* bottom bits (col) */
  100.  
  101.       /* Now cycle through all sequence elements. */
  102.  
  103.     element = 1;    /* 1st element (could be any nonzero) */
  104.     do {
  105.         row = element >> rowshift; /* find row number for this pixel */
  106.         column = element & colmask; /* and how many columns across? */
  107.         if ((row < height)    /* does element fall in the array? */
  108.             && (column < width)) /* ...must check row AND column */
  109.         copy (row, column); /* in bounds: copy the (r,c)'th pixel */
  110.  
  111.         /* Compute the next sequence element */
  112.         if (element & 1)        /* is the low bit set? */
  113.         element = (element >>1)^mask; /* yes: shift value, /*
  114.                         /* XOR in mask */
  115.         else element = (element >>1); /* no: just shift the value */
  116.     } while (element != 1);     /* loop until we return to */
  117.                     /*  original element */
  118.  
  119.     copy (0, 0);        /* kludge: element never comes up zero */
  120. }                    /* end of dissolve2() */
  121.