home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_09_06 / 9n06095a < prev    next >
Text File  |  1991-04-15  |  11KB  |  394 lines

  1. /**************************************************
  2. *  file d:\cips\ht.c
  3. *
  4. *  Purpose: This program displays an image using a
  5. *  half toning process.  The algorithm was taken
  6. *  from "Personal computer based image processing
  7. *  with halftoning," John A Saghri, Hsieh S. Hou,
  8. *  Andrew Tescher, Optical Engineering, March 1986,
  9. *  Vol.25, No. 3, pp 499-503. The
  10. *  display_using_halftoning determines display
  11. *  size and reads the image. The half_tone function
  12. *  implements the algorithm.
  13. *         
  14. *  The function print_halftone_array prints a half
  15. *  toned image array to a regular line printer.
  16. *
  17. *  External Calls:
  18. *     rtiff.c - read_tiff_image (March CUJ, Lising 3)
  19. *     rstring.c - read_string
  20. *     numcvrt.c - get_integer
  21. *
  22. *   Modifications:
  23. *       30 September 86 - created
  24. *       18 August 1990 - modified for use in the
  25. *         C Image Processing System.
  26. **************************************************/
  27.  
  28.  
  29. #include "d:\cips\cips.h"
  30.  
  31. #define  FORMFEED  '\014'
  32.  
  33. float eg[ROWS][COLS], ep[ROWS][COLS];
  34.  
  35. display_using_halftoning(in_image, file_name,
  36.     il, ie, ll, le, threshold, invert,
  37.     image_colors, image_header, monitor_type,
  38.     print)
  39.  
  40.    char  file_name[], monitor_type[];
  41.    int   image_colors, invert,
  42.          il, ie, ll, le, threshold,
  43.          print;
  44.    short in_image[ROWS][COLS];
  45.    struct tiff_header_struct *image_header;
  46.  
  47. {
  48.    char response[80];
  49.  
  50.    int  channel,
  51.         color,
  52.         display_mode,
  53.         horizontal,
  54.         i,
  55.         j,
  56.         k,
  57.         l,
  58.         max_horizontal,
  59.         max_vertical,
  60.         not_finished,
  61.         one,
  62.         vertical,
  63.         x,
  64.         y,
  65.         zero;
  66.  
  67. /*******************************************
  68. *   Use the monitor type to set the vertical
  69. *   horizontal and display_mode parameters.
  70. *   Also set the values for one and zero.
  71. *   one and zero will vary depending on the
  72. *   monitor type.
  73. ********************************************/
  74.  
  75.     if(  (monitor_type[0] == 'M')  ||
  76.          (monitor_type[0] == 'm')){
  77.        vertical     = 3;
  78.        horizontal   = 2;
  79.        display_mode = _HRESBW;
  80.        one          = 1;
  81.        zero         = 0;
  82.     }
  83.  
  84.     if(  (monitor_type[0] == 'C')  ||
  85.          (monitor_type[0] == 'c')){
  86.        vertical     = 3;
  87.        horizontal   = 2;
  88.        display_mode = _MRES4COLOR;
  89.        one          = 3;
  90.        zero         = 1;
  91.     }
  92.     if(  (monitor_type[0] == 'V')  ||
  93.          (monitor_type[0] == 'v')){
  94.        vertical     = 6;
  95.        horizontal   = 4;
  96.        display_mode = _VRES16COLOR;
  97.        one          = 15;
  98.        zero         = 1;
  99.     }
  100.  
  101.     if(  (monitor_type[0] == 'E')  ||
  102.          (monitor_type[0] == 'e')){
  103.        vertical     = 6;
  104.        horizontal   = 3;
  105.        display_mode = _ERESCOLOR;
  106.        one          = 15;
  107.        zero         = 1;
  108.     }
  109.  
  110.     max_horizontal = (image_header->image_length+
  111.                       50)/100;
  112.     max_vertical   = (image_header->image_width+
  113.                       50)/100;
  114.  
  115.     if(horizontal > max_horizontal) horizontal = 
  116.                           max_horizontal;
  117.     if(vertical > max_vertical) vertical = 
  118.                           max_vertical;
  119.  
  120.     if(print == 1){
  121.        vertical   = 1;
  122.        horizontal = 1;
  123.     }
  124.  
  125.       /* set graphics mode */
  126.     if(print == 0)
  127.        _setvideomode(display_mode); /* MSC 6.0 */
  128.     else{
  129.        printf("\n\nHT> Calculating for printing ");
  130.        printf("\nHT> Counting from 0 to 99\n");
  131.     }
  132.  
  133. /*********************************************
  134. *   Loop over horizontal and vertical. Read
  135. *   the image array and display it after
  136. *   calculating the half tone values.
  137. *********************************************/
  138.  
  139.     for(i=0; i<horizontal; i++){
  140.        for(j=0; j<vertical; j++){
  141.           read_tiff_image(file_name, in_image, 
  142.                          il+i*100, ie+j*100, 
  143.                          ll+i*100, le+j*100);
  144.           half_tone(in_image, threshold, eg, ep, 
  145.                     i, j, one, zero, invert, 
  146.                     print);
  147.        }
  148.     }
  149.  
  150.     if(print == 1) printf("\n\nHT> Hit ENTER \
  151. to continue");
  152.     read_string(response);
  153.     clear_text_screen();
  154.  
  155. }  
  156.  
  157.  
  158. /*******************************************
  159. *   half_tone(...
  160. *
  161. *   ep[m][n] = sum of erros propogated
  162. *               to position (m,n).
  163. *   eg[m][n] = total error generated at
  164. *               location (m,n).
  165. ********************************************/
  166.  
  167. half_tone(in_image, threshold, eg, ep, yoff,
  168.          xoff, one, zero, invert, print)
  169.    int   invert, threshold, xoff, yoff,
  170.          one, print, zero;
  171.    float eg[ROWS][COLS], ep[ROWS][COLS];
  172.    short in_image[ROWS][COLS];
  173. {
  174.    float c[2][3],
  175.          sum_p,
  176.          t,
  177.          tt;
  178.    int   color, count, i, j, m, n;
  179.    short srow, scol;
  180.  
  181.    c[0][0] = 0.0;
  182.    c[0][1] = 0.2;
  183.    c[0][2] = 0.0;
  184.    c[1][0] = 0.6;
  185.    c[1][1] = 0.1;
  186.    c[1][2] = 0.1;
  187.    count   =   0;
  188.  
  189. /***********************************************
  190. *   Calculate the total propogated error
  191. *   at location(m,n) due to prior
  192. *   assignment.
  193. *
  194. *   Go through the input image.  If the output
  195. *   should be one then display that pixel as such.
  196. *   If the output should be zero then display it
  197. *   that way.
  198. *
  199. *   Also set the pixels in the input image array
  200. *   to 1's and 0's in case the print option
  201. *   was chosen.
  202. ************************************************/
  203.  
  204.    for(i=0; i<ROWS; i++){
  205.       for(j=0; j<COLS; j++){
  206.          eg[i][j] = 0.0;
  207.          ep[i][j] = 0.0;
  208.       }
  209.    }
  210.  
  211. /**********************************************
  212. *   29 February 1988 - Fix to remove a solid 
  213. *   line at the bottom of each region. Loop over 
  214. *   ROWS-1 and then draw an extra line.
  215. ***********************************************/
  216.  
  217.    for(m=0; m<ROWS-1; m++){
  218.       for(n=0; n<COLS; n++){
  219.  
  220.          sum_p = 0.0;
  221.          for(i=0; i<2; i++){
  222.             for(j=0; j<3; j++){
  223.                sum_p = sum_p + c[i][j] * 
  224.                        eg[m-i+1][n-j+1];
  225.             }  /* ends loop over j */
  226.          }     /* ends loop over i */
  227.  
  228.          ep[m][n] = sum_p;
  229.          t = in_image[m][n] + ep[m][n];
  230.          tt = t;
  231.  
  232.     /**********************************
  233.     *    Here set the point [m][n]=one
  234.     ***********************************/
  235.  
  236.          if(t > threshold){
  237.             eg[m][n] = t - threshold*2;
  238.             ++count;
  239.             color = one;
  240.             if(invert == 1) color = zero;
  241.     
  242.             scol = (short)(n + xoff*COLS);
  243.             srow = (short)(m + yoff*ROWS);
  244.  
  245.             if(invert == 1)
  246.                in_image[m][n] = 1;
  247.             else
  248.                in_image[m][n] = 0;
  249.  
  250.             if(print == 0){
  251.                _setcolor(color);      /* MSC 6.0 */
  252.                _setpixel(scol, srow); /* MSC 6.0 */
  253.             }  /* ends if print == 0 */
  254.          }  /* ends if t > threshold  */
  255.  
  256.      /**********************************
  257.      *    Here set the point [m][n]=zero
  258.      ***********************************/
  259.  
  260.          else{
  261.             eg[m][n] = t;
  262.             color = zero;
  263.             if(invert == 1) color = one;
  264.       
  265.             scol = (short)(n + xoff*COLS);
  266.             srow = (short)(m + yoff*ROWS);
  267.  
  268.             if(invert == 1)
  269.                in_image[m][n] = 0;
  270.             else
  271.                in_image[m][n] = 1;
  272.  
  273.             if(print == 0){
  274.                _setcolor(color);      /* MSC 6.0 */
  275.                _setpixel(scol, srow); /* MSC 6.0 */
  276.             } /* ends if print == 0 */
  277.          }  /* ends else t <= threshold  */
  278.       }  /* ends loop over n columns */
  279.  
  280.       if(print == 1) printf("%3d", m);
  281.    }         /* ends loop over m rows */
  282.  
  283.  /* Now display an extra line if print is 0 */
  284.    if(print == 0){
  285.       for(j=0; j<COLS; j++){
  286.  
  287.         if(in_image[ROWS-2][j] == 1)
  288.            color = zero;
  289.         else
  290.            color = one;
  291.  
  292.         if(invert == 1){
  293.             if(in_image[ROWS-2][j] == 1)
  294.                color = zero;
  295.             else
  296.                color = one;
  297.         }  /* ends if invert == 1 */
  298.  
  299.         scol = (short)(j + xoff*COLS);
  300.         srow = (short)(ROWS-1 + yoff*ROWS);
  301.         _setcolor(color);      /* MSC 6.0 */
  302.         _setpixel(scol, srow); /* MSC 6.0 */
  303.  
  304.       }        /* ends loop over j */
  305.    }        /* ends if print == 0 */
  306.  
  307.  
  308.    if(print == 1) print_halftone_array(in_image);
  309.  
  310. }  /*  ends half_tone  */
  311.  
  312.  /*******************************
  313.  *   get_threshold_value(...
  314.  ********************************/
  315.  
  316. get_threshold_value(threshold, print)
  317.    int *print, *threshold;
  318. {
  319.    int i;
  320.    printf("\nHT> The threshold = %d", *threshold);
  321.    printf("\nHT> Enter new theshold value ");
  322.    printf("(0 for no change) \n___\b\b\b");
  323.    get_integer(&i);
  324.    if((i != 0) && (i!= *threshold))
  325.        *threshold = i;
  326.  
  327.    printf("\nHT> print = %d (1 for print  0 for \
  328. display)", *print);
  329.    printf("\nHT> Enter print value  \n_\b");
  330.    get_integer(&i);
  331.    *print = i;
  332. }
  333.  
  334. /********************************************
  335. *   print_halftone_array(...
  336. *
  337. *   This function takes the halftoned images
  338. *   and prints it to a line printer.  If the
  339. *   image array has a 1 then print a ' '.
  340. *   If the image array has a 0 then print
  341. *   a '*'.
  342. *********************************************/
  343.  
  344. print_halftone_array(image)
  345.    short image[ROWS][COLS];
  346. {
  347.    char printer_name[80], response[80], string[101];
  348.    FILE *printer;
  349.    int   i, j, l, line_counter;
  350.  
  351.    line_counter = 0;
  352.  
  353.    strcpy(printer_name, "prn");
  354.  
  355.    if( (printer = fopen(printer_name, "w")) == NULL)
  356.       printf("\nHT> Could not open printer");
  357.    else{
  358.       printf("\nOpened printer and now printing");
  359.  
  360. /***************************************************
  361. *   Loop over the rows in the image.  For each row
  362. *   first clear out the string print buffer.
  363. *   Then go through the columns and set the string
  364. *   to either '*' or ' '.  Finally, write the 
  365. *   string out to the printer.
  366. ***************************************************/
  367.  
  368.        for(i=0; i<ROWS; i++){
  369.           for(l=0; l<COLS+1; l++) string[l] = '\0';
  370.     
  371.           for(j=0; j<COLS; j++){
  372.              if(image[i][j] == 1)
  373.                 string[j] = '*';
  374.              else
  375.                 string[j] = ' ';
  376.           }  /* ends loop over j columns */
  377.     
  378.           printf("%3d", i);
  379.           my_fwriteln(printer, string);
  380.           line_counter = line_counter + 1;
  381.           if(line_counter >= 53){
  382.              line_counter = 0;
  383.              putc(FORMFEED, printer);
  384.           }  /* ends if line_counter >=53  */
  385.     
  386.        }  /* ends loop over i rows */
  387.     
  388.    }  /* ends opened printer */
  389.  
  390.    putc(FORMFEED, printer);
  391.    fclose(printer);
  392.  
  393. }  /* ends print_halftone_array */
  394.