home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_01 / cips1001.exe / HT.C < prev    next >
Text File  |  1990-09-08  |  16KB  |  591 lines

  1.  
  2.  
  3.        /**************************************************
  4.        *
  5.        *       file d:\cips\ht.c
  6.        *
  7.        *       Functions: This file contains
  8.        *           display_using_halftoning
  9.        *           half_tone
  10.        *           show_half_tone
  11.        *           get_threshold_value
  12.        *
  13.        *       Purpose: This program displays an image using a half
  14.        *          toning process.  The algorithm was taken from
  15.        *          "Personal computer based image processing with
  16.        *          halftoning," John A Saghri, Hsieh S. Hou, Andrew
  17.        *          Tescher, Optical Engineering, March 1986, Vol.25,
  18.        *          No. 3, pp 499-503. The display_using_halftoning
  19.        *          determines display size and reads the image.
  20.        *          The half_tone function implements the algorithm
  21.        *          shown on page 502 of the article.
  22.        *          
  23.        *          The function print_halftone_array prints a half
  24.        *          toned image array to a regular line printer.
  25.        *
  26.        *
  27.        *       External Calls:
  28.        *          rtiff.c - read_tiff_image
  29.        *          rstring.c - read_string
  30.        *          numcvrt.c - get_integer
  31.        *
  32.        *       Modifications:
  33.        *          30 September 86 - created
  34.        *          18 August 1990 - modified for use in the
  35.        *              C Image Processing System.
  36.        *
  37.        **************************************************/
  38.  
  39.  
  40. #include "d:\cips\cips.h"
  41.  
  42. #define  FORMFEED  '\014'
  43.  
  44. float eg[ROWS][COLS], ep[ROWS][COLS];
  45.  
  46. display_using_halftoning(in_image, file_name,
  47.          il, ie, ll, le, threshold, invert,
  48.          image_colors, image_header, monitor_type,
  49.          print, show_hist, color_transform)
  50.  
  51.    char  color_transform[], file_name[], monitor_type[];
  52.    int   image_colors, invert,
  53.          il, ie, ll, le, threshold,
  54.          print, show_hist;
  55.    short in_image[ROWS][COLS];
  56.    struct tiff_header_struct *image_header;
  57.  
  58. {
  59.    char response[80];
  60.  
  61.    int  a,
  62.         b,
  63.         channel,
  64.         color,
  65.         count,
  66.         data_color,
  67.         display_mode,
  68.         horizontal,
  69.         i,
  70.         j,
  71.         k,
  72.         l,
  73.         line_color,
  74.         max_horizontal,
  75.         max_vertical,
  76.         not_finished,
  77.         one,
  78.         vertical,
  79.         x,
  80.         x_offset,
  81.         y,
  82.         y_offset,
  83.         zero;
  84.  
  85.    float area, new_grays;
  86.  
  87.    unsigned long histogram[256], new_hist[256];
  88.  
  89.  
  90.        if(  (show_hist == 1)  &&
  91.             (color_transform[0] != 'H'))
  92.           zero_histogram(histogram);
  93.  
  94.          /*******************************************
  95.          *
  96.          *   Use the monitor type to set the vertical
  97.          *   horizontal and display_mode parameters.
  98.          *   Also set the values for one and zero.
  99.          *   one and zero will vary depending on the
  100.          *   monitor type.
  101.          *
  102.          ********************************************/
  103.  
  104.  
  105.       if(  (monitor_type[0] == 'M')  ||
  106.            (monitor_type[0] == 'm')){
  107.          vertical     = 3;
  108.          horizontal   = 2;
  109.          display_mode = _HRESBW;
  110.          one          = 1;
  111.          zero         = 0;
  112.       }
  113.  
  114.       if(  (monitor_type[0] == 'C')  ||
  115.            (monitor_type[0] == 'c')){
  116.          vertical     = 3;
  117.          horizontal   = 2;
  118.          display_mode = _MRES4COLOR;
  119.          one          = 3;
  120.          zero         = 1;
  121.       }
  122.  
  123.       if(  (monitor_type[0] == 'V')  ||
  124.            (monitor_type[0] == 'v')){
  125.          vertical     = 6;
  126.          horizontal   = 4;
  127.          display_mode = _VRES16COLOR;
  128.          one          = 5;
  129.          zero         = 1;
  130.       }
  131.  
  132.       if(  (monitor_type[0] == 'E')  ||
  133.            (monitor_type[0] == 'e')){
  134.          vertical     = 6;
  135.          horizontal   = 3;
  136.          display_mode = _ERESCOLOR;
  137.          one          = 5;
  138.          zero         = 1;
  139.       }
  140.  
  141.       max_horizontal = (image_header->image_length+50)/100;
  142.       max_vertical   = (image_header->image_width+50)/100;
  143.  
  144.       if(horizontal > max_horizontal) horizontal = max_horizontal;
  145.       if(vertical > max_vertical) vertical = max_vertical;
  146.  
  147.       if(print == 1){
  148.          vertical   = 1;
  149.          horizontal = 1;
  150.       }
  151.  
  152.  
  153.  
  154.         /****************************************
  155.         *
  156.         *   If color transform wants histogram
  157.         *   equalization, then read in the
  158.         *   image arrays and calculate the
  159.         *   histogram.   Zero both the histogram
  160.         *   and the new_hist.  You will need the
  161.         *   new_hist if you want to display the
  162.         *   equalized hist.
  163.         *
  164.         *****************************************/
  165.  
  166.       if(color_transform[0] == 'H'){
  167.          count = 1;
  168.          zero_histogram(histogram);
  169.          zero_histogram(new_hist);
  170.          for(a=0; a<vertical; a++){
  171.             for(b=0; b<horizontal; b++){
  172.  
  173.                x = a*100;
  174.                y = b*100;
  175.  
  176.                printf("\nHT> Calculating histogram");
  177.                printf(" %d of %d",count,vertical*horizontal);
  178.                count++;
  179.  
  180.                read_tiff_image(file_name, in_image, il+y,
  181.                             ie+x, ll+y, le+x);
  182.                calculate_histogram(in_image, histogram);
  183.  
  184.             }  /* ends loop over b */
  185.          }  /* ends loop over a */
  186.       }  /* ends if display_mode == H */
  187.  
  188.  
  189.  
  190.  
  191.            /* set graphics mode */
  192.       if(print == 0)
  193.          _setvideomode(display_mode); /* MSC 6.0 */
  194.       else{
  195.          printf("\n\nHT> Calculating for printing ");
  196.          printf("\nHT> Counting from 0 to 99\n");
  197.       }
  198.  
  199.         /*********************************************
  200.         *
  201.         *   Loop over horizontal and vertical. Read
  202.         *   the image array and display it after
  203.         *   calculating the half tone values.
  204.         *
  205.         *
  206.         *   If you want to show the histogram AND
  207.         *   do not want to do hist equalization
  208.         *   then calculate the hist from the 
  209.         *   original image array.
  210.         *
  211.         *   If you want to do hist equalization
  212.         *   then calculate the new_hist AFTER
  213.         *   the image has been equalized.
  214.         *
  215.         *   We will equalize the histogram down
  216.         *   to half the original shades of gray
  217.         *   and will cut the threshold in half.
  218.         *
  219.         *****************************************/
  220.  
  221.  
  222.  
  223.       for(i=0; i<horizontal; i++){
  224.          for(j=0; j<vertical; j++){
  225.             read_tiff_image(file_name, in_image, il+i*100,
  226.                            ie+j*100, ll+i*100, le+j*100);
  227.  
  228.             if(   (show_hist == 1)  &&
  229.                   (color_transform[0] != 'H'))
  230.                calculate_histogram(in_image, histogram);
  231.  
  232.             if(color_transform[0] == 'H'){
  233.  
  234.                area = ((long)(vertical))*((long)(horizontal));
  235.                area = area*10000.0;
  236.                new_grays = image_colors/2;
  237.  
  238.                perform_histogram_equalization(in_image,
  239.                         histogram, new_grays, area);
  240.  
  241.                calculate_histogram(in_image, new_hist);
  242.  
  243.             }  /* ends if color_transform == S */
  244.  
  245.             if(color_transform[0] == 'H')
  246.                half_tone(in_image, threshold/2, eg, ep, i, j,
  247.                       one, zero, invert, print);
  248.  
  249.             else
  250.                half_tone(in_image, threshold, eg, ep, i, j,
  251.                       one, zero, invert, print);
  252.  
  253.          }  /* ends loop over j */
  254.       }  /*  ends loop over i */
  255.  
  256.  
  257.  
  258.          /***************************
  259.          *
  260.          *   if show_hist == 1 then
  261.          *   display the histogram
  262.          *   in the lower right hand
  263.          *   corner of screen
  264.          *
  265.          ****************************/
  266.  
  267.       if(  (show_hist == 1)   &&
  268.            (print == 0)){
  269.  
  270.          if(monitor_type[0] == 'V'){
  271.             y_offset   = 470;
  272.             x_offset   = 380;
  273.             line_color = 3;
  274.             data_color = 8;
  275.          }
  276.  
  277.          if(monitor_type[0] == 'E'){
  278.             y_offset   = 310;
  279.             x_offset   = 380;
  280.             line_color = 3;
  281.             data_color = 8;
  282.          }
  283.  
  284.          if(monitor_type[0] == 'M'){
  285.             y_offset   = 190;
  286.             x_offset   = 60;
  287.             line_color = 1;
  288.             data_color = 1;
  289.          }
  290.  
  291.          if(monitor_type[0] == 'C'){
  292.             y_offset   = 190;
  293.             x_offset   = 60;
  294.             line_color = 1;
  295.             data_color = 3;
  296.          }
  297.  
  298.          if(color_transform[0] == 'S')
  299.             display_histogram(histogram, x_offset,
  300.                    y_offset, line_color, data_color);
  301.  
  302.          if(color_transform[0] == 'H')
  303.             display_histogram(new_hist, x_offset,
  304.                    y_offset, line_color, data_color);
  305.  
  306.       }  /* ends if show_hist == 1 and print == 0 */
  307.  
  308.  
  309.  
  310.       if(print == 1) printf("\n\nHT> Hit ENTER to continue");
  311.       read_string(response);
  312.       clear_text_screen();
  313.  
  314. }  /* ends main  */
  315.  
  316.  
  317.  
  318.  
  319.  
  320.        /*****************************************************
  321.        *
  322.        *   half_tone(...
  323.        *
  324.        *   ep[m][n] = sum of erros propogated
  325.        *               to position (m,n).
  326.        *   eg[m][n] = total error generated at
  327.        *               location (m,n).
  328.        *
  329.        *****************************************************/
  330.  
  331. half_tone(in_image, threshold, eg, ep, yoff,
  332.            xoff, one, zero, invert, print)
  333.    int   invert, threshold, xoff, yoff,
  334.          one, print, zero;
  335.    float eg[ROWS][COLS], ep[ROWS][COLS];
  336.    short in_image[ROWS][COLS];
  337. {
  338.    float c[2][3],
  339.          sum_p,
  340.          t,
  341.          tt;
  342.    int   color, count, i, j, m, n;
  343.    short srow, scol;
  344.  
  345.    c[0][0] = 0.0;
  346.    c[0][1] = 0.2;
  347.    c[0][2] = 0.0;
  348.    c[1][0] = 0.6;
  349.    c[1][1] = 0.1;
  350.    c[1][2] = 0.1;
  351.    count   =   0;
  352.  
  353.       /***********************************************
  354.       *
  355.       *   Calculate the total propogated error
  356.       *   at location(m,n) due to prior
  357.       *   assignment.
  358.       *
  359.       *   Go through the input image.  If the output
  360.       *   should be one then display that pixel as such.
  361.       *   If the output should be zero then display it
  362.       *   that way.
  363.       *
  364.       *   Also set the pixels in the input image array
  365.       *   to 1's and 0's in case the print option
  366.       *   was chosen.
  367.       *
  368.       ************************************************/
  369.  
  370.    for(i=0; i<ROWS; i++){
  371.       for(j=0; j<COLS; j++){
  372.          eg[i][j] = 0.0;
  373.          ep[i][j] = 0.0;
  374.       }
  375.    }
  376.  
  377.        /*******************************************************
  378.        *
  379.        *   29 February 1988 - Fix to remove a solid line at the
  380.        *   bottom of each region. Loop over ROWS-1 and then
  381.        *   draw an extra line.
  382.        *
  383.        *******************************************************/
  384.  
  385.    for(m=0; m<ROWS-1; m++){
  386.       for(n=0; n<COLS; n++){
  387.  
  388.          sum_p = 0.0;
  389.          for(i=0; i<2; i++){
  390.             for(j=0; j<3; j++){
  391.                sum_p = sum_p + c[i][j] * eg[m-i+1][n-j+1];
  392.             }  /* ends loop over j */
  393.          }     /* ends loop over i */
  394.  
  395.          ep[m][n] = sum_p;
  396.          t = in_image[m][n] + ep[m][n];
  397.          tt = t;
  398.  
  399.                /**********************************
  400.                *
  401.                *    Here set the point [m][n]=one
  402.                *
  403.                ***********************************/
  404.  
  405.          if(t > threshold){
  406.             eg[m][n] = t - threshold*2;
  407.             ++count;
  408.             color = one;
  409.             if(invert == 1) color = zero;
  410.     
  411.             scol = (short)(n + xoff*COLS);
  412.             srow = (short)(m + yoff*ROWS);
  413.  
  414.             if(invert == 1)
  415.                in_image[m][n] = 1;
  416.             else
  417.                in_image[m][n] = 0;
  418.  
  419.             if(print == 0){
  420.                _setcolor(color);      /* MSC 6.0 */
  421.                _setpixel(scol, srow); /* MSC 6.0 */
  422.             }  /* ends if print == 0 */
  423.          }  /* ends if t > threshold  */
  424.  
  425.  
  426.                /**********************************
  427.                *
  428.                *    Here set the point [m][n]=zero
  429.                *
  430.                ***********************************/
  431.  
  432.          else{
  433.             eg[m][n] = t;
  434.             color = zero;
  435.             if(invert == 1) color = one;
  436.     
  437.             scol = (short)(n + xoff*COLS);
  438.             srow = (short)(m + yoff*ROWS);
  439.  
  440.             if(invert == 1)
  441.                in_image[m][n] = 0;
  442.             else
  443.                in_image[m][n] = 1;
  444.  
  445.             if(print == 0){
  446.                _setcolor(color);      /* MSC 6.0 */
  447.                _setpixel(scol, srow); /* MSC 6.0 */
  448.             } /* ends if print == 0 */
  449.  
  450.          }  /* ends else t <= threshold  */
  451.  
  452.       }  /* ends loop over n columns */
  453.  
  454.       if(print == 1) printf("%3d", m);
  455.  
  456.    }         /* ends loop over m rows */
  457.  
  458.  
  459.       /* Now display an extra line if print is 0 */
  460.    if(print == 0){
  461.       for(j=0; j<COLS; j++){
  462.  
  463.         if(in_image[ROWS-2][j] == 1)
  464.            color = zero;
  465.         else
  466.            color = one;
  467.  
  468.         if(invert == 1){
  469.             if(in_image[ROWS-2][j] == 1)
  470.                color = zero;
  471.             else
  472.                color = one;
  473.         }  /* ends if invert == 1 */
  474.  
  475.         scol = (short)(j + xoff*COLS);
  476.         srow = (short)(ROWS-1 + yoff*ROWS);
  477.         _setcolor(color);      /* MSC 6.0 */
  478.         _setpixel(scol, srow); /* MSC 6.0 */
  479.  
  480.       }        /* ends loop over j */
  481.    }        /* ends if print == 0 */
  482.  
  483.  
  484.    if(print == 1) print_halftone_array(in_image);
  485.  
  486. }  /*  ends half_tone  */
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.    /*******************************
  496.    *
  497.    *   get_threshold_value(...
  498.    *
  499.    ********************************/
  500.  
  501. get_threshold_value(threshold, print)
  502.    int *print, *threshold;
  503. {
  504.    int i;
  505.    printf("\nHT> The threshold = %d", *threshold);
  506.    printf("\nHT> Enter new theshold value ");
  507.    printf("(0 for no change) \n___\b\b\b");
  508.    get_integer(&i);
  509.    if((i != 0) && (i!= *threshold))
  510.       *threshold = i;
  511.  
  512.    printf("\nHT> print = %d (1 for print  0 for display)", *print);
  513.    printf("\nHT> Enter print value  \n_\b");
  514.    get_integer(&i);
  515.    *print = i;
  516. }
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.    /********************************************
  525.    *
  526.    *   print_halftone_array(...
  527.    *
  528.    *   This function takes the halftoned images
  529.    *   and prints it to a line printer.  If the
  530.    *   image array has a 1 then print a ' '.
  531.    *   If the image array has a 0 then print
  532.    *   a '*'.
  533.    *
  534.    *********************************************/
  535.  
  536.  
  537. print_halftone_array(image)
  538.    short image[ROWS][COLS];
  539. {
  540.    char printer_name[80], response[80], string[101];
  541.    FILE *printer;
  542.    int        i, j, l, line_counter;
  543.  
  544.    line_counter = 0;
  545.  
  546.    strcpy(printer_name, "prn");
  547.  
  548.    if( (printer = fopen(printer_name, "w")) == NULL)
  549.       printf("\nHT> Could not open printer");
  550.    else{
  551.       printf("\nOpened printer and now printing");
  552.  
  553.     /***************************************************
  554.     *
  555.     *   Loop over the rows in the image.  For each row
  556.     *   first clear out the string print buffer.
  557.     *   Then go through the columns and set the string
  558.     *   to either '*' or ' '.  Finally, write the 
  559.     *   string out to the printer.
  560.     *
  561.     ***************************************************/
  562.  
  563.    for(i=0; i<ROWS; i++){
  564.  
  565.       for(l=0; l<COLS+1; l++) string[l] = '\0';
  566.  
  567.       for(j=0; j<COLS; j++){
  568.          if(image[i][j] == 1)
  569.             string[j] = '*';
  570.          else
  571.             string[j] = ' ';
  572.       }  /* ends loop over j columns */
  573.  
  574.       printf("%3d", i);
  575.       my_fwriteln(printer, string);
  576.       line_counter = line_counter + 1;
  577.       if(line_counter >= 53){
  578.          line_counter = 0;
  579.          putc(FORMFEED, printer);
  580.       }  /* ends if line_counter >=53  */
  581.  
  582.    }  /* ends loop over i rows */
  583.  
  584.  
  585.    }  /* ends opened printer */
  586.  
  587.    putc(FORMFEED, printer);
  588.    fclose(printer);
  589.  
  590. }  /* ends print_halftone_array */
  591.