chiark / gitweb /
undo broken deletion
[trains.git] / layout / compose-segenco.c
1 /*
2  * usage:
3  *   compose-segenco \
4  *     thing.pf.segenco.ppm \
5  *     thing.p0.segenco.ppm \
6  *     thing.p1.segenco.ppm \
7  *     thing.p2.segenco.ppm \
8  *     ...
9  *     thing.p5.segenco.ppm
10  *
11  * writes resulting composite encoding
12  */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include <ppm.h>
19
20 #include "segcmap.h"
21
22 #define FILES (MOVFEATPOS_BITS+1)
23
24 struct file {
25   const char *fn;
26   FILE *f;
27 };
28
29 typedef unsigned char val;
30
31 static struct file f[FILES];
32 static int nf, fi, rows=-1, cols;
33 static int row, col;
34
35 static void badformat(const char *m) {
36   fprintf(stderr,"bad format: %s: row=%d,col=%d:\n %s\n",
37           f[fi].fn, row,col, m);
38   exit(12);
39 }
40
41 int main(int argc, char **argv) {
42   const char *arg;
43   int trows, tcols, informat;
44   pixval maxval;
45
46   ppm_init(&argc,argv);
47   if (!*argv || !*++argv || (*argv)[0]=='-') {
48     fprintf(stderr,"bad usage\n"); exit(12);
49   }
50
51   for (fi=0, nf=0;
52        (arg= *argv++);
53        fi++, nf++) {
54     if (nf >= FILES) { fprintf(stderr,"too many files\n"); exit(12); }
55
56     f[fi].fn= arg;
57     f[fi].f= fopen(arg, "rb");
58     if (!f[fi].f) { perror(arg); exit(8); }
59
60     ppm_readppminit(f[fi].f, &tcols, &trows, &maxval, &informat);
61     if (maxval != 255) badformat("wrong maxval");
62     if (informat != RPPM_FORMAT) badformat("wrong format");
63
64     if (rows==-1) {
65       rows= trows;
66       cols= tcols;
67     } else {
68       if (rows != trows || cols != tcols) badformat("wrong size");
69     }
70   }
71     
72   ppm_writeppminit(stdout, cols, rows, 255, 0);
73
74   for (row=0; row<rows; row++)
75     for (col=0; col<cols; col++) {
76       int gotsegnum=-1, gotmovfeatpos=-1;
77       val ov[3];
78
79       DATUM2ARY(ov, BACKGROUND);
80       
81       for (fi=0; fi<nf; fi++) {
82         val iv[3];
83         unsigned long datum;
84         int segnum, movfeatpos;
85         
86         if (fread(iv,1,3,f[fi].f)!=3) {
87           if (ferror(f[fi].f)) { perror(f[fi].fn); exit(16); }
88           else badformat("truncated file");
89         }
90
91         datum= ARY2DATUM(iv);
92
93         if (datum == BACKGROUND)
94           continue;
95
96         segnum= DATUM2(SEGNUM,datum);
97         movfeatpos= DATUM2(MOVFEATPOS,datum);
98
99         if (!!fi != !!movfeatpos)
100           badformat("moveable featureness disagrees with file index");
101
102         if (gotsegnum==-1) {
103           memcpy(ov,iv,sizeof(ov));
104           gotsegnum= segnum;
105           gotmovfeatpos= movfeatpos;
106         } else if (segnum!=gotsegnum || movfeatpos!=gotmovfeatpos) {
107           continue;
108         }
109         if (fi) {
110           datum= ARY2DATUM(ov);
111           datum |= 1UL << (fi-1 + MOVFEATPOS_BASEBIT);
112           DATUM2ARY(ov,datum);
113         }
114       }
115
116       if (fwrite(ov,1,3,stdout)!=3) { perror("writing"); exit(16); }
117
118     }
119   
120   return 0;
121 }