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