home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pctchnqs / 1991 / number5 / dither2.c < prev    next >
C/C++ Source or Header  |  1991-09-25  |  6KB  |  156 lines

  1. /*--------------------------------------------------------*/
  2. /* File: LISTING2.C   By: Marv Luse, Autumn Hill Software */
  3. /*                                                        */
  4. /* Desc: Program to illustrate the results of dithering.  */
  5. /*       An 8-level filled circular region is dithered    */
  6. /*       and rendered as a bi-level image.  Result is     */
  7. /*       shown on-screen using Borland C++ and BGI.       */
  8. /*       (Use Options-Compiler-Source = "Borland C++")    */
  9. /*--------------------------------------------------------*/
  10. #include "stdlib.h"
  11. #include "stdio.h"
  12. #include "conio.h"
  13. #include "dos.h"
  14. #include "graphics.h"
  15. /*--------------------------------------------------------*/
  16. /* Dithering types and data                               */
  17. /*--------------------------------------------------------*/
  18. typedef unsigned char DITHER_CELL[4];
  19. DITHER_CELL log_4x4[] = {
  20.   { 0x00, 0x00, 0x00, 0x00, }, { 0x00, 0x04, 0x00, 0x00, },
  21.   { 0x00, 0x04, 0x04, 0x00, }, { 0x00, 0x04, 0x06, 0x00, },
  22.   { 0x04, 0x06, 0x06, 0x00, }, { 0x04, 0x06, 0x0E, 0x02, },
  23.   { 0x0C, 0x07, 0x0E, 0x0B, }, { 0x0F, 0x0F, 0x0F, 0x0F, },};
  24. /*--------------------------------------------------------*/
  25. /* Variables to create 8-level pixel array                */
  26. /*--------------------------------------------------------*/
  27. #define pxWIDTH     175
  28. #define pxHEIGHT    175
  29. #define pxRADIUS     80
  30. char pxl_array[pxHEIGHT][pxWIDTH];
  31. /*--------------------------------------------------------*/
  32. /*  compute integer square root                           */
  33. /*--------------------------------------------------------*/
  34. int isqrt( int n ) {
  35.     long xnew, xold, y, d;
  36.     y    = n; /* initialize */
  37.     xnew = y;
  38.     xold = y / 2;
  39.     d    = xold;
  40. /* compute integer part of square root */
  41.     while( (d > 1) && (xold > 0) ) {
  42.          xnew = xold;  xnew += y/xold;  xnew /= 2;
  43.          d = xold - xnew;
  44.          xold = xnew;
  45.     }
  46. /* if desired, round to nearest integer */
  47.     xold = xnew + 1;
  48.     if( (n - xnew*xnew) > (xold*xold - n) )
  49.         xnew++;
  50.     return( (int) xnew );
  51. }
  52. /*--------------------------------------------------------*/
  53. /* Build filled circular image                            */
  54. /*--------------------------------------------------------*/
  55. void create_image( void ) {
  56.     int   i, j, xo, yo;
  57.     int   d, dx, dy, dxy;
  58.  
  59.     xo = pxWIDTH / 2;    /* center of circle */
  60.     yo = pxHEIGHT / 2;
  61. /* compute pixel values for filled circle */
  62.     for( i=0; i<pxHEIGHT; i++ ) {
  63.        dy = i - yo;
  64.        for( j=0; j<pxWIDTH; j++ ) {
  65.           dx = j - xo;
  66.           dxy = dx*dx + dy*dy;
  67.           d  = isqrt( dxy );
  68.           if( d <= pxRADIUS ) {
  69.              d *= 7;
  70.              d /= pxRADIUS;
  71.              pxl_array[i][j] = d;
  72.           }
  73.           else
  74.              pxl_array[i][j] = 0;
  75.        }
  76.     }
  77. }
  78. /*--------------------------------------------------------*/
  79. /* Draw 8-level version of circle                         */
  80. /*--------------------------------------------------------*/
  81. void draw_color_image( void ) {
  82.    int i, j;
  83.  
  84.     for( i=0; i<pxHEIGHT; i++ ) {
  85.        for( j=0; j<pxWIDTH; j++ ) {
  86.           putpixel( j, i, pxl_array[i][j] );
  87.        }
  88.     }
  89. }
  90. /*--------------------------------------------------------*/
  91. /* Draw dithered version of circle                        */
  92. /*--------------------------------------------------------*/
  93. void draw_dithered_image( void ) {
  94.     int           i, j, r, p;
  95.     unsigned char mask;
  96.  
  97.     for( i=0; i<pxHEIGHT; i++ ) {
  98.        r  = i % 4;
  99.        mask = 0x08;
  100.        for( j=0; j<pxWIDTH; j++ ) {
  101.           p  = pxl_array[i][j];
  102.           if( log_4x4[p][r] & mask )
  103.               putpixel( pxWIDTH+j+5, i, 7 );
  104.           if( (mask>>=1) == 0 ) mask = 0x08;
  105.        }
  106.     }
  107. }
  108. /*------------------------------------------------------------------*/
  109. /* Get contents of specified VGA palette register...                */
  110. /*------------------------------------------------------------------*/
  111. int get_vga_pal_register( int reg_no ) {
  112.      union REGS r;
  113.  
  114.      r.h.ah = 0x10;                    /* function 10h */
  115.      r.h.al = 0x07;                    /* subfunction 07h */
  116.      r.h.bl = (unsigned char) reg_no;  /* register number */
  117.      int86( 0x10, &r, &r );
  118.      return( (int) r.h.bh );
  119. }
  120. /*------------------------------------------------------------------*/
  121. /* Set contents of specified VGA DAC register...                    */
  122. /*------------------------------------------------------------------*/
  123. void set_vga_dac_register( int reg_no, unsigned char rgb[] ) {
  124.      union REGS r;
  125.  
  126.      r.h.ah = 0x10;      /* function 10h */
  127.      r.h.al = 0x10;      /* subfunction 10h */
  128.      r.x.bx = reg_no;    /* register number */
  129.      r.h.dh = rgb[0];    /* 6-bit red component */
  130.      r.h.ch = rgb[1];    /* 6-bit grn component */
  131.      r.h.cl = rgb[2];    /* 6-bit blu component */
  132.      int86( 0x10, &r, &r );
  133. }
  134. /*--------------------------------------------------------*/
  135. /* Main to illustrate dithering visually                  */
  136. /*--------------------------------------------------------*/
  137. void main( void ) {
  138.      int  i, dac, gDrvr=0, gMode;
  139.      unsigned char rgb[3];
  140.  
  141.      printf( "building image, please wait..." );
  142.      create_image();
  143.      printf( "done\n" );
  144.      initgraph( &gDrvr, &gMode, "" );
  145. /* modify VGA palette to show 8 gray scales */
  146.      for( i=0; i<8; i++ ) {
  147.         dac = get_vga_pal_register( i );
  148.         rgb[0] = rgb[1] = rgb[2] = i << 3;
  149.         set_vga_dac_register( dac, rgb );
  150.      }
  151.      draw_color_image();
  152.      draw_dithered_image();
  153.      getch();
  154.      closegraph();
  155. }
  156.