home *** CD-ROM | disk | FTP | other *** search
-
- /*+
- Name: pcx.c
- Author: Kent J. Quirk
- Abstract: This file contains subroutines to read PCX files.
- -*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "pcx.h"
-
- /**** p c x _ r e a d _ h e a d e r ****
- Abstract: Reads the header of a PCX file.
- Parameters: A data storage area for the header, an open file.
- Returns: The pointer to the data storage area passed, or NULL if error.
- Comments: The file should be opened in binary mode.
- ****************************/
- PCX_HDR *pcx_read_header(PCX_HDR *hdr, FILE *f)
- {
- fseek(f, 0L, SEEK_SET); /* header is at top of file */
- if (fread(hdr, 1, sizeof(PCX_HDR), f) != sizeof(PCX_HDR))
- return(NULL);
- else
- return(hdr);
- }
-
- /**** p c x _ p r i n t _ h e a d e r ****
- Abstract: Printf's a PCX file header data to a given file.
- Parameters: The PCX file header, the file to write the data to.
- Returns: Nothing
- ****************************/
- void pcx_print_header(PCX_HDR *hdr, FILE *f)
- {
- char *t;
- if (hdr->pcx_id != 0x0A)
- {
- fprintf(f, "Not a PCX file.\n");
- return;
- }
- switch (hdr->version) {
- case 0: t="2.5"; break;
- case 2: t="2.8 with palette info."; break;
- case 3: t="2.8 without palette info."; break;
- case 5: t="3.0"; break;
- default: t="unknown."; break;
- }
- fprintf(f, "PCX Version %s\n", t);
- fprintf(f, "Compression: %s\n",
- hdr->encoding==1 ? "Run length" : "Unknown");
- fprintf(f, "%d bits per pixel\n", hdr->bpp);
- fprintf(f, "Image from (%d, %d) to (%d, %d) pixels.\n",
- hdr->upleftx, hdr->uplefty, hdr->lorightx, hdr->lorighty);
- fprintf(f, "Created on a device with %d x %d dpi resolution.\n",
- hdr->display_xres, hdr->display_yres);
- fprintf(f, "The image contains %d image planes.\n", hdr->nplanes);
- fprintf(f, "There are %d bytes per line of data after decompression.\n",
- hdr->bytesperline);
- fprintf(f, "There are %ld total bytes in the image.\n",
- ((long)hdr->lorighty - (long)hdr->uplefty + 1) *
- (long)hdr->bytesperline);
- return;
- }
-
- /**** p c x _ a l l o c _ l i n e ****
- Abstract: Allocates enough space to store a complete scan line from the
- current PCX file.
- Parameters: The header pointer.
- Returns: A pointer to a "big enough" block of allocated space, or
- null if not enough space or an error occurred.
- ****************************/
- BYTE *pcx_alloc_line(PCX_HDR *hdr)
- {
- return(calloc(hdr->nplanes, hdr->bytesperline));
- }
-
- /**** p c x _ n e x t _ l i n e ****
- Abstract: Reads the next line from the PCX file.
- Parameters: Pointer to the header, a pointer to the line area (or NULL
- for automatic allocation), and the open data file.
- Returns: A pointer to the line area, or NULL if there was a problem.
- Comments: To read the first line, call pcx_read_header() first.
- This sets the file position to the beginning of the data.
- ****************************/
- BYTE *pcx_next_line(PCX_HDR *hdr, BYTE *line, FILE *f)
- {
- int c, len;
- BYTE *dp;
- WORD linesize = hdr->nplanes * hdr->bytesperline;
- WORD i;
- if (line == NULL)
- if ((line = pcx_alloc_line(hdr)) == NULL)
- return(line);
- dp = line; /* point to data */
- for (i=0; i<linesize; )
- {
- if ((c = fgetc(f)) == EOF)
- return(NULL);
- if ((c & PCX_COMPRESSED) == PCX_COMPRESSED)
- {
- len = (c & PCX_MASK);
- if ((c = fgetc(f)) == EOF)
- return(NULL);
- memset(dp, (BYTE)c, len);
- dp += len;
- i += len;
- }
- else
- {
- *dp++ = (BYTE)c;
- i++;
- }
- }
- return(line);
- }
-