home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 350_01 / pcx_exam.c < prev    next >
C/C++ Source or Header  |  1991-12-01  |  10KB  |  341 lines

  1. /*
  2.  *************************************************************************
  3.  *
  4.  *  PCX_EXAM.C - PCX_LIB File Header Examination Utility
  5.  *
  6.  *  Version:    1.00C
  7.  *
  8.  *  History:    91/02/14 - Created
  9.  *              91/04/01 - Release 1.00A
  10.  *              91/04/06 - Release 1.00B
  11.  *              91/12/01 - Release 1.00C
  12.  *
  13.  *  Compiler:   Microsoft C V6.0
  14.  *
  15.  *  Author:     Ian Ashdown, P.Eng.
  16.  *              byHeart Software
  17.  *              620 Ballantree Road
  18.  *              West Vancouver, B.C.
  19.  *              Canada V7S 1W3
  20.  *              Tel. (604) 922-6148
  21.  *              Fax. (604) 987-7621
  22.  *
  23.  *  Copyright:  Public Domain
  24.  *
  25.  *************************************************************************
  26.  */
  27.  
  28. /*
  29.  *************************************************************************
  30.  *
  31.  *  PORTABILITY NOTES
  32.  *
  33.  *  1.  When porting this program to other processors, remember that words
  34.  *      are stored by 80x86-based machines in the big-endian format.  That
  35.  *      is, the eight least significant bits (lower byte) are stored
  36.  *      first, followed by the eight most significant bits (upper byte).
  37.  *      If PCX-format files are transferred to little-endian machines
  38.  *      (such as those based on 680x0 and Z8000 processors), the order of
  39.  *      bytes within each word will have to be reversed before they can 
  40.  *      be interpreted.  (This applies to the file header only, since the
  41.  *      encoded image data and optional 256-color palette are stored as
  42.  *      bytes.)
  43.  *
  44.  ************************************************************************* 
  45.  */
  46.  
  47. /*      INCLUDE FILES                                                   */
  48.  
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include "pcx_int.h"
  52.  
  53. /*      FORWARD REFERENCES                                              */
  54.  
  55. /*      GLOBALS                                                         */
  56.  
  57. /*      PUBLIC FUNCTIONS                                                */
  58.  
  59. /*
  60.  *************************************************************************
  61.  *
  62.  *  MAIN - Executive Function
  63.  *
  64.  *  Purpose:    To read and display a PCX-format image file header.
  65.  *
  66.  *  Setup:      int main
  67.  *              (
  68.  *                int argc,
  69.  *                char **argv
  70.  *              )
  71.  *
  72.  *  Where:      argc is the number of command-line arguments.
  73.  *              argv is a pointer to an array of command-line argument
  74.  *                strings.
  75.  *
  76.  *  Return:     0 if successful; otherwise 2.
  77.  *
  78.  *  Result:     The file header information is written to "stdout".
  79.  *
  80.  *  Note:       Usage is:
  81.  *
  82.  *                PCX_EXAM filename
  83.  *
  84.  *              where "filename" is the name of a PCX-format image file.
  85.  *
  86.  *************************************************************************
  87.  */
  88.  
  89. int main
  90. (
  91.   int argc,
  92.   char **argv
  93. )
  94. {
  95.   char *vers;                   /* Version number string pointer        */
  96.   char *pal_type;               /* Palette type string pointer          */
  97.   int range;                    /* Palette range                        */
  98.   int indicator;                /* Extended palette indicator byte      */
  99.   BOOL status = TRUE;           /* Return status                        */
  100.   BOOL ep_flag = FALSE;         /* Extended palette flag                */
  101.   FILE *fp;                     /* File pointer                         */
  102.   PCX_HDR *hdrp;                /* File header structure pointer        */
  103.   PCX_PAL *ext_palettep;        /* Extended palette pointer             */
  104.  
  105.   /* Display program title                                              */
  106.  
  107.   puts("\nPCX_EXAM - PCX Image File Examination Utility\n");
  108.  
  109.   /* Check for filename                                                 */
  110.  
  111.   if (argc < 2)
  112.   {
  113.     /* Display usage information                                        */
  114.  
  115.     fputs("  Synopsis:  This public domain utility displays inf", stderr);
  116.     fputs("ormation contained in the\n             header of a ", stderr);
  117.     fputs("Paintbrush (R) PCX-format image file.\n\n  Usage:   ", stderr);
  118.     fputs("  PCX_EXAM filename\n\n  Example:   PCX_EXAM picture", stderr);
  119.     fputs(".pcx\n", stderr);
  120.  
  121.     return (2);
  122.   }
  123.  
  124.   /* Allocate a PCX file header buffer                                  */
  125.  
  126.   if ((hdrp = (PCX_HDR *) malloc(sizeof(PCX_HDR))) == (PCX_HDR *) NULL)
  127.   {
  128.     fputs("ERROR: out of memory\n", stderr);
  129.     return (2);
  130.   }
  131.  
  132.   /* Open the PCX image file in binary mode                             */
  133.  
  134.   if ((fp = fopen(argv[1], "rb")) == (FILE *) NULL)
  135.   {
  136.     fprintf(stderr, "ERROR: cannot open file %s\n", argv[1]);
  137.  
  138.     free(hdrp);         /* Free the file header memory                  */
  139.  
  140.     return (2);
  141.   }
  142.  
  143.   /* Read the file header                                               */
  144.  
  145.   if (status == TRUE)
  146.     if (fseek(fp, 0L, SEEK_SET) != 0)
  147.     {
  148.       fprintf(stderr, "ERROR: cannot read file %s\n", argv[1]);
  149.       status = FALSE;
  150.     }
  151.  
  152.   if (status == TRUE)
  153.     if (fread(hdrp, sizeof(PCX_HDR), 1, fp) != 1)
  154.     {
  155.       fprintf(stderr, "ERROR: cannot read file %s\n", argv[1]);
  156.       status = FALSE;
  157.     }
  158.  
  159.   /* Validate the PCX file format                                       */
  160.  
  161.   if (status == TRUE)
  162.     if ((hdrp->pcx_id != 0x0a) || (hdrp->encoding != 1))
  163.     {
  164.       fprintf(stderr, "ERROR: file %s not valid PCX format\n", argv[1]);
  165.       status = FALSE;
  166.     }
  167.  
  168.   /* Determine the version number                                       */
  169.  
  170.   switch (hdrp->version)
  171.   {
  172.     case 0:
  173.  
  174.       vers = "PC Paintbrush 2.5";
  175.  
  176.       break;
  177.  
  178.     case 2:
  179.  
  180.       vers = "PC Paintbrush 2.8 (with palette information)";
  181.  
  182.       break;
  183.  
  184.     case 3:
  185.  
  186.       vers = "PC Paintbrush 2.8 (without palette information)";
  187.  
  188.       break;
  189.  
  190.     case 4:
  191.  
  192.       vers = "PC Paintbrush for Windows (not 3.0)";
  193.  
  194.       break;
  195.  
  196.     case 5:
  197.  
  198.       vers = "PC Paintbrush 3.0 and greater";
  199.  
  200.       break;
  201.  
  202.     default:
  203.  
  204.       vers = "Unknown version";
  205.  
  206.       break;
  207.   }
  208.  
  209.   /* Display the PCX file header information                            */
  210.  
  211.   printf("PCX filename: %s\n", argv[1]);
  212.   printf("Version: %s\n", vers);
  213.   printf("Encoding: %s\n", hdrp->encoding == 1 ? "Run length" :
  214.       "Unknown");
  215.   printf("%d bits per pixel\n", hdrp->bppixel);
  216.   printf("Image from (%d, %d) to (%d, %d) pixels.\n", hdrp->xul,
  217.       hdrp->yul, hdrp->xlr, hdrp->ylr);
  218.   printf("Created on a device with %d x %d dpi resolution\n",
  219.       hdrp->horz_res, hdrp->vert_res);
  220.   printf("Number of color planes: %d\n", hdrp->nplanes);
  221.   printf("Bytes per color plane scan line: %d\n", hdrp->bppscan);
  222.  
  223.   switch (hdrp->palette_type & PCX_PAL_MASK)
  224.   {
  225.     case 1:
  226.  
  227.       pal_type = "color or B&W";
  228.  
  229.       break;
  230.  
  231.     case 2:
  232.  
  233.       pal_type = "grayscale";
  234.  
  235.       break;
  236.  
  237.     default:
  238.  
  239.       pal_type = "unknown";
  240.  
  241.       break;
  242.   }
  243.  
  244.   printf("Palette type: %s\n", pal_type);
  245.  
  246.   /* Check for extended (256-color) palette                             */
  247.  
  248.   if (hdrp->version == 5)
  249.   {
  250.     /* Check for valid palette indicator byte                           */
  251.  
  252.     if (fseek(fp, -769L, SEEK_END) != 0)
  253.     {
  254.       fprintf(stderr, "ERROR: cannot read file %s\n", argv[1]);
  255.       status = FALSE;
  256.     }
  257.  
  258.     if (status == TRUE)
  259.     {
  260.       if ((indicator = getc(fp)) == PCX_EPAL_FLAG)
  261.       {
  262.         /* Allocate an extended palette buffer                          */
  263.  
  264.         if ((ext_palettep = (PCX_PAL *) calloc(sizeof(PCX_PAL),
  265.             PCX_EPAL_SIZE)) == (PCX_PAL *) NULL)
  266.         {
  267.           fputs("ERROR: out of memory\n", stderr);
  268.           status = FALSE;
  269.         }
  270.  
  271.         /* Read the extended palette                                    */
  272.  
  273.         if (status == TRUE)
  274.         {
  275.           if (fread(ext_palettep, sizeof(PCX_PAL), PCX_EPAL_SIZE, fp) !=
  276.               PCX_EPAL_SIZE)
  277.           {
  278.             free(ext_palettep);         /* Free extended palette buffer */
  279.             status = FALSE;
  280.           }
  281.         }
  282.  
  283.         ep_flag = TRUE;         /* Indicate extended palette exists     */
  284.       }
  285.     }
  286.   }
  287.  
  288.   if (status == TRUE)
  289.     if (ep_flag == TRUE)
  290.     {
  291.       /* Display extended (256-color) palette                           */
  292.  
  293.       puts("Extended 256-color palette:\n");
  294.  
  295.       puts("COLOR   RED     GREEN   BLUE\n");
  296.  
  297.       for (range = 0; range < PCX_EPAL_SIZE; range++)
  298.         printf(" %03d      %2x      %2x     %2x\n", range,
  299.             ext_palettep[range].red, ext_palettep[range].green,
  300.             ext_palettep[range].blue);
  301.  
  302.       putchar('\n');
  303.  
  304.       free(ext_palettep);       /* Free the extended palette            */
  305.     }
  306.     else
  307.     {
  308.       /* Display file header palette                                    */
  309.  
  310.       puts("File header color palette:\n");
  311.  
  312.       printf("RED ...   ");
  313.  
  314.       for (range = 0; range < PCX_PAL_SIZE; range++)
  315.         printf("%2x  ", hdrp->palette[range].red);
  316.  
  317.       printf("\nGREEN ... ");
  318.  
  319.       for (range = 0; range < PCX_PAL_SIZE; range++)
  320.         printf("%2x  ", hdrp->palette[range].green);
  321.  
  322.       printf("\nBLUE ...  ");
  323.  
  324.       for (range = 0; range < PCX_PAL_SIZE; range++)
  325.         printf("%2x  ", hdrp->palette[range].blue);
  326.  
  327.       putchar('\n');
  328.     }
  329.  
  330.   if (fclose(fp) == EOF)        /* Close the file                       */
  331.   {
  332.     fprintf(stderr, "Error: cannot close file %s\n", argv[1]);
  333.     status = FALSE;
  334.   }
  335.  
  336.   free (hdrp);          /* Free the file header buffer                  */
  337.  
  338.   return (0);
  339. }
  340.  
  341.