home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gems / graphics / orderdit.c < prev    next >
C/C++ Source or Header  |  1992-04-09  |  2KB  |  100 lines

  1. /*
  2. Ordered Dithering
  3. by Stephen Hawley
  4. from "Graphics Gems", Academic Press, 1990
  5. */
  6.  
  7. /* Program to generate dithering matrices.
  8.  * written by Jim Blandy, Oberlin College, jimb@occs.oberlin.edu
  9.  * Gifted to, documented and revised by Stephen Hawley,
  10.  * sdh@flash.bellcore.com
  11.  * 
  12.  * Generates a dithering matrix from the command line arguments.
  13.  * The first argument, size, determines the dimensions of the 
  14.  * matrix: 2^size by 2^size
  15.  * The optional range argument is the range of values to be 
  16.  * dithered over. By default, it is (2^size)^2, or simply the
  17.  * total number of elements in the matrix.
  18.  * The final output is suitable for inclusion in a C program.
  19.  * A typical dithering function is something like this:
  20.  * extern int dm[], size;
  21.  *
  22.  * int
  23.  * dither(x,y, level)
  24.  * register int x,y, level;
  25.  * {
  26.  *    return(level > dm[(x % size) + size * (y % size)];
  27.  * }
  28.  */
  29.  
  30. main(argc, argv)
  31. int argc;
  32. char **argv;
  33. {
  34.     register int size, range;
  35.  
  36.     if (argc >= 2) size = atoi(argv[1]);
  37.     else size = 2;
  38.  
  39.     if (argc == 3) range = atoi(argv[2]);
  40.     else range = (1 << size) * (1 << size);
  41.  
  42.     printdither (size, range);
  43. }
  44.  
  45.  
  46. printdither (size, range)
  47. register int size, range;
  48. {
  49.     register int l = (1 << size), i;
  50.      /*
  51.       * print a dithering matrix.
  52.       * l is the length on a side.
  53.       */
  54.     range = range / (l * l);
  55.     puts("int dm[] = {");
  56.     for (i=0; i < l*l; i++) {
  57.         if (i % l == 0) /* tab in 4 spaces per row */
  58.             printf("    ");
  59.         /* print the dither value for this location
  60.           * scaled to the given range
  61.          */
  62.         printf("%4d", range * dithervalue(i / l, i % l, size));
  63.  
  64.         /* commas after all but the last */
  65.         if (i + 1 < l * l)
  66.             putchar(',');
  67.         /* newline at the end of the row */
  68.         if ((i + 1) % l == 0)
  69.             putchar('\n');
  70.     }
  71.     puts("\n}; ");
  72. }
  73. dithervalue(x, y, size)
  74. register int x, y, size;
  75. {
  76.     register int d;
  77.     /*
  78.      * calculate the dither value at a particular
  79.      * (x, y) over the size of the matrix.
  80.      */
  81.     d=0;
  82.     while (size-->0)    {
  83.         /* Think of d as the density. At every iteration,
  84.          * d is shifted left one and a new bit is put in the
  85.          * low bit based on x and y. If x is odd and y is even,
  86.          * or x is even and y is odd, a bit is put in. This
  87.          * generates the checkerboard seen in dithering.
  88.          * This quantity is shifted left again and the low bit of
  89.          * y is added in.
  90.          * This whole thing interleaves a checkerboard bit pattern
  91.          * and y's bits, which is the value you want.
  92.          */
  93.         d = (d <<1 | (x&1 ^ y&1))<<1 | y&1;
  94.         x >>= 1;
  95.         y >>= 1;
  96.     }
  97.     return(d);
  98. }
  99.  
  100.