1 // This file is part of Deark.
2 // Copyright (C) 2016 Jason Summers
3 // See the file COPYING for terms of use.
5 #include <deark-config.h>
6 #include <deark-private.h>
7 #include <deark-fmtutil.h>
8 DE_DECLARE_MODULE(de_module_degas
);
9 DE_DECLARE_MODULE(de_module_prismpaint
);
10 DE_DECLARE_MODULE(de_module_ftc
);
11 DE_DECLARE_MODULE(de_module_eggpaint
);
12 DE_DECLARE_MODULE(de_module_indypaint
);
13 DE_DECLARE_MODULE(de_module_godpaint
);
14 DE_DECLARE_MODULE(de_module_tinystuff
);
15 DE_DECLARE_MODULE(de_module_doodle
);
16 DE_DECLARE_MODULE(de_module_neochrome
);
17 DE_DECLARE_MODULE(de_module_neochrome_ani
);
18 DE_DECLARE_MODULE(de_module_fpaint_pi4
);
19 DE_DECLARE_MODULE(de_module_fpaint_pi9
);
20 DE_DECLARE_MODULE(de_module_atari_pi7
);
21 DE_DECLARE_MODULE(de_module_falcon_xga
);
22 DE_DECLARE_MODULE(de_module_coke
);
23 DE_DECLARE_MODULE(de_module_animatic
);
24 DE_DECLARE_MODULE(de_module_videomaster
);
26 static void fix_dark_pal(deark
*c
, struct atari_img_decode_data
*adata
);
28 static void help_respectpal(deark
*c
)
30 de_msg(c
, "-opt atari:respectpal : Don't ignore a seemingly bad 2-color palette");
33 // **************************************************************************
34 // DEGAS / DEGAS Elite images
35 // **************************************************************************
37 typedef struct degasctx_struct
{
38 unsigned int compression_code
;
43 static void do_degas_anim_fields(deark
*c
, degasctx
*d
, i64 pos
)
49 n
= de_getu16be(pos
+ 2*i
);
50 de_dbg2(c
, "left_color_anim[%d] = %d", (int)i
, (int)n
);
53 n
= de_getu16be(pos
+ 8 + 2*i
);
54 de_dbg2(c
, "right_color_anim[%d] = %d", (int)i
, (int)n
);
57 n
= de_getu16be(pos
+ 16 + 2*i
);
58 de_dbg2(c
, "channel_direction[%d] = %d", (int)i
, (int)n
);
61 n
= de_getu16be(pos
+ 24 + 2*i
);
62 de_dbg2(c
, "channel_delay_code[%d] = %d", (int)i
, (int)n
);
65 // TODO: Can we determine if palette animation is actually used,
66 // and only show the warning if it is?
67 //de_warn(c, "This image may use palette cycling animation, which is not supported.");
70 // Try to figure out if this is a DEGAS Elite file (as opposed to original DEGAS).
71 static int is_degas_elite(deark
*c
, degasctx
*d
)
78 if(d
->compression_code
) return 1; // Only DEGAS Elite supports compression.
79 if(c
->infile
->len
< 32066) return 0;
81 // Test if the animation segment seems to have valid values, to try to distinguish
82 // it from meaningless padding. (This is overkill.)
85 // The first 8 fields are "color numbers".
86 // Guessing that they should be 0-15.
87 x
= de_getu16be(pos
+n
*2);
93 // The next 4 fields (channel direction) should be 0, 1, or 2.
94 x
= de_getu16be(pos
+n
*2);
100 // The next 4 fields (delay) must be from 0 to 128.
101 x
= de_getu16be(pos
+n
*2);
106 if(all_zero
&& c
->infile
->len
>32068) {
107 // If every field was 0, and the file size doesn't suggest Elite,
108 // just assume it's not valid.
115 static void de_run_degas(deark
*c
, de_module_params
*mparams
)
118 struct atari_img_decode_data
*adata
= NULL
;
121 unsigned int format_code
, resolution_code
;
123 i64 cmpr_bytes_consumed
= 0;
125 d
= de_malloc(c
, sizeof(degasctx
));
126 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
131 format_code
= (unsigned int)de_getu16be(pos
);
132 de_dbg(c
, "format code: 0x%04x", format_code
);
133 resolution_code
= format_code
& 0x0003;
134 d
->compression_code
= (format_code
& 0x8000)>>15;
136 de_dbg(c
, "resolution code: %u", resolution_code
);
137 de_dbg(c
, "compression code: %u", d
->compression_code
);
138 de_dbg_indent(c
, -1);
141 switch(resolution_code
) {
158 de_dbg(c
, "Invalid or unsupported resolution (%u)", resolution_code
);
161 adata
->ncolors
= de_pow2(adata
->bpp
);
163 de_dbg(c
, "dimensions: %d"DE_CHAR_TIMES
"%d, colors: %d", (int)adata
->w
, (int)adata
->h
, (int)adata
->ncolors
);
165 d
->degas_elite_flag
= is_degas_elite(c
, d
);
166 de_declare_fmtf(c
, "DEGAS%s %d-color %scompressed",
167 d
->degas_elite_flag
?" Elite":"",
169 d
->compression_code
?"":"un");
171 fmtutil_read_atari_palette(c
, c
->infile
, pos
, adata
->pal
, 16, adata
->ncolors
, 0);
173 fix_dark_pal(c
, adata
);
175 if(d
->compression_code
) {
176 adata
->was_compressed
= 1;
177 adata
->unc_pixels
= dbuf_create_membuf(c
, 32000, 1);
178 dbuf_enable_wbuffer(adata
->unc_pixels
);
180 if(!fmtutil_decompress_packbits(c
->infile
, pos
, c
->infile
->len
-pos
, adata
->unc_pixels
, &cmpr_bytes_consumed
))
182 dbuf_flush(adata
->unc_pixels
);
184 de_dbg(c
, "Compressed bytes found: %d", (int)cmpr_bytes_consumed
);
185 pos
+= cmpr_bytes_consumed
;
188 i64 avail_bytes
= 32000;
189 if(pos
+32000 > c
->infile
->len
) {
190 avail_bytes
= c
->infile
->len
- pos
;
191 de_warn(c
, "Unexpected end of file (expected 32000 bytes, got %d)", (int)avail_bytes
);
193 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, pos
, avail_bytes
);
197 if(pos
+ 32 == c
->infile
->len
) {
198 do_degas_anim_fields(c
, d
, pos
);
201 is_grayscale
= de_is_grayscale_palette(adata
->pal
, adata
->ncolors
);
203 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, is_grayscale
?1:3);
205 fi
= de_finfo_create(c
);
206 fmtutil_atari_set_standard_density(c
, adata
, fi
);
208 fmtutil_atari_decode_image(c
, adata
);
210 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
214 dbuf_close(adata
->unc_pixels
);
215 de_bitmap_destroy(adata
->img
);
218 de_finfo_destroy(c
, fi
);
222 static int de_identify_degas(deark
*c
)
224 static const char *exts
[6] = {"pi1", "pi2", "pi3", "pc1", "pc2", "pc3" };
231 if(de_input_file_has_ext(c
, exts
[i
])) {
238 sig
= de_getu16be(0);
239 if(sig
==0x0000 || sig
==0x0001 || sig
==0x0002) {
240 if(c
->infile
->len
==32034) return 100; // DEGAS
241 if(c
->infile
->len
==32066) return 100; // DEGAS Elite
242 if(c
->infile
->len
==32128) return 40; // Could be padded to a multiple of 128 bytes
243 if(c
->infile
->len
>16000) return 10;
245 else if(sig
==0x8000 || sig
==0x8001 || sig
==0x8002) {
252 static void de_help_degas(deark
*c
)
254 fmtutil_atari_help_palbits(c
);
258 void de_module_degas(deark
*c
, struct deark_module_info
*mi
)
261 mi
->desc
= "Atari DEGAS or DEGAS Elite image";
262 mi
->run_fn
= de_run_degas
;
263 mi
->identify_fn
= de_identify_degas
;
264 mi
->help_fn
= de_help_degas
;
267 // **************************************************************************
268 // Atari Prism Paint (.pnt)
269 // **************************************************************************
271 typedef struct prismctx_struct
{
278 // A color value of N does not necessarily refer to Nth color in the palette.
279 // Some of them are mixed up. Apparently this is called "VDI order".
280 // Reference: http://toshyp.atari.org/en/VDI_fundamentals.html
281 static unsigned int map_vdi_pal(i64 bpp
, unsigned int v
)
287 case 3: return bpp
>2 ? 6 : 1;
297 case 15: return bpp
==8 ? 255 : 1;
303 static void do_prism_read_palette(deark
*c
, prismctx
*d
, struct atari_img_decode_data
*adata
)
310 i64 num_entries_to_read
;
313 de_zeromem(pal1
, sizeof(pal1
));
314 num_entries_to_read
= de_min_int(d
->pal_size
, 256);
316 for(i
=0; i
<num_entries_to_read
; i
++) {
317 r1
= de_getu16be(128+6*i
+0);
318 g1
= de_getu16be(128+6*i
+2);
319 b1
= de_getu16be(128+6*i
+4);
320 r
= de_scale_1000_to_255(r1
);
321 g
= de_scale_1000_to_255(g1
);
322 b
= de_scale_1000_to_255(b1
);
323 clr
= DE_MAKE_RGB(r
,g
,b
);
324 de_snprintf(tmps
, sizeof(tmps
), "(%4d,%4d,%4d) "DE_CHAR_RIGHTARROW
" ",
325 (int)r1
, (int)g1
, (int)b1
);
326 de_dbg_pal_entry2(c
, i
, clr
, tmps
, NULL
, NULL
);
330 for(i
=0; i
<num_entries_to_read
; i
++) {
331 d
->pal
[i
] = pal1
[map_vdi_pal(adata
->bpp
, (unsigned int)i
)];
335 static void de_run_prismpaint(deark
*c
, de_module_params
*mparams
)
339 struct atari_img_decode_data
*adata
= NULL
;
341 d
= de_malloc(c
, sizeof(prismctx
));
343 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
346 d
->pal_size
= de_getu16be(6);
347 de_dbg(c
, "pal_size: %d", (int)d
->pal_size
);
348 adata
->w
= de_getu16be(8);
349 adata
->h
= de_getu16be(10);
350 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
351 if(!de_good_image_dimensions(c
, adata
->w
, adata
->h
)) goto done
;
353 adata
->bpp
= de_getu16be(12);
354 de_dbg(c
, "bits/pixel: %d", (int)adata
->bpp
);
355 d
->compression_code
= (UI
)de_getu16be(14);
356 de_dbg(c
, "compression: %u", d
->compression_code
);
358 d
->pic_data_size
= de_getu32be(16);
359 de_dbg(c
, "reported (uncompressed) picture data size: %"I64_FMT
, d
->pic_data_size
);
361 do_prism_read_palette(c
, d
, adata
);
363 if(adata
->bpp
!=1 && adata
->bpp
!=2 && adata
->bpp
!=4
364 && adata
->bpp
!=8 && adata
->bpp
!=16)
366 de_err(c
, "Unsupported bits/pixel: %d", (int)adata
->bpp
);
369 if(d
->compression_code
!=0 && d
->compression_code
!=1) {
370 de_err(c
, "Unsupported compression: %u", d
->compression_code
);
373 if(adata
->bpp
==16 && d
->compression_code
!=0) {
374 de_warn(c
, "Compressed 16-bit image support is untested, and may not work.");
377 pixels_start
= 128 + 2*3*d
->pal_size
;
378 de_dbg(c
, "pixel data starts at %"I64_FMT
, pixels_start
);
379 if(pixels_start
>= c
->infile
->len
) goto done
;
381 if(d
->compression_code
==0) {
382 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, pixels_start
,
383 c
->infile
->len
- pixels_start
);
386 adata
->was_compressed
= 1;
387 // TODO: Calculate the initial size more accurately.
388 adata
->unc_pixels
= dbuf_create_membuf(c
, adata
->w
*adata
->h
, 0);
389 //dbuf_set_max_length(unc_pixels, ...);
390 dbuf_enable_wbuffer(adata
->unc_pixels
);
392 fmtutil_decompress_packbits(c
->infile
, pixels_start
, c
->infile
->len
- pixels_start
,
393 adata
->unc_pixels
, NULL
);
394 dbuf_flush(adata
->unc_pixels
);
395 de_dbg(c
, "decompressed to %"I64_FMT
" bytes", adata
->unc_pixels
->len
);
398 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
399 fmtutil_atari_decode_image(c
, adata
);
400 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
404 dbuf_close(adata
->unc_pixels
);
405 de_bitmap_destroy(adata
->img
);
411 static int de_identify_prismpaint(deark
*c
)
413 if(!dbuf_memcmp(c
->infile
, 0, "PNT\x00", 4))
418 void de_module_prismpaint(deark
*c
, struct deark_module_info
*mi
)
420 mi
->id
= "prismpaint";
421 mi
->desc
= "Atari Prism Paint .PNT, a.k.a. TruePaint .TPI";
422 mi
->run_fn
= de_run_prismpaint
;
423 mi
->identify_fn
= de_identify_prismpaint
;
426 // **************************************************************************
427 // Atari Falcon True Color .FTC
428 // **************************************************************************
430 static void de_run_ftc(deark
*c
, de_module_params
*mparams
)
432 struct atari_img_decode_data
*adata
= NULL
;
435 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
439 adata
->unc_pixels
= c
->infile
;
440 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
441 fi
= de_finfo_create(c
);
442 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
443 fi
->density
.xdens
= 288;
444 fi
->density
.ydens
= 240;
445 fmtutil_atari_decode_image(c
, adata
);
446 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
447 de_bitmap_destroy(adata
->img
);
448 de_finfo_destroy(c
, fi
);
452 static int de_identify_ftc(deark
*c
)
454 if(c
->infile
->len
!= 184320) return 0;
455 if(!de_input_file_has_ext(c
, "ftc")) return 0;
459 void de_module_ftc(deark
*c
, struct deark_module_info
*mi
)
462 mi
->desc
= "Atari Falcon True Color .FTC";
463 mi
->run_fn
= de_run_ftc
;
464 mi
->identify_fn
= de_identify_ftc
;
467 // **************************************************************************
468 // Atari Falcon EggPaint .TRP
469 // **************************************************************************
471 static void de_run_eggpaint(deark
*c
, de_module_params
*mparams
)
473 struct atari_img_decode_data
*adata
= NULL
;
475 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
477 if(!dbuf_memcmp(c
->infile
, 0, "tru?", 4)) {
478 de_declare_fmt(c
, "Spooky Sprites");
481 de_declare_fmt(c
, "EggPaint");
485 adata
->w
= de_getu16be(4);
486 adata
->h
= de_getu16be(6);
487 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
488 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 8, c
->infile
->len
-8);
489 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
490 fmtutil_atari_decode_image(c
, adata
);
491 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
493 dbuf_close(adata
->unc_pixels
);
494 de_bitmap_destroy(adata
->img
);
498 static int de_identify_eggpaint(deark
*c
)
500 if(!dbuf_memcmp(c
->infile
, 0, "TRUP", 4)) {
503 if(!dbuf_memcmp(c
->infile
, 0, "tru?", 4)) {
509 void de_module_eggpaint(deark
*c
, struct deark_module_info
*mi
)
512 mi
->desc
= "Atari EggPaint .TRP";
513 mi
->run_fn
= de_run_eggpaint
;
514 mi
->identify_fn
= de_identify_eggpaint
;
517 // **************************************************************************
518 // Atari Falcon IndyPaint .TRU
519 // **************************************************************************
521 static void de_run_indypaint(deark
*c
, de_module_params
*mparams
)
523 struct atari_img_decode_data
*adata
= NULL
;
525 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
527 adata
->w
= de_getu16be(4);
528 adata
->h
= de_getu16be(6);
529 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
530 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 256, c
->infile
->len
-256);
531 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
532 fmtutil_atari_decode_image(c
, adata
);
533 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
535 dbuf_close(adata
->unc_pixels
);
536 de_bitmap_destroy(adata
->img
);
540 static int de_identify_indypaint(deark
*c
)
542 if(!dbuf_memcmp(c
->infile
, 0, "Indy", 4)) {
548 void de_module_indypaint(deark
*c
, struct deark_module_info
*mi
)
550 mi
->id
= "indypaint";
551 mi
->desc
= "Atari IndyPaint .TRU";
552 mi
->run_fn
= de_run_indypaint
;
553 mi
->identify_fn
= de_identify_indypaint
;
556 // **************************************************************************
557 // Atari Falcon GodPaint .GOD
558 // **************************************************************************
560 static void de_run_godpaint(deark
*c
, de_module_params
*mparams
)
562 struct atari_img_decode_data
*adata
= NULL
;
564 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
566 adata
->w
= de_getu16be(2);
567 adata
->h
= de_getu16be(4);
568 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
569 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 6, c
->infile
->len
-6);
570 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
571 fmtutil_atari_decode_image(c
, adata
);
572 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
574 dbuf_close(adata
->unc_pixels
);
575 de_bitmap_destroy(adata
->img
);
579 static int de_identify_godpaint(deark
*c
)
583 sig
= de_getu16be(0);
584 if(sig
!=0x4734 && sig
!=0x0400) return 0;
585 if(de_input_file_has_ext(c
, "god")) return 100;
586 if(sig
==0x4734) return 5;
590 void de_module_godpaint(deark
*c
, struct deark_module_info
*mi
)
593 mi
->desc
= "Atari Falcon GodPaint";
594 mi
->run_fn
= de_run_godpaint
;
595 mi
->identify_fn
= de_identify_godpaint
;
598 // **************************************************************************
600 // **************************************************************************
602 typedef struct tinyctx_struct
{
604 i64 num_control_bytes
;
606 i64 data_words_nbytes
;
609 // Decompression params:
614 // Decompression state:
620 i64 dcmpr_word_count
;
623 static void tiny_setword(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
, const u8
*wordbuf
)
627 // As each word is emitted from the decompressor, we store it in the unc_pixels buffer
628 // in a particular location. The location is chosen so as to make the pixel data more
629 // contiguous, but (for 2bpp and 4bpp images) more work will still have to be done when
630 // the image is generated.
632 if(d
->stopflag
) return;
633 d
->dcmpr_word_count
++;
634 dstpos
= d
->stripe
* 8 + d
->column
*2 + (d
->ypos
* d
->numscans
+ d
->scan
)*d
->dst_rowspan
;
635 dbuf_write_at(adata
->unc_pixels
, dstpos
, wordbuf
, 2);
640 if(d
->stripe
>= d
->numstripes
) {
643 if(d
->scan
>= d
->numscans
) {
655 // Uncompress to adata->unc_pixels.
656 static int tiny_uncompress(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
, i64 pos
)
658 u8
*control_bytes
= NULL
;
673 d
->dst_rowspan
= 160;
676 de_dbg(c
, "RLE control bytes at %"I64_FMT
, pos
);
677 control_bytes
= de_malloc(c
, d
->num_control_bytes
+2);
678 de_read(control_bytes
, pos
, d
->num_control_bytes
);
679 pos
+= d
->num_control_bytes
;
681 de_dbg(c
, "RLE data words at %"I64_FMT
, pos
);
690 d
->dcmpr_word_count
= 0;
693 if(d
->stopflag
) break;
694 if(cpos
>= d
->num_control_bytes
) break;
695 ctrl
= control_bytes
[cpos
++];
697 if(ctrl
>= 128) { // Uncompressed run, count encoded in control byte
698 count
= 256 - (i64
)ctrl
;
699 for(k
=0; k
<count
; k
++) {
700 dbuf_read(c
->infile
, wordbuf
, pos
, 2);
702 tiny_setword(c
, d
, adata
, wordbuf
);
705 else if(ctrl
== 0) { // RLE, 16-bit count in next 2 control bytes
706 count
= de_getu16be_direct(&control_bytes
[cpos
]);
708 dbuf_read(c
->infile
, wordbuf
, pos
, 2);
710 for(k
=0; k
<count
; k
++) {
711 tiny_setword(c
, d
, adata
, wordbuf
);
714 else if(ctrl
== 1) { // Uncompressed run, 16-bit count in next 2 control bytes
715 count
= de_getu16be_direct(&control_bytes
[cpos
]);
718 for(k
=0; k
<count
; k
++) {
719 dbuf_read(c
->infile
, wordbuf
, pos
, 2);
721 tiny_setword(c
, d
, adata
, wordbuf
);
724 else { // RLE, count encoded in control byte
726 dbuf_read(c
->infile
, wordbuf
, pos
, 2);
728 for(k
=0; k
<count
; k
++) {
729 tiny_setword(c
, d
, adata
, wordbuf
);
734 de_dbg(c
, "decompressed words: %"I64_FMT
, d
->dcmpr_word_count
);
735 if(d
->dcmpr_word_count
<16000) {
736 de_warn(c
, "Expected 16000 decompressed words, got %"I64_FMT
, d
->dcmpr_word_count
);
739 de_free(c
, control_bytes
);
743 static void do_tinystuff_1bpp(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
)
745 de_convert_image_paletted(adata
->unc_pixels
, 0, 1, d
->dst_rowspan
, adata
->pal
,
749 static void do_tinystuff_2or4bpp(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
)
756 bpp
= (UI
)adata
->bpp
;
757 if(bpp
!=2 && bpp
!=4) return;
759 if(bpp
==2) width
= 640;
762 for(y
=0; y
<200; y
++) {
763 for(x
=0; x
<width
; x
+=16) {
768 // 2bpp: Every 2 words (4 bytes; 32 bits) makes 16 pixels
769 // 4bpp: Every 4 words (8 bytes; 64 bits) makes 16 pixels
770 for(b_idx
=0; b_idx
<bpp
; b_idx
++) {
771 n
[b_idx
] = (UI
)dbuf_getu16be_p(adata
->unc_pixels
, &pos
);
774 for(k
=0; k
<16; k
++) {
777 for(b_idx
=0; b_idx
<bpp
; b_idx
++) {
778 if(n
[b_idx
]&(1U<<(15-k
))) v
+= (1U<<b_idx
);
780 de_bitmap_setpixel_rgb(adata
->img
, x
+(i64
)k
, y
, adata
->pal
[v
]);
786 static void do_tinystuff_image(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
)
790 do_tinystuff_1bpp(c
, d
, adata
);
794 do_tinystuff_2or4bpp(c
, d
, adata
);
799 // Some 1bpp images apparently have the palette set to [001, 000],
800 // or other nonsense, instead of [777, 000].
801 // Try to handle that.
802 static void fix_dark_pal(deark
*c
, struct atari_img_decode_data
*adata
)
806 if(adata
->bpp
!=1) return;
808 ap
[0] = adata
->pal
[0]&0xffffff;
809 ap
[1] = adata
->pal
[1]&0xffffff;
811 // Always respect white/black and black/white palettes.
812 if(ap
[0]==0xffffff && ap
[1]==0x000000) return; // The usual palette
813 if(ap
[0]==0x000000 && ap
[1]==0xffffff) return;
815 // Otherwise assume white/black, unless the user told us not to.
816 if(de_get_ext_option(c
, "atari:respectpal")) return;
818 adata
->pal
[0] = DE_STOCKCOLOR_WHITE
;
819 adata
->pal
[1] = DE_STOCKCOLOR_BLACK
;
822 static void de_run_tinystuff(deark
*c
, de_module_params
*mparams
)
824 struct atari_img_decode_data
*adata
= NULL
;
828 i64 expected_min_file_size
;
829 i64 expected_max_file_size
;
832 d
= de_malloc(c
, sizeof(tinyctx
));
834 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
836 adata
->was_compressed
= 1;
838 d
->res_code
= de_getbyte(pos
);
840 de_dbg(c
, "resolution code: %u", (UI
)d
->res_code
);
842 switch(d
->res_code
) {
859 de_err(c
, "Invalid resolution code (%u). This is not a Tiny Stuff file.",
864 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
865 adata
->ncolors
= de_pow2(adata
->bpp
);
866 de_dbg(c
, "colors: %d", (int)adata
->ncolors
);
869 de_warn(c
, "This image uses palette cycling animation, which is not supported.");
870 pos
+= 4; // skip animation_info
873 fmtutil_read_atari_palette(c
, c
->infile
, pos
, adata
->pal
, 16, adata
->ncolors
, 0);
874 fix_dark_pal(c
, adata
);
877 d
->num_control_bytes
= de_getu16be(pos
);
879 de_dbg(c
, "number of RLE control bytes: %d", (int)d
->num_control_bytes
);
881 d
->num_data_words
= de_getu16be(pos
);
883 d
->data_words_nbytes
= 2*d
->num_data_words
;
884 de_dbg(c
, "number of RLE data words: %d (%d bytes)", (int)d
->num_data_words
,
885 (int)d
->data_words_nbytes
);
887 // It seems that files are often padded to the next multiple of 128 bytes,
888 // so don't warn about that.
889 expected_min_file_size
= pos
+ d
->num_control_bytes
+ d
->data_words_nbytes
;
890 expected_max_file_size
= de_pad_to_n(expected_min_file_size
, 128);
891 de_dbg(c
, "expected file size: %"I64_FMT
" or %"I64_FMT
, expected_min_file_size
,
892 expected_max_file_size
);
893 if(c
->infile
->len
<expected_min_file_size
|| c
->infile
->len
>expected_max_file_size
) {
894 de_warn(c
, "Expected file size to be %"I64_FMT
", but it is %"I64_FMT
".",
895 expected_min_file_size
, c
->infile
->len
);
898 adata
->unc_pixels
= dbuf_create_membuf(c
, 32000, 1);
900 if(!tiny_uncompress(c
, d
, adata
, pos
)) {
904 is_grayscale
= de_is_grayscale_palette(adata
->pal
, adata
->ncolors
);
906 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, is_grayscale
?1:3);
908 fi
= de_finfo_create(c
);
909 fmtutil_atari_set_standard_density(c
, adata
, fi
);
911 do_tinystuff_image(c
, d
, adata
);
912 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
916 de_bitmap_destroy(adata
->img
);
917 dbuf_close(adata
->unc_pixels
);
920 de_finfo_destroy(c
, fi
);
924 static int de_identify_tinystuff(deark
*c
)
926 // TODO: Can we identify these files?
927 if(de_getbyte(0)>0x05) return 0;
928 if(de_input_file_has_ext(c
, "tny") ||
929 de_input_file_has_ext(c
, "tn1") ||
930 de_input_file_has_ext(c
, "tn2") ||
931 de_input_file_has_ext(c
, "tn3") ||
932 de_input_file_has_ext(c
, "tn4"))
939 static void de_help_tinystuff(deark
*c
)
941 fmtutil_atari_help_palbits(c
);
945 void de_module_tinystuff(deark
*c
, struct deark_module_info
*mi
)
947 mi
->id
= "tinystuff";
948 mi
->desc
= "Atari Tiny Stuff, a.k.a. Tiny image format";
949 mi
->run_fn
= de_run_tinystuff
;
950 mi
->identify_fn
= de_identify_tinystuff
;
951 mi
->help_fn
= de_help_tinystuff
;
954 // **************************************************************************
956 // **************************************************************************
958 static void de_run_doodle(deark
*c
, de_module_params
*mparams
)
960 struct atari_img_decode_data
*adata
= NULL
;
964 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
971 adata
->pal
[0] = DE_STOCKCOLOR_WHITE
;
972 adata
->pal
[1] = DE_STOCKCOLOR_BLACK
;
974 adata
->unc_pixels
= c
->infile
;
975 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 1);
976 fi
= de_finfo_create(c
);
977 fmtutil_atari_set_standard_density(c
, adata
, fi
);
978 fmtutil_atari_decode_image(c
, adata
);
979 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
982 de_bitmap_destroy(adata
->img
);
985 de_finfo_destroy(c
, fi
);
988 static int de_identify_doodle(deark
*c
)
990 if(c
->infile
->len
!=32000) return 0;
991 if(de_input_file_has_ext(c
, "doo")) {
997 void de_module_doodle(deark
*c
, struct deark_module_info
*mi
)
1000 mi
->desc
= "Atari Doodle";
1001 mi
->run_fn
= de_run_doodle
;
1002 mi
->identify_fn
= de_identify_doodle
;
1005 // **************************************************************************
1007 // **************************************************************************
1009 static void de_run_neochrome(deark
*c
, de_module_params
*mparams
)
1011 struct atari_img_decode_data
*adata
= NULL
;
1012 de_finfo
*fi
= NULL
;
1013 unsigned int resolution_code
;
1017 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1020 resolution_code
= (unsigned int)de_getu16be(2);
1021 de_dbg(c
, "resolution code: %u", resolution_code
);
1022 if(resolution_code
!=0) {
1023 de_err(c
, "Invalid or unsupported NEOchrome image (resolution=%d)", (int)resolution_code
);
1027 // TODO: Warn about palette animation settings.
1028 // TODO: (Maybe) Use the embedded filename, if it seems valid.
1033 adata
->ncolors
= de_pow2(adata
->bpp
);
1034 de_dbg(c
, "dimensions: %d"DE_CHAR_TIMES
"%d, colors: %d", (int)adata
->w
, (int)adata
->h
, (int)adata
->ncolors
);
1036 fmtutil_read_atari_palette(c
, c
->infile
, 4, adata
->pal
, 16, adata
->ncolors
, 0);
1037 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 128, 32000);
1038 is_grayscale
= de_is_grayscale_palette(adata
->pal
, adata
->ncolors
);
1039 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, is_grayscale
?1:3);
1040 fi
= de_finfo_create(c
);
1041 fmtutil_atari_set_standard_density(c
, adata
, fi
);
1042 fmtutil_atari_decode_image(c
, adata
);
1043 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
1047 dbuf_close(adata
->unc_pixels
);
1048 de_bitmap_destroy(adata
->img
);
1051 de_finfo_destroy(c
, fi
);
1054 static int de_identify_neochrome(deark
*c
)
1056 if(de_input_file_has_ext(c
, "neo")) {
1057 if(c
->infile
->len
== 32128) {
1060 else if(c
->infile
->len
> 32128) {
1067 static void de_help_neochrome(deark
*c
)
1069 fmtutil_atari_help_palbits(c
);
1072 void de_module_neochrome(deark
*c
, struct deark_module_info
*mi
)
1074 mi
->id
= "neochrome";
1075 mi
->desc
= "Atari NEOchrome image";
1076 mi
->run_fn
= de_run_neochrome
;
1077 mi
->identify_fn
= de_identify_neochrome
;
1078 mi
->help_fn
= de_help_neochrome
;
1081 // **************************************************************************
1082 // NEOchrome animation (.ani)
1083 // **************************************************************************
1085 static void de_run_neochrome_ani(deark
*c
, de_module_params
*mparams
)
1087 struct atari_img_decode_data
*adata
= NULL
;
1090 i64 bytes_per_frame
;
1095 de_declare_fmt(c
, "NEOchrome Animation");
1097 de_warn(c
, "NEOchrome Animation images may not be decoded correctly.");
1099 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1101 // TODO: What palette should we use?
1102 for(k
=0; k
<16; k
++) {
1103 pal
[k
] = DE_MAKE_GRAY((unsigned int)(k
*17));
1107 adata
->ncolors
= 16;
1109 width_in_bytes
= de_getu16be(4); // Always a multiple of 8
1110 adata
->w
= ((width_in_bytes
+7)/8)*16;
1111 adata
->h
= de_getu16be(6);
1112 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1113 if(!de_good_image_dimensions(c
, adata
->w
, adata
->h
)) goto done
;
1115 bytes_per_frame
= de_getu16be(8);
1116 bytes_per_frame
-= 10;
1117 de_dbg(c
, "bytes/frame: %d", (int)bytes_per_frame
);
1118 if(bytes_per_frame
<1) goto done
;
1120 nframes
= de_getu16be(14);
1121 de_dbg(c
, "number of frames: %d", (int)nframes
);
1122 if(!de_good_image_count(c
, nframes
)) goto done
;
1124 for(frame
=0; frame
<nframes
; frame
++) {
1125 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 22 + frame
*bytes_per_frame
, bytes_per_frame
);
1126 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1128 fmtutil_atari_decode_image(c
, adata
);
1129 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
1131 de_bitmap_destroy(adata
->img
);
1134 dbuf_close(adata
->unc_pixels
);
1135 adata
->unc_pixels
= NULL
;
1142 static int de_identify_neochrome_ani(deark
*c
)
1144 if(!dbuf_memcmp(c
->infile
, 0, "\xba\xbe\xeb\xea", 4)) {
1150 void de_module_neochrome_ani(deark
*c
, struct deark_module_info
*mi
)
1152 mi
->id
= "neochrome_ani";
1153 mi
->desc
= "NEOchrome Animation";
1154 mi
->run_fn
= de_run_neochrome_ani
;
1155 mi
->identify_fn
= de_identify_neochrome_ani
;
1156 mi
->flags
|= DE_MODFLAG_NONWORKING
;
1159 // **************************************************************************
1160 // Animatic Film (.flm)
1161 // **************************************************************************
1163 static void de_run_animatic(deark
*c
, de_module_params
*mparams
)
1165 struct atari_img_decode_data
*adata
= NULL
;
1168 i64 planespan
, rowspan
, framespan
;
1169 i64 frame_bitmap_pos
;
1172 de_declare_fmt(c
, "Animatic Film");
1174 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1176 nframes
= de_getu16be(0);
1177 de_dbg(c
, "number of frames: %d", (int)nframes
);
1178 if(!de_good_image_count(c
, nframes
)) goto done
;
1181 adata
->ncolors
= 16;
1183 de_dbg_indent(c
, 1);
1184 fmtutil_read_atari_palette(c
, c
->infile
, 2, adata
->pal
, 16, adata
->ncolors
, 0);
1185 de_dbg_indent(c
, -1);
1187 adata
->w
= de_getu16be(40);
1188 adata
->h
= de_getu16be(42);
1189 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1190 if(!de_good_image_dimensions(c
, adata
->w
, adata
->h
)) goto done
;
1192 planespan
= 2*((adata
->w
+15)/16);
1193 rowspan
= planespan
*adata
->bpp
;
1194 framespan
= rowspan
*adata
->h
;
1196 for(frame
=0; frame
<nframes
; frame
++) {
1197 frame_bitmap_pos
= 64 + frame
*framespan
;
1198 de_dbg(c
, "frame %d bitmap at %d", (int)frame
, (int)frame_bitmap_pos
);
1200 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, frame_bitmap_pos
, framespan
);
1201 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1203 fmtutil_atari_decode_image(c
, adata
);
1204 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
1206 de_bitmap_destroy(adata
->img
);
1209 dbuf_close(adata
->unc_pixels
);
1210 adata
->unc_pixels
= NULL
;
1217 static int de_identify_animatic(deark
*c
)
1219 if(!dbuf_memcmp(c
->infile
, 48, "\x27\x18\x28\x18", 4)) {
1225 static void de_help_animatic(deark
*c
)
1227 fmtutil_atari_help_palbits(c
);
1230 void de_module_animatic(deark
*c
, struct deark_module_info
*mi
)
1232 mi
->id
= "animatic";
1233 mi
->desc
= "Animatic Film";
1234 mi
->run_fn
= de_run_animatic
;
1235 mi
->identify_fn
= de_identify_animatic
;
1236 mi
->help_fn
= de_help_animatic
;
1239 // **************************************************************************
1241 // **************************************************************************
1243 static void decode_falcon_8bit_image(deark
*c
, struct atari_img_decode_data
*adata
, i64 pos
)
1248 de_finfo
*fi
= NULL
;
1250 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1252 fi
= de_finfo_create(c
);
1253 if(adata
->w
==320 && adata
->h
==200) {
1254 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
1255 fi
->density
.xdens
= 240.0;
1256 fi
->density
.ydens
= 200.0;
1259 for(j
=0; j
<adata
->h
; j
++) {
1260 for(i
=0; i
<adata
->w
; i
++) {
1262 for(k
=0; k
<8; k
++) {
1263 n
= (u32
)de_getu16be(pos
+j
*adata
->w
+ (i
-i
%16) +2*k
);
1264 if(n
&(1<<(15-i
%16))) v
|= 1<<k
;
1266 de_bitmap_setpixel_rgb(adata
->img
, i
, j
, adata
->pal
[v
]);
1270 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
1271 de_bitmap_destroy(adata
->img
);
1273 de_finfo_destroy(c
, fi
);
1276 static void do_atari_falcon_8bit_img(deark
*c
, i64 width
, i64 height
)
1278 struct atari_img_decode_data
*adata
= NULL
;
1283 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1284 de_zeromem(pal
, sizeof(pal
));
1287 adata
->ncolors
= 256;
1290 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1292 for(k
=0; k
<256; k
++) {
1293 cr
= de_getbyte(k
*4+0);
1294 cg
= de_getbyte(k
*4+1);
1295 cb
= de_getbyte(k
*4+3);
1296 pal
[k
] = DE_MAKE_RGB(cr
, cg
, cb
);
1297 de_dbg_pal_entry(c
, k
, pal
[k
]);
1300 decode_falcon_8bit_image(c
, adata
, 1024);
1305 static void de_run_fpaint_pi4(deark
*c
, de_module_params
*mparams
)
1307 do_atari_falcon_8bit_img(c
, 320, 240);
1310 // Atari falcon 320x240
1311 static int de_identify_fpaint_pi4(deark
*c
)
1313 if(c
->infile
->len
==77824) {
1314 if(de_input_file_has_ext(c
, "pi4") ||
1315 de_input_file_has_ext(c
, "pi9"))
1317 return 50; // Must be lower than fpaint_pi9
1323 void de_module_fpaint_pi4(deark
*c
, struct deark_module_info
*mi
)
1325 mi
->id
= "fpaint_pi4";
1326 mi
->desc
= "Atari Falcon PI4 image";
1327 mi
->run_fn
= de_run_fpaint_pi4
;
1328 mi
->identify_fn
= de_identify_fpaint_pi4
;
1331 static void de_run_fpaint_pi9(deark
*c
, de_module_params
*mparams
)
1333 do_atari_falcon_8bit_img(c
, 320, 200);
1336 // Atari falcon 320x200
1337 static int de_identify_fpaint_pi9(deark
*c
)
1339 int pi4_ext
, pi9_ext
;
1341 if(c
->infile
->len
!=77824 && c
->infile
->len
!=65024) return 0;
1343 pi4_ext
= de_input_file_has_ext(c
, "pi4");
1344 pi9_ext
= de_input_file_has_ext(c
, "pi9");
1345 if(!pi4_ext
&& !pi9_ext
) return 0;
1347 if(c
->infile
->len
==65024) return 60;
1349 // If file size is 77824, we need to distinguish between PI4 (320x240) and
1350 // PI9 (320x200) format.
1351 // Best guess is that if the last 12800 bytes are all 0, we should assume PI9.
1352 if(!dbuf_is_all_zeroes(c
->infile
, 65024, 12800)) {
1353 return 0; // Will be identified elsewhere as PI4.
1356 return 60; // PI9. Must be higher than the value PI4 uses.
1359 void de_module_fpaint_pi9(deark
*c
, struct deark_module_info
*mi
)
1361 mi
->id
= "fpaint_pi9";
1362 mi
->desc
= "Atari Falcon PI9 image";
1363 mi
->run_fn
= de_run_fpaint_pi9
;
1364 mi
->identify_fn
= de_identify_fpaint_pi9
;
1367 // **************************************************************************
1369 // **************************************************************************
1371 static void de_run_atari_pi7(deark
*c
, de_module_params
*mparams
)
1373 do_atari_falcon_8bit_img(c
, 640, 480);
1376 static int de_identify_atari_pi7(deark
*c
)
1378 if(c
->infile
->len
==308224) {
1379 if(de_input_file_has_ext(c
, "pi7"))
1387 void de_module_atari_pi7(deark
*c
, struct deark_module_info
*mi
)
1389 mi
->id
= "atari_pi7";
1390 mi
->desc
= "Atari PI7 image";
1391 mi
->run_fn
= de_run_atari_pi7
;
1392 mi
->identify_fn
= de_identify_atari_pi7
;
1395 // **************************************************************************
1397 // **************************************************************************
1399 static void de_run_falcon_xga(deark
*c
, de_module_params
*mparams
)
1401 struct atari_img_decode_data
*adata
= NULL
;
1402 de_finfo
*fi
= NULL
;
1404 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1405 if(c
->infile
->len
==153600) {
1415 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1416 adata
->unc_pixels
= c
->infile
;
1417 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1418 fi
= de_finfo_create(c
);
1419 if(adata
->w
==384 && adata
->h
== 480) {
1420 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
1421 fi
->density
.xdens
= 384;
1422 fi
->density
.ydens
= 640;
1424 fmtutil_atari_decode_image(c
, adata
);
1425 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
1426 de_bitmap_destroy(adata
->img
);
1427 de_finfo_destroy(c
, fi
);
1431 static int de_identify_falcon_xga(deark
*c
)
1433 if(c
->infile
->len
==153600 || c
->infile
->len
==368640) {
1434 if(de_input_file_has_ext(c
, "xga"))
1442 void de_module_falcon_xga(deark
*c
, struct deark_module_info
*mi
)
1444 mi
->id
= "falcon_xga";
1445 mi
->desc
= "Atari Falcon XGA image";
1446 mi
->run_fn
= de_run_falcon_xga
;
1447 mi
->identify_fn
= de_identify_falcon_xga
;
1450 // **************************************************************************
1451 // Atari Falcon COKE (.tg1)
1452 // **************************************************************************
1454 static void de_run_coke(deark
*c
, de_module_params
*mparams
)
1457 struct atari_img_decode_data
*adata
= NULL
;
1458 de_finfo
*fi
= NULL
;
1460 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1462 adata
->w
= de_getu16be(12);
1463 adata
->h
= de_getu16be(14);
1464 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1465 imgdatapos
= de_getu16be(16);
1466 de_dbg(c
, "image data pos: %d", (int)imgdatapos
);
1468 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
,
1469 imgdatapos
, c
->infile
->len
-imgdatapos
);
1470 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1472 fi
= de_finfo_create(c
);
1473 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
1474 fi
->density
.xdens
= 288;
1475 fi
->density
.ydens
= 240;
1477 fmtutil_atari_decode_image(c
, adata
);
1478 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
1481 dbuf_close(adata
->unc_pixels
);
1482 de_bitmap_destroy(adata
->img
);
1485 de_finfo_destroy(c
, fi
);
1488 static int de_identify_coke(deark
*c
)
1490 if(!dbuf_memcmp(c
->infile
, 0, (const void*)"COKE format.", 12)) {
1496 void de_module_coke(deark
*c
, struct deark_module_info
*mi
)
1499 mi
->desc
= "Atari Falcon COKE image (.TG1)";
1500 mi
->run_fn
= de_run_coke
;
1501 mi
->identify_fn
= de_identify_coke
;
1504 // **************************************************************************
1505 // Video Master .FLM, etc. (Amiga & Atari ST)
1506 // **************************************************************************
1508 #define VMAS_FRAME_PAL_SIZE 32
1509 #define VMAS_FRAME_BITMAP_SIZE 8000
1510 #define VMAS_FRAME_TOTAL_SIZE (VMAS_FRAME_PAL_SIZE+VMAS_FRAME_BITMAP_SIZE)
1512 static void de_run_videomaster(deark
*c
, de_module_params
*mparams
)
1514 struct atari_img_decode_data
*adata
= NULL
;
1515 de_finfo
*fi
= NULL
;
1518 i64 frames_startpos
;
1522 nframes
= de_getu16be(6);
1523 de_dbg(c
, "num frames: %u", (UI
)nframes
);
1524 frames_startpos
= 32;
1525 if(frames_startpos
+ nframes
*VMAS_FRAME_TOTAL_SIZE
> c
->infile
->len
) {
1526 de_err(c
, "Invalid or truncated file");
1530 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1535 adata
->ncolors
= 16;
1536 adata
->unc_pixels
= dbuf_create_membuf(c
, VMAS_FRAME_BITMAP_SIZE
, 0x1);
1537 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1538 fi
= de_finfo_create(c
);
1539 // This might not be the right aspect ratio in all cases, but I think it's
1540 // probably better than nothing.
1541 fmtutil_atari_set_standard_density(c
, adata
, fi
);
1543 pos
= frames_startpos
;
1544 for(frameidx
=0; frameidx
<nframes
; frameidx
++) {
1545 de_dbg(c
, "frame #%d at %"I64_FMT
, (int)frameidx
, pos
);
1546 de_dbg_indent(c
, 1);
1547 de_read_simple_palette(c
, c
->infile
, pos
, 16, 2, adata
->pal
, 16, DE_RDPALTYPE_AMIGA12BIT
, 0);
1548 pos
+= VMAS_FRAME_PAL_SIZE
;
1550 de_dbg(c
, "bitmap at %"I64_FMT
, pos
);
1551 dbuf_truncate(adata
->unc_pixels
, 0);
1552 dbuf_copy(c
->infile
, pos
, VMAS_FRAME_BITMAP_SIZE
, adata
->unc_pixels
);
1553 pos
+= VMAS_FRAME_BITMAP_SIZE
;
1555 fmtutil_atari_decode_image(c
, adata
);
1556 de_bitmap_write_to_file_finfo(adata
->img
, fi
, DE_CREATEFLAG_OPT_IMAGE
);
1557 de_dbg_indent(c
, -1);
1562 dbuf_close(adata
->unc_pixels
);
1563 de_bitmap_destroy(adata
->img
);
1566 de_finfo_destroy(c
, fi
);
1569 static int de_identify_videomaster(deark
*c
)
1571 if(!dbuf_memcmp(c
->infile
, 0, (const void*)"VMAS1", 5)) {
1577 void de_module_videomaster(deark
*c
, struct deark_module_info
*mi
)
1579 mi
->id
= "videomaster";
1580 mi
->desc
= "Video Master (.flm/.vid/.vsq)";
1581 mi
->run_fn
= de_run_videomaster
;
1582 mi
->identify_fn
= de_identify_videomaster
;