megadrive_test2

view tools/ppm2md.c @ 5:ea70f3da150f

color cycling tunnel
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 20 Jun 2017 06:08:58 +0300
parents 72ab63f262bf
children
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
6 #define RODATA_STR "__attribute__((section(\".rodata\")))"
8 unsigned char *read_image(int *xsz, int *ysz, int *maxval);
10 int main(int argc, char **argv)
11 {
12 int i, j, width, height, xtiles, ytiles, maxval;
13 unsigned char *pixels, *tiles, *src, *dest;
14 const char *prefix = "img_";
16 if(argv[1]) {
17 prefix = argv[1];
18 }
20 if(!(pixels = read_image(&width, &height, &maxval))) {
21 return 1;
22 }
23 fprintf(stderr, "read image %dx%d (maxval: %d)\n", width, height, maxval);
25 xtiles = width / 8;
26 ytiles = height / 8;
27 /* each tile is 32 bytes, 8 rows of 4 bytes each */
28 if(!(tiles = malloc(xtiles * ytiles * 32))) {
29 free(pixels);
30 return 1;
31 }
33 /* if we have 15 as max val, we'll assume they are straight palette indices
34 * otherwise, do color quantization and palette allocation
35 */
36 if(maxval == 15) {
37 /* just drop green/blue components in-place, keep red as index */
38 dest = src = pixels;
39 for(i=0; i<width * height; i++) {
40 *dest++ = *src;
41 src += 3;
42 }
43 } else {
44 /* TODO */
45 }
47 /* after processing, we have 1 color index per byte */
49 /* slice tiles and pack indices as nibbles */
50 dest = tiles;
51 for(i=0; i<ytiles; i++) {
52 for(j=0; j<xtiles; j++) {
53 int x, y;
54 int tilestart = (i * xtiles * 8 + j) * 8;
56 for(y=0; y<8; y++) {
57 for(x=0; x<4; x++) {
58 src = pixels + tilestart + y * width + x * 2;
59 *dest++ = (src[0] << 4) | (src[1] & 0xf);
60 }
61 }
63 }
64 }
66 /* output as C array */
67 printf("/* generated by ppm2md */\n");
68 printf("int %sxtiles " RODATA_STR " = %d;\n", prefix, xtiles);
69 printf("int %sytiles " RODATA_STR " = %d;\n", prefix, ytiles);
70 printf("unsigned char %stiles[][32] " RODATA_STR " = {", prefix);
72 src = tiles;
73 for(i=0; i<xtiles * ytiles; i++) {
74 if(i > 0) {
75 printf(",\n");
76 } else {
77 putchar('\n');
78 }
79 printf("\t{");
80 for(j=0; j<32; j++) {
81 if(j == 0) {
82 printf("%u", (unsigned int)*src++);
83 } else {
84 printf(", %u", (unsigned int)*src++);
85 }
86 }
87 printf(" }");
88 }
89 printf("\n};\n");
92 return 0;
93 }
95 char *clean_line(char *s)
96 {
97 char *tmp;
99 while(*s && isspace(*s)) {
100 ++s;
101 }
103 tmp = strchr(s, '#');
104 if(tmp) *tmp = 0;
105 tmp = strchr(s, '\n');
106 if(tmp) *tmp = 0;
107 tmp = strchr(s, '\r');
108 if(tmp) *tmp = 0;
110 return s;
111 }
113 unsigned char *read_image(int *width, int *height, int *maxval)
114 {
115 char buf[256];
116 int i, xsz, ysz, hdrline = 0;
117 unsigned char *pixels;
119 while(hdrline < 3 && fgets(buf, sizeof buf, stdin)) {
120 char *line = clean_line(buf);
121 if(!*line) continue;
123 switch(hdrline) {
124 case 0:
125 if(strcmp(line, "P6") != 0) {
126 goto inval;
127 }
128 break;
130 case 1:
131 if(sscanf(line, "%d %d", &xsz, &ysz) != 2) {
132 goto inval;
133 }
134 break;
136 case 2:
137 if(sscanf(line, "%d", maxval) != 1) {
138 goto inval;
139 }
140 break;
141 }
142 ++hdrline;
143 }
145 if(!(pixels = malloc(xsz * ysz * 3))) {
146 fprintf(stderr, "failed to allocate image: %dx%d\n", xsz, ysz);
147 return 0;
148 }
150 for(i=0; i<xsz * ysz * 3; i++) {
151 int c = getchar();
152 if(c == -1) goto inval;
153 pixels[i] = c;
154 }
156 *width = xsz;
157 *height = ysz;
158 return pixels;
160 inval:
161 fprintf(stderr, "invalid input\n");
162 return 0;
163 }