home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Science / Science.zip / imdisp79.zip / DISPLAY.C < prev    next >
C/C++ Source or Header  |  1993-04-17  |  17KB  |  542 lines

  1. /***  IMDISP module DISPLAY.C
  2.  
  3.         DISPLAY contains the routines to handle the actual display
  4.     screen.
  5.  
  6. ***/
  7.  
  8. #define __MSC
  9.  
  10. /* * * * INCLUDE files * * * */
  11.  
  12. #include <conio.h>
  13. #include <malloc.h>
  14. #include <math.h>
  15. #include <stdio.h>
  16. #include <io.h>
  17. #include "mshell.h"
  18. #include "imdef.h"
  19. #include "imdisp.h"
  20. #include "imdutil.h"
  21. #include "dispio.h"
  22. #include "disputil.h"
  23. #include "imageio.h"
  24. #include "fileio.h"
  25. #include "labutil.h"
  26. #include "refresh.h"
  27. #include "textutil.h"
  28. #include "buffer.h"
  29. #include "keywutil.h"
  30.  
  31. /* * * * External functions * * * */
  32.  
  33. /* * * * Function declarations * * * */
  34.  
  35. int DisplayImage (void);
  36.  
  37. /* * * * Global Variables * * * */
  38.  
  39. char Source_File_Name[64] = {""};
  40. int  Sampling_Factor;
  41. int Image_Line;
  42. int Image_Sample;
  43. int Image_Height;
  44. int Image_Length;
  45. int Image_Zoom;
  46. int Image_Subsample;
  47. int Image_Line1;
  48. int Image_Sample1;
  49. int Image_Height1;
  50. int Image_Length1;
  51. int Image_Zoom1;
  52. int Image_Subsample1;
  53.  
  54. int DisplayImage(void)
  55.  
  56. /* DisplayImage performs the display command.
  57.     First it gets the values (or defaults) of all of the possible
  58.     parameters.  Then it checks them for validity and processes
  59.     the parameters into useful form.  It then loops through the
  60.     image, reading a line, formatting it, displaying it, and stuffing
  61.     it into the refresh buffer.
  62.  
  63. */
  64. {
  65.     int     line, samp, i, j, k;
  66.     int     bitshift, NoScale, flag;
  67.     int     centsub, centerflag, flipflag;
  68.     int     up, down, left, right, upflag, downflag, leftflag, rightflag;
  69.     int     noprompt_flag;
  70.     int     buffer_flag=0;
  71.     int     index;
  72.     int     auto_stretch_flag;
  73.     int     Source_Flag;
  74.     int     auto_amount;
  75.     char    dispstr[80];
  76.     long    histbuf[256];
  77.     long    limit,total_samples,count=0L;
  78.     int     nl_save, ns_save;
  79.     int     nld_save, nsd_save, sl_save, ss_save;
  80.     int     nldd_save, nsdd_save, sldd_save, ssdd_save;
  81.     int     center1_save, center2_save;
  82.     long    high_save, low_save;
  83.     int     bits_save, sub_save;
  84.     int     htile,vtile,tile;
  85.     int     fmidr,c1midr,c2midr,c3midr;
  86.  
  87.     FILE    *fp;
  88.  
  89.     unsigned int   bytesneeded;
  90.     char    status[100];
  91.     unsigned char *tempbuf,ch;
  92.  
  93.     fmidr = FALSE;
  94.     c1midr = FALSE;
  95.     c2midr = FALSE;
  96.     c3midr = FALSE;
  97.  
  98.     for (i = 0;  i < 256;  i++)
  99.        histbuf[i] = 0L;
  100.  
  101.     if (OpenFileFlag == 0)
  102.     {
  103.        StatusLine(0,"Use the \'FILE fname\' command to select image");
  104.        return(0);
  105.     }
  106.  
  107.     if (IMCB[0].nl == 0)
  108.     {
  109.        StatusLine(0,"No lines in image");
  110.        return(0);
  111.     }
  112.  
  113. /*  Check to see if buffer is to be displayed - Ron Baalke - 06/91 */
  114.     GetKeywordString (CommandString, "DIS", " ",dispstr, &flag);
  115.  
  116.     if ((flag)                 &&
  117.         (strlen(dispstr) == 1) &&
  118.         (dispstr[0] >= 'A')    &&
  119.         (dispstr[0] <= 'Z'))
  120.     {
  121.        buffer_flag = 1;
  122.        index = dispstr[0] - 'A';
  123.        if (Buffers[index].location == NOWHERE)
  124.        {
  125.           strcpy(status,"A");
  126.           status[0] += index;
  127.           sprintf(dispstr,"Buffer %s is empty",status);
  128.           StatusLine(0,dispstr);
  129.           return(1);
  130.        }
  131.        nl_save = nl;
  132.        ns_save = ns;
  133.        nl = Buffers[index].dispnl;
  134.        ns = Buffers[index].dispns;
  135.        nld_save = nld; nsd_save = nsd; sl_save = sl; ss_save = ss;
  136.        nldd_save = nldd; nsdd_save = nsdd; sldd_save = sldd; ssdd_save = ssdd;
  137.        center1_save = centerline;
  138.        center2_save = centersamp;
  139.        high_save = DNhigh;
  140.        low_save = DNlow;
  141.        DNhigh = numDN-1;
  142.        DNlow = 0;
  143.        bits_save = bitsperpix;
  144.        bitsperpix = 8;
  145.     }
  146.  
  147.  
  148.     GetKeywordInteger (CommandString, "SL", 1, &sl, &flag);
  149.     GetKeywordInteger (CommandString, "SS", 1, &ss, &flag);
  150.     if (ss > ns) ss = 1;
  151.     GetKeywordInteger (CommandString, "NL", nl-sl+1, &nld, &flag);
  152.     GetKeywordInteger (CommandString, "NS", ns-ss+1, &nsd, &flag);
  153.     GetKeywordInteger (CommandString, "DSL", 1, &sldd, &flag);
  154.     GetKeywordInteger (CommandString, "DSS", 1, &ssdd, &flag);
  155.     GetKeywordSubcommand (CommandString, "CUR", &flag);
  156.     if (flag > 0) MoveCursor(&sldd,&ssdd);
  157.     GetKeywordInteger (CommandString, "SUB", 1, &sub_save, &flag);
  158.     if (sub_save != 1)
  159.     {
  160. /*
  161.  *  If we found a value for SUB, multiply it into the old value
  162.  *  and set the flag to say we're subsampling
  163.  */
  164.        SubsampleFlag = TRUE;
  165.        subsample = sub_save;
  166.     }
  167.     else if (flag > 0)
  168.     {
  169. /*
  170.  *  If we found a value for SUB, but it was 1, we're resetting back
  171.  *  to no subsampling - reset the flag and the subsample factor
  172.  */
  173.        SubsampleFlag = FALSE;
  174.        subsample = 1;
  175.     }
  176.     GetKeywordInteger (CommandString, "ZOO", 1, &zoom, &flag);
  177.     GetKeywordSubcommand (CommandString, "CEN", ¢erflag);
  178.     GetKeywordInteger (CommandString, "LEF", dispns, &left, &leftflag);
  179.     GetKeywordInteger (CommandString, "RIG", dispns, &right, &rightflag);
  180.     GetKeywordInteger (CommandString, "UP", dispnl, &up, &upflag);
  181.     GetKeywordInteger (CommandString, "DOW", dispnl, &down, &downflag);
  182.     GetKeywordSubcommand (CommandString, "FLI", &flipflag);
  183.     GetKeywordSubcommand (CommandString, "NOP", &noprompt_flag);
  184.     GetKeywordSubcommand (CommandString, "SOU", &Source_Flag);
  185.     GetKeywordInteger (CommandString, "AUT", 5 ,&auto_amount, &auto_stretch_flag);
  186.     strcat(CommandString," ");
  187.  
  188.     if (Source_Flag > 0) /* display source image */
  189.      {
  190.         if (Source_File_Name[0] == '\0')
  191.           StatusLine(0,"No source file specified in label");
  192.         else
  193.          {
  194.           fp     =  fopen (BrowseName,"w");
  195.           if (fp == NULL)
  196.            StatusLine(0,"File can not be opened. Use SET BROWSE filename");
  197.           else
  198.            {
  199.             if (strcmp(Source_File_Name,"FFXX.LBL") == 0)
  200.                fmidr = TRUE;
  201.             if (strcmp(Source_File_Name,"C1FXX.LBL") == 0)
  202.                c1midr = TRUE;
  203.             if (strcmp(Source_File_Name,"C2FXX.LBL") == 0)
  204.                c2midr = TRUE;
  205.             if (strcmp(Source_File_Name,"C3FXX.LBL") == 0)
  206.                c3midr = TRUE;
  207.  
  208.             if (fmidr || c1midr || c2midr || c3midr)
  209.              {
  210.  
  211.               /* MJM's replacement code */
  212.               htile = centersamp/128 + 1;
  213.               vtile = centerline/128;
  214.               tile  = vtile*8 + htile;
  215.               centerline = (centerline % 128);
  216.               centersamp = (centersamp % 128);
  217.               /* statusline(0,dispstr); what does this do?*/
  218.               strncpy(Source_File_Name,ImageFileName,
  219.                       strlen(ImageFileName)-10);
  220.               Source_File_Name[strlen(ImageFileName)-10] = '\0';
  221.               if (fmidr)
  222.                  strcat(Source_File_Name,"FF");
  223.               else if (c1midr)
  224.                  strcat(Source_File_Name,"C1F");
  225.               else if (c2midr)
  226.                  strcat(Source_File_Name,"C2F");
  227.               else if (c3midr)
  228.                  strcat(Source_File_Name,"C3F");
  229.  
  230.               /*  MJM's original code */
  231.               strcpy(dispstr,Source_File_Name);
  232.               sprintf(Source_File_Name,"%s%02d.LBL",dispstr,tile);
  233.               Sampling_Factor = 8;
  234.              }
  235.             fprintf(fp,"file %s \n",Source_File_Name);
  236.             sl = Sampling_Factor*centerline-dispnl/2; if (sl < 1) sl = 1;
  237.             ss = Sampling_Factor*centersamp-dispns/2; if (ss < 1) ss = 1;
  238.             fprintf(fp,"disp sl %d ss %d\n",sl,ss);
  239.             centerline = Sampling_Factor*centerline;
  240.             centersamp = Sampling_Factor*centersamp;
  241.             fclose(fp);        /* Close batch file and then execute it */
  242.             strcpy(CommandString,"BATCH ");
  243.             strcat(CommandString,BrowseName);
  244.             ClearDisplay(0);
  245.             DoBatch();
  246.            }
  247.         }
  248.       return(0);
  249.      }
  250.  
  251.     strcpy(status,"");
  252.     if (auto_stretch_flag >= 0 && bitsperpix == 8 && !buffer_flag)
  253.      {
  254.         if (Histogram > 0L)
  255.           {
  256.            lseek(FCB[0].handle,Histogram,SEEK_SET);
  257.            read(FCB[0].handle,(char *)histbuf,1024);
  258.            total_samples = (long)IMCB[0].nl * (long)IMCB[0].ns;
  259.           }
  260.         else
  261.          {
  262.          if ((tempbuf = malloc(IMCB[0].ns)) == NULL)
  263.            {
  264.             FatalError( "Not enough memory for pixel buffer.\n");
  265.             return(1);
  266.            }
  267.          for (i = 1;  i < IMCB[0].nl;  i+=10)
  268.            {
  269.             if (ImageLocation == VIRTUAL_FILE)
  270.                ReadLine (0, tempbuf, i, 1, IMCB[0].ns, status);
  271.             else
  272.                ReadXMSLine (tempbuf, i, 1, IMCB[0].ns);
  273.             if (BadStatus(status))
  274.              {
  275.                 free (tempbuf);
  276.                 return(1);
  277.              }
  278.             for (samp = 1;  samp < IMCB[0].ns; samp+=10)
  279.              {
  280.                  (histbuf[tempbuf[samp]])++;
  281.              }
  282.            }
  283.             total_samples = ((long)IMCB[0].nl * (long)IMCB[0].ns)/100L;
  284.             free(tempbuf);
  285.          }
  286.         if (auto_amount > 49) auto_amount = 49;
  287.         limit = ((long)total_samples*(long)auto_amount)/100L;
  288.         count = 0L;
  289.         for (i=0;i<256 && count < limit;i++) count += histbuf[i];
  290.         DNlow = i;
  291.         count = 0L;
  292.         for (i=255;i>0 && count < limit;i--) count += histbuf[i];
  293.         DNhigh = i;
  294.         if (DNlow >= DNhigh) DNhigh = DNlow + 1;
  295.         sprintf (dispstr, "DN low : %5d   DN high : %5d     ",
  296.          DNlow, DNhigh);
  297.         StatusLine(2,dispstr);
  298.     }
  299.  
  300.     else if (auto_stretch_flag >= 0)
  301.       StatusLine(0,"AUTOset only works on 8-bit images.");
  302.  
  303.     if (subsample < 1)      subsample = 1;
  304.     if (zoom < 1)           zoom = 1;
  305.     if (subsample > 1)      zoom = 1;
  306.  
  307.     if ( (leftflag > -1) || (rightflag > -1) ||
  308.          (upflag > -1)   || (downflag > -1) )
  309.     {
  310.        sl = lastsl;
  311.        ss = lastss;
  312.        if (leftflag > -1)
  313.            ss -= left;
  314.        if (rightflag > -1)
  315.            ss += right;
  316.        if (upflag > -1)
  317.            sl -= up;
  318.        if (downflag > -1)
  319.            sl += down;
  320.     }
  321.  
  322.     if (sl < 1)
  323.        sl = 1;
  324.     else if (sl > nl)
  325.        sl = nl;
  326.     if (ss < 1)
  327.        ss = 1;
  328.     else if (ss > ns)
  329.        ss = ns;
  330.  
  331. /* CENTer command stuff */
  332.     if ( (centerflag >= 0) && (centerline > 0) )
  333.     {
  334.        nldd = zoom*nld / subsample;
  335.        nsdd = zoom*nsd / subsample;
  336.        if (nldd+sldd-1 > dispnl)
  337.            nldd = dispnl-sldd+1;
  338.        if (nsdd+ssdd-1 > dispns)
  339.            nsdd = dispns-ssdd+1;
  340.        nld = subsample*nldd / zoom;
  341.        nsd = subsample*nsdd / zoom;
  342.        sl = centerline - (nld / 2);
  343.        if (sl < 1)  sl = 1;
  344.        ss = centersamp - (nsd / 2);
  345.        if (ss < 1)  ss = 1;
  346.        CursorLine = zoom*(centerline - sl) / subsample + sldd;
  347.        CursorSample = zoom*(centersamp - ss) / subsample + ssdd;
  348.     }
  349.  
  350.     lastsl = sl;
  351.     lastss = ss;
  352.  
  353.     if (nld+sl-1 > nl)
  354.        nld = nl-sl+1;
  355.     if (nsd+ss-1 > ns)
  356.        nsd = ns-ss+1;
  357.     nldd = zoom*nld / subsample;
  358.     nsdd = zoom*nsd / subsample;
  359.     if (nldd+sldd-1 > dispnl)
  360.        nldd = dispnl-sldd+1;
  361.     if (nsdd+ssdd-1 > dispns)
  362.        nsdd = dispns-ssdd+1;
  363.     nld = subsample*nldd / zoom;
  364.     nsd = subsample*nsdd / zoom;
  365.     nldd = zoom*nld / subsample;
  366.     nsdd = zoom*nsd / subsample;
  367.  
  368.     if (bitsperpix <= 8)
  369.        bytesneeded = zoom*nsd;
  370.     else if (bitsperpix == 32)
  371.        bytesneeded = 4*zoom*nsd;
  372.     else
  373.        bytesneeded = 2*zoom*nsd;
  374.  
  375.     if ((tempbuf = malloc(bytesneeded)) == NULL)
  376.     {
  377.         FatalError( "Not enough memory for pixel buffer.\n");
  378.     }
  379.  
  380.     if (bitsperpix >= 8)
  381.     {
  382.        bitshift = Round(log(((double)DNhigh-DNlow+1)/numDN) /0.693147);
  383.        NoScale = (DNlow==0) && (DNhigh==(1 << bitsperpix)-1);
  384.     }
  385.     else
  386.        bitshift =  bitsperpix - Round(log((double)numDN)/0.693147);
  387.  
  388. /* Loop through image line by line */
  389.  
  390.     strcpy(status,"");
  391.     if (zoom == 1)
  392.     {
  393.        line = sl;
  394.        Image_Line = sldd;      /* Remember where image is displayed */
  395.        Image_Sample = ssdd;    /* Ron Baalke - 05/91 */
  396.        Image_Height = nldd;
  397.        Image_Length = nsdd;
  398.        Image_Zoom = zoom;
  399.        Image_Subsample = subsample;
  400.        Image_Line1 = Image_Line; /* Make another copy for the WINDOW command */
  401.        Image_Sample1 = Image_Sample;      /* Ron Baalke - 09/18/91 */
  402.        Image_Height1 = Image_Height;
  403.        Image_Length1 = Image_Length;
  404.        Image_Zoom1 = Image_Zoom;
  405.        Image_Subsample1 = Image_Subsample;
  406.  
  407.        for (i = sldd;  i < nldd+sldd;  i++)
  408.        {
  409.            if (flipflag == 1)
  410.               j = nldd+sldd - i;
  411.            else
  412.               j = i;
  413.            if (buffer_flag)
  414.               GetBuffer(index, tempbuf, line, ss, nsd);
  415.            else if (ImageLocation == VIRTUAL_FILE)
  416.               ReadLine (0, tempbuf, line, ss, nsd, status);
  417.            else
  418.               ReadXMSLine (tempbuf, line, ss, nsd);
  419.  
  420.            if (BadStatus(status))
  421.            {
  422.                free (tempbuf);
  423.                return(1);
  424.            }
  425.            FormatLine (tempbuf, nsdd, nsd, bitshift, NoScale, status);
  426.            if (BadStatus(status))
  427.            {
  428.                free (tempbuf);
  429.                return(1);
  430.            }
  431.  
  432.            DisplayLine (tempbuf, j, ssdd, nsdd);
  433.            if (RefreshLines >= j)
  434.                PutRefresh (tempbuf, j, ssdd, nsdd);
  435.            line += subsample;
  436.            if (kbhit())  /* abort disp if keypressed mdm 2/19/88*/
  437.            {
  438.                if ((ch = getch()) == 0) ch = 0x80 | getch();
  439.                if (ch != 17) /* don't abort if cntl q */
  440.                {
  441.                    i=nldd+sldd;
  442.                    abort_disp = 1;
  443.                }
  444.            }
  445.        }
  446.        free(tempbuf);
  447.     }
  448.     else
  449.     {
  450.        i = sldd;
  451.        Image_Line = sldd;        /* Remember where image is displayed */
  452.        Image_Sample = ssdd;      /* Ron Baalke - 05/91 */
  453.        Image_Height = nld * zoom;
  454.        Image_Length = nsdd;
  455.        Image_Zoom = zoom;
  456.        Image_Subsample = subsample;
  457.        Image_Line1 = Image_Line; /* Make another copy for the WINDOW command */
  458.        Image_Sample1 = Image_Sample;      /* Ron Baalke - 09/18/91 */
  459.        Image_Height1 = Image_Height;
  460.        Image_Length1 = Image_Length;
  461.        Image_Zoom1 = Image_Zoom;
  462.        Image_Subsample1 = Image_Subsample;
  463.  
  464.        for (line = sl;  line < nld+sl;  line++)
  465.        {
  466.            if (flipflag == 1)
  467.               j = nld*zoom - i;
  468.            else
  469.               j = i;
  470.            if (buffer_flag)
  471.               GetBuffer(index, tempbuf, line, ss, nsd);
  472.            else if (ImageLocation == VIRTUAL_FILE)
  473.               ReadLine (0, tempbuf, line, ss, nsd, status);
  474.            else
  475.               ReadXMSLine (tempbuf, line, ss, nsd);
  476.            if (BadStatus(status))
  477.                {
  478.                 free (tempbuf);
  479.                 return(1);
  480.                }
  481.            FormatLine (tempbuf, nsdd, nsd, bitshift, NoScale, status);
  482.            if (BadStatus(status))
  483.                {
  484.                 free (tempbuf);
  485.                 return(1);
  486.                }
  487.            for (k = 1;  k <= zoom;  k++)
  488.            {
  489.                DisplayLine (tempbuf, j, ssdd, nsdd);
  490.                if (RefreshLines >= j)
  491.                    PutRefresh (tempbuf, j, ssdd, nsdd);
  492.                i++; j++;
  493.                if (kbhit()) /* abort disp if keypressed mdm 2/19/88*/
  494.                {
  495.                    if ((ch = getch()) == 0) ch = 0x80 | getch();
  496.                    if (ch != 17) /* don't abort if cntl q */
  497.                    {
  498.                        line = nld+sl;
  499.                        k=zoom;
  500.                        abort_disp = 1;
  501.                    }
  502.                }
  503.            }
  504.        }
  505.        free(tempbuf);
  506.     }
  507.  
  508.     if (buffer_flag)
  509.     {
  510.        nl = nl_save;
  511.        ns = ns_save;
  512.        DNhigh = high_save;
  513.        DNlow = low_save;
  514.        nld = nld_save; nsd = nsd_save; sl = sl_save; ss = ss_save;
  515.        nldd = nldd_save; nsdd = nsdd_save; sldd = sldd_save; ssdd = ssdd_save;
  516.        centerline = center1_save;
  517.        centersamp = center2_save;
  518.        bitsperpix = bits_save;
  519.     }
  520.  
  521.     /* If noprompt_flag is raised, then pause until a key is hit by the
  522.        user.  This will delay the command line prompt from being delayed */
  523.  
  524.     if (noprompt_flag == 1)
  525.        i = getch();
  526.  
  527.     /* If SelectFlag is raised indicating the SELECT option has been
  528.        selected in the BROWSE command, then prompt user
  529.        Ron Baalke  11/04/90                             */
  530.  
  531.     if (SelectFlag)
  532.     {
  533.         StatusLine(1,"Select this image (Y=Yes N=No (default) Q=Quit) ?");
  534.         i = getch();
  535.         if ((i == 89) || (i == 121))                  /* 'Y' or 'y' */
  536.            fprintf(SelectFile,"%s\n",ImageFileName);
  537.         else if ((i == 81) || (i == 113) || (i==27))  /* 'Q', 'q' or ESC */
  538.            abort_disp = 1;
  539.     }
  540. }
  541.  
  542.