home *** CD-ROM | disk | FTP | other *** search
/ Sound Sensations! / sound_sensations.iso / misc / fileid13 / fileid.c < prev    next >
C/C++ Source or Header  |  1991-01-26  |  10KB  |  407 lines

  1. /**************************************************
  2.  *
  3.  * FileID.c
  4.  *
  5.  *    Identify picture/IFF file
  6.  *      and give info about it.
  7.  *
  8.  *    Copyright(c), 1990, 1991. Lloyd B. Eldred
  9.  *                            & Fredrick R Homan
  10.  **************************************************/
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include "fi_iff.h"
  14.  
  15. UBYTE VERBOSE, TERSE,COMMENT;  /* Yuck, global variables... */
  16.  
  17. void main(argc, argv)
  18. char **argv;
  19. {
  20.     FILE *picfile;
  21.     char buf[256];
  22.    char *filename; 
  23.     int type,width,height,color,i,planes,start,start2,offset;
  24.     UBYTE c,c1,c2,c3,c4,gct,cr,sf,bci,p;
  25.     long pos;
  26.     UWORD par;
  27.     LONG makelong(char,char,char,char),ch_size;
  28.    int cfind(char * , int , char * , int);
  29.    int cfindws(char * , int , char * , int, int);
  30.    void Gif_PlainText(FILE *, UBYTE),Gif_Application(FILE *, UBYTE),
  31.       Gif_Comment(FILE *, UBYTE),Gif_Image(FILE *, UBYTE),
  32.       Gif_Graphic(FILE *, UBYTE),fi_getc(FILE *,char *),
  33.       fi_exit();
  34.    float ar;
  35. /*
  36.    struct stat *st;
  37. */   
  38.       if ((argc < 2) | (argc > 3)) {
  39.         printf(
  40.         "FileID -- File IDentifier. V 1.30\n"
  41.       "Copyright (c) 1990, 1991 Lloyd B. Eldred and Fredrick R Homan.\n"
  42.         "Gives information about GIF and IFF files\n"
  43.         "Usage: FileID [-flag] filename\n"
  44.       "Valid flags: -c : Give included comments only\n"
  45.       "             -t : terse mode, gives one line output\n"
  46.       "             -v : verbose mode, gives lots of extra information\n");
  47.         fi_exit();
  48.     }
  49.    
  50.    COMMENT = FALSE;
  51.    VERBOSE = FALSE;
  52.    TERSE = FALSE;
  53.    type = 0;
  54.    filename = argv[1];
  55.    
  56.    c1 = argv[1][0];
  57.    c2 = argv[1][1];
  58.    if(c1 == '-'){
  59.       if(c2 == 'v' || c2 == 'V'){
  60.           VERBOSE=TRUE;
  61.           if(argc == 3) filename = argv[2];
  62.           else{
  63.              printf("No file specified\n");
  64.              fi_exit();
  65.              }
  66.        }
  67.        else if(c2 == 't' || c2 == 'T'){
  68.           TERSE=TRUE;
  69.           if(argc == 3) filename = argv[2];
  70.           else{
  71.              printf("No file specified\n");
  72.              fi_exit();
  73.              }
  74.        }
  75.        else if(c2 == 'c' || c2 == 'C'){
  76.           COMMENT=TRUE;
  77.           if(argc == 3) filename = argv[2];
  78.           else{
  79.              printf("No file specified\n");
  80.              fi_exit();
  81.              }
  82.        } 
  83.        else{
  84.             printf("Invalid flag -%c\n",c2);
  85.             fi_exit();
  86.        }
  87.       }   
  88.       
  89.     if ((picfile = fopen(filename, "rb")) == NULL) {
  90.             perror(filename);
  91.             fi_exit();
  92.            }
  93. /* 
  94.    if(stat(filename,st) == -1){
  95.          printf("Error reading file statistics.\n");
  96.          fi_exit();
  97.       }
  98.    
  99.    filesize = (long)st->st_size;
  100. */      
  101.     /* search for header line */
  102.     for (;;) {
  103.         if (fread(buf, sizeof(buf), 1,picfile) != 1) {
  104.             fprintf(stderr, "Unrecognized filetype\n");
  105.             fclose(picfile);
  106.             fi_exit();
  107.         }
  108.         start = cfind(buf,3,"GIF",3);
  109.         if (start != -1){
  110.             type=GIF;
  111.             break;
  112.         }
  113.         
  114.         start = cfind(buf,4,"FORM",4);
  115.         if (start != -1){
  116.             type=IFF;
  117.             break;
  118.         }
  119.         
  120.         start = cfind(buf,4,"CAT ",4);
  121.         if (start != -1){
  122.             type=IFF;
  123.             break;
  124.         }
  125.  
  126.         start = cfind(buf,4,"LIST",4);
  127.         if (start != -1){
  128.             type=IFF;
  129.             break;
  130.         }
  131.       
  132. /* Well, one last try: check for a Mac-padded GIF */
  133.         start = cfind(buf,sizeof(buf),"GIF",3);
  134.         if (start != -1){
  135.             type=GIF;
  136.             break;
  137.         }
  138.  
  139.  
  140.             
  141.     }
  142.     
  143.     fclose(picfile);
  144.  
  145. /********************************************************************/
  146. /*                          GIF analysis                            */
  147. /********************************************************************/
  148.     
  149.     if(type == GIF){
  150.  
  151.         if(start != 0){
  152.             printf("Padding encountered at the beginning of the file.\n" 
  153.                 "Some viewers may not like this file.\n");
  154.            start2 = cfindws(buf,sizeof(buf),"GIF",3,128);
  155.            if (start2 != -1){
  156.                printf("Macintosh resource fork found. Recommend using"
  157.                 " StripGif to remove the header.\n");
  158.             start=start2;
  159.          }
  160.       }
  161.  
  162.          c1 = buf[start+3];
  163.         c2 = buf[start+4];
  164.         c3 = buf[start+5];
  165.  
  166.         if(!TERSE){
  167.          printf("GIF -- Version %c%c%c:",c1,c2,c3);
  168.            if( c1 != '8' || (c2 != '7' && c2 != '9') || c3 != 'a'){
  169.               printf(" non recognized version, the following are guesses");
  170.             }
  171.             if (COMMENT) printf("\n");
  172.          if(!COMMENT) printf("\n  Image Header\n");
  173.       }
  174.       else printf("GIF%c%c%c",c1,c2,c3);
  175.          
  176.         c1 = buf[start+6];
  177.         c2 = buf[start+7];
  178.         c3 = buf[start+8];
  179.         c4 = buf[start+9];
  180.         c  = buf[start+10];
  181.       bci= buf[start+11];
  182.       p= buf[start+12];
  183.             
  184.   /* Expand Logical Screen Descriptor packed fields */
  185.       gct = (UBYTE)(c & 0x80);
  186.       cr =  (UBYTE)(c & 0x70)>>4;
  187.       cr++;
  188.       sf =  (UBYTE)(c & 0x08);
  189.         planes = (int)(c & 0x7) + 1;
  190.       par=(UWORD)p+15;
  191.  
  192.       ar = par/64.0;
  193.          
  194.       if(VERBOSE){
  195.          if(gct && !sf)
  196.            printf("    Global Color Table Flag set (table unsorted)\n");
  197.          if(gct && sf)
  198.            printf("    Global Color Table Flag set (table sorted)\n");
  199.          printf("    Color resolution: %d bits of RG&B per palette color\n",
  200.                cr);
  201.          if(gct)
  202.             printf("    Background color is color number %d\n",bci);
  203.          if(!p)
  204.             printf("    No pixel aspect ratio information given.\n");
  205.          else
  206.             printf("    Aspect ratio (pixel's width/height) is %g\n",ar);
  207.       }
  208.       
  209.         color=1;
  210.         
  211.         for(i=0; i<planes ; i++)
  212.           color = color * 2;
  213.         
  214.         width=c1 + 256 * c2;
  215.         
  216.         height=c3 + 256 * c4;
  217.         
  218.         if(!TERSE && !COMMENT) 
  219.                  printf("    Width : %5d\n"
  220.                           "    Height: %5d\n"
  221.                           "    Colors: %5d\n",width,height,color);
  222.                         
  223.       if(TERSE) printf(" %5d %5d %5d\n",width,height,color);              
  224.         
  225.       /* 
  226.        *Done with logical screen descriptor, continue
  227.        * only if user has selected verbose mode
  228.        */
  229.    if(!VERBOSE && !COMMENT) fi_exit();
  230.    
  231.    offset=start+13;
  232.    
  233.    if(gct){ /* if Global Color Table, skip it... */
  234.       offset += 3 * color; 
  235.       }
  236.    
  237.     if ((picfile = fopen(filename, "rb")) == NULL) {
  238.             perror(filename);
  239.             fi_exit();
  240.            }
  241.    if (fseek(picfile,offset,1) == -1){
  242.          printf(" Unexpected end of file. (1)\n");  
  243.          fclose(picfile);
  244.          fi_exit();
  245.       }
  246.    
  247.    for(;;){
  248.    
  249.       fi_getc(picfile,&c1);
  250.       
  251.       switch(c1){
  252.          case 0x2c:
  253.             Gif_Image(picfile,!COMMENT);
  254.             break;
  255.          
  256.          case 0x21:
  257.             if (!COMMENT) printf("  Extension:");
  258.             fi_getc(picfile,&c2);
  259.             
  260.             if(c2 == 0xf9) Gif_Graphic(picfile,!COMMENT);
  261.             if(c2 == 0xfe) {
  262.              if (!COMMENT) printf("Comment\n");
  263.              Gif_Comment(picfile,1);
  264.             }
  265.             if(c2 == 0x01) Gif_PlainText(picfile,!COMMENT);
  266.             if(c2 == 0xff) Gif_Application(picfile,!COMMENT);
  267.  
  268.             break;
  269.               
  270.          case 0x3b:
  271.             printf("  Normal End of GIF reached.\n");               
  272.             pos = ftell(picfile);
  273.             printf("  GIF terminator found at %d bytes offset.\n"
  274.                         ,pos);            
  275.             fclose(picfile);
  276.             fi_exit();
  277.             break;
  278. /***/            
  279.          default:
  280.             pos = ftell(picfile);
  281.             printf(
  282.             "  Unknown block type: (Label 0x%x) at %d bytes offset.\n"
  283.                ,c1,pos);            
  284.             fclose(picfile);
  285.             fi_exit();
  286.             break;
  287.          
  288.          } /* end of switch */
  289.  
  290.    } /* end of for(;;) */
  291.  
  292.    
  293.     } /* End of GIF analysis section */
  294.  
  295. /********************************************************************/
  296. /*                          IFF analysis                            */
  297. /********************************************************************/
  298.  
  299.     if(type == IFF){
  300.         if(!TERSE) printf("IFF file:\n");
  301.       if(TERSE) printf("IFF - ");
  302.       
  303.       c = buf[start];
  304.        if ((picfile = fopen(filename, "rb")) == NULL) {
  305.             perror(filename);
  306.             fi_exit();
  307.            }
  308.       if (fseek(picfile,start+4,1) == -1){
  309.          printf(" Unexpected end of file. (I-1)\n");  
  310.          fclose(picfile);
  311.          fi_exit();
  312.       }
  313.  
  314.       ch_size = IFF_size(picfile);
  315.             
  316.       if(c == 'F') IFF_FORM(picfile,ch_size);
  317.       if(c == 'C') IFF_CAT(picfile,ch_size);
  318.       if(c == 'L') IFF_LIST(picfile,ch_size);
  319.       
  320.       if(VERBOSE) printf("End of File.\n");
  321.       pos = ftell(picfile);
  322.       if(VERBOSE) printf("  IFF file ended at %d bytes offset.\n"
  323.                         ,pos);
  324.       fclose(picfile);
  325.       fi_exit();
  326.       } /* End of IFF code */
  327.     
  328. } /* end of main() */
  329.  
  330. int cfind(buffer,blength,string,slength)
  331. char *buffer;
  332. char *string;
  333. int blength,slength;
  334. {
  335.     int i,start;
  336.     int found;
  337.     
  338.     start = 0;
  339.     
  340.     while(start <= (blength-slength)){
  341.         found = 1;
  342.         
  343.         for(i=0;i<slength;i++)
  344.             if(buffer[start+i] != string[i]){
  345.                 found = 0;
  346.                 break;
  347.             }
  348.         
  349.         if(found == 1) return(start);
  350.         
  351.         start++;
  352.     }
  353.     
  354.     return(-1);  /* string not found */
  355.         
  356. } /* end of cfind() */    
  357.  
  358. int cfindws(buffer,blength,string,slength,init)
  359. char *buffer;
  360. char *string;
  361. int blength,slength,init;
  362. {
  363.     int i,start;
  364.     int found;
  365.     
  366.     start = init;
  367.     
  368.     while(start <= (blength-slength)){
  369.         found = 1;
  370.         
  371.         for(i=0;i<slength;i++)
  372.             if(buffer[start+i] != string[i]){
  373.                 found = 0;
  374.                 break;
  375.             }
  376.         
  377.         if(found == 1) return(start);
  378.         
  379.         start++;
  380.     }
  381.     
  382.     return(-1);  /* string not found */
  383.         
  384. } /* end of cfindws() */    
  385.  
  386. LONG makelong(c1,c2,c3,c4)  /* makes 4 bytes into a long, MSB first */
  387. char c1,c2,c3,c4;
  388. {
  389.     union value_union{
  390.       LONG number;
  391.       char text[4];} value; 
  392.     
  393.    value.text[0]=c1;
  394.    value.text[1]=c2;
  395.    value.text[2]=c3;
  396.    value.text[3]=c4;
  397.    
  398.     return(value.number);
  399.     
  400. } /* end of makelong() */
  401.  
  402.  
  403. void fi_exit()
  404. {
  405.    exit(0);
  406. }
  407.