1 /* pbmtoatk.c - convert portable bitmap to Andrew Toolkit raster object
2 **
3 ** Copyright (C) 1991 by Bill Janssen.
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 <stdio.h>
14 #include <string.h>
15 
16 #include "pm_c_util.h"
17 #include "nstring.h"
18 #include "pbm.h"
19 
20 #define DEFAULTSCALE (1<<16)
21 #define RASTERVERSION 2
22 
23 
24 static void
write_atk_bytes(FILE * const file,unsigned char const curbyte,unsigned int const startcount)25 write_atk_bytes(FILE *        const file,
26                 unsigned char const curbyte,
27                 unsigned int  const startcount) {
28 
29     /* codes for data stream */
30     static unsigned char const whitezero   = 'f';
31     static unsigned char const whitetwenty = 'z';
32     static unsigned char const blackzero   = 'F';
33     static unsigned char const blacktwenty = 'Z';
34     static unsigned char const otherzero   = 0x1F;
35 
36     #define WHITEBYTE 0x00
37     #define BLACKBYTE 0xFF
38 
39     /* WriteRow table for conversion of a byte value to two character
40        hex representation
41     */
42 
43     static unsigned char hex[16] = {
44     '0', '1', '2', '3', '4', '5', '6', '7',
45     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
46     };
47 
48     unsigned int curcount;
49 
50     curcount = startcount;  /* initial value */
51 
52     switch (curbyte) {
53     case WHITEBYTE:
54         while (curcount > 20) {
55             fputc(whitetwenty, file);
56             curcount -= 20;
57         }
58         fputc(whitezero + curcount, file);
59         break;
60     case BLACKBYTE:
61         while (curcount > 20) {
62             fputc(blacktwenty, file);
63             curcount -= 20;
64         }
65         fputc(blackzero + curcount, file);
66         break;
67     default:
68         while (curcount > 16) {
69             fputc(otherzero + 16, file);
70             fputc(hex[curbyte / 16], file);
71             fputc(hex[curbyte & 15], file);
72             curcount -= 16;
73         }
74         if (curcount > 1)
75             fputc(otherzero + curcount, file);
76         else ;  /* the byte written will represent a single instance */
77         fputc(hex[curbyte / 16], file);
78         fputc(hex[curbyte & 15], file);
79     }
80 }
81 
82 
83 
84 static void
process_atk_byte(int * const pcurcount,unsigned char * const pcurbyte,FILE * const file,unsigned char const newbyte,int const eolflag)85 process_atk_byte(int *           const pcurcount,
86                  unsigned char * const pcurbyte,
87                  FILE *          const file,
88                  unsigned char   const newbyte,
89                  int             const eolflag) {
90 
91     int curcount;
92     unsigned char curbyte;
93 
94     curcount = *pcurcount;  /* initial value */
95     curbyte  = *pcurbyte;  /* initial value */
96 
97     if (curcount < 1) {
98         *pcurbyte = curbyte = newbyte;
99         *pcurcount = curcount = 1;
100     } else if (newbyte == curbyte) {
101         *pcurcount = (curcount += 1);
102     }
103 
104     if (curcount > 0 && newbyte != curbyte) {
105         write_atk_bytes (file, curbyte, curcount);
106         *pcurcount = 1;
107         *pcurbyte = newbyte;
108     }
109 
110     if (eolflag) {
111         write_atk_bytes (file, *pcurbyte, *pcurcount);
112         fprintf(file, " |\n");
113         *pcurcount = 0;
114         *pcurbyte = 0;
115     }
116 }
117 
118 
119 
120 int
main(int argc,const char ** argv)121 main(int argc, const char ** argv) {
122 
123     FILE * ifP;
124     bit * bitrow;
125     int rows, cols, format;
126     unsigned int row;
127     unsigned char curbyte;
128     int curcount;
129 
130     pm_proginit(&argc, argv);
131 
132     if (argc-1 > 1)
133         pm_error("Too many arguments.  Only argument is file name");
134 
135     else if (argc-1 == 1) {
136         ifP = pm_openr(argv[1]);
137     } else {
138         ifP = stdin;
139     }
140 
141     pbm_readpbminit(ifP, &cols, &rows, &format);
142     bitrow = pbm_allocrow_packed(cols);
143 
144     printf("\\begindata{raster,%d}\n", 1);
145     printf("%d %d %d %d ", RASTERVERSION, 0, DEFAULTSCALE, DEFAULTSCALE);
146     printf("%d %d %d %d\n", 0, 0, cols, rows); /* subraster */
147     printf("bits %d %d %d\n", 1, cols, rows);
148 
149     for (row = 0; row < rows; ++row) {
150         unsigned int const byteCt = pbm_packed_bytes(cols);
151         unsigned int i;
152 
153         pbm_readpbmrow_packed(ifP, bitrow, cols, format);
154         pbm_cleanrowend_packed(bitrow, cols);
155 
156         for (i = 0, curbyte = 0, curcount = 0; i < byteCt; ++i) {
157             process_atk_byte(&curcount, &curbyte, stdout,
158                              bitrow[i],
159                              i + 1 < byteCt ? FALSE : TRUE );
160         }
161     }
162 
163     pbm_freerow_packed(bitrow);
164     pm_close(ifP);
165 
166     printf("\\enddata{raster, %d}\n", 1);
167 
168     return 0;
169 }
170