twintig: Be less verbose by default
[svpe-tools.git] / tpl2ppm.c
blobcffab02d61e451657ae96ffeac5b37c5ddbecd41
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 #include "tools.h"
9 static u8 buf[5000000]; // yeah yeah, static buffer, whatever
11 static void i4(int w, int h, int o, char *name)
13 FILE *out;
14 int x, y;
16 out = fopen(name, "wb");
18 fprintf(out, "P6 %d %d 255\n", w, h);
20 for (y = 0; y < h; y++)
21 for (x = 0; x < w; x++) {
22 u8 pix[3];
23 u16 raw;
24 int x0, x1, y0, y1, off;
25 int ww = round_up(w, 8);
27 x0 = x & 7;
28 x1 = x >> 3;
29 y0 = y & 7;
30 y1 = y >> 3;
31 off = x0 + 8*y0 + 64*x1 + 8*ww*y1;
33 raw = buf[o + off/2];
34 if ((x0 & 1) == 0)
35 raw >>= 4;
36 else
37 raw &= 0x0f;
39 pix[0] = raw * 0x11;
40 pix[1] = raw * 0x11;
41 pix[2] = raw * 0x11;
43 fwrite(pix, 1, 3, out);
46 fclose(out);
49 static void i8(int w, int h, int o, char *name)
51 FILE *out;
52 int x, y;
54 out = fopen(name, "wb");
56 fprintf(out, "P6 %d %d 255\n", w, h);
58 for (y = 0; y < h; y++)
59 for (x = 0; x < w; x++) {
60 u8 pix[3];
61 u16 raw;
62 int x0, x1, y0, y1, off;
63 int ww = round_up(w, 8);
65 x0 = x & 7;
66 x1 = x >> 3;
67 y0 = y & 3;
68 y1 = y >> 2;
69 off = x0 + 8*y0 + 32*x1 + 4*ww*y1;
71 raw = buf[o + off];
73 pix[0] = raw;
74 pix[1] = raw;
75 pix[2] = raw;
77 fwrite(pix, 1, 3, out);
80 fclose(out);
83 static void ia4(int w, int h, int o, char *name)
85 FILE *out;
86 int x, y;
88 out = fopen(name, "wb");
90 fprintf(out, "P6 %d %d 255\n", w, h);
92 for (y = 0; y < h; y++)
93 for (x = 0; x < w; x++) {
94 u8 pix[3];
95 u16 raw;
96 int x0, x1, y0, y1, off;
97 int ww = round_up(w, 8);
99 x0 = x & 7;
100 x1 = x >> 3;
101 y0 = y & 3;
102 y1 = y >> 2;
103 off = x0 + 8*y0 + 32*x1 + 4*ww*y1;
105 raw = buf[o + off];
107 //raw = (raw >> 4) * 0x11;
108 raw = (raw & 0xf) * 0x11;
110 pix[0] = raw;
111 pix[1] = raw;
112 pix[2] = raw;
114 fwrite(pix, 1, 3, out);
117 fclose(out);
120 static void rgb5a3(int w, int h, int o, char *name)
122 FILE *out;
123 int x, y;
125 out = fopen(name, "wb");
127 fprintf(out, "P6 %d %d 255\n", w, h);
129 for (y = 0; y < h; y++)
130 for (x = 0; x < w; x++) {
131 u8 pix[3];
132 u16 raw;
133 int x0, x1, y0, y1, off;
134 int ww = round_up(w, 4);
136 x0 = x & 3;
137 x1 = x >> 2;
138 y0 = y & 3;
139 y1 = y >> 2;
140 off = x0 + 4*y0 + 16*x1 + 4*ww*y1;
142 raw = buf[o + 2*off] << 8;
143 raw |= buf[o + 2*off + 1];
145 // RGB5A3
146 if (raw & 0x8000) {
147 pix[0] = (raw >> 7) & 0xf8;
148 pix[1] = (raw >> 2) & 0xf8;
149 pix[2] = (raw << 3) & 0xf8;
150 } else {
151 pix[0] = (raw >> 4) & 0xf0;
152 pix[1] = raw & 0xf0;
153 pix[2] = (raw << 4) & 0xf0;
156 fwrite(pix, 1, 3, out);
159 fclose(out);
162 static u16 avg(u16 w0, u16 w1, u16 c0, u16 c1)
164 u16 a0, a1;
165 u16 a, c;
167 a0 = c0 >> 11;
168 a1 = c1 >> 11;
169 a = (w0*a0 + w1*a1) / (w0 + w1);
170 c = a << 11;
172 a0 = (c0 >> 5) & 63;
173 a1 = (c1 >> 5) & 63;
174 a = (w0*a0 + w1*a1) / (w0 + w1);
175 c |= a << 5;
177 a0 = c0 & 31;
178 a1 = c1 & 31;
179 a = (w0*a0 + w1*a1) / (w0 + w1);
180 c |= a;
182 return c;
185 static void cmp(int w, int h, int o, char *name)
187 FILE *out;
188 int x, y;
190 out = fopen(name, "wb");
192 fprintf(out, "P6 %d %d 255\n", w, h);
194 for (y = 0; y < h; y++)
195 for (x = 0; x < w; x++) {
196 u8 pix[3];
197 u16 raw;
198 u16 c[4];
199 int x0, x1, x2, y0, y1, y2, off;
200 int ww = round_up(w, 8);
201 int ix;
202 u32 px;
204 x0 = x & 3;
205 x1 = (x >> 2) & 1;
206 x2 = x >> 3;
207 y0 = y & 3;
208 y1 = (y >> 2) & 1;
209 y2 = y >> 3;
210 off = 8*x1 + 16*y1 + 32*x2 + 4*ww*y2;
212 c[0] = be16(buf + o + off);
213 c[1] = be16(buf + o + off + 2);
214 if (c[0] > c[1]) {
215 c[2] = avg(2, 1, c[0], c[1]);
216 c[3] = avg(1, 2, c[0], c[1]);
217 } else {
218 c[2] = avg(1, 1, c[0], c[1]);
219 c[3] = 0;
222 px = be32(buf + o + off + 4);
223 ix = x0 + 4*y0;
224 raw = c[(px >> (30 - 2*ix)) & 3];
226 pix[0] = (raw >> 8) & 0xf8;
227 pix[1] = (raw >> 3) & 0xf8;
228 pix[2] = (raw << 3) & 0xf8;
230 fwrite(pix, 1, 3, out);
233 fclose(out);
236 int main(int argc, char **argv)
238 FILE *in;
239 u16 w, h, o, t;
241 in = fopen(argv[1], "rb");
242 fread(buf, 1, sizeof buf, in);
243 fclose(in);
245 h = be16(buf + 0x14);
246 w = be16(buf + 0x16);
247 t = be32(buf + 0x18);
248 o = be32(buf + 0x1c);
250 fprintf(stderr, "type %02x -- %s\n", t, argv[1]);
252 // XXX: check more header stuff here
253 switch (t) {
254 case 0:
255 i4(w, h, o, argv[2]);
256 break;
258 case 1:
259 i8(w, h, o, argv[2]);
260 break;
262 case 2:
263 ia4(w, h, o, argv[2]);
264 break;
266 case 5:
267 rgb5a3(w, h, o, argv[2]);
268 break;
270 case 14:
271 cmp(w, h, o, argv[2]);
272 break;
274 default:
275 fprintf(stderr, "unhandled type %02x\n", t);
278 return 0;