1 | /* this produces a raw ppm file, with a 15-character header of
2 | * "P6 3-digit-width 3-digit-height 255\n"
3 | */
4 |
5 | #include "config.h"
6 | #include "tile.h"
7 |
8 | #ifndef MONITOR_HEAP
9 | extern long *FDECL(alloc, (unsigned int));
10 | #endif
11 |
12 | FILE *ppm_file;
13 |
14 | struct ppmscreen {
15 | int Width;
16 | int Height;
17 | } PpmScreen;
18 |
19 | static int tiles_across, tiles_down, curr_tiles_across;
20 | static pixel **image;
21 |
22 | static void NDECL(write_header);
23 | static void NDECL(WriteTileStrip);
24 |
25 | static void
26 | write_header()
27 | {
28 | (void) fprintf(ppm_file, "P6 %03d %03d 255\n",
29 | PpmScreen.Width, PpmScreen.Height);
30 | }
31 |
32 | static void
33 | WriteTileStrip()
34 | {
35 | int i, j;
36 |
37 | for (j = 0; j < TILE_Y; j++) {
38 | for (i = 0; i < PpmScreen.Width; i++) {
39 | (void) fputc((char)image[j][i].r, ppm_file);
40 | (void) fputc((char)image[j][i].g, ppm_file);
41 | (void) fputc((char)image[j][i].b, ppm_file);
42 | }
43 | }
44 | }
45 |
46 | boolean
47 | fopen_ppm_file(filename, type)
48 | const char *filename;
49 | const char *type;
50 | {
51 | int i;
52 |
53 | if (strcmp(type, WRBMODE)) {
54 | Fprintf(stderr, "using writing routine for non-writing?\n");
55 | return FALSE;
56 | }
57 | ppm_file = fopen(filename, type);
58 | if (ppm_file == (FILE *)0) {
59 | Fprintf(stderr, "cannot open ppm file %s\n", filename);
60 | return FALSE;
61 | }
62 |
63 | if (!colorsinmainmap) {
64 | Fprintf(stderr, "no colormap set yet\n");
65 | return FALSE;
66 | }
67 |
68 | tiles_across = 20;
69 | curr_tiles_across = 0;
70 | PpmScreen.Width = 20 * TILE_X;
71 |
72 | tiles_down = 0;
73 | PpmScreen.Height = 0; /* will be rewritten later */
74 |
75 | write_header();
76 |
77 | image = (pixel **)alloc(TILE_Y * sizeof(pixel *));
78 | for (i = 0; i < TILE_Y; i++) {
79 | image[i] = (pixel *) alloc(PpmScreen.Width * sizeof(pixel));
80 | }
81 |
82 | return TRUE;
83 | }
84 |
85 | boolean
86 | write_ppm_tile(pixels)
87 | pixel (*pixels)[TILE_X];
88 | {
89 | int i, j;
90 |
91 | for (j = 0; j < TILE_Y; j++) {
92 | for (i = 0; i < TILE_X; i++) {
93 | image[j][curr_tiles_across*TILE_X + i] = pixels[j][i];
94 | }
95 | }
96 | curr_tiles_across++;
97 | if (curr_tiles_across == tiles_across) {
98 | WriteTileStrip();
99 | curr_tiles_across = 0;
100 | tiles_down++;
101 | }
102 | return TRUE;
103 | }
104 |
105 | int
106 | fclose_ppm_file()
107 | {
108 | int i, j;
109 |
110 | if (curr_tiles_across) { /* partial row */
111 | /* fill with checkerboard, for lack of a better idea */
112 | for (j = 0; j < TILE_Y; j++) {
113 | for (i = curr_tiles_across * TILE_X;
114 | i < PpmScreen.Width; i += 2 ) {
115 | image[j][i].r = MainColorMap[CM_RED][0];
116 | image[j][i].g = MainColorMap[CM_GREEN][0];
117 | image[j][i].b = MainColorMap[CM_BLUE][0];
118 | image[j][i+1].r = MainColorMap[CM_RED][1];
119 | image[j][i+1].g = MainColorMap[CM_GREEN][1];
120 | image[j][i+1].b = MainColorMap[CM_BLUE][1];
121 | }
122 | }
123 | WriteTileStrip();
124 | curr_tiles_across = 0;
125 | tiles_down++;
126 | }
127 |
128 | for (i = 0; i < TILE_Y; i++) {
129 | free((genericptr_t)image[i]);
130 | }
131 | free((genericptr_t)image);
132 |
133 | PpmScreen.Height = tiles_down * TILE_Y;
134 | rewind(ppm_file);
135 | write_header(); /* update size */
136 |
137 | return(fclose(ppm_file));
138 | }
139 |
140 |
141 | int
142 | main(argc, argv)
143 | int argc;
144 | char *argv[];
145 | {
146 | pixel pixels[TILE_Y][TILE_X];
147 |
148 | if (argc != 3) {
149 | Fprintf(stderr, "usage: txt2ppm txtfile ppmfile\n");
150 | exit(EXIT_FAILURE);
151 | }
152 |
153 | if (!fopen_text_file(argv[1], RDTMODE))
154 | exit(EXIT_FAILURE);
155 |
156 | init_colormap();
157 |
158 | if (!fopen_ppm_file(argv[2], WRBMODE)) {
159 | (void) fclose_text_file();
160 | exit(EXIT_FAILURE);
161 | }
162 |
163 | while (read_text_tile(pixels))
164 | (void) write_ppm_tile(pixels);
165 |
166 | (void) fclose_text_file();
167 | (void) fclose_ppm_file();
168 | exit(EXIT_SUCCESS);
169 | /*NOTREACHED*/
170 | return 0;
171 | }