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

  1. /*** Module FILEUTIL.C 
  2.  
  3.      This module provides utility routines for browsing through
  4.      directories and selecting files for subsequent display.
  5.      It also contains public domain programs for locating files
  6.      meeting wildcard specifications, and for determining the
  7.      current default drive and path name.
  8.      
  9. ***/
  10.  
  11. #define __MSC
  12.  
  13. /********************************************************************/
  14. /* The file selection subroutine allows the user to browse          */
  15. /* directories and select image files for display in IMDISP.        */
  16. /* Also contains subroutines wildexp and drpath, used by DoBrowse.  */
  17. /*                                                                  */
  18. /* Written by: Dan Nakamura, Jet Propulsion Lab, October 10, 1987   */
  19. /********************************************************************/
  20.  
  21. /* * * * INCLUDE files * * * */
  22.  
  23. #include <conio.h>
  24. #include <ctype.h>
  25. #include <direct.h>
  26. #include <dos.h>
  27. #include <errno.h>
  28. #include <malloc.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "mshell.h"
  33. #include "imdef.h"
  34. #include "imdisp.h"
  35. #include "imdutil.h"
  36. #include "dispio.h"
  37. #include "imageio.h"
  38. #include "keywutil.h"
  39. #include "textutil.h"
  40.  
  41. /* * * * External functions * * * */
  42.  
  43. /* * * * Function declarations * * * */
  44.  
  45. int  FileSel (char *, int);
  46. int  GetFile (void);
  47. int  ChangeDir (char *);
  48.  
  49. /* * * * Global Variables * * * */
  50.  
  51.  
  52. int FileSel(char * selFilename, int type)
  53.  
  54. {
  55.     union  REGS  inregs, outregs;
  56.     struct SREGS segregs;
  57.     char  *selection[MAXNUMFILES];   /* Filename selected */
  58.     char   tempFileName[80];         /* Full filename to be passed back */
  59.     char   defDir[51];               /* Directory user enters from */
  60.     char   curDir[51];               /* Path to dir with wanted filename */
  61.     char   dta[128];
  62.     char   choice[10];
  63.     char   scratchbuf[20];           /* Buf used for small manipulations */
  64.     char   pBuff[80];                /* printing Buffer */
  65.     char  *attribute, *fname;
  66.     char   subMask[4];
  67.     char   dchar;
  68.     int    defDrive, curDrive, newDrive, numDrivesInstal;
  69.     int    topList, lowList;
  70.     int    index, numResponse;
  71.     int    error, okFilename, done, initDispFirst, i;
  72.     int    isSubDir[MAXNUMFILES];
  73.     int    dummy;
  74.     int    tltemp, len;
  75.  
  76.     /** Initialize Parameters **/
  77.     strcpy( subMask, "*.*");
  78.  
  79.     if (getcwd( defDir, 50) == NULL)
  80.        perror( "Unable to register default directory" );
  81.     strcpy( curDir, defDir);                        /* Init current directory */
  82.     defDrive = 0x00FF & bdos( WHAT_DRIVE, 0, 0);    /* Init default Drive     */
  83.     numDrivesInstal = 0x00FF &                      /* Find drives            */
  84.        bdos( SEL_DRIVE, defDrive, 0);
  85.     curDrive = defDrive;                            /* Init current drive     */
  86.     done     = FALSE;
  87.     initDispFirst = TRUE;
  88.  
  89. /** Setup for Loop **/
  90.  
  91.     bdos( ALLOC_DTA, (unsigned) dta, 0);          /* Setup Disk Transfer Area */
  92.  
  93. /** Main Loop For Valid Filename **/
  94.     while( !done )
  95.     {
  96.        /** Looking for SubDirectorie Names **/
  97.        index       = 1;                           /* Set index for file array */
  98.        inregs.h.ah = SRCH_FIRST;
  99.        inregs.x.dx = (unsigned) subMask;
  100.        inregs.h.cl = 0x10;
  101.        intdos( &inregs, &outregs);
  102.        error = outregs.x.ax;
  103.  
  104.        if ( !error )
  105.        {
  106.            while( !error )
  107.            {
  108.                attribute = dta + 21;   /* Ptr to attribute sect of DTA */
  109.                fname     = dta + 30;   /* Ptr to filename sect of DTA */
  110.                if ( (*attribute & 0x10) == 0x10)
  111.                {
  112.                    isSubDir[index] = TRUE;
  113.                    if ((selection[index] = malloc(strlen(fname)+3)) == NULL)
  114.                     {
  115.                         FatalError( "Not enough memory for filesel.\n");
  116.                     }
  117.  
  118.                    strcpy( selection[index++], fname );
  119.                    if (index > 511)
  120.                    {
  121.                        for (dummy=1; dummy<index; dummy++)
  122.                            free( selection[dummy] );
  123.                        StatusLine(0, "Too many files in directory." );
  124.                        return(0);
  125.                    }
  126.                }
  127.                error = bdos( SRCH_NEXT, 0, 0);
  128.            }
  129.        }
  130.  
  131.        /** Find files with Mask specs **/
  132.        if (type == 1)
  133.           error = bdos( SRCH_FIRST, (unsigned) dirMask, 0);
  134.        else
  135.           error = bdos( SRCH_FIRST, (unsigned) palMask, 0);
  136.        if (!error)
  137.        {
  138.            while(!error)
  139.            {
  140.                attribute = dta + 21;
  141.                fname     = dta + 30;
  142.                if ((*attribute & 0x10) == 0x00)
  143.                {
  144.                    isSubDir[index] = FALSE;
  145.                    if ((selection[index] = malloc(strlen(fname)+1)) == NULL)
  146.                     {
  147.                         FatalError( "Not enough memory for filesel2.\n");
  148.                     }
  149.                    strcpy( selection[index++], fname);
  150.                    if (index > 511)
  151.                    {
  152.                        for (dummy = 1; dummy < index; dummy++)
  153.                            free( selection[dummy] );
  154.                        StatusLine(0,"Too many files in directory.");
  155.                        return(0);
  156.                    }
  157.                }
  158.                error = bdos( SRCH_NEXT, 0, 0);
  159.            }
  160.        }
  161.  
  162. /** Graphics display dependent portion of the directory listing for
  163.     file selection.  (Only need to change this section plus other
  164.     extraneous prompts in the program to use this in any MS-Dos
  165.     environment.
  166. **/
  167.  
  168.        if (index > 1)
  169.        {
  170.            if (initDispFirst)
  171.            {
  172.                topList = 1;
  173.                lowList = (index-1 < DISPMAXNUM) ? index-1 : DISPMAXNUM;
  174.                initDispFirst = FALSE;
  175.            }
  176.            ClearDisplay(0);
  177.            TextLine   = TextHeight+5;
  178.            TextSample = 1;
  179.            sprintf( pBuff, "Current Path: %s #files: %d", curDir, index-1);
  180.            WriteText( pBuff );
  181.  
  182.            strcpy(pBuff,"");
  183.            for (i=topList; i <= lowList; i++)
  184.            {
  185.                if (isSubDir[i])
  186.                {
  187.  
  188.                    if ( !strcmp( selection[i], ".") )
  189.                        sprintf( scratchbuf, "%3d) %-10s<d>", i, "ROOT");
  190.                    else if ( !strcmp( selection[i], "..") )
  191.                        sprintf( scratchbuf, "%3d) %-10s<d>", i, "PARENT");
  192.                    else
  193.                        sprintf( scratchbuf, "%3d) %-10s<d>", i, selection[i]);
  194.                }
  195.                else
  196.                    sprintf( scratchbuf, "%3d) %-13s", i, selection[i]);
  197.                strcat(pBuff, scratchbuf);
  198.                if ((i%3)==0)
  199.                {
  200.                    WriteText( pBuff );
  201.                    strcpy( pBuff, "");
  202.                }
  203.            }
  204.            if ( (i%3) != 1)
  205.                WriteText( pBuff );
  206.            if (DisplayDevice != CGA200)
  207.                WriteText( " " );
  208.            WriteText( "<#>, M(ask), D(rive), P(rev), N(ext), Q(uit)");
  209.            tltemp = TextLine;
  210.            WriteText( "OPTION>>" );
  211.            TextLine = tltemp;
  212.            LengthText( "OPTION>> ", TextHeight, &len);
  213.            TextSample = len;
  214.            AcceptText(choice);
  215.        }
  216.        else
  217.        {
  218.            ClearDisplay(0);
  219.            WriteText( "?? SYSTEM FAILURE ??" );
  220.            WriteText( "Press any key to return to Imdisp" );
  221.            getch();
  222.            strcpy( choice, "Quit");
  223.        }
  224. /* End of most Graphics dependent portion */
  225.  
  226.        /** Process user choice **/
  227.        switch( choice[0] )
  228.        {
  229.        case 'M':
  230.        case 'm':
  231.            WriteText( "Please enter new mask" );
  232.            if (type == 1)
  233.               AcceptText( dirMask );
  234.            else
  235.               AcceptText( palMask );
  236.            initDispFirst = TRUE;
  237.            break;
  238.  
  239.        case 'D':
  240.        case 'd':
  241.            WriteText( "Please enter letter of desired drive (ex. A)" );
  242.            AcceptText( scratchbuf );
  243.            dchar = scratchbuf[0];
  244.            if ( isalpha(dchar) )
  245.            {
  246.                newDrive = toupper(dchar)-'A';
  247.                bdos( SEL_DRIVE, newDrive, 0);
  248.                curDrive = newDrive;
  249.                if (getcwd( curDir, 50) == NULL)
  250.                    perror( "Directory lookup failure" );
  251.            }
  252.            initDispFirst = TRUE;
  253.            break;
  254.  
  255.        case 'P':
  256.        case 'p':
  257.            topList = ((topList-DISPMAXNUM) < 1) ? 1 : topList-DISPMAXNUM;
  258.            lowList = ((topList+DISPMAXNUM) >= index-1) ? index-1 :
  259.                                                       topList+DISPMAXNUM-1;
  260.            break;
  261.  
  262.        case 'N':
  263.        case 'n':
  264.            topList = ((topList+DISPMAXNUM) >= index-1) ? index-1 :
  265.                                                      topList+DISPMAXNUM;
  266.            lowList = ((topList+DISPMAXNUM-1) >= index-1) ? index-1 :
  267.                                                      topList+DISPMAXNUM-1;
  268.            break;
  269.  
  270.        case 'Q':
  271.        case 'q':
  272.        /* Dealloc space saved for sel */
  273.            for (dummy = 1; dummy<index; dummy++)
  274.                free( selection[dummy] );
  275.            ClearDisplay(0);
  276.            return (0);
  277.  
  278.        default:
  279.            if (isdigit( choice[0] ))
  280.                if (numResponse = atoi(choice))
  281.                {
  282.                    okFilename = TRUE; /* init before checks */
  283.                    if (numResponse > 0 && numResponse < index)
  284.                    {
  285.                        if (isSubDir[numResponse])
  286.                        {
  287.                            if (numResponse == 1 &&
  288.                                !strcmp( selection[numResponse], ".") )
  289.                            {
  290.                                strncpy( selection[numResponse], curDir, 3);
  291.                                selection[numResponse][3] = '\0';
  292.                            }
  293.                            segregs.ds  = FP_SEG( selection[numResponse] );
  294.                            inregs.h.ah = 0x3B;
  295.                            inregs.x.dx = (unsigned) selection[numResponse];
  296.                            intdosx( &inregs, &outregs, &segregs);
  297.                            getcwd( curDir, 50);
  298.                            okFilename    = FALSE;
  299.                            initDispFirst = TRUE;
  300.                        }
  301.                    if (okFilename)
  302.                    {
  303.                        strcpy( tempFileName, curDir);
  304.                        if (tempFileName[3] != '\0')
  305.                            strcat( tempFileName, "\\");
  306.                        strcat( tempFileName, selection[numResponse]);
  307.                        strcpy( selFilename, tempFileName);
  308.                        /* Dealloc space saved for sel */
  309.                        for (dummy = 1; dummy<index; dummy++)
  310.                            free( selection[dummy] );
  311.                        ClearDisplay(0);
  312.                        return(1);
  313.                    }
  314.                }
  315.            }
  316.            break;
  317.        }
  318.        for (dummy = 1; dummy<index; dummy++) /* Dealloc space saved for sel */
  319.            free(selection[dummy]);
  320.     }
  321. }
  322.  
  323.  
  324.  
  325. int GetFile(void)
  326. /* GetFile gets the filename from the command string, opens the
  327.     image file, and prints out the image info.
  328. */
  329.  
  330. {
  331.     char  filename[128], status[128], dispstr[128];
  332.     char  savemask[30];
  333.     int   flag, sel;
  334.     int   i,j;
  335.     int   done;
  336.     int   end;
  337.  
  338.     Histogram = 0;     /* Make sure to reinit var when new file */
  339.     Palette   = 0L;
  340.     SubsampleFlag = FALSE;
  341.     subsample = 1;
  342.     strcpy(PaletteFileName,"");
  343.     ByteSwap  = FALSE;
  344.     GetKeywordString (CommandString, "FIL", " ", filename, &flag);
  345.     if (flag < 1)
  346.     {
  347.        sel = FileSel(filename,1);
  348.        if (sel==0) return (0);
  349.     }
  350.     else          /* Ron Baalke - 07/13/90 - Added wildcard processing */
  351.     {
  352.        done = FALSE;
  353.        for (i=0; (i<strlen(filename) && !done); i++)
  354.        {
  355.            if (strncmp(&filename[i],"*",1) == 0)
  356.            {
  357.                strcpy(savemask,dirMask);
  358.                strcpy(dirMask,filename);
  359.                sel = ChangeDir(filename);
  360.                if (sel != 0)
  361.                {
  362.                    strcpy(dirMask,savemask);
  363.                    strcpy(status,"Bad Pathname");
  364.                    TextLine = 30;   TextSample = 1;
  365.                    WriteText (status);
  366.                    return(0);
  367.                }
  368.  
  369.                end = strlen(filename) - 1;   /* extract out filename portion */
  370.                for (j=end; j > 0; j--)
  371.                {
  372.                   if ((strnicmp(&filename[j],"\\",1) == 0) ||
  373.                       (strnicmp(&filename[j],":",1) == 0))
  374.                   {
  375.                      strncpy(&dirMask[0],&filename[j+1],end-j);
  376.                      dirMask[end-j] = '\0';
  377.                      break;
  378.                   }
  379.                }
  380.                sel = FileSel(filename,1);
  381.                if (sel == 0)
  382.                {
  383.                    strcpy(dirMask,savemask);
  384.                    return(0);
  385.                }
  386.                done = TRUE;
  387.            }
  388.        }
  389.     }
  390.  
  391.     if (OpenFileFlag)
  392.     {
  393.        CloseImage (0, status);
  394.        if (BadStatus (status)) return(1);
  395.        OpenFileFlag = 0;
  396.     }
  397.  
  398.     GetKeywordString (CommandString, "NOM", "",status, &flag);
  399.     if (flag != -1)
  400.        ImageMemory = FALSE;
  401.     else
  402.        ImageMemory = TRUE;
  403.     OpenImage (filename, 0, "read", &nl, &ns, &bitsperpix, status);
  404.     if (BadStatus (status))
  405.     {
  406.        if (BatchFlag == 1)
  407.        {
  408.            strcpy(status,"Bad file name in batch file, aborting batch.");
  409.            StatusLine(0,status);
  410.            abort_disp = 1;
  411.        }
  412.        return(1);
  413.     }
  414.     OpenFileFlag = 1;
  415.  
  416.     if ((bitsperpix != 8) && (bitsperpix != 16) &&
  417.     (bitsperpix != 4) && (bitsperpix != 1) &&
  418.     (bitsperpix != 32) )
  419.     {
  420.        BadStatus ("Non valid bits per sample");
  421.        CloseImage (0, status);
  422.        if (BadStatus (status)) return(1);
  423.        OpenFileFlag = 0;
  424.        return(0);
  425.     }
  426.  
  427.     DNlow = 0;
  428. /*  Fix for full dynamic range - AW3
  429.     DNlow  = -1 * ( 1 << ((bitsperpix < 14) ? bitsperpix : 14) );
  430.     DNhigh = ( 1 << ((bitsperpix < 14) ? bitsperpix : 14) ) - 1;
  431. */
  432.     if (bitsperpix <= 8)
  433.        DNhigh = 255L;
  434.     else if (bitsperpix <= 16)
  435.        DNhigh = 0x00007fffL;
  436.     else
  437.        DNhigh = 0x7ffffffL;
  438.  
  439.     if (!BatchFlag)
  440.     {
  441.        sprintf (dispstr, "Lines : %5d   Samples : %5d  Sample_Bits : %2d",
  442.                           nl, ns, bitsperpix );
  443.        StatusLine(1,dispstr);
  444.     }
  445.     if ((PaletteFileName[0] != '\0')
  446.        || (Palette != 0L))
  447.     {
  448.        strcpy(CommandString,"PAL LOAD ");
  449.        strcat(CommandString,PaletteFileName);
  450.        DoPalette();
  451.     }
  452.     strcpy (ImageFileName, filename);
  453. }
  454.  
  455. int ChangeDir(char * pathname)
  456. /****************************************************************************/
  457. /* ChangeDir                                                                */
  458. /*                                                                          */
  459. /* Written by Ron Baalke - 07/29/90                                         */
  460. /* Given a full pathname (with the filename embedded in the pathname) this  */
  461. /* routine will change directories, ignoring the filename.  It will first   */
  462. /* change directory to the drive, and then to the directory itself.  It     */
  463. /* returns 0 on success, non-zero if unsuccessful.                          */
  464. /****************************************************************************/
  465. {
  466.  char drive[2];
  467.  char directory[81];
  468.  int i;
  469.  int begin=0;
  470.  int end;
  471.  int error;
  472.  
  473.  strcpy(drive,"");
  474.  strcpy(directory,"");
  475.  
  476.  if (strnicmp(&pathname[1],":",1) == 0)
  477.  {
  478.    drive[0] = pathname[0];
  479.    drive[1] = '\0';
  480.    strupr(drive);
  481.    begin = begin + 2;
  482.    error = bdos(14,(int)drive[0]-'A',0);
  483.  }
  484.  
  485.  end = strlen(pathname) - 1;
  486.  
  487.  for (i=end; i>begin; i--)
  488.  {
  489.   if (strnicmp(&pathname[i],"\\",1) == 0)
  490.   {
  491.    strncpy(&directory[0],&pathname[begin],i-begin);
  492.    directory[i-begin] = '\0';
  493.    error = chdir(directory);
  494.    if (error) return(-1);
  495.    break;
  496.   }
  497.  }
  498.  
  499.  return(0);
  500. }
  501.