]>
Commit | Line | Data |
---|---|---|
06f04fb6 L |
1 | /* |
2 | * (C) Copyright 2019 Leo C. <erbl259-lmu@yahoo.de> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | ||
8 | #include <stdlib.h> | |
9 | #include <stdio.h> | |
10 | #include <stdint.h> | |
11 | #include <errno.h> | |
12 | #include <stdarg.h> | |
13 | #include <string.h> | |
14 | ||
15 | char *progname; | |
16 | FILE *prlfile; | |
17 | char *prlfilename; | |
18 | FILE *outfile; | |
19 | char *outfilename; | |
20 | uint16_t progsize; | |
21 | ||
22 | void die(int status, const char *format, ...) | |
23 | { | |
24 | va_list arg; | |
25 | ||
26 | fflush(stdout); | |
27 | va_start(arg, format); | |
28 | fprintf(stderr, "%s: ", progname); | |
29 | vfprintf(stderr, format, arg); | |
30 | va_end(arg); | |
31 | ||
32 | exit(status); | |
33 | } | |
34 | ||
35 | static | |
36 | int get_bit(void) | |
37 | { | |
38 | static unsigned bitpos; | |
39 | static int bytebuf; | |
40 | int retval; | |
41 | ||
42 | if (bitpos == progsize) { | |
43 | return -2; | |
44 | } | |
45 | if (bitpos%8 == 0) { | |
46 | bytebuf = fgetc(prlfile); | |
47 | if (bytebuf == EOF) { | |
48 | return -1; | |
49 | } | |
50 | } | |
51 | retval = (bytebuf & 0x80) !=0; | |
52 | bytebuf <<= 1; | |
53 | bitpos++; | |
54 | ||
55 | return retval; | |
56 | } | |
57 | ||
58 | static | |
59 | int get_nr_of_bits(void) | |
60 | { | |
61 | int bits = 0; | |
62 | int bit; | |
63 | ||
64 | do { | |
65 | bits++; | |
66 | } while ((bit = get_bit()) == 0); | |
67 | ||
68 | if (bit >= 0) | |
69 | return bits; | |
70 | ||
71 | if (bit == -2) | |
72 | return 0; | |
73 | ||
74 | return bit; | |
75 | } | |
76 | ||
77 | static | |
78 | void put_bits(int width, unsigned val) | |
79 | { | |
80 | static unsigned bytebuf; | |
81 | static int bitcount = 8; | |
82 | ||
83 | while (width--) { | |
84 | bytebuf <<= 1; | |
85 | if (val & (1 << width)) | |
86 | bytebuf += 1; | |
87 | bitcount--; | |
88 | if (bitcount == 0) { | |
89 | if (fputc(bytebuf, outfile) == EOF) | |
90 | die(1,"Error writing output file %s: %s\n", | |
91 | outfilename, strerror(errno)); | |
92 | bitcount = 8; | |
93 | } | |
94 | } | |
95 | } | |
96 | ||
97 | static | |
98 | void fill_sector(void) | |
99 | { | |
100 | long curpos; | |
101 | ||
102 | if ((curpos = ftell(outfile)) == -1) | |
103 | die(1,"File error %s: %s\n", outfilename, strerror(errno)); | |
104 | ||
105 | for (int i = 0; i < 128 - curpos % 128; i++) | |
106 | if (fputc(0, outfile) == EOF) | |
107 | die(1,"Error writing output file %s: %s\n", | |
108 | outfilename, strerror(errno)); | |
109 | ||
110 | return; | |
111 | } | |
112 | ||
113 | ||
114 | static | |
115 | int process_prlfile(void) | |
116 | { | |
117 | fgetc(prlfile); | |
118 | progsize = fgetc(prlfile) + (fgetc(prlfile) << 8); | |
119 | ||
120 | /* skip header */ | |
121 | fseek(prlfile, 0x100, SEEK_SET); | |
122 | ||
123 | for (unsigned i = 0; i < progsize; i++) { | |
124 | int c = fgetc(prlfile); | |
125 | if (c == EOF) | |
126 | die(1,"Unexpected end of prl file %s\n", prlfilename); | |
127 | if (fputc(c, outfile) == EOF) | |
128 | die(1,"Error writing output file %s: %s\n", | |
129 | outfilename, strerror(errno)); | |
130 | } | |
131 | ||
132 | ||
133 | int bits; | |
134 | while ((bits = get_nr_of_bits()) >= 2) { | |
135 | unsigned off = bits - 2; | |
136 | if (off < (1<<2)) { | |
137 | put_bits(0 + 2 + 1, off); | |
138 | } else if (off < (1<<4) + (1<<2)) { | |
139 | off -= (1<<2); | |
140 | off += (1<<(4+1)); | |
141 | put_bits(1 + 4 + 1, off); | |
142 | } else if (off < (1<<8) + (1<<4) + (1<<2)) { | |
143 | off -= (1<<4) + (1<<2); | |
144 | off += (1<<(8+1)); | |
145 | off += (1<<(8+2)); | |
146 | put_bits(2 + 8 + 1, off); | |
147 | } else { | |
148 | off -= (1<<8) + (1<<4) + (1<<2); | |
149 | off += (1<<(16+1)); | |
150 | off += (1<<(16+2)); | |
151 | off += (1<<(16+3)); | |
152 | put_bits(3 + 16 + 1, off); | |
153 | } | |
154 | } | |
155 | ||
156 | if (bits == 1) | |
157 | die(1,"Bitmap error"); | |
158 | ||
159 | if (bits < 0) | |
160 | die(1,"Error while reading bitmap from prl file %s\n", prlfilename); | |
161 | ||
162 | /* end mark */ | |
163 | put_bits(4, 0xf); | |
164 | ||
165 | /* flush output bit buffer */ | |
166 | put_bits(7, 0); | |
167 | ||
168 | fill_sector(); | |
169 | ||
170 | return 0; | |
171 | } | |
172 | ||
173 | static | |
174 | void usage(void) | |
175 | { | |
176 | fprintf(stderr, | |
177 | "Usage:\n" | |
178 | "%s prlfile outfile\n", progname); | |
179 | ||
180 | } | |
181 | ||
182 | int main(int argc, char **argv) | |
183 | { | |
184 | progname = argv[0]; | |
185 | ||
186 | if (argc != 3) { | |
187 | usage(); | |
188 | die(1, ""); | |
189 | } | |
190 | ||
191 | prlfilename = argv[1]; | |
192 | prlfile=fopen(prlfilename,"rb"); | |
193 | if (prlfile==NULL) | |
194 | die(1,"Cannot open prl file %s: %s\n", | |
195 | prlfilename, strerror(errno)); | |
196 | ||
197 | outfilename = argv[2]; | |
198 | outfile=fopen(outfilename,"wb"); | |
199 | if (outfile==NULL) | |
200 | die(1,"Cannot open output file %s: %s\n", | |
201 | outfilename, strerror(errno)); | |
202 | ||
203 | process_prlfile(); | |
204 | fclose(prlfile); | |
205 | fclose(outfile); | |
206 | ||
207 | return 0; | |
208 | } |