megadrive_test2

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