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
);
25 static void fix_dark_pal(deark
*c
, struct atari_img_decode_data
*adata
);
27 static void help_respectpal(deark
*c
)
29 de_msg(c
, "-opt atari:respectpal : Don't ignore a seemingly bad 2-color palette");
32 // **************************************************************************
33 // DEGAS / DEGAS Elite images
34 // **************************************************************************
36 typedef struct degasctx_struct
{
37 unsigned int compression_code
;
42 static void do_degas_anim_fields(deark
*c
, degasctx
*d
, i64 pos
)
48 n
= de_getu16be(pos
+ 2*i
);
49 de_dbg2(c
, "left_color_anim[%d] = %d", (int)i
, (int)n
);
52 n
= de_getu16be(pos
+ 8 + 2*i
);
53 de_dbg2(c
, "right_color_anim[%d] = %d", (int)i
, (int)n
);
56 n
= de_getu16be(pos
+ 16 + 2*i
);
57 de_dbg2(c
, "channel_direction[%d] = %d", (int)i
, (int)n
);
60 n
= de_getu16be(pos
+ 24 + 2*i
);
61 de_dbg2(c
, "channel_delay_code[%d] = %d", (int)i
, (int)n
);
64 // TODO: Can we determine if palette animation is actually used,
65 // and only show the warning if it is?
66 //de_warn(c, "This image may use palette cycling animation, which is not supported.");
69 // Try to figure out if this is a DEGAS Elite file (as opposed to original DEGAS).
70 static int is_degas_elite(deark
*c
, degasctx
*d
)
77 if(d
->compression_code
) return 1; // Only DEGAS Elite supports compression.
78 if(c
->infile
->len
< 32066) return 0;
80 // Test if the animation segment seems to have valid values, to try to distinguish
81 // it from meaningless padding. (This is overkill.)
84 // The first 8 fields are "color numbers".
85 // Guessing that they should be 0-15.
86 x
= de_getu16be(pos
+n
*2);
92 // The next 4 fields (channel direction) should be 0, 1, or 2.
93 x
= de_getu16be(pos
+n
*2);
99 // The next 4 fields (delay) must be from 0 to 128.
100 x
= de_getu16be(pos
+n
*2);
105 if(all_zero
&& c
->infile
->len
>32068) {
106 // If every field was 0, and the file size doesn't suggest Elite,
107 // just assume it's not valid.
114 static void de_run_degas(deark
*c
, de_module_params
*mparams
)
117 struct atari_img_decode_data
*adata
= NULL
;
120 unsigned int format_code
, resolution_code
;
122 i64 cmpr_bytes_consumed
= 0;
124 d
= de_malloc(c
, sizeof(degasctx
));
125 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
130 format_code
= (unsigned int)de_getu16be(pos
);
131 de_dbg(c
, "format code: 0x%04x", format_code
);
132 resolution_code
= format_code
& 0x0003;
133 d
->compression_code
= (format_code
& 0x8000)>>15;
135 de_dbg(c
, "resolution code: %u", resolution_code
);
136 de_dbg(c
, "compression code: %u", d
->compression_code
);
137 de_dbg_indent(c
, -1);
140 switch(resolution_code
) {
157 de_dbg(c
, "Invalid or unsupported resolution (%u)", resolution_code
);
160 adata
->ncolors
= de_pow2(adata
->bpp
);
162 de_dbg(c
, "dimensions: %d"DE_CHAR_TIMES
"%d, colors: %d", (int)adata
->w
, (int)adata
->h
, (int)adata
->ncolors
);
164 d
->degas_elite_flag
= is_degas_elite(c
, d
);
165 de_declare_fmtf(c
, "DEGAS%s %d-color %scompressed",
166 d
->degas_elite_flag
?" Elite":"",
168 d
->compression_code
?"":"un");
170 fmtutil_read_atari_palette(c
, c
->infile
, pos
, adata
->pal
, 16, adata
->ncolors
, 0);
172 fix_dark_pal(c
, adata
);
174 if(d
->compression_code
) {
175 adata
->was_compressed
= 1;
176 adata
->unc_pixels
= dbuf_create_membuf(c
, 32000, 1);
178 if(!fmtutil_decompress_packbits(c
->infile
, pos
, c
->infile
->len
-pos
, adata
->unc_pixels
, &cmpr_bytes_consumed
))
181 de_dbg(c
, "Compressed bytes found: %d", (int)cmpr_bytes_consumed
);
182 pos
+= cmpr_bytes_consumed
;
185 i64 avail_bytes
= 32000;
186 if(pos
+32000 > c
->infile
->len
) {
187 avail_bytes
= c
->infile
->len
- pos
;
188 de_warn(c
, "Unexpected end of file (expected 32000 bytes, got %d)", (int)avail_bytes
);
190 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, pos
, avail_bytes
);
194 if(pos
+ 32 == c
->infile
->len
) {
195 do_degas_anim_fields(c
, d
, pos
);
198 is_grayscale
= de_is_grayscale_palette(adata
->pal
, adata
->ncolors
);
200 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, is_grayscale
?1:3);
202 fi
= de_finfo_create(c
);
203 fmtutil_atari_set_standard_density(c
, adata
, fi
);
205 fmtutil_atari_decode_image(c
, adata
);
207 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
211 dbuf_close(adata
->unc_pixels
);
212 de_bitmap_destroy(adata
->img
);
215 de_finfo_destroy(c
, fi
);
219 static int de_identify_degas(deark
*c
)
221 static const char *exts
[6] = {"pi1", "pi2", "pi3", "pc1", "pc2", "pc3" };
228 if(de_input_file_has_ext(c
, exts
[i
])) {
235 sig
= de_getu16be(0);
236 if(sig
==0x0000 || sig
==0x0001 || sig
==0x0002) {
237 if(c
->infile
->len
==32034) return 100; // DEGAS
238 if(c
->infile
->len
==32066) return 100; // DEGAS Elite
239 if(c
->infile
->len
==32128) return 40; // Could be padded to a multiple of 128 bytes
240 if(c
->infile
->len
>16000) return 10;
242 else if(sig
==0x8000 || sig
==0x8001 || sig
==0x8002) {
249 static void de_help_degas(deark
*c
)
251 fmtutil_atari_help_palbits(c
);
255 void de_module_degas(deark
*c
, struct deark_module_info
*mi
)
258 mi
->desc
= "Atari DEGAS or DEGAS Elite image";
259 mi
->run_fn
= de_run_degas
;
260 mi
->identify_fn
= de_identify_degas
;
261 mi
->help_fn
= de_help_degas
;
264 // **************************************************************************
265 // Atari Prism Paint (.pnt)
266 // **************************************************************************
268 typedef struct prismctx_struct
{
270 i64 compression_code
;
275 // A color value of N does not necessarily refer to Nth color in the palette.
276 // Some of them are mixed up. Apparently this is called "VDI order".
277 // Reference: http://toshyp.atari.org/en/VDI_fundamentals.html
278 static unsigned int map_vdi_pal(i64 bpp
, unsigned int v
)
284 case 3: return bpp
>2 ? 6 : 1;
294 case 15: return bpp
==8 ? 255 : 1;
300 static void do_prism_read_palette(deark
*c
, prismctx
*d
, struct atari_img_decode_data
*adata
)
309 de_zeromem(pal1
, sizeof(pal1
));
311 for(i
=0; i
<d
->pal_size
; i
++) {
312 r1
= de_getu16be(128+6*i
+0);
313 g1
= de_getu16be(128+6*i
+2);
314 b1
= de_getu16be(128+6*i
+4);
315 r
= de_scale_1000_to_255(r1
);
316 g
= de_scale_1000_to_255(g1
);
317 b
= de_scale_1000_to_255(b1
);
318 clr
= DE_MAKE_RGB(r
,g
,b
);
319 de_snprintf(tmps
, sizeof(tmps
), "(%4d,%4d,%4d) "DE_CHAR_RIGHTARROW
" ",
320 (int)r1
, (int)g1
, (int)b1
);
321 de_dbg_pal_entry2(c
, i
, clr
, tmps
, NULL
, NULL
);
327 for(i
=0; i
<d
->pal_size
; i
++) {
328 d
->pal
[i
] = pal1
[map_vdi_pal(adata
->bpp
, (unsigned int)i
)];
332 static void de_run_prismpaint(deark
*c
, de_module_params
*mparams
)
336 struct atari_img_decode_data
*adata
= NULL
;
338 d
= de_malloc(c
, sizeof(prismctx
));
340 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
343 d
->pal_size
= de_getu16be(6);
344 adata
->w
= de_getu16be(8);
345 adata
->h
= de_getu16be(10);
346 de_dbg(c
, "pal_size: %d, dimensions: %d"DE_CHAR_TIMES
"%d", (int)d
->pal_size
,
347 (int)adata
->w
, (int)adata
->h
);
348 if(!de_good_image_dimensions(c
, adata
->w
, adata
->h
)) goto done
;
350 adata
->bpp
= de_getu16be(12);
351 d
->compression_code
= de_getu16be(14);
352 de_dbg(c
, "bits/pixel: %d, compression: %d", (int)adata
->bpp
,
353 (int)d
->compression_code
);
355 d
->pic_data_size
= de_getu32be(16);
356 de_dbg(c
, "reported (uncompressed) picture data size: %d", (int)d
->pic_data_size
);
358 do_prism_read_palette(c
, d
, adata
);
360 if(adata
->bpp
!=1 && adata
->bpp
!=2 && adata
->bpp
!=4
361 && adata
->bpp
!=8 && adata
->bpp
!=16)
363 de_err(c
, "Unsupported bits/pixel (%d)", (int)adata
->bpp
);
366 if(d
->compression_code
!=0 && d
->compression_code
!=1) {
367 de_err(c
, "Unsupported compression (%d)", (int)d
->compression_code
);
370 if(adata
->bpp
==16 && d
->compression_code
!=0) {
371 de_warn(c
, "Compressed 16-bit image support is untested, and may not work.");
374 pixels_start
= 128 + 2*3*d
->pal_size
;
375 de_dbg(c
, "pixel data starts at %d", (int)pixels_start
);
376 if(pixels_start
>= c
->infile
->len
) goto done
;
378 if(d
->compression_code
==0) {
379 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, pixels_start
,
380 c
->infile
->len
- pixels_start
);
383 adata
->was_compressed
= 1;
384 // TODO: Calculate the initial size more accurately.
385 adata
->unc_pixels
= dbuf_create_membuf(c
, adata
->w
*adata
->h
, 0);
386 //dbuf_set_max_length(unc_pixels, ...);
388 fmtutil_decompress_packbits(c
->infile
, pixels_start
, c
->infile
->len
- pixels_start
,
389 adata
->unc_pixels
, NULL
);
390 de_dbg(c
, "decompressed to %d bytes", (int)adata
->unc_pixels
->len
);
393 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
394 fmtutil_atari_decode_image(c
, adata
);
395 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
399 dbuf_close(adata
->unc_pixels
);
400 de_bitmap_destroy(adata
->img
);
406 static int de_identify_prismpaint(deark
*c
)
408 if(!dbuf_memcmp(c
->infile
, 0, "PNT\x00", 4))
413 void de_module_prismpaint(deark
*c
, struct deark_module_info
*mi
)
415 mi
->id
= "prismpaint";
416 mi
->desc
= "Atari Prism Paint .PNT, a.k.a. TruePaint .TPI";
417 mi
->run_fn
= de_run_prismpaint
;
418 mi
->identify_fn
= de_identify_prismpaint
;
421 // **************************************************************************
422 // Atari Falcon True Color .FTC
423 // **************************************************************************
425 static void de_run_ftc(deark
*c
, de_module_params
*mparams
)
427 struct atari_img_decode_data
*adata
= NULL
;
430 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
434 adata
->unc_pixels
= c
->infile
;
435 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
436 fi
= de_finfo_create(c
);
437 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
438 fi
->density
.xdens
= 288;
439 fi
->density
.ydens
= 240;
440 fmtutil_atari_decode_image(c
, adata
);
441 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
442 de_bitmap_destroy(adata
->img
);
443 de_finfo_destroy(c
, fi
);
447 static int de_identify_ftc(deark
*c
)
449 if(c
->infile
->len
!= 184320) return 0;
450 if(!de_input_file_has_ext(c
, "ftc")) return 0;
454 void de_module_ftc(deark
*c
, struct deark_module_info
*mi
)
457 mi
->desc
= "Atari Falcon True Color .FTC";
458 mi
->run_fn
= de_run_ftc
;
459 mi
->identify_fn
= de_identify_ftc
;
462 // **************************************************************************
463 // Atari Falcon EggPaint .TRP
464 // **************************************************************************
466 static void de_run_eggpaint(deark
*c
, de_module_params
*mparams
)
468 struct atari_img_decode_data
*adata
= NULL
;
470 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
472 if(!dbuf_memcmp(c
->infile
, 0, "tru?", 4)) {
473 de_declare_fmt(c
, "Spooky Sprites");
476 de_declare_fmt(c
, "EggPaint");
480 adata
->w
= de_getu16be(4);
481 adata
->h
= de_getu16be(6);
482 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
483 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 8, c
->infile
->len
-8);
484 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
485 fmtutil_atari_decode_image(c
, adata
);
486 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
488 dbuf_close(adata
->unc_pixels
);
489 de_bitmap_destroy(adata
->img
);
493 static int de_identify_eggpaint(deark
*c
)
495 if(!dbuf_memcmp(c
->infile
, 0, "TRUP", 4)) {
498 if(!dbuf_memcmp(c
->infile
, 0, "tru?", 4)) {
504 void de_module_eggpaint(deark
*c
, struct deark_module_info
*mi
)
507 mi
->desc
= "Atari EggPaint .TRP";
508 mi
->run_fn
= de_run_eggpaint
;
509 mi
->identify_fn
= de_identify_eggpaint
;
512 // **************************************************************************
513 // Atari Falcon IndyPaint .TRU
514 // **************************************************************************
516 static void de_run_indypaint(deark
*c
, de_module_params
*mparams
)
518 struct atari_img_decode_data
*adata
= NULL
;
520 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
522 adata
->w
= de_getu16be(4);
523 adata
->h
= de_getu16be(6);
524 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
525 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 256, c
->infile
->len
-256);
526 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
527 fmtutil_atari_decode_image(c
, adata
);
528 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
530 dbuf_close(adata
->unc_pixels
);
531 de_bitmap_destroy(adata
->img
);
535 static int de_identify_indypaint(deark
*c
)
537 if(!dbuf_memcmp(c
->infile
, 0, "Indy", 4)) {
543 void de_module_indypaint(deark
*c
, struct deark_module_info
*mi
)
545 mi
->id
= "indypaint";
546 mi
->desc
= "Atari IndyPaint .TRU";
547 mi
->run_fn
= de_run_indypaint
;
548 mi
->identify_fn
= de_identify_indypaint
;
551 // **************************************************************************
552 // Atari Falcon GodPaint .GOD
553 // **************************************************************************
555 static void de_run_godpaint(deark
*c
, de_module_params
*mparams
)
557 struct atari_img_decode_data
*adata
= NULL
;
559 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
561 adata
->w
= de_getu16be(2);
562 adata
->h
= de_getu16be(4);
563 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
564 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 6, c
->infile
->len
-6);
565 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
566 fmtutil_atari_decode_image(c
, adata
);
567 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
569 dbuf_close(adata
->unc_pixels
);
570 de_bitmap_destroy(adata
->img
);
574 static int de_identify_godpaint(deark
*c
)
578 sig
= de_getu16be(0);
579 if(sig
!=0x4734 && sig
!=0x0400) return 0;
580 if(de_input_file_has_ext(c
, "god")) return 100;
581 if(sig
==0x4734) return 5;
585 void de_module_godpaint(deark
*c
, struct deark_module_info
*mi
)
588 mi
->desc
= "Atari Falcon GodPaint";
589 mi
->run_fn
= de_run_godpaint
;
590 mi
->identify_fn
= de_identify_godpaint
;
593 // **************************************************************************
595 // **************************************************************************
597 typedef struct tinyctx_struct
{
599 i64 num_control_bytes
;
603 // Decompression params:
608 // Decompression state:
614 i64 dcmpr_word_count
;
617 static void tiny_setword(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
, const u8
*wordbuf
)
621 // As each word is emitted from the decompressor, we store it in the unc_pixels buffer
622 // in a particular location. The location is chosen so as to make the pixel data more
623 // contiguous, but (for 2bpp and 4bpp images) more work will still have to be done when
624 // the image is generated.
626 if(d
->stopflag
) return;
627 d
->dcmpr_word_count
++;
628 dstpos
= d
->stripe
* 8 + d
->column
*2 + (d
->ypos
* d
->numscans
+ d
->scan
)*d
->dst_rowspan
;
629 dbuf_write_at(adata
->unc_pixels
, dstpos
, wordbuf
, 2);
634 if(d
->stripe
>= d
->numstripes
) {
637 if(d
->scan
>= d
->numscans
) {
649 // Uncompress to adata->unc_pixels.
650 static int tiny_uncompress(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
, i64 pos
)
652 u8
*control_bytes
= NULL
;
667 d
->dst_rowspan
= 160;
670 de_dbg(c
, "RLE control bytes at %d", (int)pos
);
671 control_bytes
= de_malloc(c
, d
->num_control_bytes
+2);
672 de_read(control_bytes
, pos
, d
->num_control_bytes
);
673 pos
+= d
->num_control_bytes
;
675 de_dbg(c
, "RLE data words at %d", (int)pos
);
684 d
->dcmpr_word_count
= 0;
687 if(d
->stopflag
) break;
688 if(cpos
>= d
->num_control_bytes
) break;
689 ctrl
= control_bytes
[cpos
++];
691 if(ctrl
>= 128) { // Uncompressed run, count encoded in control byte
692 count
= 256 - (i64
)ctrl
;
693 for(k
=0; k
<count
; k
++) {
694 dbuf_read(c
->infile
, wordbuf
, pos
, 2);
696 tiny_setword(c
, d
, adata
, wordbuf
);
699 else if(ctrl
== 0) { // RLE, 16-bit count in next 2 control bytes
700 count
= de_getu16be_direct(&control_bytes
[cpos
]);
702 dbuf_read(c
->infile
, wordbuf
, pos
, 2);
704 for(k
=0; k
<count
; k
++) {
705 tiny_setword(c
, d
, adata
, wordbuf
);
708 else if(ctrl
== 1) { // Uncompressed run, 16-bit count in next 2 control bytes
709 count
= de_getu16be_direct(&control_bytes
[cpos
]);
712 for(k
=0; k
<count
; k
++) {
713 dbuf_read(c
->infile
, wordbuf
, pos
, 2);
715 tiny_setword(c
, d
, adata
, wordbuf
);
718 else { // RLE, count encoded in control byte
720 dbuf_read(c
->infile
, wordbuf
, pos
, 2);
722 for(k
=0; k
<count
; k
++) {
723 tiny_setword(c
, d
, adata
, wordbuf
);
728 de_dbg(c
, "decompressed words: %d", (int)d
->dcmpr_word_count
);
729 if(d
->dcmpr_word_count
<16000) {
730 de_warn(c
, "Expected 16000 decompressed words, got %d", (int)d
->dcmpr_word_count
);
733 de_free(c
, control_bytes
);
737 static void do_tinystuff_1bpp(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
)
739 de_convert_image_paletted(adata
->unc_pixels
, 0, 1, d
->dst_rowspan
, adata
->pal
,
743 static void do_tinystuff_2or4bpp(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
)
750 bpp
= (UI
)adata
->bpp
;
751 if(bpp
!=2 && bpp
!=4) return;
753 if(bpp
==2) width
= 640;
756 for(y
=0; y
<200; y
++) {
757 for(x
=0; x
<width
; x
+=16) {
762 // 2bpp: Every 2 words (4 bytes; 32 bits) makes 16 pixels
763 // 4bpp: Every 4 words (8 bytes; 64 bits) makes 16 pixels
764 for(b_idx
=0; b_idx
<bpp
; b_idx
++) {
765 n
[b_idx
] = (UI
)dbuf_getu16be_p(adata
->unc_pixels
, &pos
);
768 for(k
=0; k
<16; k
++) {
771 for(b_idx
=0; b_idx
<bpp
; b_idx
++) {
772 if(n
[b_idx
]&(1U<<(15-k
))) v
+= (1U<<b_idx
);
774 de_bitmap_setpixel_rgb(adata
->img
, x
+(i64
)k
, y
, adata
->pal
[v
]);
780 static void do_tinystuff_image(deark
*c
, tinyctx
*d
, struct atari_img_decode_data
*adata
)
784 do_tinystuff_1bpp(c
, d
, adata
);
788 do_tinystuff_2or4bpp(c
, d
, adata
);
793 // Some 1bpp images apparently have the palette set to [001, 000],
794 // or other nonsense, instead of [777, 000].
795 // Try to handle that.
796 static void fix_dark_pal(deark
*c
, struct atari_img_decode_data
*adata
)
800 if(adata
->bpp
!=1) return;
802 ap
[0] = adata
->pal
[0]&0xffffff;
803 ap
[1] = adata
->pal
[1]&0xffffff;
805 // Always respect white/black and black/white palettes.
806 if(ap
[0]==0xffffff && ap
[1]==0x000000) return; // The usual palette
807 if(ap
[0]==0x000000 && ap
[1]==0xffffff) return;
809 // Otherwise assume white/black, unless the user told us not to.
810 if(de_get_ext_option(c
, "atari:respectpal")) return;
812 adata
->pal
[0] = DE_STOCKCOLOR_WHITE
;
813 adata
->pal
[1] = DE_STOCKCOLOR_BLACK
;
816 static void de_run_tinystuff(deark
*c
, de_module_params
*mparams
)
818 struct atari_img_decode_data
*adata
= NULL
;
822 i64 expected_min_file_size
;
823 i64 expected_max_file_size
;
826 d
= de_malloc(c
, sizeof(tinyctx
));
828 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
830 adata
->was_compressed
= 1;
832 d
->res_code
= de_getbyte(pos
);
834 de_dbg(c
, "resolution code: %d", (int)d
->res_code
);
836 switch(d
->res_code
) {
853 de_err(c
, "Invalid resolution code (%d). This is not a Tiny Stuff file.",
858 adata
->ncolors
= de_pow2(adata
->bpp
);
860 de_dbg(c
, "dimensions: %d"DE_CHAR_TIMES
"%d, colors: %d", (int)adata
->w
, (int)adata
->h
, (int)adata
->ncolors
);
863 de_warn(c
, "This image uses palette cycling animation, which is not supported.");
864 pos
+= 4; // skip animation_info
867 fmtutil_read_atari_palette(c
, c
->infile
, pos
, adata
->pal
, 16, adata
->ncolors
, 0);
868 fix_dark_pal(c
, adata
);
871 d
->num_control_bytes
= de_getu16be(pos
);
873 de_dbg(c
, "number of RLE control bytes: %d", (int)d
->num_control_bytes
);
875 d
->num_data_words
= de_getu16be(pos
);
877 de_dbg(c
, "number of RLE data words: %d (%d bytes)", (int)d
->num_data_words
,
878 2*(int)(d
->num_data_words
));
880 // It seems that files are often padded to the next multiple of 128 bytes,
881 // so don't warn about that.
882 expected_min_file_size
= pos
+ d
->num_control_bytes
+ 2*d
->num_data_words
;
883 expected_max_file_size
= ((expected_min_file_size
+127)/128)*128;
884 de_dbg(c
, "expected file size: %d or %d", (int)expected_min_file_size
, (int)expected_max_file_size
);
885 if(c
->infile
->len
<expected_min_file_size
|| c
->infile
->len
>expected_max_file_size
) {
886 de_warn(c
, "Expected file size to be %d, but it is %d.", (int)expected_min_file_size
,
887 (int)c
->infile
->len
);
890 adata
->unc_pixels
= dbuf_create_membuf(c
, 32000, 1);
892 if(!tiny_uncompress(c
, d
, adata
, pos
)) {
896 is_grayscale
= de_is_grayscale_palette(adata
->pal
, adata
->ncolors
);
898 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, is_grayscale
?1:3);
900 fi
= de_finfo_create(c
);
901 fmtutil_atari_set_standard_density(c
, adata
, fi
);
903 do_tinystuff_image(c
, d
, adata
);
904 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
908 de_bitmap_destroy(adata
->img
);
909 dbuf_close(adata
->unc_pixels
);
912 de_finfo_destroy(c
, fi
);
916 static int de_identify_tinystuff(deark
*c
)
918 // TODO: Can we identify these files?
919 if(de_getbyte(0)>0x05) return 0;
920 if(de_input_file_has_ext(c
, "tny") ||
921 de_input_file_has_ext(c
, "tn1") ||
922 de_input_file_has_ext(c
, "tn2") ||
923 de_input_file_has_ext(c
, "tn3") ||
924 de_input_file_has_ext(c
, "tn4"))
931 static void de_help_tinystuff(deark
*c
)
933 fmtutil_atari_help_palbits(c
);
937 void de_module_tinystuff(deark
*c
, struct deark_module_info
*mi
)
939 mi
->id
= "tinystuff";
940 mi
->desc
= "Atari Tiny Stuff, a.k.a. Tiny image format";
941 mi
->run_fn
= de_run_tinystuff
;
942 mi
->identify_fn
= de_identify_tinystuff
;
943 mi
->help_fn
= de_help_tinystuff
;
946 // **************************************************************************
948 // **************************************************************************
950 static void de_run_doodle(deark
*c
, de_module_params
*mparams
)
952 struct atari_img_decode_data
*adata
= NULL
;
956 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
963 adata
->pal
[0] = DE_STOCKCOLOR_WHITE
;
964 adata
->pal
[1] = DE_STOCKCOLOR_BLACK
;
966 adata
->unc_pixels
= c
->infile
;
967 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 1);
968 fi
= de_finfo_create(c
);
969 fmtutil_atari_set_standard_density(c
, adata
, fi
);
970 fmtutil_atari_decode_image(c
, adata
);
971 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
974 de_bitmap_destroy(adata
->img
);
977 de_finfo_destroy(c
, fi
);
980 static int de_identify_doodle(deark
*c
)
982 if(c
->infile
->len
!=32000) return 0;
983 if(de_input_file_has_ext(c
, "doo")) {
989 void de_module_doodle(deark
*c
, struct deark_module_info
*mi
)
992 mi
->desc
= "Atari Doodle";
993 mi
->run_fn
= de_run_doodle
;
994 mi
->identify_fn
= de_identify_doodle
;
997 // **************************************************************************
999 // **************************************************************************
1001 static void de_run_neochrome(deark
*c
, de_module_params
*mparams
)
1003 struct atari_img_decode_data
*adata
= NULL
;
1004 de_finfo
*fi
= NULL
;
1005 unsigned int resolution_code
;
1009 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1012 resolution_code
= (unsigned int)de_getu16be(2);
1013 de_dbg(c
, "resolution code: %u", resolution_code
);
1014 if(resolution_code
!=0) {
1015 de_err(c
, "Invalid or unsupported NEOchrome image (resolution=%d)", (int)resolution_code
);
1019 // TODO: Warn about palette animation settings.
1020 // TODO: (Maybe) Use the embedded filename, if it seems valid.
1025 adata
->ncolors
= de_pow2(adata
->bpp
);
1026 de_dbg(c
, "dimensions: %d"DE_CHAR_TIMES
"%d, colors: %d", (int)adata
->w
, (int)adata
->h
, (int)adata
->ncolors
);
1028 fmtutil_read_atari_palette(c
, c
->infile
, 4, adata
->pal
, 16, adata
->ncolors
, 0);
1029 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 128, 32000);
1030 is_grayscale
= de_is_grayscale_palette(adata
->pal
, adata
->ncolors
);
1031 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, is_grayscale
?1:3);
1032 fi
= de_finfo_create(c
);
1033 fmtutil_atari_set_standard_density(c
, adata
, fi
);
1034 fmtutil_atari_decode_image(c
, adata
);
1035 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
1039 dbuf_close(adata
->unc_pixels
);
1040 de_bitmap_destroy(adata
->img
);
1043 de_finfo_destroy(c
, fi
);
1046 static int de_identify_neochrome(deark
*c
)
1048 if(de_input_file_has_ext(c
, "neo")) {
1049 if(c
->infile
->len
== 32128) {
1052 else if(c
->infile
->len
> 32128) {
1059 static void de_help_neochrome(deark
*c
)
1061 fmtutil_atari_help_palbits(c
);
1064 void de_module_neochrome(deark
*c
, struct deark_module_info
*mi
)
1066 mi
->id
= "neochrome";
1067 mi
->desc
= "Atari NEOchrome image";
1068 mi
->run_fn
= de_run_neochrome
;
1069 mi
->identify_fn
= de_identify_neochrome
;
1070 mi
->help_fn
= de_help_neochrome
;
1073 // **************************************************************************
1074 // NEOchrome animation (.ani)
1075 // **************************************************************************
1077 static void de_run_neochrome_ani(deark
*c
, de_module_params
*mparams
)
1079 struct atari_img_decode_data
*adata
= NULL
;
1082 i64 bytes_per_frame
;
1087 de_declare_fmt(c
, "NEOchrome Animation");
1089 de_warn(c
, "NEOchrome Animation images may not be decoded correctly.");
1091 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1093 // TODO: What palette should we use?
1094 for(k
=0; k
<16; k
++) {
1095 pal
[k
] = DE_MAKE_GRAY((unsigned int)(k
*17));
1099 adata
->ncolors
= 16;
1101 width_in_bytes
= de_getu16be(4); // Always a multiple of 8
1102 adata
->w
= ((width_in_bytes
+7)/8)*16;
1103 adata
->h
= de_getu16be(6);
1104 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1105 if(!de_good_image_dimensions(c
, adata
->w
, adata
->h
)) goto done
;
1107 bytes_per_frame
= de_getu16be(8);
1108 bytes_per_frame
-= 10;
1109 de_dbg(c
, "bytes/frame: %d", (int)bytes_per_frame
);
1110 if(bytes_per_frame
<1) goto done
;
1112 nframes
= de_getu16be(14);
1113 de_dbg(c
, "number of frames: %d", (int)nframes
);
1114 if(!de_good_image_count(c
, nframes
)) goto done
;
1116 for(frame
=0; frame
<nframes
; frame
++) {
1117 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, 22 + frame
*bytes_per_frame
, bytes_per_frame
);
1118 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1120 fmtutil_atari_decode_image(c
, adata
);
1121 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
1123 de_bitmap_destroy(adata
->img
);
1126 dbuf_close(adata
->unc_pixels
);
1127 adata
->unc_pixels
= NULL
;
1134 static int de_identify_neochrome_ani(deark
*c
)
1136 if(!dbuf_memcmp(c
->infile
, 0, "\xba\xbe\xeb\xea", 4)) {
1142 void de_module_neochrome_ani(deark
*c
, struct deark_module_info
*mi
)
1144 mi
->id
= "neochrome_ani";
1145 mi
->desc
= "NEOchrome Animation";
1146 mi
->run_fn
= de_run_neochrome_ani
;
1147 mi
->identify_fn
= de_identify_neochrome_ani
;
1148 mi
->flags
|= DE_MODFLAG_NONWORKING
;
1151 // **************************************************************************
1152 // Animatic Film (.flm)
1153 // **************************************************************************
1155 static void de_run_animatic(deark
*c
, de_module_params
*mparams
)
1157 struct atari_img_decode_data
*adata
= NULL
;
1160 i64 planespan
, rowspan
, framespan
;
1161 i64 frame_bitmap_pos
;
1164 de_declare_fmt(c
, "Animatic Film");
1166 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1168 nframes
= de_getu16be(0);
1169 de_dbg(c
, "number of frames: %d", (int)nframes
);
1170 if(!de_good_image_count(c
, nframes
)) goto done
;
1173 adata
->ncolors
= 16;
1175 de_dbg_indent(c
, 1);
1176 fmtutil_read_atari_palette(c
, c
->infile
, 2, adata
->pal
, 16, adata
->ncolors
, 0);
1177 de_dbg_indent(c
, -1);
1179 adata
->w
= de_getu16be(40);
1180 adata
->h
= de_getu16be(42);
1181 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1182 if(!de_good_image_dimensions(c
, adata
->w
, adata
->h
)) goto done
;
1184 planespan
= 2*((adata
->w
+15)/16);
1185 rowspan
= planespan
*adata
->bpp
;
1186 framespan
= rowspan
*adata
->h
;
1188 for(frame
=0; frame
<nframes
; frame
++) {
1189 frame_bitmap_pos
= 64 + frame
*framespan
;
1190 de_dbg(c
, "frame %d bitmap at %d", (int)frame
, (int)frame_bitmap_pos
);
1192 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
, frame_bitmap_pos
, framespan
);
1193 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1195 fmtutil_atari_decode_image(c
, adata
);
1196 de_bitmap_write_to_file(adata
->img
, NULL
, 0);
1198 de_bitmap_destroy(adata
->img
);
1201 dbuf_close(adata
->unc_pixels
);
1202 adata
->unc_pixels
= NULL
;
1209 static int de_identify_animatic(deark
*c
)
1211 if(!dbuf_memcmp(c
->infile
, 48, "\x27\x18\x28\x18", 4)) {
1217 static void de_help_animatic(deark
*c
)
1219 fmtutil_atari_help_palbits(c
);
1222 void de_module_animatic(deark
*c
, struct deark_module_info
*mi
)
1224 mi
->id
= "animatic";
1225 mi
->desc
= "Animatic Film";
1226 mi
->run_fn
= de_run_animatic
;
1227 mi
->identify_fn
= de_identify_animatic
;
1228 mi
->help_fn
= de_help_animatic
;
1231 // **************************************************************************
1233 // **************************************************************************
1235 static void decode_falcon_8bit_image(deark
*c
, struct atari_img_decode_data
*adata
, i64 pos
)
1240 de_finfo
*fi
= NULL
;
1242 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1244 fi
= de_finfo_create(c
);
1245 if(adata
->w
==320 && adata
->h
==200) {
1246 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
1247 fi
->density
.xdens
= 240.0;
1248 fi
->density
.ydens
= 200.0;
1251 for(j
=0; j
<adata
->h
; j
++) {
1252 for(i
=0; i
<adata
->w
; i
++) {
1254 for(k
=0; k
<8; k
++) {
1255 n
= (u32
)de_getu16be(pos
+j
*adata
->w
+ (i
-i
%16) +2*k
);
1256 if(n
&(1<<(15-i
%16))) v
|= 1<<k
;
1258 de_bitmap_setpixel_rgb(adata
->img
, i
, j
, adata
->pal
[v
]);
1262 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
1263 de_bitmap_destroy(adata
->img
);
1265 de_finfo_destroy(c
, fi
);
1268 static void do_atari_falcon_8bit_img(deark
*c
, i64 width
, i64 height
)
1270 struct atari_img_decode_data
*adata
= NULL
;
1275 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1276 de_zeromem(pal
, sizeof(pal
));
1279 adata
->ncolors
= 256;
1282 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1284 for(k
=0; k
<256; k
++) {
1285 cr
= de_getbyte(k
*4+0);
1286 cg
= de_getbyte(k
*4+1);
1287 cb
= de_getbyte(k
*4+3);
1288 pal
[k
] = DE_MAKE_RGB(cr
, cg
, cb
);
1289 de_dbg_pal_entry(c
, k
, pal
[k
]);
1292 decode_falcon_8bit_image(c
, adata
, 1024);
1297 static void de_run_fpaint_pi4(deark
*c
, de_module_params
*mparams
)
1299 do_atari_falcon_8bit_img(c
, 320, 240);
1302 // Atari falcon 320x240
1303 static int de_identify_fpaint_pi4(deark
*c
)
1305 if(c
->infile
->len
==77824) {
1306 if(de_input_file_has_ext(c
, "pi4") ||
1307 de_input_file_has_ext(c
, "pi9"))
1309 return 50; // Must be lower than fpaint_pi9
1315 void de_module_fpaint_pi4(deark
*c
, struct deark_module_info
*mi
)
1317 mi
->id
= "fpaint_pi4";
1318 mi
->desc
= "Atari Falcon PI4 image";
1319 mi
->run_fn
= de_run_fpaint_pi4
;
1320 mi
->identify_fn
= de_identify_fpaint_pi4
;
1323 static void de_run_fpaint_pi9(deark
*c
, de_module_params
*mparams
)
1325 do_atari_falcon_8bit_img(c
, 320, 200);
1328 // Atari falcon 320x200
1329 static int de_identify_fpaint_pi9(deark
*c
)
1331 int pi4_ext
, pi9_ext
;
1333 if(c
->infile
->len
!=77824 && c
->infile
->len
!=65024) return 0;
1335 pi4_ext
= de_input_file_has_ext(c
, "pi4");
1336 pi9_ext
= de_input_file_has_ext(c
, "pi9");
1337 if(!pi4_ext
&& !pi9_ext
) return 0;
1339 if(c
->infile
->len
==65024) return 60;
1341 // If file size is 77824, we need to distinguish between PI4 (320x240) and
1342 // PI9 (320x200) format.
1343 // Best guess is that if the last 12800 bytes are all 0, we should assume PI9.
1344 if(!dbuf_is_all_zeroes(c
->infile
, 65024, 12800)) {
1345 return 0; // Will be identified elsewhere as PI4.
1348 return 60; // PI9. Must be higher than the value PI4 uses.
1351 void de_module_fpaint_pi9(deark
*c
, struct deark_module_info
*mi
)
1353 mi
->id
= "fpaint_pi9";
1354 mi
->desc
= "Atari Falcon PI9 image";
1355 mi
->run_fn
= de_run_fpaint_pi9
;
1356 mi
->identify_fn
= de_identify_fpaint_pi9
;
1359 // **************************************************************************
1361 // **************************************************************************
1363 static void de_run_atari_pi7(deark
*c
, de_module_params
*mparams
)
1365 do_atari_falcon_8bit_img(c
, 640, 480);
1368 static int de_identify_atari_pi7(deark
*c
)
1370 if(c
->infile
->len
==308224) {
1371 if(de_input_file_has_ext(c
, "pi7"))
1379 void de_module_atari_pi7(deark
*c
, struct deark_module_info
*mi
)
1381 mi
->id
= "atari_pi7";
1382 mi
->desc
= "Atari PI7 image";
1383 mi
->run_fn
= de_run_atari_pi7
;
1384 mi
->identify_fn
= de_identify_atari_pi7
;
1387 // **************************************************************************
1389 // **************************************************************************
1391 static void de_run_falcon_xga(deark
*c
, de_module_params
*mparams
)
1393 struct atari_img_decode_data
*adata
= NULL
;
1394 de_finfo
*fi
= NULL
;
1396 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1397 if(c
->infile
->len
==153600) {
1407 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1408 adata
->unc_pixels
= c
->infile
;
1409 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1410 fi
= de_finfo_create(c
);
1411 if(adata
->w
==384 && adata
->h
== 480) {
1412 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
1413 fi
->density
.xdens
= 384;
1414 fi
->density
.ydens
= 640;
1416 fmtutil_atari_decode_image(c
, adata
);
1417 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
1418 de_bitmap_destroy(adata
->img
);
1419 de_finfo_destroy(c
, fi
);
1423 static int de_identify_falcon_xga(deark
*c
)
1425 if(c
->infile
->len
==153600 || c
->infile
->len
==368640) {
1426 if(de_input_file_has_ext(c
, "xga"))
1434 void de_module_falcon_xga(deark
*c
, struct deark_module_info
*mi
)
1436 mi
->id
= "falcon_xga";
1437 mi
->desc
= "Atari Falcon XGA image";
1438 mi
->run_fn
= de_run_falcon_xga
;
1439 mi
->identify_fn
= de_identify_falcon_xga
;
1442 // **************************************************************************
1443 // Atari Falcon COKE (.tg1)
1444 // **************************************************************************
1446 static void de_run_coke(deark
*c
, de_module_params
*mparams
)
1449 struct atari_img_decode_data
*adata
= NULL
;
1450 de_finfo
*fi
= NULL
;
1452 adata
= de_malloc(c
, sizeof(struct atari_img_decode_data
));
1454 adata
->w
= de_getu16be(12);
1455 adata
->h
= de_getu16be(14);
1456 de_dbg_dimensions(c
, adata
->w
, adata
->h
);
1457 imgdatapos
= de_getu16be(16);
1458 de_dbg(c
, "image data pos: %d", (int)imgdatapos
);
1460 adata
->unc_pixels
= dbuf_open_input_subfile(c
->infile
,
1461 imgdatapos
, c
->infile
->len
-imgdatapos
);
1462 adata
->img
= de_bitmap_create(c
, adata
->w
, adata
->h
, 3);
1464 fi
= de_finfo_create(c
);
1465 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
1466 fi
->density
.xdens
= 288;
1467 fi
->density
.ydens
= 240;
1469 fmtutil_atari_decode_image(c
, adata
);
1470 de_bitmap_write_to_file_finfo(adata
->img
, fi
, 0);
1473 dbuf_close(adata
->unc_pixels
);
1474 de_bitmap_destroy(adata
->img
);
1477 de_finfo_destroy(c
, fi
);
1480 static int de_identify_coke(deark
*c
)
1482 if(!dbuf_memcmp(c
->infile
, 0, (const void*)"COKE format.", 12)) {
1488 void de_module_coke(deark
*c
, struct deark_module_info
*mi
)
1491 mi
->desc
= "Atari Falcon COKE image (.TG1)";
1492 mi
->run_fn
= de_run_coke
;
1493 mi
->identify_fn
= de_identify_coke
;