tpl2ppm: Renamed from tpl.
[svpe-tools.git] / tpl2ppm.c
blob6db193592832166cbd4be7dc7876738f2fe3fae8
1 // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
2 // Licensed under the terms of the GNU GPL, version 2
3 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
5 #include <stdio.h>
7 typedef unsigned char u8;
8 typedef unsigned short u16;
9 typedef unsigned int u32;
11 static u8 buf[5000000]; // yeah yeah, static buffer, whatever
13 static u16 be16(u8 *p)
15 return (p[0] << 8) | p[1];
18 static u32 be32(u8 *p)
20 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
23 static void i4(int w, int h, int o, char *name)
25 FILE *out;
26 int x, y;
28 out = fopen(name, "wb");
30 fprintf(out, "P6 %d %d 255\n", w, h);
32 for (y = 0; y < h; y++)
33 for (x = 0; x < w; x++) {
34 u8 pix[3];
35 u16 raw;
36 int x0, x1, y0, y1, off;
37 int ww = (w + 7) & ~7;
39 x0 = x & 7;
40 x1 = x >> 3;
41 y0 = y & 7;
42 y1 = y >> 3;
43 off = x0 + 8*y0 + 64*x1 + 8*ww*y1;
45 raw = buf[o + off/2];
46 if ((x0 & 1) == 0)
47 raw >>= 4;
48 else
49 raw &= 0x0f;
51 pix[0] = raw * 0x11;
52 pix[1] = raw * 0x11;
53 pix[2] = raw * 0x11;
55 fwrite(pix, 1, 3, out);
58 fclose(out);
61 static void i8(int w, int h, int o, char *name)
63 FILE *out;
64 int x, y;
66 out = fopen(name, "wb");
68 fprintf(out, "P6 %d %d 255\n", w, h);
70 for (y = 0; y < h; y++)
71 for (x = 0; x < w; x++) {
72 u8 pix[3];
73 u16 raw;
74 int x0, x1, y0, y1, off;
75 int ww = (w + 7) & ~7;
77 x0 = x & 7;
78 x1 = x >> 3;
79 y0 = y & 3;
80 y1 = y >> 2;
81 off = x0 + 8*y0 + 32*x1 + 4*ww*y1;
83 raw = buf[o + off];
85 pix[0] = raw;
86 pix[1] = raw;
87 pix[2] = raw;
89 fwrite(pix, 1, 3, out);
92 fclose(out);
95 static void ia4(int w, int h, int o, char *name)
97 FILE *out;
98 int x, y;
100 out = fopen(name, "wb");
102 fprintf(out, "P6 %d %d 255\n", w, h);
104 for (y = 0; y < h; y++)
105 for (x = 0; x < w; x++) {
106 u8 pix[3];
107 u16 raw;
108 int x0, x1, y0, y1, off;
109 int ww = (w + 7) & ~7;
111 x0 = x & 7;
112 x1 = x >> 3;
113 y0 = y & 3;
114 y1 = y >> 2;
115 off = x0 + 8*y0 + 32*x1 + 4*ww*y1;
117 raw = buf[o + off];
119 //raw = (raw >> 4) * 0x11;
120 raw = (raw & 0xf) * 0x11;
122 pix[0] = raw;
123 pix[1] = raw;
124 pix[2] = raw;
126 fwrite(pix, 1, 3, out);
129 fclose(out);
132 static void rgb5a3(int w, int h, int o, char *name)
134 FILE *out;
135 int x, y;
137 out = fopen(name, "wb");
139 fprintf(out, "P6 %d %d 255\n", w, h);
141 for (y = 0; y < h; y++)
142 for (x = 0; x < w; x++) {
143 u8 pix[3];
144 u16 raw;
145 int x0, x1, y0, y1, off;
146 int ww = (w + 3) & ~3;
148 x0 = x & 3;
149 x1 = x >> 2;
150 y0 = y & 3;
151 y1 = y >> 2;
152 off = x0 + 4*y0 + 16*x1 + 4*ww*y1;
154 raw = buf[o + 2*off] << 8;
155 raw |= buf[o + 2*off + 1];
157 // RGB5A3
158 if (raw & 0x8000) {
159 pix[0] = (raw >> 7) & 0xf8;
160 pix[1] = (raw >> 2) & 0xf8;
161 pix[2] = (raw << 3) & 0xf8;
162 } else {
163 pix[0] = (raw >> 4) & 0xf0;
164 pix[1] = raw & 0xf0;
165 pix[2] = (raw << 4) & 0xf0;
168 fwrite(pix, 1, 3, out);
171 fclose(out);
174 static u16 avg(u16 w0, u16 w1, u16 c0, u16 c1)
176 u16 a0, a1;
177 u16 a, c;
179 a0 = c0 >> 11;
180 a1 = c1 >> 11;
181 a = (w0*a0 + w1*a1) / (w0 + w1);
182 c = a << 11;
184 a0 = (c0 >> 5) & 63;
185 a1 = (c1 >> 5) & 63;
186 a = (w0*a0 + w1*a1) / (w0 + w1);
187 c |= a << 5;
189 a0 = c0 & 31;
190 a1 = c1 & 31;
191 a = (w0*a0 + w1*a1) / (w0 + w1);
192 c |= a;
194 return c;
197 static void cmp(int w, int h, int o, char *name)
199 FILE *out;
200 int x, y;
202 out = fopen(name, "wb");
204 fprintf(out, "P6 %d %d 255\n", w, h);
206 for (y = 0; y < h; y++)
207 for (x = 0; x < w; x++) {
208 u8 pix[3];
209 u16 raw;
210 u16 c[4];
211 int x0, x1, x2, y0, y1, y2, off;
212 int ww = (w + 7) & ~7;
213 int ix;
214 u32 px;
216 x0 = x & 3;
217 x1 = (x >> 2) & 1;
218 x2 = x >> 3;
219 y0 = y & 3;
220 y1 = (y >> 2) & 1;
221 y2 = y >> 3;
222 off = 8*x1 + 16*y1 + 32*x2 + 4*ww*y2;
224 c[0] = be16(buf + o + off);
225 c[1] = be16(buf + o + off + 2);
226 if (c[0] > c[1]) {
227 c[2] = avg(2, 1, c[0], c[1]);
228 c[3] = avg(1, 2, c[0], c[1]);
229 } else {
230 c[2] = avg(1, 1, c[0], c[1]);
231 c[3] = 0;
234 px = be32(buf + o + off + 4);
235 ix = x0 + 4*y0;
236 raw = c[(px >> (30 - 2*ix)) & 3];
238 pix[0] = (raw >> 8) & 0xf8;
239 pix[1] = (raw >> 3) & 0xf8;
240 pix[2] = (raw << 3) & 0xf8;
242 fwrite(pix, 1, 3, out);
245 fclose(out);
248 int main(int argc, char **argv)
250 FILE *in;
251 u16 w, h, o, t;
253 in = fopen(argv[1], "rb");
254 fread(buf, 1, sizeof buf, in);
255 fclose(in);
257 h = be16(buf + 0x14);
258 w = be16(buf + 0x16);
259 t = be32(buf + 0x18);
260 o = be32(buf + 0x1c);
262 fprintf(stderr, "type %02x -- %s\n", t, argv[1]);
264 // XXX: check more header stuff here
265 switch (t) {
266 case 0:
267 i4(w, h, o, argv[2]);
268 break;
270 case 1:
271 i8(w, h, o, argv[2]);
272 break;
274 case 2:
275 ia4(w, h, o, argv[2]);
276 break;
278 case 5:
279 rgb5a3(w, h, o, argv[2]);
280 break;
282 case 14:
283 cmp(w, h, o, argv[2]);
284 break;
286 default:
287 fprintf(stderr, "unhandled type %02x\n", t);
290 return 0;