1 /*
2 * xvmaki.c - load routine for `MAKI' format pictures.
3 *
4 * The `MAKI' format was used by some Japanese personal computer users.
5 */
6
7 #include "xv.h"
8 #include <setjmp.h>
9
10 #ifdef HAVE_MAKI
11
12 typedef unsigned short data16;
13 typedef unsigned int data32;
14
15 struct maki_info {
16 jmp_buf jmp;
17 FILE *fp;
18 long fsize;
19 int x0, y0, x1, y1;
20 int width, height;
21 float aspect;
22 long fb_size;
23 long pa_size, pb_size;
24 int m_maki01b, m_200, m_dig8;
25 data16 ext_flag;
26 byte *fa, *fb, *pa, *pb;
27 byte *vs;
28 int numcols;
29 byte *forma, *formb;
30 };
31
32
33 static void maki_open_file PARM((struct maki_info*, char*));
34 static void maki_check_id PARM((struct maki_info*));
35 static void maki_skip_comment PARM((struct maki_info*));
36 static void maki_read_header PARM((struct maki_info*));
37 static void maki_read_palette PARM((struct maki_info*,
38 byte*, byte*, byte*));
39 static void maki_read_flags PARM((struct maki_info*));
40 static void maki_read_pixel_data PARM((struct maki_info*));
41 static void maki_expand_virtual_screen PARM((struct maki_info*));
42 static void maki_expand_pixel_data PARM((struct maki_info*, byte**));
43 static void maki_init_info PARM((struct maki_info*));
44
45 static void maki_make_pixel_data PARM((struct maki_info*, byte*));
46 static void maki_make_virtual_screen PARM((struct maki_info*));
47 static void maki_make_flags PARM((struct maki_info*));
48 static void maki_write_check_id PARM((struct maki_info*));
49 static void maki_write_comment PARM((struct maki_info*));
50 static void maki_write_header PARM((struct maki_info*));
51 static void maki_write_palette PARM((struct maki_info*,
52 byte*, byte*, byte*, int));
53 static void maki_write_flags PARM((struct maki_info*));
54 static void maki_write_pixel_data PARM((struct maki_info*));
55
56 static void maki_cleanup_maki_info PARM((struct maki_info*, int));
57 static void maki_cleanup_pinfo PARM((PICINFO*));
58 static void maki_memory_error PARM((char*, char*));
59 static void maki_error PARM((struct maki_info*, int));
60 static void maki_file_error PARM((struct maki_info*, int));
61 static void maki_file_warning PARM((struct maki_info*, int));
62 static void maki_show_maki_info PARM((struct maki_info*));
63 static void *maki_malloc PARM((size_t, char*));
64 static void *maki_realloc PARM((void *, size_t, char*));
65
66 static char maki_id_a[] = "MAKI01A ";
67 static char maki_id_b[] = "MAKI01B ";
68
69 static char *maki_msgs[] = {
70 NULL,
71 #define MAKI_OPEN 1
72 "can't open file.",
73 #define MAKI_CORRUPT 2
74 "file corrupted.",
75 #define MAKI_FORMAT 3
76 "not MAKI format.",
77 #define MAKI_BAD_DATA 4
78 "bad data.",
79 #define MAKI_COMMENT 5
80 "no '^Z' after comment.",
81 #define MAKI_SIZE 6
82 "bad size.",
83 #define MAKI_WRITE 7
84 "write failed.",
85 };
86
87 #define H4(b) ((b) >> 4 & 0xf)
88 #define L4(b) ((b) & 0xf)
89 #define error(msg_num) longjmp(mi->jmp, msg_num)
90
LoadMAKI(fname,pinfo)91 int LoadMAKI(fname, pinfo)
92 char *fname;
93 PICINFO *pinfo;
94 {
95 struct maki_info maki;
96 int e;
97
98 if(DEBUG) fputs("LoadMAKI:\n", stderr);
99
100 pinfo->comment = NULL;
101 maki_init_info(&maki);
102 if((e = setjmp(maki.jmp)) != 0){
103 /* When an error occurs, comes here. */
104 maki_cleanup_maki_info(&maki, 0);
105 maki_cleanup_pinfo(pinfo);
106 return 0;
107 }
108
109 maki_open_file(&maki, fname);
110 maki_check_id(&maki);
111 maki_skip_comment(&maki);
112 maki_read_header(&maki);
113 maki_read_palette(&maki, pinfo->r, pinfo->g, pinfo->b);
114 maki_read_flags(&maki);
115 maki_read_pixel_data(&maki);
116 maki_expand_virtual_screen(&maki);
117 maki_expand_pixel_data(&maki, &pinfo->pic);
118
119 pinfo->w = pinfo->normw = maki.width;
120 pinfo->h = pinfo->normh = maki.height;
121 pinfo->type = PIC8;
122 pinfo->frmType = F_MAKI;
123 pinfo->colType = F_FULLCOLOR;
124 sprintf(pinfo->fullInfo, "MAKI, 16 colors (%ld bytes)", maki.fsize);
125 sprintf(pinfo->shrtInfo, "%dx%d MAKI", maki.width, maki.height);
126 normaspect = maki.aspect;
127
128 maki_cleanup_maki_info(&maki, 0);
129 return 1;
130 }
131
maki_open_file(mi,fname)132 static void maki_open_file(mi, fname)
133 struct maki_info *mi;
134 char *fname;
135 {
136 if((mi->fp = fopen(fname, "rb")) == NULL)
137 maki_file_error(mi, MAKI_OPEN);
138 fseek(mi->fp, (size_t) 0, SEEK_END);
139 mi->fsize = ftell(mi->fp);
140 fseek(mi->fp, (size_t) 0, SEEK_SET);
141 }
142
maki_check_id(mi)143 static void maki_check_id(mi)
144 struct maki_info *mi;
145 {
146 char buf[8];
147 if(fread(buf, (size_t) 8, (size_t) 1, mi->fp) != 1)
148 maki_file_error(mi, MAKI_CORRUPT);
149 if(strncmp(buf, maki_id_a, (size_t) 8) != 0 &&
150 strncmp(buf, maki_id_b, (size_t) 8) != 0)
151 maki_error(mi, MAKI_FORMAT);
152 mi->m_maki01b = (buf[6] == 'B');
153 }
154
maki_skip_comment(mi)155 static void maki_skip_comment(mi)
156 struct maki_info *mi;
157 {
158 int i;
159 int c;
160
161 for(i = 0; i < 24; i++){
162 if((c = fgetc(mi->fp)) == EOF)
163 maki_file_error(mi, MAKI_CORRUPT);
164 if(c == '\032') /* ^Z, 0x1a */
165 break;
166 }
167 if(c != '\032')
168 maki_file_error(mi, MAKI_COMMENT);
169
170 fseek(mi->fp, 32L, SEEK_SET);
171 }
172
maki_read_header(mi)173 static void maki_read_header(mi)
174 struct maki_info *mi;
175 {
176 byte buf[16];
177
178 if(fread(buf, (size_t) 16, (size_t) 1, mi->fp) != 1)
179 maki_file_error(mi, MAKI_CORRUPT);
180
181 mi->fb_size = (long)buf[ 0] << 8 | (long)buf[ 1];
182 mi->pa_size = (long)buf[ 2] << 8 | (long)buf[ 3];
183 mi->pb_size = (long)buf[ 4] << 8 | (long)buf[ 5];
184 mi->ext_flag = (long)buf[ 6] << 8 | (long)buf[ 7];
185 mi->x0 = (long)buf[ 8] << 8 | (long)buf[ 9];
186 mi->y0 = (long)buf[10] << 8 | (long)buf[11];
187 mi->x1 = (long)buf[12] << 8 | (long)buf[13];
188 mi->y1 = (long)buf[14] << 8 | (long)buf[15];
189
190 mi->width = mi->x1-- - mi->x0;
191 mi->height = mi->y1-- - mi->y0;
192 mi->m_200 = mi->ext_flag & 1;
193 mi->m_dig8 = mi->ext_flag & 2;
194 mi->aspect = mi->m_200 ? 0.5 : 1.0;
195
196 if(DEBUG) maki_show_maki_info(mi);
197 }
198
maki_read_palette(mi,r,g,b)199 static void maki_read_palette(mi, r, g, b)
200 struct maki_info *mi;
201 byte *r, *g, *b;
202 {
203 byte buf[48], *p;
204
205 if(fread(buf, (size_t) 48, (size_t) 1, mi->fp) != 1)
206 maki_file_error(mi, MAKI_CORRUPT);
207
208 for(p = buf; p < &buf[48]; ){
209 *g++ = *p++;
210 *r++ = *p++;
211 *b++ = *p++;
212 }
213 }
214
maki_read_flags(mi)215 static void maki_read_flags(mi)
216 struct maki_info *mi;
217 {
218 mi->fa = maki_malloc((size_t) 1000 , "maki_read_flags#1");
219 mi->fb = maki_malloc((size_t) mi->fb_size, "maki_read_flags#2");
220
221 if(fread(mi->fa, (size_t) 1000, (size_t) 1, mi->fp) != 1)
222 maki_file_warning(mi, MAKI_CORRUPT);
223 if(fread(mi->fb, (size_t) mi->fb_size, (size_t) 1, mi->fp) != 1)
224 maki_file_warning(mi, MAKI_CORRUPT);
225 }
226
maki_read_pixel_data(mi)227 static void maki_read_pixel_data(mi)
228 struct maki_info *mi;
229 {
230 mi->pa = maki_malloc((size_t) mi->pa_size, "maki_read_pixel_data#1");
231 mi->pb = maki_malloc((size_t) mi->pb_size, "maki_read_pixel_data#2");
232
233 if(fread(mi->pa, (size_t) mi->pa_size, (size_t) 1, mi->fp) != 1)
234 maki_file_warning(mi, MAKI_CORRUPT);
235 if(fread(mi->pb, (size_t) mi->pb_size, (size_t) 1, mi->fp) != 1)
236 maki_file_warning(mi, MAKI_CORRUPT);
237 }
238
maki_expand_virtual_screen(mi)239 static void maki_expand_virtual_screen(mi)
240 struct maki_info *mi;
241 {
242 int x, y, fai, fbi;
243 int bpl = mi->width / 2 / 8; /* bytes per line */
244 byte mask;
245 mi->vs = maki_malloc((size_t) bpl * mi->height, // GRR POSSIBLE OVERFLOW / FIXME
246 "maki_expand_virtual_screen");
247
248 fai = fbi = 0;
249 mask = 0x80;
250 for(y = 0; y < mi->height; y += 4){
251 for(x = 0; x < mi->width / 2; x += 4){
252 if(mi->fa[fai] & mask){
253 byte bh, bl;
254 bh = mi->fb[fbi++];
255 bl = mi->fb[fbi++];
256 if(x % 8 == 0){
257 mi->vs[ y * bpl + x / 8] = H4(bh) << 4;
258 mi->vs[(y + 1) * bpl + x / 8] = L4(bh) << 4;
259 mi->vs[(y + 2) * bpl + x / 8] = H4(bl) << 4;
260 mi->vs[(y + 3) * bpl + x / 8] = L4(bl) << 4;
261 }else{
262 mi->vs[ y * bpl + x / 8] |= H4(bh);
263 mi->vs[(y + 1) * bpl + x / 8] |= L4(bh);
264 mi->vs[(y + 2) * bpl + x / 8] |= H4(bl);
265 mi->vs[(y + 3) * bpl + x / 8] |= L4(bl);
266 }
267 }else{
268 if(x % 8 == 0){
269 mi->vs[ y * bpl + x / 8] = 0;
270 mi->vs[(y + 1) * bpl + x / 8] = 0;
271 mi->vs[(y + 2) * bpl + x / 8] = 0;
272 mi->vs[(y + 3) * bpl + x / 8] = 0;
273 }else{
274 /* mi->vs[ y * bpl + x / 8] |= 0;
275 mi->vs[(y + 1) * bpl + x / 8] |= 0;
276 mi->vs[(y + 2) * bpl + x / 8] |= 0;
277 mi->vs[(y + 3) * bpl + x / 8] |= 0; */
278 }
279 }
280
281 if((mask >>= 1) == 0){
282 mask = 0x80;
283 fai++;
284 }
285 }
286 }
287 }
288
maki_expand_pixel_data(mi,pic)289 static void maki_expand_pixel_data(mi, pic)
290 struct maki_info *mi;
291 byte **pic;
292 {
293 int x, y;
294 int vsi, pi, max_pi;
295 byte *p;
296 byte mask;
297 int gap;
298 *pic = maki_malloc((size_t) mi->width * mi->height, // GRR POSSIBLE OVERFLOW / FIXME
299 "maki_expand_pixel_data");
300
301 vsi = pi = 0;
302 p = mi->pa;
303 max_pi = mi->pa_size - 1;
304 mask = 0x80;
305 for(y = 0; y < mi->height; y++){
306 for(x = 0; x < mi->width; x += 2){
307 if(mi->vs[vsi] & mask){
308 if(pi > max_pi){
309 if(p == mi->pb)
310 maki_error(mi, MAKI_BAD_DATA);
311 pi = 0;
312 p = mi->pb;
313 max_pi = mi->pb_size - 1;
314 }
315 (*pic)[y * mi->width + x ] = H4(p[pi]);
316 (*pic)[y * mi->width + x + 1] = L4(p[pi]);
317 pi++;
318 }else{
319 (*pic)[y * mi->width + x ] = 0;
320 (*pic)[y * mi->width + x + 1] = 0;
321 }
322
323 if((mask >>= 1) == 0){
324 mask = 0x80;
325 vsi++;
326 }
327 }
328 }
329
330 gap = mi->m_maki01b ? 4 : 2;
331
332 for(y = gap; y < mi->height; y++){
333 for(x = 0; x < mi->width; x++)
334 (*pic)[y * mi->width + x] ^= (*pic)[(y - gap) * mi->width + x];
335 }
336 }
337
338
WriteMAKI(fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle)339 int WriteMAKI(fp, pic, ptype, w, h, rmap, gmap, bmap, numcols, colorstyle)
340 FILE *fp;
341 byte *pic;
342 int ptype, w, h;
343 byte *rmap, *gmap, *bmap;
344 int numcols, colorstyle;
345 {
346 byte rtemp[256], gtemp[256], btemp[256];
347 struct maki_info maki, *mi = &maki;
348 int e;
349
350 if(DEBUG) fputs("WriteMAKI:\n", stderr);
351
352 maki_init_info(&maki);
353 if((e = setjmp(maki.jmp)) != 0){
354 /* An error occurs */
355 maki_cleanup_maki_info(&maki, 1);
356 return -1;
357 }
358
359 if(w != 640 || h != 400) {
360 char str[512];
361 sprintf(str,"MAKI: %s Should be 640x400", maki_msgs[MAKI_SIZE]);
362 ErrPopUp(str, "\nBummer!");
363 maki_error(mi, MAKI_SIZE);
364 }
365
366 maki.fp = fp;
367 maki.width = w;
368 maki.height = h;
369 maki.x1 = w - 1;
370 maki.y1 = h - 1;
371
372 if(ptype == PIC24){
373 if(!(pic = Conv24to8(pic, w, h, 16, rtemp, gtemp, btemp)))
374 maki_memory_error("Conv24to8#1", "WriteMAKI");
375 rmap = rtemp;
376 gmap = gtemp;
377 bmap = btemp;
378 }else if(numcols > 16){
379 if(!(pic = Conv8to24(pic, w, h, rmap, gmap, bmap)))
380 maki_memory_error("Conv8to24", "WriteMAKI");
381 if(!(pic = Conv24to8(pic, w, h, 16, rtemp, gtemp, btemp)))
382 maki_memory_error("Conv24to8#2", "WriteMAKI");
383 rmap = rtemp;
384 gmap = gtemp;
385 bmap = btemp;
386 }else
387 maki.numcols = numcols;
388
389 maki_make_pixel_data(&maki, pic);
390 maki_make_virtual_screen(&maki);
391 maki_make_flags(&maki);
392 maki_write_check_id(&maki);
393 maki_write_comment(&maki);
394 maki_write_header(&maki);
395 maki_write_palette(&maki, rmap, gmap, bmap, colorstyle == F_GREYSCALE);
396 maki_write_flags(&maki);
397 maki_write_pixel_data(&maki);
398
399 maki_cleanup_maki_info(&maki, 1);
400 return 0;
401 }
402
maki_make_pixel_data(mi,pic)403 static void maki_make_pixel_data(mi, pic)
404 struct maki_info *mi;
405 byte *pic;
406 {
407 int x, y, i;
408 int nza, nzb;
409
410 mi->forma = maki_malloc((size_t) mi->width / 2 * mi->height, // GRR POSSIBLE OVERFLOW / FIXME
411 "maki_make_pixel_data#1");
412 mi->formb = maki_malloc((size_t) mi->width / 2 * mi->height, // GRR POSSIBLE OVERFLOW / FIXME
413 "maki_make_pixel_data#2");
414
415 for(y = 0; y < mi->height; y++){
416 for(x = 0; x < mi->width; x += 2){
417 byte b;
418 b = pic[y * mi->width + x] << 4 | pic[y * mi->width + x + 1];
419 mi->forma[y * mi->width / 2 + x / 2] = b;
420 mi->formb[y * mi->width / 2 + x / 2] = b;
421 }
422 }
423
424 for(y = mi->height - 1; y >= 2; y--){
425 for(x = 0; x < mi->width / 2; x++){
426 mi->forma[y * mi->width / 2 + x] ^=
427 mi->forma[(y - 2) * mi->width / 2 + x];
428 }
429 }
430
431 for(y = mi->height - 1; y >= 4; y--){
432 for(x = 0; x < mi->width / 2; x++){
433 mi->formb[y * mi->width / 2 + x] ^=
434 mi->formb[(y - 4) * mi->width / 2 + x];
435 }
436 }
437
438 nza = nzb = 0;
439 for(i = 0; i < mi->width / 2 * mi->height; i++){
440 if(mi->forma[i] != 0)
441 nza++;
442 if(mi->formb[i] != 0)
443 nzb++;
444 }
445 if(nza > nzb){
446 mi->m_maki01b = 1;
447 free(mi->forma);
448 mi->forma = NULL;
449 }else{
450 mi->m_maki01b = 0;
451 free(mi->formb);
452 mi->formb = NULL;
453 }
454 }
455
maki_make_virtual_screen(mi)456 static void maki_make_virtual_screen(mi)
457 struct maki_info *mi;
458 {
459 int bpl = mi->width / 2 / 8;
460 int vsi, pai, pbi, max_pai, max_pbi;
461 byte mask;
462 byte *pixels;
463 int x, y;
464
465 mi->vs = maki_malloc((size_t) bpl * mi->height, // GRR POSSIBLE OVERFLOW / FIXME
466 "maki_make_virtual_screen#1");
467
468 if(mi->m_maki01b)
469 pixels = mi->formb;
470 else
471 pixels = mi->forma;
472
473 vsi = pai = pbi = 0;
474 max_pai = max_pbi = -1;
475 mask = 0x80;
476 for(y = 0; y < mi->height; y++){
477 for(x = 0; x < mi->width / 2; x++){
478 if(pixels[y * mi->width / 2 + x] == 0){
479 mi->vs[vsi] &= ~mask;
480 }else{
481 mi->vs[vsi] |= mask;
482 if(y < 200){
483 if(pai > max_pai){
484 max_pai += 1024;
485 mi->pa = maki_realloc(mi->pa, (size_t) max_pai + 1,
486 "maki_make_virtual_screen#2");
487 }
488 mi->pa[pai++] = pixels[y * mi->width / 2 + x];
489 }else{
490 if(pbi > max_pbi){
491 max_pbi += 1024;
492 mi->pb = maki_realloc(mi->pb, (size_t) max_pbi + 2,
493 "maki_make_virtual_screen#3");
494 }
495 mi->pb[pbi++] = pixels[y * mi->width / 2 + x];
496 }
497 }
498
499 if((mask >>= 1) == 0){
500 mask = 0x80;
501 vsi++;
502 }
503 }
504 }
505
506 mi->pa_size = pai;
507 mi->pb_size = pbi;
508 }
509
maki_make_flags(mi)510 static void maki_make_flags(mi)
511 struct maki_info *mi;
512 {
513 int bpl = mi->width / 2 / 8;
514 int fbi, max_fbi;
515 int fai;
516 int x, y;
517 byte mask;
518
519 mi->fa = maki_malloc((size_t) bpl * mi->height, "maki_make_flags#1"); // GRR POSSIBLE OVERFLOW / FIXME
520
521 fbi = fai = 0;
522 max_fbi = -1;
523 mask = 0x80;
524 for(y = 0; y < mi->height; y += 4){
525 for(x = 0; x < mi->width / 2; x += 4){
526 if(x % 8 == 0){
527 if(H4(mi->vs[ y * bpl + x / 8]) == 0 &&
528 H4(mi->vs[(y + 1) * bpl + x / 8]) == 0 &&
529 H4(mi->vs[(y + 2) * bpl + x / 8]) == 0 &&
530 H4(mi->vs[(y + 3) * bpl + x / 8]) == 0){
531 mi->fa[fai] &= ~mask;
532 }else{
533 mi->fa[fai] |= mask;
534 if(fbi + 1 > max_fbi){
535 max_fbi += 1024;
536 mi->fb = maki_realloc(mi->fb, (size_t) max_fbi + 1,
537 "maki_make_flags#2");
538 }
539 mi->fb[fbi++] = H4(mi->vs[ y * bpl + x / 8]) << 4
540 | H4(mi->vs[(y + 1) * bpl + x / 8]);
541 mi->fb[fbi++] = H4(mi->vs[(y + 2) * bpl + x / 8]) << 4
542 | H4(mi->vs[(y + 3) * bpl + x / 8]);
543 }
544 }else{
545 if(L4(mi->vs[ y * bpl + x / 8]) == 0 &&
546 L4(mi->vs[(y + 1) * bpl + x / 8]) == 0 &&
547 L4(mi->vs[(y + 2) * bpl + x / 8]) == 0 &&
548 L4(mi->vs[(y + 3) * bpl + x / 8]) == 0){
549 mi->fa[fai] &= ~mask;
550 }else{
551 mi->fa[fai] |= mask;
552 if(fbi + 1 > max_fbi){
553 max_fbi += 1024;
554 mi->fb = maki_realloc(mi->fb, (size_t) max_fbi + 1,
555 "maki_make_flags#3");
556 }
557 mi->fb[fbi++] = L4(mi->vs[ y * bpl + x / 8]) << 4
558 | L4(mi->vs[(y + 1) * bpl + x / 8]);
559 mi->fb[fbi++] = L4(mi->vs[(y + 2) * bpl + x / 8]) << 4
560 | L4(mi->vs[(y + 3) * bpl + x / 8]);
561 }
562 }
563
564 if((mask >>= 1) == 0){
565 mask = 0x80;
566 fai++;
567 }
568 }
569 }
570
571 mi->fb_size = fbi;
572 }
573
maki_write_check_id(mi)574 static void maki_write_check_id(mi)
575 struct maki_info *mi;
576 {
577 char *id = mi->m_maki01b ? maki_id_b : maki_id_a;
578 if(fwrite(id, (size_t) 8, (size_t) 1, mi->fp) != 1)
579 maki_file_error(mi, MAKI_WRITE);
580 }
581
maki_write_comment(mi)582 static void maki_write_comment(mi)
583 struct maki_info *mi;
584 {
585 char buf[24];
586 char *p;
587 int i = 0;
588
589 strcpy(buf, "XV ");
590
591 if((p = (char *) getenv("USER")) == NULL)
592 p = "????????";
593 for(i = 5; i < 23; i++){
594 if(*p == '\0')
595 break;
596 buf[i] = *p++;
597 }
598 for( ; i < 23; i++)
599 buf[i] = ' ';
600
601 buf[i] = '\032'; /* ^Z, 0x1a */
602
603 if(fwrite(buf, (size_t) 24, (size_t) 1, mi->fp) != 1)
604 maki_file_error(mi, MAKI_WRITE);
605 }
606
maki_write_header(mi)607 static void maki_write_header(mi)
608 struct maki_info *mi;
609 {
610 byte buf[16];
611
612 if(DEBUG) maki_show_maki_info(mi);
613
614 #define set_word(i, v) {buf[i]=(v)>>8&0xff;buf[i+1]=(v)&0xff;}
615 set_word(0, mi->fb_size);
616 set_word(2, mi->pa_size);
617 set_word(4, mi->pb_size);
618 set_word(6, mi->ext_flag);
619 set_word(8, mi->x0);
620 set_word(10, mi->y0);
621 set_word(12, mi->x1 + 1);
622 set_word(14, mi->y1 + 1);
623 #undef set_word
624
625 if(fwrite(buf, (size_t) 16, (size_t) 1, mi->fp) != 1)
626 maki_file_error(mi, MAKI_WRITE);
627 }
628
maki_write_palette(mi,r,g,b,grey)629 static void maki_write_palette(mi, r, g, b, grey)
630 struct maki_info *mi;
631 byte *r, *g, *b;
632 int grey;
633 {
634 int i;
635 char buf[3];
636 for(i = 0; i < mi->numcols; i++){
637 buf[0] = *g++;
638 buf[1] = *r++;
639 buf[2] = *b++;
640 if(grey)
641 buf[0] = buf[1] = buf[2] = MONO(buf[1], buf[0], buf[2]);
642 if(fwrite(buf, (size_t) 3, (size_t) 1, mi->fp) != 1)
643 maki_file_error(mi, MAKI_WRITE);
644 }
645 for( ; i < 16; i++){
646 if(fwrite(buf, (size_t) 3, (size_t) 1, mi->fp) != 1)
647 maki_file_error(mi, MAKI_WRITE);
648 }
649 }
650
maki_write_flags(mi)651 static void maki_write_flags(mi)
652 struct maki_info *mi;
653 {
654 int bpl = mi->width / 2 / 8;
655 if(fwrite(mi->fa, (size_t) bpl * mi->height / 16, (size_t) 1, mi->fp) != 1)
656 maki_file_error(mi, MAKI_WRITE);
657
658 if(fwrite(mi->fb, (size_t) mi->fb_size, (size_t) 1, mi->fp) != 1)
659 maki_file_error(mi, MAKI_WRITE);
660 }
661
maki_write_pixel_data(mi)662 static void maki_write_pixel_data(mi)
663 struct maki_info *mi;
664 {
665 if(fwrite(mi->pa, (size_t) mi->pa_size, (size_t) 1, mi->fp) != 1)
666 maki_file_error(mi, MAKI_WRITE);
667
668 if(fwrite(mi->pb, (size_t) mi->pb_size, (size_t) 1, mi->fp) != 1)
669 maki_file_error(mi, MAKI_WRITE);
670 }
671
672
673
maki_init_info(mi)674 static void maki_init_info(mi)
675 struct maki_info *mi;
676 {
677 xvbzero((char *)mi, sizeof(struct maki_info));
678 mi->fp = NULL;
679 mi->fsize = 0;
680 mi->x0 = mi->y0 = mi->x1 = mi->y1 = 0;
681 mi->width = mi->height = 0;
682 mi->aspect = 1.0;
683 mi->fb_size = mi->pa_size = mi->pb_size = 0;
684 mi->m_maki01b = mi->m_200 = mi->m_dig8 = 0;
685 mi->ext_flag = 0;
686 mi->fa = mi->fb = mi->pa = mi->pb = NULL;
687 mi->vs = NULL;
688 mi->numcols = 16;
689 mi->forma = mi->formb = NULL;
690 }
691
maki_cleanup_maki_info(mi,writing)692 static void maki_cleanup_maki_info(mi, writing)
693 struct maki_info *mi;
694 int writing;
695 {
696 if(mi->fp && !writing)
697 fclose(mi->fp);
698 if(mi->fa)
699 free(mi->fa);
700 if(mi->fb)
701 free(mi->fb);
702 if(mi->pa)
703 free(mi->pa);
704 if(mi->pb)
705 free(mi->pb);
706 if(mi->vs)
707 free(mi->vs);
708 if(mi->forma)
709 free(mi->forma);
710 if(mi->formb)
711 free(mi->formb);
712 }
713
maki_cleanup_pinfo(pi)714 static void maki_cleanup_pinfo(pi)
715 PICINFO *pi;
716 {
717 if(pi->pic){
718 free(pi->pic);
719 pi->pic = NULL;
720 }
721 }
722
maki_memory_error(scm,fn)723 static void maki_memory_error(scm, fn)
724 char *scm, *fn;
725 {
726 char buf[128];
727 sprintf(buf, "%s: coulndn't allocate memory. (%s)", scm, fn);
728 FatalError(buf);
729 }
730
maki_error(mi,mn)731 static void maki_error(mi, mn)
732 struct maki_info *mi;
733 int mn;
734 {
735 SetISTR(ISTR_WARNING, "%s", maki_msgs[mn]);
736 longjmp(mi->jmp, 1);
737 }
738
maki_file_error(mi,mn)739 static void maki_file_error(mi, mn)
740 struct maki_info *mi;
741 int mn;
742 {
743 if(feof(mi->fp))
744 SetISTR(ISTR_WARNING, "%s (end of file)", maki_msgs[mn]);
745 else
746 SetISTR(ISTR_WARNING, "%s (%s)", maki_msgs[mn], ERRSTR(errno));
747 longjmp(mi->jmp, 1);
748 }
749
maki_file_warning(mi,mn)750 static void maki_file_warning(mi, mn)
751 struct maki_info *mi;
752 int mn;
753 {
754 if(feof(mi->fp))
755 SetISTR(ISTR_WARNING, "%s (end of file)", maki_msgs[mn]);
756 else
757 SetISTR(ISTR_WARNING, "%s (%s)", maki_msgs[mn], ERRSTR(errno));
758 }
759
maki_show_maki_info(mi)760 static void maki_show_maki_info(mi)
761 struct maki_info *mi;
762 {
763 fprintf(stderr, " file size: %ld.\n", mi->fsize);
764 fprintf(stderr, " image size: %dx%d.\n", mi->width, mi->height);
765 fprintf(stderr, " aspect: %f.\n", mi->aspect);
766 fprintf(stderr, " flag B size: %ld.\n", mi->fb_size);
767 fprintf(stderr, " pixel data size: A:%ld, B:%ld.\n",
768 mi->pa_size, mi->pb_size);
769 fprintf(stderr, " MAKI01B: %s.\n", mi->m_maki01b ? "true" : "false");
770 fprintf(stderr, " 200 line mode: %s.\n", mi->m_200 ? "true" : "false");
771 fprintf(stderr, " digital 8 colors: %s.\n", mi->m_dig8 ? "true" : "false");
772 }
773
maki_malloc(n,fn)774 static void *maki_malloc(n, fn)
775 size_t n;
776 char *fn;
777 {
778 void *r = (void *) malloc(n);
779 if(r == NULL)
780 maki_memory_error("malloc", fn);
781 return r;
782 }
783
maki_realloc(p,n,fn)784 static void *maki_realloc(p, n, fn)
785 void *p;
786 size_t n;
787 char *fn;
788 {
789 void *r = (p == NULL) ? (void *) malloc(n) : (void *) realloc(p, n);
790 if(r == NULL)
791 maki_memory_error("realloc", fn);
792 return r;
793 }
794 #endif /* HAVE_MAKI */
795