1 /* brushtopbm.c - read a doodle brush file and write a PBM image
2 **
3 ** Copyright (C) 1988 by Jef Poskanzer.
4 **
5 ** Permission to use, copy, modify, and distribute this software and its
6 ** documentation for any purpose and without fee is hereby granted, provided
7 ** that the above copyright notice appear in all copies and that both that
8 ** copyright notice and this permission notice appear in supporting
9 ** documentation.  This software is provided "as is" without express or
10 ** implied warranty.
11 */
12 
13 #include "pbm.h"
14 
15 #define HEADERSIZE 16   /* 16 is just a guess at the header size */
16 
17 
18 
19 static void
getinit(FILE * const ifP,unsigned int * const colsP,unsigned int * const rowsP)20 getinit(FILE *         const ifP,
21         unsigned int * const colsP,
22         unsigned int * const rowsP) {
23 
24     unsigned char header[HEADERSIZE];
25     size_t bytesRead;
26 
27     bytesRead = fread(header, sizeof(header), 1, ifP);
28     if (bytesRead !=1)
29         pm_error("Error reading header");
30 
31     if (header[0] != 1)
32         pm_error("bad magic number 1");
33     if (header[1] != 0)
34         pm_error("bad magic number 2");
35 
36     *colsP =  (header[2] << 8) + header[3];  /* Max 65535 */
37     *rowsP =  (header[4] << 8) + header[5];  /* Max 65535 */
38 }
39 
40 
41 
42 static void
validateEof(FILE * const ifP)43 validateEof(FILE * const ifP) {
44 
45     int rc;
46     rc = getc(ifP);
47     if (rc != EOF)
48         pm_message("Extraneous data at end of file");
49 }
50 
51 
52 /*
53    The routine for converting the raster closely resembles the pbm
54    case of pnminvert.  Input is padded up to 16 bit border.
55    afu December 2013
56  */
57 
58 
59 
60 int
main(int argc,const char ** argv)61 main(int argc, const char ** argv)  {
62 
63     FILE * ifP;
64     bit * bitrow;
65     unsigned int rows, cols, row;
66 
67     pm_proginit(&argc, argv);
68 
69     if (argc-1 > 0) {
70         ifP = pm_openr(argv[1]);
71         if (argc-1 > 1)
72             pm_error("Too many arguments (%u).  "
73                      "The only argument is the brush file name.", argc-1);
74     } else
75         ifP = stdin;
76 
77     getinit(ifP, &cols, &rows);
78 
79     pbm_writepbminit(stdout, cols, rows, 0);
80 
81     bitrow = pbm_allocrow_packed(cols + 16);
82 
83     for (row = 0; row < rows; ++row) {
84         unsigned int const inRowBytes = ((cols + 15) / 16) * 2;
85         unsigned int i;
86         size_t bytesRead;
87 
88         bytesRead = fread (bitrow, 1, inRowBytes, ifP);
89         if (bytesRead != inRowBytes)
90             pm_error("Error reading a row of data from brushfile");
91 
92         for (i = 0; i < inRowBytes; ++i)
93             bitrow[i] = ~bitrow[i];
94 
95         /* Clean off remainder of fractional last character */
96         pbm_cleanrowend_packed(bitrow, cols);
97 
98         pbm_writepbmrow_packed(stdout, bitrow, cols, 0);
99     }
100 
101     validateEof(ifP);
102 
103     pm_close(ifP);
104     pm_close(stdout);
105 
106     return 0;
107 }
108