1 /* ybmtopbm.c - read a file from Bennet Yee's 'xbm' program and write a pbm.
2 **
3 ** Written by Jamie Zawinski based on code (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 "pm.h"
14 #include "pbm.h"
15 #include "bitreverse.h"
16 
17 static short const ybmMagic = ( ( '!' << 8 ) | '!' );
18 
19 
20 
21 static void
getinit(FILE * const ifP,short * const colsP,short * const rowsP,short * const depthP)22 getinit(FILE *  const ifP,
23         short * const colsP,
24         short * const rowsP,
25         short * const depthP) {
26 
27     short magic;
28     int rc;
29 
30     rc = pm_readbigshort(ifP, &magic);
31     if (rc == -1)
32         pm_error("EOF / read error");
33 
34     if (magic != ybmMagic)
35         pm_error("bad magic number in YBM file");
36 
37     rc = pm_readbigshort(ifP, colsP);
38     if (rc == -1 )
39         pm_error("EOF / read error");
40 
41     rc = pm_readbigshort(ifP, rowsP);
42     if (rc == -1)
43         pm_error("EOF / read error");
44 
45     *depthP = 1;
46 }
47 
48 
49 
50 
51 
52 
53 int
main(int argc,const char * argv[])54 main(int argc, const char * argv[]) {
55 
56     FILE * ifP;
57     bit * bitrow;
58     short rows, cols;
59     unsigned int row;
60     short depth;
61     const char * inputFile;
62 
63     pm_proginit(&argc, argv);
64 
65     if (argc-1 < 1)
66         inputFile = "-";
67     else {
68         inputFile = argv[1];
69 
70         if (argc-1 > 1)
71             pm_error("Too many arguments.  The only argument is the optional "
72                      "input file name");
73     }
74 
75     ifP = pm_openr(inputFile);
76 
77     getinit(ifP, &cols, &rows, &depth);
78     if (depth != 1)
79         pm_error("YBM file has depth of %u, must be 1", (unsigned)depth);
80 
81     pbm_writepbminit(stdout, cols, rows, 0);
82 
83     bitrow = pbm_allocrow_packed(cols + 8);
84 
85     for (row = 0; row < rows; ++row) {
86         uint16_t *   const itemrow = (uint16_t *) bitrow;
87         unsigned int const itemCt  = (cols + 15) / 16;
88 
89         unsigned int i;
90 
91         /* Get raster. */
92         for (i = 0; i < itemCt; ++i) {
93             short int item;
94             pm_readbigshort(ifP, &item);
95             itemrow[i] = (uint16_t) item;
96         }
97 
98         for (i = 0; i < pbm_packed_bytes(cols); ++i)
99             bitrow[i] = bitreverse[bitrow[i]];
100 
101         pbm_cleanrowend_packed(bitrow, cols);
102         pbm_writepbmrow_packed(stdout, bitrow, cols, 0);
103     }
104 
105     pbm_freerow_packed(bitrow);
106     pm_close(ifP);
107     pm_close(stdout);
108 
109     return 0;
110 }
111