1 /*
2  * tumble: build a PDF file from image files
3  *
4  * G4 table generator
5  * Copyright 2003, 2017 Eric Smith <spacewar@gmail.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.  Note that permission is
10  * not granted to redistribute this program under the terms of any
11  * other version of the General Public License.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21  */
22 
23 
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 
emit_code(int indent,char * code,int last,bool comment,int cval)31 void emit_code (int indent, char *code, int last, bool comment, int cval)
32 {
33   int i;
34   int count = 0;
35   uint32_t val = 0;
36 
37   printf ("%*s{ ", indent, "");
38 
39   printf ("%d, ", (int) strlen (code));
40 
41   for (i = 0; i < strlen (code); i++)
42     switch (code [i])
43       {
44       case '0': val = (val << 1);     count++; break;
45       case '1': val = (val << 1) + 1; count++; break;
46       case ' ': break;
47       default:
48 	fprintf (stderr, "internal error\n");
49 	exit (2);
50       }
51 
52   printf ("0x%0*x", (count + 3)/4, val);
53 
54   printf (" }");
55   if (! last)
56     printf (",");
57   if (comment)
58     printf ("  /* %d */", cval);
59   printf ("\n");
60 }
61 
62 
63 char *long_makeup_code [12] =
64   {
65     /* 1792 */ "00000001000",
66     /* 1856 */ "00000001100",
67     /* 1920 */ "00000001101",
68     /* 1984 */ "000000010010",
69     /* 2048 */ "000000010011",
70     /* 2112 */ "000000010100",
71     /* 2176 */ "000000010101",
72     /* 2240 */ "000000010110",
73     /* 2304 */ "000000010111",
74     /* 2368 */ "000000011100",
75     /* 2432 */ "000000011101",
76     /* 2496 */ "000000011110"
77     /* 2560    "000000011111"  hard-coded, doesn't need to be in table */
78   };
79 
80 
print_long_makeup_code(bool header)81 void print_long_makeup_code (bool header)
82 {
83   int i;
84 
85   if (header)
86     printf ("extern ");
87   printf ("const g4_bits g4_long_makeup_code [12]");
88   if (header)
89     {
90       printf (";\n");
91       return;
92     }
93   printf (" =\n");
94   printf ("  {\n");
95   for (i = 0; i < 12; i++)
96     emit_code (4, long_makeup_code [i], i == 11, 1, i * 64 + 1792);
97   printf ("  };\n");
98 }
99 
100 
101 char *makeup_code [64][2] =
102   {
103     { /*   64 */ "11011",     "0000001111" },
104     { /*  128 */ "10010",     "000011001000" },
105     { /*  192 */ "010111",    "000011001001" },
106     { /*  256 */ "0110111",   "000001011011" },
107     { /*  320 */ "00110110",  "000000110011" },
108     { /*  384 */ "00110111",  "000000110100" },
109     { /*  448 */ "01100100",  "000000110101" },
110     { /*  512 */ "01100101",  "0000001101100" },
111     { /*  576 */ "01101000",  "0000001101101" },
112     { /*  640 */ "01100111",  "0000001001010" },
113     { /*  704 */ "011001100", "0000001001011" },
114     { /*  768 */ "011001101", "0000001001100" },
115     { /*  832 */ "011010010", "0000001001101" },
116     { /*  896 */ "011010011", "0000001110010" },
117     { /*  960 */ "011010100", "0000001110011" },
118     { /* 1024 */ "011010101", "0000001110100" },
119     { /* 1088 */ "011010110", "0000001110101" },
120     { /* 1152 */ "011010111", "0000001110110" },
121     { /* 1216 */ "011011000", "0000001110111" },
122     { /* 1280 */ "011011001", "0000001010010" },
123     { /* 1344 */ "011011010", "0000001010011" },
124     { /* 1408 */ "011011011", "0000001010100" },
125     { /* 1472 */ "010011000", "0000001010101" },
126     { /* 1536 */ "010011001", "0000001011010" },
127     { /* 1600 */ "010011010", "0000001011011" },
128     { /* 1664 */ "011000",    "0000001100100" },
129     { /* 1728 */ "010011011", "0000001100101" }
130   };
131 
132 
print_makeup_code(bool header)133 void print_makeup_code (bool header)
134 {
135   int i;
136 
137   if (header)
138     printf ("extern ");
139   printf ("const g4_bits g4_makeup_code [2] [27]");
140   if (header)
141     {
142       printf (";\n");
143       return;
144     }
145   printf (" =\n");
146   printf ("  {\n");
147   printf ("    {\n");
148   printf ("      /* white */\n");
149   for (i = 0; i <= 26; i++)
150     emit_code (6, makeup_code [i][0], i == 26, 1, (i + 1) * 64);
151   printf ("    },\n");
152   printf ("    {\n");
153   printf ("      /* black */\n");
154   for (i = 0; i <= 26; i++)
155     emit_code (6, makeup_code [i][1], i == 26, 1, (i + 1) * 64);
156   printf ("    }\n");
157   printf ("  };\n");
158 }
159 
160 
161 char *h_code [64][2] =
162   {
163     { /*  0 */ "00110101", "0000110111" },
164     { /*  1 */ "000111",   "010" },
165     { /*  2 */ "0111",     "11" },
166     { /*  3 */ "1000",     "10" },
167     { /*  4 */ "1011",     "011" },
168     { /*  5 */ "1100",     "0011" },
169     { /*  6 */ "1110",     "0010" },
170     { /*  7 */ "1111",     "00011" },
171     { /*  8 */ "10011",    "000101" },
172     { /*  9 */ "10100",    "000100" },
173     { /* 10 */ "00111",    "0000100" },
174     { /* 11 */ "01000",    "0000101" },
175     { /* 12 */ "001000",   "0000111" },
176     { /* 13 */ "000011",   "00000100" },
177     { /* 14 */ "110100",   "00000111" },
178     { /* 15 */ "110101",   "000011000" },
179     { /* 16 */ "101010",   "0000010111" },
180     { /* 17 */ "101011",   "0000011000" },
181     { /* 18 */ "0100111",  "0000001000" },
182     { /* 19 */ "0001100",  "00001100111" },
183     { /* 20 */ "0001000",  "00001101000" },
184     { /* 21 */ "0010111",  "00001101100" },
185     { /* 22 */ "0000011",  "00000110111" },
186     { /* 23 */ "0000100",  "00000101000" },
187     { /* 24 */ "0101000",  "00000010111" },
188     { /* 25 */ "0101011",  "00000011000" },
189     { /* 26 */ "0010011",  "000011001010" },
190     { /* 27 */ "0100100",  "000011001011" },
191     { /* 28 */ "0011000",  "000011001100" },
192     { /* 29 */ "00000010", "000011001101" },
193     { /* 30 */ "00000011", "000001101000" },
194     { /* 31 */ "00011010", "000001101001" },
195     { /* 32 */ "00011011", "000001101010" },
196     { /* 33 */ "00010010", "000001101011" },
197     { /* 34 */ "00010011", "000011010010" },
198     { /* 35 */ "00010100", "000011010011" },
199     { /* 36 */ "00010101", "000011010100" },
200     { /* 37 */ "00010110", "000011010101" },
201     { /* 38 */ "00010111", "000011010110" },
202     { /* 39 */ "00101000", "000011010111" },
203     { /* 40 */ "00101001", "000001101100" },
204     { /* 41 */ "00101010", "000001101101" },
205     { /* 42 */ "00101011", "000011011010" },
206     { /* 43 */ "00101100", "000011011011" },
207     { /* 44 */ "00101101", "000001010100" },
208     { /* 45 */ "00000100", "000001010101" },
209     { /* 46 */ "00000101", "000001010110" },
210     { /* 47 */ "00001010", "000001010111" },
211     { /* 48 */ "00001011", "000001100100" },
212     { /* 49 */ "01010010", "000001100101" },
213     { /* 50 */ "01010011", "000001010010" },
214     { /* 51 */ "01010100", "000001010011" },
215     { /* 52 */ "01010101", "000000100100" },
216     { /* 53 */ "00100100", "000000110111" },
217     { /* 54 */ "00100101", "000000111000" },
218     { /* 55 */ "01011000", "000000100111" },
219     { /* 56 */ "01011001", "000000101000" },
220     { /* 57 */ "01011010", "000001011000" },
221     { /* 58 */ "01011011", "000001011001" },
222     { /* 59 */ "01001010", "000000101011" },
223     { /* 60 */ "01001011", "000000101100" },
224     { /* 61 */ "00110010", "000001011010" },
225     { /* 62 */ "00110011", "000001100110" },
226     { /* 63 */ "00110100", "000001100111" }
227   };
228 
229 
print_h_code(bool header)230 void print_h_code (bool header)
231 {
232   int i;
233 
234   if (header)
235     printf ("extern ");
236   printf ("const g4_bits g4_h_code [2] [64]");
237   if (header)
238     {
239       printf (";\n");
240       return;
241     }
242   printf (" =\n");
243   printf ("  {\n");
244   printf ("    {\n");
245   printf ("      /* white */\n");
246   for (i = 0; i <= 63; i++)
247     emit_code (6, h_code [i][0], i == 63, 1, i);
248   printf ("    },\n");
249   printf ("    {\n");
250   printf ("      /* black */\n");
251   for (i = 0; i <= 63; i++)
252     emit_code (6, h_code [i][1], i == 63, 1, i);
253   printf ("    }\n");
254   printf ("  };\n");
255 }
256 
257 
258 char *v_code [7] =
259   {
260     /* -3 */ "0000010",
261     /* -2 */ "000010",
262     /* -1 */ "010",
263     /*  0 */ "1",
264     /*  1 */ "011",
265     /*  2 */ "000011",
266     /*  3 */ "0000011"
267   };
268 
269 
print_v_code(bool header)270 void print_v_code (bool header)
271 {
272   int i;
273 
274   if (header)
275     printf ("extern ");
276   printf ("const g4_bits g4_vert_code [7]");
277   if (header)
278     {
279       printf (";\n");
280       return;
281     }
282   printf ("=\n");
283   printf ("  {\n");
284   for (i = 0; i <= 6; i++)
285     emit_code (4, v_code [i], i == 6, 1, i - 3);
286   printf ("  };\n");
287 }
288 
289 
main(int argc,char * argv[])290 int main (int argc, char *argv [])
291 {
292   bool header;
293 
294   if (argc != 2)
295     {
296       fprintf (stderr, "wrong arg count\n");
297       exit (2);
298     }
299   if (strcmp (argv [1], "-h") == 0)
300     header = 1;
301   else if (strcmp (argv [1], "-c") == 0)
302     header = 0;
303   else
304     {
305       fprintf (stderr, "wrong args\n");
306       exit (2);
307     }
308 
309   printf ("/* This file is automatically generated; do not edit */\n");
310   printf ("\n");
311 
312   if (header)
313     {
314       printf ("typedef struct\n");
315       printf ("{\n");
316       printf ("  uint32_t count;\n");
317       printf ("  uint32_t bits;\n");
318       printf ("} g4_bits;\n");
319     }
320   else
321     {
322       printf ("#include <stdint.h>\n");
323       printf ("#include \"g4_tables.h\"\n");
324     }
325   printf ("\n");
326 
327   print_long_makeup_code (header);
328   printf ("\n");
329 
330   print_makeup_code (header);
331   printf ("\n");
332 
333   print_h_code (header);
334   printf ("\n");
335 
336   print_v_code (header);
337 
338   exit (0);
339 }
340