home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsi / dissolve.c < prev    next >
Text File  |  1992-09-15  |  5KB  |  123 lines

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