home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 19 Printer / 19-Printer.zip / PRPCX2.ZIP / PCX.C < prev    next >
Text File  |  1992-06-03  |  4KB  |  117 lines

  1.  
  2. /*+
  3.     Name:       pcx.c
  4.     Author:     Kent J. Quirk
  5.     Abstract:   This file contains subroutines to read PCX files.
  6. -*/
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "pcx.h"
  12.  
  13. /**** p c x _ r e a d _ h e a d e r ****
  14.     Abstract:   Reads the header of a PCX file.
  15.     Parameters: A data storage area for the header, an open file.
  16.     Returns:    The pointer to the data storage area passed, or NULL if error.
  17.     Comments:   The file should be opened in binary mode.
  18. ****************************/
  19. PCX_HDR *pcx_read_header(PCX_HDR *hdr, FILE *f)
  20. {
  21.     fseek(f, 0L, SEEK_SET);     /* header is at top of file */
  22.     if (fread(hdr, 1, sizeof(PCX_HDR), f) != sizeof(PCX_HDR))
  23.         return(NULL);
  24.     else
  25.         return(hdr);
  26. }
  27.  
  28. /**** p c x _ p r i n t _ h e a d e r ****
  29.     Abstract:   Printf's a PCX file header data to a given file.
  30.     Parameters: The PCX file header, the file to write the data to.
  31.     Returns:    Nothing
  32. ****************************/
  33. void pcx_print_header(PCX_HDR *hdr, FILE *f)
  34. {
  35.     char *t;
  36.     if (hdr->pcx_id != 0x0A)
  37.     {    
  38.         fprintf(f, "Not a PCX file.\n");
  39.         return;
  40.     }
  41.     switch (hdr->version) {
  42.     case 0: t="2.5"; break;
  43.     case 2: t="2.8 with palette info."; break;
  44.     case 3: t="2.8 without palette info."; break;
  45.     case 5: t="3.0"; break;
  46.     default: t="unknown."; break;
  47.     }
  48.     fprintf(f, "PCX Version %s\n", t);
  49.     fprintf(f, "Compression: %s\n", 
  50.                 hdr->encoding==1 ? "Run length" : "Unknown");
  51.     fprintf(f, "%d bits per pixel\n", hdr->bpp);
  52.     fprintf(f, "Image from (%d, %d) to (%d, %d) pixels.\n", 
  53.             hdr->upleftx, hdr->uplefty, hdr->lorightx, hdr->lorighty);
  54.     fprintf(f, "Created on a device with %d x %d dpi resolution.\n", 
  55.             hdr->display_xres, hdr->display_yres);
  56.     fprintf(f, "The image contains %d image planes.\n", hdr->nplanes);
  57.     fprintf(f, "There are %d bytes per line of data after decompression.\n",
  58.                 hdr->bytesperline);
  59.     fprintf(f, "There are %ld total bytes in the image.\n", 
  60.                 ((long)hdr->lorighty - (long)hdr->uplefty + 1) * 
  61.                  (long)hdr->bytesperline);
  62.     return;
  63. }
  64.  
  65. /**** p c x _ a l l o c _ l i n e ****
  66.     Abstract:   Allocates enough space to store a complete scan line from the
  67.                 current PCX file.
  68.     Parameters: The header pointer.
  69.     Returns:    A pointer to a "big enough" block of allocated space, or
  70.                 null if not enough space or an error occurred.
  71. ****************************/
  72. BYTE *pcx_alloc_line(PCX_HDR *hdr)
  73. {
  74.     return(calloc(hdr->nplanes, hdr->bytesperline));
  75. }
  76.  
  77. /**** p c x _ n e x t _ l i n e ****
  78.     Abstract:   Reads the next line from the PCX file.
  79.     Parameters: Pointer to the header, a pointer to the line area (or NULL
  80.                 for automatic allocation), and the open data file.
  81.     Returns:    A pointer to the line area, or NULL if there was a problem.
  82.     Comments:   To read the first line, call pcx_read_header() first.
  83.                 This sets the file position to the beginning of the data.
  84. ****************************/
  85. BYTE *pcx_next_line(PCX_HDR *hdr, BYTE *line, FILE *f)
  86. {
  87.     int c, len;
  88.     BYTE *dp;
  89.     WORD linesize = hdr->nplanes * hdr->bytesperline;
  90.     WORD i;
  91.     if (line == NULL)
  92.         if ((line = pcx_alloc_line(hdr)) == NULL)
  93.             return(line);
  94.     dp = line;                  /* point to data */
  95.     for (i=0; i<linesize; )
  96.     {    
  97.         if ((c = fgetc(f)) == EOF)
  98.             return(NULL);
  99.         if ((c & PCX_COMPRESSED) == PCX_COMPRESSED)
  100.         {
  101.             len = (c & PCX_MASK);
  102.             if ((c = fgetc(f)) == EOF)
  103.                 return(NULL);
  104.             memset(dp, (BYTE)c, len);
  105.             dp += len;
  106.             i += len;
  107.         }
  108.         else
  109.         {
  110.             *dp++ = (BYTE)c;
  111.             i++;
  112.         }
  113.     }
  114.     return(line);
  115. }
  116.  
  117.