1 // This file is part of Deark.
2 // Copyright (C) 2016 Jason Summers
3 // See the file COPYING for terms of use.
5 // This file is for format-specific functions that are used by multiple modules.
7 #define DE_NOT_IN_MODULE
8 #include "deark-config.h"
9 #include "deark-private.h"
10 #include "deark-fmtutil.h"
12 void fmtutil_get_bmp_compression_name(u32 code
, char *s
, size_t s_len
,
15 const char *name1
= "?";
17 case 0: name1
= "BI_RGB, uncompressed"; break;
18 case 1: name1
= "BI_RLE8"; break;
19 case 2: name1
= "BI_RLE4"; break;
24 name1
= "BI_BITFIELDS, uncompressed";
32 case 5: name1
= "BI_PNG"; break;
34 de_strlcpy(s
, name1
, s_len
);
37 // Gathers information about a DIB.
38 // If DE_BMPINFO_HAS_FILEHEADER flag is set, pos points to the BITMAPFILEHEADER.
39 // Otherwise, it points to the BITMAPINFOHEADER.
40 // Caller allocates bi.
41 // Returns 0 if BMP is invalid.
42 int fmtutil_get_bmpinfo(deark
*c
, dbuf
*f
, struct de_bmpinfo
*bi
, i64 pos
,
43 i64 len
, unsigned int flags
)
45 i64 fhs
; // file header size
47 struct de_fourcc cmpr4cc
;
48 char cmprname_dbgstr
[80];
50 de_zeromem(bi
, sizeof(struct de_bmpinfo
));
51 de_zeromem(&cmpr4cc
, sizeof(struct de_fourcc
));
53 fhs
= (flags
& DE_BMPINFO_HAS_FILEHEADER
) ? 14 : 0;
55 if(fhs
+len
< 16) return 0;
58 if(flags
& DE_BMPINFO_HAS_HOTSPOT
) {
59 bi
->hotspot_x
= (int)dbuf_getu16le(f
, pos
+6);
60 bi
->hotspot_y
= (int)dbuf_getu16le(f
, pos
+8);
61 de_dbg(c
, "hotspot: (%d,%d)", bi
->hotspot_x
, bi
->hotspot_y
);
64 bi
->bitsoffset
= dbuf_getu32le(f
, pos
+10);
65 de_dbg(c
, "bits offset: %d", (int)bi
->bitsoffset
);
70 bi
->infohdrsize
= dbuf_getu32le(f
, bmih_pos
);
72 if(bi
->infohdrsize
==0x474e5089 && (flags
& DE_BMPINFO_ICO_FORMAT
)) {
73 // We don't examine PNG-formatted icons, but we can identify them.
75 bi
->file_format
= DE_BMPINFO_FMT_PNG
;
79 de_dbg(c
, "info header size: %d", (int)bi
->infohdrsize
);
81 if(bi
->infohdrsize
==12) {
82 bi
->bytes_per_pal_entry
= 3;
83 bi
->width
= dbuf_getu16le(f
, bmih_pos
+4);
84 bi
->height
= dbuf_getu16le(f
, bmih_pos
+6);
85 bi
->bitcount
= dbuf_getu16le(f
, bmih_pos
+10);
87 else if(bi
->infohdrsize
>=16 && bi
->infohdrsize
<=124) {
88 bi
->bytes_per_pal_entry
= 4;
89 bi
->width
= dbuf_getu32le(f
, bmih_pos
+4);
90 bi
->height
= dbuf_geti32le(f
, bmih_pos
+8);
93 bi
->height
= -bi
->height
;
95 bi
->bitcount
= dbuf_getu16le(f
, bmih_pos
+14);
96 if(bi
->infohdrsize
>=20) {
97 bi
->compression_field
= (u32
)dbuf_getu32le(f
, bmih_pos
+16);
98 if(flags
& DE_BMPINFO_CMPR_IS_4CC
) {
99 dbuf_read_fourcc(f
, bmih_pos
+16, &cmpr4cc
, 4, 0x0);
102 if(bi
->infohdrsize
>=24) {
103 bi
->sizeImage_field
= dbuf_getu32le(f
, bmih_pos
+20);
105 if(bi
->infohdrsize
>=36) {
106 bi
->pal_entries
= dbuf_getu32le(f
, bmih_pos
+32);
113 if(flags
& DE_BMPINFO_ICO_FORMAT
) bi
->height
/= 2;
115 if(bi
->bitcount
>=1 && bi
->bitcount
<=8) {
116 if(bi
->pal_entries
==0) {
117 bi
->pal_entries
= de_pow2(bi
->bitcount
);
119 // I think the NumColors field (in icons) is supposed to be the maximum number of
120 // colors implied by the bit depth, not the number of colors in the palette.
121 bi
->num_colors
= de_pow2(bi
->bitcount
);
124 // An arbitrary value. All that matters is that it's >=256.
125 bi
->num_colors
= 16777216;
128 de_dbg_dimensions(c
, bi
->width
, bi
->height
);
129 de_dbg(c
, "bit count: %d", (int)bi
->bitcount
);
131 if((flags
& DE_BMPINFO_CMPR_IS_4CC
) && (bi
->compression_field
>0xffff)) {
132 de_snprintf(cmprname_dbgstr
, sizeof(cmprname_dbgstr
), "'%s'", cmpr4cc
.id_dbgstr
);
135 fmtutil_get_bmp_compression_name(bi
->compression_field
,
136 cmprname_dbgstr
, sizeof(cmprname_dbgstr
), 0);
138 de_dbg(c
, "compression: %u (%s)", (unsigned int)bi
->compression_field
, cmprname_dbgstr
);
140 if(bi
->sizeImage_field
!=0) {
141 de_dbg(c
, "sizeImage: %u", (unsigned int)bi
->sizeImage_field
);
144 de_dbg(c
, "palette entries: %u", (unsigned int)bi
->pal_entries
);
145 if(bi
->pal_entries
>256 && bi
->bitcount
>8) {
146 de_warn(c
, "Ignoring bad palette size (%u entries)", (unsigned int)bi
->pal_entries
);
150 bi
->pal_bytes
= bi
->bytes_per_pal_entry
*bi
->pal_entries
;
151 bi
->size_of_headers_and_pal
= fhs
+ bi
->infohdrsize
+ bi
->pal_bytes
;
153 // FIXME: cmpr type 3 doesn't always mean BITFIELDS
154 if(bi
->compression_field
==3) {
155 bi
->size_of_headers_and_pal
+= 12; // BITFIELDS
158 bi
->is_compressed
= !((bi
->compression_field
==0) ||
159 (bi
->compression_field
==3 && bi
->bitcount
>1));
161 if(!de_good_image_dimensions(c
, bi
->width
, bi
->height
)) {
165 // TODO: This needs work, to decide how to handle compressed images.
166 // TODO: What about BI_BITFIELDS images?
167 if(bi
->compression_field
==0) {
168 // Try to figure out the true size of the resource, minus any padding.
170 bi
->rowspan
= ((bi
->bitcount
*bi
->width
+31)/32)*4;
171 bi
->foreground_size
= bi
->rowspan
* bi
->height
;
172 de_dbg(c
, "foreground size: %d", (int)bi
->foreground_size
);
174 if(flags
& DE_BMPINFO_ICO_FORMAT
) {
175 bi
->mask_rowspan
= ((bi
->width
+31)/32)*4;
176 bi
->mask_size
= bi
->mask_rowspan
* bi
->height
;
177 de_dbg(c
, "mask size: %d", (int)bi
->mask_size
);
183 bi
->total_size
= bi
->size_of_headers_and_pal
+ bi
->foreground_size
+ bi
->mask_size
;
186 // Don't try to figure out the true size of compressed or other unusual images.
187 bi
->total_size
= len
;
193 // TODO: Document and review whether the bi->total_size and
194 // bi->size_of_headers_and_pal fields include the 14-byte fileheader.
195 void fmtutil_generate_bmpfileheader(deark
*c
, dbuf
*outf
, const struct de_bmpinfo
*bi
,
196 i64 file_size_override
)
198 i64 file_size_to_write
;
200 dbuf_write(outf
, (const u8
*)"BM", 2);
202 if(file_size_override
)
203 file_size_to_write
= file_size_override
;
205 file_size_to_write
= 14 + bi
->total_size
;
206 dbuf_writeu32le(outf
, file_size_to_write
);
208 dbuf_write_zeroes(outf
, 4);
209 dbuf_writeu32le(outf
, 14 + bi
->size_of_headers_and_pal
);
212 // Extracts Exif if extract_level>=2, or "extractexif" option is set.
213 // Otherwise decodes.
214 void fmtutil_handle_exif2(deark
*c
, i64 pos
, i64 len
,
215 u32
*returned_flags
, u32
*orientation
, u32
*exifversion
)
218 de_module_params
*mparams
= NULL
;
224 user_opt
= de_get_ext_option_bool(c
, "extractexif", -1);
225 if(user_opt
==1 || (c
->extract_level
>=2 && user_opt
!=0)) {
226 // Writing raw Exif data isn't very useful, but do so if requested.
227 dbuf_create_file_from_slice(c
->infile
, pos
, len
, "exif.tif", NULL
, DE_CREATEFLAG_IS_AUX
);
229 // Caller will have to reprocess the Exif file to extract anything from it.
233 mparams
= de_malloc(c
, sizeof(de_module_params
));
234 mparams
->in_params
.codes
= "E";
236 de_run_module_by_id_on_slice(c
, "tiff", mparams
, c
->infile
, pos
, len
);
238 // FIXME: It's an unfortunate bug that returned_flags does not work if
239 // extract_level>=2, but for now there's no reasonable way to fix it.
240 // We have to process -- not extract -- the Exif chunk if we want to
241 // know what's in it.
242 *returned_flags
= mparams
->out_params
.flags
;
243 if((mparams
->out_params
.flags
& 0x20) && orientation
) {
244 *orientation
= mparams
->out_params
.uint1
;
247 if((mparams
->out_params
.flags
& 0x40) && exifversion
) {
248 *exifversion
= mparams
->out_params
.uint2
;
255 void fmtutil_handle_exif(deark
*c
, i64 pos
, i64 len
)
257 fmtutil_handle_exif2(c
, pos
, len
, NULL
, NULL
, NULL
);
260 static void wrap_in_tiff(deark
*c
, dbuf
*f
, i64 dpos
, i64 dlen
,
261 const char *swstring
, unsigned int tag
, const char *ext
, unsigned int createflags
);
263 // Either extract IPTC-IIM data to a file, or drill down into it.
265 // 0 = default behavior (currently: depends on c->extract_level and options)
266 // 2 = this came from our TIFF-encapsulated format
267 void fmtutil_handle_iptc(deark
*c
, dbuf
*f
, i64 pos
, i64 len
,
273 int extract_fmt
= 1; // 0=raw, 1=TIFF-wrapped
277 user_opt
= de_get_ext_option_bool(c
, "extractiptc", -1);
279 if(user_opt
==1 || (c
->extract_level
>=2 && user_opt
!=0)) {
283 // Avoid "extracting" in a way that would just recreate the exact same file.
293 de_run_module_by_id_on_slice(c
, "iptc", NULL
, f
, pos
, len
);
296 if(should_extract
&& extract_fmt
==0) {
297 dbuf_create_file_from_slice(f
, pos
, len
, "iptc", NULL
, DE_CREATEFLAG_IS_AUX
);
299 else if(should_extract
&& extract_fmt
==1) {
300 wrap_in_tiff(c
, f
, pos
, len
, "Deark extracted IPTC", 33723, "iptctiff",
301 DE_CREATEFLAG_IS_AUX
);
305 // If oparams is not NULL, if must be initialized by the caller. If the data is
306 // decoded, oparams will be used by the submodule, and values may be returned in
309 // 0 = default behavior (currently: always decode)
310 // 1 = always write to file
311 // 2 = this came from our TIFF-encapsulated format
312 void fmtutil_handle_photoshop_rsrc2(deark
*c
, dbuf
*f
, i64 pos
, i64 len
,
313 unsigned int flags
, struct de_module_out_params
*oparams
)
317 int extract_fmt
= 1; // 0=raw, 1=TIFF-wrapped
323 else if(de_get_ext_option_bool(c
, "extract8bim", 0)) {
327 // Avoid "extracting" in a way that would just recreate the exact same file.
337 de_module_params
*mparams
= NULL
;
339 mparams
= de_malloc(c
, sizeof(de_module_params
));
340 mparams
->in_params
.codes
= "R";
342 // Since mparams->out_params is an embedded struct, not a pointer,
343 // we have to copy oparam's fields to and from it.
344 mparams
->out_params
= *oparams
; // struct copy
346 de_run_module_by_id_on_slice(c
, "psd", mparams
, f
, pos
, len
);
348 *oparams
= mparams
->out_params
; // struct copy
353 if(should_extract
&& extract_fmt
==0) {
354 dbuf_create_file_from_slice(f
, pos
, len
, "8bim", NULL
, DE_CREATEFLAG_IS_AUX
);
356 else if(should_extract
&& extract_fmt
==1) {
357 wrap_in_tiff(c
, f
, pos
, len
, "Deark extracted 8BIM", 34377, "8bimtiff",
358 DE_CREATEFLAG_IS_AUX
);
362 void fmtutil_handle_photoshop_rsrc(deark
*c
, dbuf
*f
, i64 pos
, i64 len
,
365 fmtutil_handle_photoshop_rsrc2(c
, f
, pos
, len
, flags
, NULL
);
369 // 0 = default behavior (currently: decode unless -opt extractplist was used)
370 void fmtutil_handle_plist(deark
*c
, dbuf
*f
, i64 pos
, i64 len
,
371 de_finfo
*fi
, unsigned int flags
)
373 if(de_get_ext_option_bool(c
, "extractplist", 0)) {
374 dbuf_create_file_from_slice(f
, pos
, len
,
375 fi
?NULL
:"plist", fi
, DE_CREATEFLAG_IS_AUX
);
379 de_run_module_by_id_on_slice(c
, "plist", NULL
, f
, pos
, len
);
382 // Caller allocates sdd. It does not need to be initialized.
383 // flags: 0x1 = Print a debug message if signature is found.
384 int fmtutil_detect_SAUCE(deark
*c
, dbuf
*f
, struct de_SAUCE_detection_data
*sdd
,
387 de_zeromem(sdd
, sizeof(struct de_SAUCE_detection_data
));
388 if(f
->len
<128) return 0;
389 if(dbuf_memcmp(f
, f
->len
-128, "SAUCE00", 7)) return 0;
391 de_dbg(c
, "SAUCE metadata, signature at %"I64_FMT
, f
->len
-128);
394 sdd
->data_type
= dbuf_getbyte(f
, f
->len
-128+94);
395 sdd
->file_type
= dbuf_getbyte(f
, f
->len
-128+95);
396 return (int)sdd
->has_SAUCE
;
399 void fmtutil_handle_SAUCE(deark
*c
, dbuf
*f
, struct de_SAUCE_info
*si
)
401 de_module_params mparams
;
403 de_zeromem(&mparams
, sizeof(de_module_params
));
404 mparams
.out_params
.obj1
= (void*)si
;
405 de_run_module_by_id_on_slice(c
, "sauce", &mparams
, f
, 0, f
->len
);
408 struct de_SAUCE_info
*fmtutil_create_SAUCE(deark
*c
)
410 return de_malloc(c
, sizeof(struct de_SAUCE_info
));
413 void fmtutil_free_SAUCE(deark
*c
, struct de_SAUCE_info
*si
)
416 ucstring_destroy(si
->title
);
417 ucstring_destroy(si
->artist
);
418 ucstring_destroy(si
->organization
);
419 ucstring_destroy(si
->comment
);
423 // Helper functions for the "boxes" (or "atoms") format used by MP4, JPEG 2000, etc.
425 double dbuf_fmtutil_read_fixed_16_16(dbuf
*f
, i64 pos
)
428 n
= dbuf_geti32be(f
, pos
);
429 return ((double)n
)/65536.0;
432 static void do_box_sequence(deark
*c
, struct de_boxesctx
*bctx
,
433 i64 pos1
, i64 len
, i64 max_nboxes
, int level
);
435 // Make a printable version of a UUID (or a big-endian GUID).
436 // Caller supplies s.
437 void fmtutil_render_uuid(deark
*c
, const u8
*uuid
, char *s
, size_t s_len
)
439 de_snprintf(s
, s_len
, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
440 uuid
[0], uuid
[1], uuid
[2], uuid
[3], uuid
[4], uuid
[5], uuid
[6], uuid
[7],
441 uuid
[8], uuid
[9], uuid
[10], uuid
[11], uuid
[12], uuid
[13], uuid
[14], uuid
[15]);
444 // Swap some bytes to convert a (little-endian) GUID to a UUID, in-place
445 void fmtutil_guid_to_uuid(u8
*id
)
448 de_memcpy(tmp
, id
, 16);
449 id
[0] = tmp
[3]; id
[1] = tmp
[2]; id
[2] = tmp
[1]; id
[3] = tmp
[0];
450 id
[4] = tmp
[5]; id
[5] = tmp
[4];
451 id
[6] = tmp
[7]; id
[7] = tmp
[6];
454 #define DE_BOX_uuid 0x75756964U
456 static int do_box(deark
*c
, struct de_boxesctx
*bctx
, i64 pos
, i64 len
,
457 int level
, i64
*pbytes_consumed
)
460 i64 header_len
; // Not including UUIDs
461 i64 payload_len
; // Including UUIDs
463 struct de_fourcc box4cc
;
464 char uuid_string
[50];
467 struct de_boxdata
*parentbox
;
468 struct de_boxdata
*curbox
;
470 parentbox
= bctx
->curbox
;
471 bctx
->curbox
= de_malloc(c
, sizeof(struct de_boxdata
));
472 curbox
= bctx
->curbox
;
473 curbox
->parent
= parentbox
;
476 de_dbg(c
, "(ignoring %d extra bytes at %"I64_FMT
")", (int)len
, pos
);
480 size32
= dbuf_getu32be(bctx
->f
, pos
);
481 dbuf_read_fourcc(bctx
->f
, pos
+4, &box4cc
, 4, 0x0);
482 curbox
->boxtype
= box4cc
.id
;
486 payload_len
= size32
-8;
494 de_dbg(c
, "(ignoring %d extra bytes at %"I64_FMT
")", (int)len
, pos
);
498 size64
= dbuf_geti64be(bctx
->f
, pos
+8);
499 if(size64
<16) goto done
;
500 payload_len
= size64
-16;
503 de_err(c
, "Invalid or unsupported box format");
507 total_len
= header_len
+ payload_len
;
509 if(curbox
->boxtype
==DE_BOX_uuid
&& payload_len
>=16) {
511 dbuf_read(bctx
->f
, curbox
->uuid
, pos
+header_len
, 16);
514 curbox
->level
= level
;
515 curbox
->box_pos
= pos
;
516 curbox
->box_len
= total_len
;
517 curbox
->payload_pos
= pos
+header_len
;
518 curbox
->payload_len
= payload_len
;
519 if(curbox
->is_uuid
) {
520 curbox
->payload_pos
+= 16;
521 curbox
->payload_len
-= 16;
524 if(bctx
->identify_box_fn
) {
525 bctx
->identify_box_fn(c
, bctx
);
528 if(c
->debug_level
>0) {
531 if(curbox
->box_name
) {
532 de_snprintf(name_str
, sizeof(name_str
), " (%s)", curbox
->box_name
);
538 if(curbox
->is_uuid
) {
539 fmtutil_render_uuid(c
, curbox
->uuid
, uuid_string
, sizeof(uuid_string
));
540 de_dbg(c
, "box '%s'{%s}%s at %"I64_FMT
", len=%"I64_FMT
,
541 box4cc
.id_dbgstr
, uuid_string
, name_str
,
545 de_dbg(c
, "box '%s'%s at %"I64_FMT
", len=%"I64_FMT
", dlen=%"I64_FMT
,
546 box4cc
.id_dbgstr
, name_str
, pos
,
547 total_len
, payload_len
);
551 if(total_len
> len
) {
552 de_err(c
, "Invalid oversized box, or unexpected end of file "
553 "(box at %"I64_FMT
" ends at %"I64_FMT
", "
554 "parent ends at %"I64_FMT
")",
555 pos
, pos
+total_len
, pos
+len
);
560 ret
= bctx
->handle_box_fn(c
, bctx
);
561 de_dbg_indent(c
, -1);
564 if(curbox
->is_superbox
) {
565 i64 children_pos
, children_len
;
569 children_pos
= curbox
->payload_pos
+ curbox
->extra_bytes_before_children
;
570 children_len
= curbox
->payload_len
- curbox
->extra_bytes_before_children
;
571 max_nchildren
= (curbox
->num_children_is_known
) ? curbox
->num_children
: -1;
572 do_box_sequence(c
, bctx
, children_pos
, children_len
, max_nchildren
, level
+1);
573 de_dbg_indent(c
, -1);
576 *pbytes_consumed
= total_len
;
580 de_free(c
, bctx
->curbox
);
581 bctx
->curbox
= parentbox
; // Restore the curbox pointer
585 // max_nboxes: -1 = no maximum
586 static void do_box_sequence(deark
*c
, struct de_boxesctx
*bctx
,
587 i64 pos1
, i64 len
, i64 max_nboxes
, int level
)
595 if(level
>= 32) { // An arbitrary recursion limit.
602 while(pos
< endpos
) {
603 if(max_nboxes
>=0 && box_count
>=max_nboxes
) break;
604 ret
= do_box(c
, bctx
, pos
, endpos
-pos
, level
, &box_len
);
611 // Handle some box types that might be common to multiple formats.
612 // This function should be called as needed by the client's box handler function.
613 // TODO: A way to identify (name) the boxes that we handle here.
614 int fmtutil_default_box_handler(deark
*c
, struct de_boxesctx
*bctx
)
616 struct de_boxdata
*curbox
= bctx
->curbox
;
618 if(curbox
->is_uuid
) {
619 if(!de_memcmp(curbox
->uuid
, "\xb1\x4b\xf8\xbd\x08\x3d\x4b\x43\xa5\xae\x8c\xd7\xd5\xa6\xce\x03", 16)) {
620 de_dbg(c
, "GeoTIFF data at %"I64_FMT
", len=%"I64_FMT
, curbox
->payload_pos
, curbox
->payload_len
);
621 dbuf_create_file_from_slice(bctx
->f
, curbox
->payload_pos
, curbox
->payload_len
, "geo.tif", NULL
, DE_CREATEFLAG_IS_AUX
);
623 else if(!de_memcmp(curbox
->uuid
, "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac", 16)) {
624 de_dbg(c
, "XMP data at %"I64_FMT
", len=%"I64_FMT
, curbox
->payload_pos
, curbox
->payload_len
);
625 dbuf_create_file_from_slice(bctx
->f
, curbox
->payload_pos
, curbox
->payload_len
, "xmp", NULL
, DE_CREATEFLAG_IS_AUX
);
627 else if(!de_memcmp(curbox
->uuid
, "\x2c\x4c\x01\x00\x85\x04\x40\xb9\xa0\x3e\x56\x21\x48\xd6\xdf\xeb", 16)) {
628 de_dbg(c
, "Photoshop resources at %"I64_FMT
", len=%"I64_FMT
, curbox
->payload_pos
, curbox
->payload_len
);
630 fmtutil_handle_photoshop_rsrc(c
, bctx
->f
, curbox
->payload_pos
, curbox
->payload_len
, 0x0);
631 de_dbg_indent(c
, -1);
633 else if(!de_memcmp(curbox
->uuid
, "\x05\x37\xcd\xab\x9d\x0c\x44\x31\xa7\x2a\xfa\x56\x1f\x2a\x11\x3e", 16) ||
634 !de_memcmp(curbox
->uuid
, "JpgTiffExif->JP2", 16))
636 de_dbg(c
, "Exif data at %"I64_FMT
", len=%"I64_FMT
, curbox
->payload_pos
, curbox
->payload_len
);
638 fmtutil_handle_exif(c
, curbox
->payload_pos
, curbox
->payload_len
);
639 de_dbg_indent(c
, -1);
645 void fmtutil_read_boxes_format(deark
*c
, struct de_boxesctx
*bctx
)
647 if(!bctx
->f
|| !bctx
->handle_box_fn
) return; // Internal error
648 if(bctx
->curbox
) return; // Internal error
649 do_box_sequence(c
, bctx
, 0, bctx
->f
->len
, -1, 0);
652 static u8
scale_7_to_255(u8 x
)
654 return (u8
)(0.5+(((double)x
)*(255.0/7.0)));
657 static u8
scale_15_to_255(u8 x
)
662 void fmtutil_read_atari_palette(deark
*c
, dbuf
*f
, i64 pos
,
663 de_color
*dstpal
, i64 ncolors_to_read
, i64 ncolors_used
, unsigned int flags
)
667 int pal_bits
= 0; // 9, 12, or 15. 0 = not yet determined
674 s
= de_get_ext_option(c
, "atari:palbits");
676 pal_bits
= de_atoi(s
);
679 if(pal_bits
==0 && (flags
&DE_FLAG_ATARI_15BIT_PAL
)) {
684 // Pre-scan the palette, and try to guess whether Atari STE-style 12-bit
685 // colors are used, instead of the usual 9-bit colors.
686 // I don't know the best way to do this. Sometimes the 4th bit in each
687 // nibble is used for extra color detail, and sometimes it just seems to
688 // contain garbage. Maybe the logic should also depend on the file
689 // format, or the number of colors.
691 int nibble_3_used
= 0;
693 for(i
=0; i
<ncolors_to_read
; i
++) {
694 n
= (unsigned int)dbuf_getu16be(f
, pos
+ i
*2);
703 if(bit_3_used
&& !nibble_3_used
) {
704 de_dbg(c
, "12-bit palette colors detected");
709 if(pal_bits
<12) { // Default to 9 if <12
712 else if(pal_bits
<15) {
719 for(i
=0; i
<ncolors_to_read
; i
++) {
720 n
= (unsigned int)dbuf_getu16be(f
, pos
+ 2*i
);
723 cr1
= (u8
)((n
>>6)&0x1c);
726 cg1
= (u8
)((n
>>2)&0x1c);
729 cb1
= (u8
)((n
<<2)&0x1c);
732 cr
= de_scale_n_to_255(31, cr1
);
733 cg
= de_scale_n_to_255(31, cg1
);
734 cb
= de_scale_n_to_255(31, cb1
);
735 de_snprintf(cbuf
, sizeof(cbuf
), "%2d,%2d,%2d",
736 (int)cr1
, (int)cg1
, (int)cb1
);
738 else if(pal_bits
==12) {
739 cr1
= (u8
)((n
>>7)&0x0e);
741 cg1
= (u8
)((n
>>3)&0x0e);
743 cb1
= (u8
)((n
<<1)&0x0e);
745 cr
= scale_15_to_255(cr1
);
746 cg
= scale_15_to_255(cg1
);
747 cb
= scale_15_to_255(cb1
);
748 de_snprintf(cbuf
, sizeof(cbuf
), "%2d,%2d,%2d",
749 (int)cr1
, (int)cg1
, (int)cb1
);
752 cr1
= (u8
)((n
>>8)&0x07);
753 cg1
= (u8
)((n
>>4)&0x07);
755 cr
= scale_7_to_255(cr1
);
756 cg
= scale_7_to_255(cg1
);
757 cb
= scale_7_to_255(cb1
);
758 de_snprintf(cbuf
, sizeof(cbuf
), "%d,%d,%d",
759 (int)cr1
, (int)cg1
, (int)cb1
);
762 dstpal
[i
] = DE_MAKE_RGB(cr
, cg
, cb
);
763 de_snprintf(tmps
, sizeof(tmps
), "0x%04x (%s) "DE_CHAR_RIGHTARROW
" ", n
, cbuf
);
764 de_dbg_pal_entry2(c
, i
, dstpal
[i
], tmps
, NULL
,
765 (i
>=ncolors_used
)?" [unused]":"");
770 * Given an x-coordinate and a color index, returns the corresponding
771 * Spectrum palette index.
773 * by Steve Belczyk; placed in the public domain December, 1990.
774 * [Adapted for Deark.]
776 static unsigned int spectrum512_FindIndex(i64 x
, unsigned int c
)
782 if (c
& 1) /* If c is odd */
784 else /* If c is even */
787 if (x
>= x1
&& x
< x1
+160)
789 else if (x
>= x1
+160)
795 static int decode_atari_image_paletted(deark
*c
, struct atari_img_decode_data
*adata
)
805 planespan
= 2*((adata
->w
+15)/16);
806 rowspan
= planespan
*adata
->bpp
;
808 ncolors
= adata
->ncolors
;
810 ncolors
= ((i64
)1)<<adata
->bpp
;
812 for(j
=0; j
<adata
->h
; j
++) {
813 for(i
=0; i
<adata
->w
; i
++) {
816 for(plane
=0; plane
<adata
->bpp
; plane
++) {
817 if(adata
->was_compressed
==0) {
818 // TODO: Simplify this.
820 b
= de_get_bits_symbol(adata
->unc_pixels
, 1, j
*rowspan
, i
);
822 else if(adata
->bpp
==2) {
823 b
= de_get_bits_symbol(adata
->unc_pixels
, 1,
824 j
*rowspan
+ 2*plane
+ (i
/16)*2, i
);
826 else if(adata
->bpp
==4) {
827 b
= de_get_bits_symbol(adata
->unc_pixels
, 1,
828 j
*rowspan
+ 2*plane
+ (i
/2-(i
/2)%16)+8*((i
%32)/16), i
%16);
830 else if(adata
->bpp
==8) {
831 b
= de_get_bits_symbol(adata
->unc_pixels
, 1,
832 j
*rowspan
+ 2*plane
+ (i
-i
%16), i
%16);
839 b
= de_get_bits_symbol(adata
->unc_pixels
, 1, j
*rowspan
+ plane
*planespan
, i
);
844 if(adata
->is_spectrum512
) {
845 v
= spectrum512_FindIndex(i
, v
);
847 v
+= (unsigned int)(48*(j
));
850 if(v
>=(unsigned int)ncolors
) v
=(unsigned int)(ncolors
-1);
852 de_bitmap_setpixel_rgb(adata
->img
, i
, j
, adata
->pal
[v
]);
858 static int decode_atari_image_16(deark
*c
, struct atari_img_decode_data
*adata
)
864 rowspan
= adata
->w
* 2;
866 for(j
=0; j
<adata
->h
; j
++) {
867 for(i
=0; i
<adata
->w
; i
++) {
868 v
= (u32
)dbuf_getu16be(adata
->unc_pixels
, j
*rowspan
+ 2*i
);
869 v
= de_rgb565_to_888(v
);
870 de_bitmap_setpixel_rgb(adata
->img
, i
, j
,v
);
876 int fmtutil_atari_decode_image(deark
*c
, struct atari_img_decode_data
*adata
)
880 return decode_atari_image_16(c
, adata
);
881 case 8: case 4: case 2: case 1:
882 return decode_atari_image_paletted(c
, adata
);
885 de_err(c
, "Unsupported bits/pixel (%d)", (int)adata
->bpp
);
889 void fmtutil_atari_set_standard_density(deark
*c
, struct atari_img_decode_data
*adata
,
894 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
895 fi
->density
.xdens
= 240.0;
896 fi
->density
.ydens
= 200.0;
899 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
900 fi
->density
.xdens
= 480.0;
901 fi
->density
.ydens
= 200.0;
904 fi
->density
.code
= DE_DENSITY_UNK_UNITS
;
905 fi
->density
.xdens
= 480.0;
906 fi
->density
.ydens
= 400.0;
911 void fmtutil_atari_help_palbits(deark
*c
)
913 de_msg(c
, "-opt atari:palbits=<9|12|15> : Numer of significant bits "
914 "per palette color");
917 #define CODE__c_ 0x28632920U // "(c) "
918 #define CODE_ANNO 0x414e4e4fU
919 #define CODE_AUTH 0x41555448U
920 #define CODE_NAME 0x4e414d45U
921 #define CODE_TEXT 0x54455854U
922 #define CODE_RIFF 0x52494646U
924 static void do_iff_text_chunk(deark
*c
, struct de_iffctx
*ictx
, i64 dpos
, i64 dlen
,
927 de_ucstring
*s
= NULL
;
930 s
= ucstring_create(c
);
931 dbuf_read_to_ucstring_n(ictx
->f
,
932 dpos
, dlen
, DE_DBG_MAX_STRLEN
,
933 s
, DE_CONVFLAG_STOP_AT_NUL
, ictx
->input_encoding
);
934 de_dbg(c
, "%s: \"%s\"", name
, ucstring_getpsz(s
));
938 static void do_iff_anno(deark
*c
, struct de_iffctx
*ictx
, i64 pos
, i64 len
)
944 // Some ANNO chunks seem to be padded with one or more NUL bytes. Probably
945 // best not to save them.
946 if(dbuf_search_byte(ictx
->f
, 0x00, pos
, len
, &foundpos
)) {
947 len
= foundpos
- pos
;
950 if(c
->extract_level
>=2) {
951 dbuf_create_file_from_slice(ictx
->f
, pos
, len
, "anno.txt", NULL
, DE_CREATEFLAG_IS_AUX
);
954 de_ucstring
*s
= NULL
;
955 s
= ucstring_create(c
);
956 dbuf_read_to_ucstring_n(ictx
->f
, pos
, len
, DE_DBG_MAX_STRLEN
, s
, 0, ictx
->input_encoding
);
957 de_dbg(c
, "annotation: \"%s\"", ucstring_getpsz(s
));
962 void fmtutil_default_iff_chunk_identify(deark
*c
, struct de_iffctx
*ictx
)
964 const char *name
= NULL
;
966 switch(ictx
->chunkctx
->chunk4cc
.id
) {
967 case CODE__c_
: name
="copyright"; break;
968 case CODE_ANNO
: name
="annotation"; break;
969 case CODE_AUTH
: name
="author"; break;
973 ictx
->chunkctx
->chunk_name
= name
;
977 // Note that some of these chunks are *not* defined in the generic IFF
979 // They might be defined in the 8SVX specification. They seem to have
980 // become unofficial standard chunks.
981 static int de_fmtutil_default_iff_chunk_handler(deark
*c
, struct de_iffctx
*ictx
)
983 i64 dpos
= ictx
->chunkctx
->dpos
;
984 i64 dlen
= ictx
->chunkctx
->dlen
;
985 u32 chunktype
= ictx
->chunkctx
->chunk4cc
.id
;
988 // Note that chunks appearing here should also be listed below,
989 // in de_fmtutil_is_standard_iff_chunk().
991 do_iff_text_chunk(c
, ictx
, dpos
, dlen
, "copyright");
994 do_iff_anno(c
, ictx
, dpos
, dlen
);
997 do_iff_text_chunk(c
, ictx
, dpos
, dlen
, "author");
1000 do_iff_text_chunk(c
, ictx
, dpos
, dlen
, "name");
1003 do_iff_text_chunk(c
, ictx
, dpos
, dlen
, "text");
1007 // Note we do not set ictx->handled. The caller is responsible for that.
1012 int fmtutil_is_standard_iff_chunk(deark
*c
, struct de_iffctx
*ictx
,
1026 static void fourcc_clear(struct de_fourcc
*fourcc
)
1028 de_zeromem(fourcc
, sizeof(struct de_fourcc
));
1031 static int do_iff_chunk_sequence(deark
*c
, struct de_iffctx
*ictx
,
1032 i64 pos1
, i64 len
, int level
);
1034 // Returns 0 if we can't continue
1035 static int do_iff_chunk(deark
*c
, struct de_iffctx
*ictx
, i64 pos
, i64 bytes_avail
,
1036 int level
, i64
*pbytes_consumed
)
1040 i64 chunk_dlen_padded
;
1041 i64 data_bytes_avail
;
1043 struct de_iffchunkctx chunkctx
;
1044 int saved_indent_level
;
1048 de_zeromem(&chunkctx
, sizeof(struct de_iffchunkctx
));
1050 de_dbg_indent_save(c
, &saved_indent_level
);
1052 hdrsize
= 4+ictx
->sizeof_len
;
1053 if(bytes_avail
<hdrsize
) {
1054 de_warn(c
, "Ignoring %"I64_FMT
" bytes at %"I64_FMT
"; too small "
1055 "to be a chunk", bytes_avail
, pos
);
1058 data_bytes_avail
= bytes_avail
-hdrsize
;
1060 dbuf_read_fourcc(ictx
->f
, pos
, &chunkctx
.chunk4cc
, 4,
1061 ictx
->reversed_4cc
? DE_4CCFLAG_REVERSED
: 0x0);
1062 if(chunkctx
.chunk4cc
.id
==0 && level
==0) {
1063 de_warn(c
, "Chunk ID not found at %"I64_FMT
"; assuming the data ends "
1068 if(ictx
->sizeof_len
==2) {
1069 chunk_dlen_raw
= dbuf_getu16x(ictx
->f
, pos
+4, ictx
->is_le
);
1072 chunk_dlen_raw
= dbuf_getu32x(ictx
->f
, pos
+4, ictx
->is_le
);
1074 chunkctx
.dlen
= chunk_dlen_raw
;
1075 chunkctx
.dpos
= pos
+hdrsize
;
1077 // TODO: Setting these fields (prior to the identify function) is enough
1078 // for now, but we should also set the other fields here if we can.
1079 ictx
->level
= level
;
1080 ictx
->chunkctx
= &chunkctx
;
1082 if(ictx
->preprocess_chunk_fn
) {
1083 ictx
->preprocess_chunk_fn(c
, ictx
);
1086 if(chunkctx
.chunk_name
) {
1087 de_snprintf(name_str
, sizeof(name_str
), " (%s)", chunkctx
.chunk_name
);
1093 de_dbg(c
, "chunk '%s'%s at %"I64_FMT
", dpos=%"I64_FMT
", dlen=%"I64_FMT
,
1094 chunkctx
.chunk4cc
.id_dbgstr
, name_str
, pos
,
1095 chunkctx
.dpos
, chunkctx
.dlen
);
1096 de_dbg_indent(c
, 1);
1098 if(chunkctx
.dlen
> data_bytes_avail
) {
1099 int should_warn
= 1;
1101 if(chunkctx
.chunk4cc
.id
==CODE_RIFF
&& pos
==0 && bytes_avail
==ictx
->f
->len
) {
1103 // This apparent error, in which the RIFF chunk's length field gives the
1104 // length of the entire file, is too common (particularly in .ani files)
1110 de_warn(c
, "Invalid oversized chunk, or unexpected end of file "
1111 "(chunk at %d ends at %" I64_FMT
", "
1112 "parent ends at %" I64_FMT
")",
1113 (int)pos
, chunkctx
.dlen
+chunkctx
.dpos
, pos
+bytes_avail
);
1116 chunkctx
.dlen
= data_bytes_avail
; // Try to continue
1117 de_dbg(c
, "adjusting chunk data len to %"I64_FMT
, chunkctx
.dlen
);
1120 chunk_dlen_padded
= de_pad_to_n(chunkctx
.dlen
, ictx
->alignment
);
1121 *pbytes_consumed
= hdrsize
+ chunk_dlen_padded
;
1123 // We've set *pbytes_consumed, so we can return "success"
1126 // Set ictx fields, prior to calling the handler
1128 chunkctx
.len
= bytes_avail
;
1130 ictx
->is_std_container
= 0;
1131 ictx
->is_raw_container
= 0;
1133 ret
= ictx
->handle_chunk_fn(c
, ictx
);
1139 if(ictx
->is_std_container
|| ictx
->is_raw_container
) {
1140 i64 contents_dpos
, contents_dlen
;
1142 ictx
->chunkctx
= NULL
;
1143 ictx
->curr_container_fmt4cc
= chunkctx
.chunk4cc
;
1144 fourcc_clear(&ictx
->curr_container_contentstype4cc
);
1146 if(ictx
->is_std_container
) {
1147 contents_dpos
= chunkctx
.dpos
+4;
1148 contents_dlen
= chunkctx
.dlen
-4;
1150 // First 4 bytes of payload are the "contents type" or "FORM type"
1151 dbuf_read_fourcc(ictx
->f
, chunkctx
.dpos
, &ictx
->curr_container_contentstype4cc
, 4,
1152 ictx
->reversed_4cc
? DE_4CCFLAG_REVERSED
: 0);
1155 ictx
->main_fmt4cc
= ictx
->curr_container_fmt4cc
;
1156 ictx
->main_contentstype4cc
= ictx
->curr_container_contentstype4cc
; // struct copy
1158 de_dbg(c
, "contents type: '%s'", ictx
->curr_container_contentstype4cc
.id_dbgstr
);
1160 if(ictx
->on_std_container_start_fn
) {
1161 // Call only for standard-format containers.
1162 ret
= ictx
->on_std_container_start_fn(c
, ictx
);
1166 else { // ictx->is_raw_container
1167 contents_dpos
= chunkctx
.dpos
;
1168 contents_dlen
= chunkctx
.dlen
;
1171 ret
= do_iff_chunk_sequence(c
, ictx
, contents_dpos
, contents_dlen
, level
+1);
1177 if(ictx
->on_container_end_fn
) {
1178 // Call for all containers (not just standard-format containers).
1180 // TODO: Decide exactly what ictx->* fields to set here.
1181 ictx
->level
= level
;
1183 ictx
->chunkctx
= NULL
;
1184 ret
= ictx
->on_container_end_fn(c
, ictx
);
1191 else if(!ictx
->handled
) {
1192 de_fmtutil_default_iff_chunk_handler(c
, ictx
);
1196 fourcc_clear(&ictx
->curr_container_fmt4cc
);
1197 fourcc_clear(&ictx
->curr_container_contentstype4cc
);
1199 de_dbg_indent_restore(c
, saved_indent_level
);
1203 static int do_iff_chunk_sequence(deark
*c
, struct de_iffctx
*ictx
,
1204 i64 pos1
, i64 len
, int level
)
1209 struct de_fourcc saved_container_fmt4cc
;
1210 struct de_fourcc saved_container_contentstype4cc
;
1213 if(level
>= 16) { // An arbitrary recursion limit.
1218 saved_container_fmt4cc
= ictx
->curr_container_fmt4cc
;
1219 saved_container_contentstype4cc
= ictx
->curr_container_contentstype4cc
;
1222 while(pos
< endpos
) {
1223 ictx
->curr_container_fmt4cc
= saved_container_fmt4cc
;
1224 ictx
->curr_container_contentstype4cc
= saved_container_contentstype4cc
;
1226 if(ictx
->handle_nonchunk_data_fn
) {
1228 ret
= ictx
->handle_nonchunk_data_fn(c
, ictx
, pos
, &skip_len
);
1229 if(ret
&& skip_len
>0) {
1230 pos
+= de_pad_to_n(skip_len
, ictx
->alignment
);
1235 ret
= do_iff_chunk(c
, ictx
, pos
, endpos
-pos
, level
, &chunk_len
);
1240 ictx
->curr_container_fmt4cc
= saved_container_fmt4cc
;
1241 ictx
->curr_container_contentstype4cc
= saved_container_contentstype4cc
;
1246 void fmtutil_read_iff_format(deark
*c
, struct de_iffctx
*ictx
,
1249 if(!ictx
->f
|| !ictx
->handle_chunk_fn
) return; // Internal error
1252 fourcc_clear(&ictx
->main_fmt4cc
);
1253 fourcc_clear(&ictx
->main_contentstype4cc
);
1254 fourcc_clear(&ictx
->curr_container_fmt4cc
);
1255 fourcc_clear(&ictx
->curr_container_contentstype4cc
);
1256 if(ictx
->alignment
==0) {
1257 ictx
->alignment
= 2;
1259 if(ictx
->sizeof_len
==0) {
1260 ictx
->sizeof_len
= 4;
1263 if(ictx
->input_encoding
==DE_ENCODING_UNKNOWN
) {
1264 ictx
->input_encoding
= DE_ENCODING_ASCII
;
1267 do_iff_chunk_sequence(c
, ictx
, pos
, len
, 0);
1270 const char *fmtutil_tiff_orientation_name(i64 n
)
1272 static const char *names
[9] = {
1273 "?", "top-left", "top-right", "bottom-right", "bottom-left",
1274 "left-top", "right-top", "right-bottom", "left-bottom"
1276 if(n
>=1 && n
<=8) return names
[n
];
1280 const char *fmtutil_get_windows_charset_name(u8 cs
)
1282 struct csname_struct
{ u8 id
; const char *name
; };
1283 static const struct csname_struct csname_arr
[] = {
1288 {0x80, "Shift-JIS"},
1295 {0xa3, "Vietnamese"},
1301 {0xee, "Eastern Europe"},
1306 for(i
=0; i
<DE_ARRAYCOUNT(csname_arr
); i
++) {
1307 if(cs
==csname_arr
[i
].id
) return csname_arr
[i
].name
;
1312 const char *fmtutil_get_windows_cb_data_type_name(unsigned int ty
)
1314 const char *name
= "?";
1317 case 1: name
="CF_TEXT"; break;
1318 case 2: name
="CF_BITMAP"; break;
1319 case 3: name
="CF_METAFILEPICT"; break;
1320 case 6: name
="CF_TIFF"; break;
1321 case 7: name
="CF_OEMTEXT"; break;
1322 case 8: name
="CF_DIB"; break;
1323 case 11: name
="CF_RIFF"; break;
1324 case 12: name
="CF_WAVE"; break;
1325 case 13: name
="CF_UNICODETEXT"; break;
1326 case 14: name
="CF_ENHMETAFILE"; break;
1327 case 17: name
="CF_DIBV5"; break;
1332 // Search for the ZIP "end of central directory" object.
1333 // Also useful for detecting hybrid ZIP files, such as self-extracting EXE.
1334 int fmtutil_find_zip_eocd(deark
*c
, dbuf
*f
, i64
*foundpos
)
1344 if(f
->len
< 22) goto done
;
1346 // End-of-central-dir record usually starts 22 bytes from EOF. Try that first.
1347 sig
= (u32
)dbuf_getu32le(f
, f
->len
- 22);
1348 if(sig
== 0x06054b50U
) {
1349 *foundpos
= f
->len
- 22;
1354 // Search for the signature.
1355 // The end-of-central-directory record could theoretically appear anywhere
1356 // in the file. We'll follow Info-Zip/UnZip's lead and search the last 66000
1358 #define MAX_ZIP_EOCD_SEARCH 66000
1360 if(buf_size
> MAX_ZIP_EOCD_SEARCH
) buf_size
= MAX_ZIP_EOCD_SEARCH
;
1362 buf
= de_malloc(c
, buf_size
);
1363 buf_offset
= f
->len
- buf_size
;
1364 dbuf_read(f
, buf
, buf_offset
, buf_size
);
1366 for(i
=buf_size
-22; i
>=0; i
--) {
1367 if(buf
[i
]=='P' && buf
[i
+1]=='K' && buf
[i
+2]==5 && buf
[i
+3]==6) {
1368 *foundpos
= buf_offset
+ i
;
1379 // Quick & dirty encoder that can wrap some formats in a TIFF container.
1380 static void wrap_in_tiff(deark
*c
, dbuf
*f
, i64 dpos
, i64 dlen
,
1381 const char *swstring
, unsigned int tag
, const char *ext
, unsigned int createflags
)
1385 i64 sw_len
, sw_len_padded
;
1386 i64 data_len_padded
;
1388 sw_len
= 1+(i64
)de_strlen(swstring
);
1389 if(sw_len
<=4) return;
1390 sw_len_padded
= de_pad_to_2(sw_len
);
1393 data_len_padded
= de_pad_to_2(dlen
);
1396 data_len_padded
= 0;
1399 outf
= dbuf_create_output_file(c
, ext
, NULL
, 0);
1400 dbuf_write(outf
, (const u8
*)"\x4d\x4d\x00\x2a", 4);
1401 ifdoffs
= 8 + sw_len_padded
+ data_len_padded
;
1402 dbuf_writeu32be(outf
, ifdoffs
);
1403 dbuf_write(outf
, (const u8
*)swstring
, sw_len
);
1404 if(sw_len
%2) dbuf_writebyte(outf
, 0);
1406 dbuf_copy(f
, dpos
, dlen
, outf
);
1407 if(dlen
%2) dbuf_writebyte(outf
, 0);
1410 dbuf_writeu16be(outf
, 2); // number of dir entries;
1412 dbuf_writeu16be(outf
, 305); // Software tag
1413 dbuf_writeu16be(outf
, 2); // type=ASCII
1414 dbuf_writeu32be(outf
, sw_len
);
1415 dbuf_writeu32be(outf
, 8); // offset
1417 dbuf_writeu16be(outf
, (i64
)tag
);
1418 dbuf_writeu16be(outf
, 1);
1419 dbuf_writeu32be(outf
, dlen
);
1421 dbuf_writeu32be(outf
, 8+sw_len_padded
);
1424 dbuf_copy(f
, dpos
, dlen
, outf
);
1425 dbuf_write_zeroes(outf
, 4-dlen
);
1428 dbuf_writeu32be(outf
, 0); // end of IFD
1432 // Find ID3 tag data at the beginning and end of file, process it, and return
1433 // information about its location.
1434 // Caller allocates id3i.
1435 void fmtutil_handle_id3(deark
*c
, dbuf
*f
, struct de_id3info
*id3i
,
1441 de_zeromem(id3i
, sizeof(struct de_id3info
));
1442 id3i
->main_start
= 0;
1443 id3i
->main_end
= f
->len
;
1445 id3i
->has_id3v2
= !dbuf_memcmp(f
, 0, "ID3", 3);
1446 if(id3i
->has_id3v2
) {
1447 de_module_params id3v2mparams
;
1449 de_dbg(c
, "ID3v2 data at %d", 0);
1450 de_dbg_indent(c
, 1);
1451 de_zeromem(&id3v2mparams
, sizeof(de_module_params
));
1452 id3v2mparams
.in_params
.codes
= "I";
1453 de_run_module_by_id_on_slice(c
, "id3", &id3v2mparams
, f
, 0, f
->len
);
1454 de_dbg_indent(c
, -1);
1455 id3i
->main_start
+= id3v2mparams
.out_params
.int64_1
;
1459 if(look_for_id3v1
) {
1460 id3v1pos
= f
->len
-128;
1461 if(!dbuf_memcmp(f
, id3v1pos
, "TAG", 3)) {
1462 id3i
->has_id3v1
= 1;
1466 if(id3i
->has_id3v1
) {
1467 de_module_params id3v1mparams
;
1469 de_dbg(c
, "ID3v1 data at %"I64_FMT
, id3v1pos
);
1470 de_dbg_indent(c
, 1);
1471 de_zeromem(&id3v1mparams
, sizeof(de_module_params
));
1472 id3v1mparams
.in_params
.codes
= "1";
1473 de_run_module_by_id_on_slice(c
, "id3", &id3v1mparams
, f
, id3v1pos
, 128);
1474 de_dbg_indent(c
, -1);
1475 id3i
->main_end
= id3v1pos
;
1479 static void dbg_timestamp(deark
*c
, struct de_timestamp
*ts
, const char *name
)
1481 char timestamp_buf
[64];
1483 de_timestamp_to_string(ts
, timestamp_buf
, sizeof(timestamp_buf
), 0);
1484 de_dbg(c
, "%s: %s", name
, timestamp_buf
);
1487 void fmtutil_riscos_read_load_exec(deark
*c
, dbuf
*f
, struct de_riscos_file_attrs
*rfa
, i64 pos1
)
1491 rfa
->load_addr
= (u32
)dbuf_getu32le_p(f
, &pos
);
1492 rfa
->exec_addr
= (u32
)dbuf_getu32le_p(f
, &pos
);
1493 de_dbg(c
, "load/exec addrs: 0x%08x, 0x%08x", (unsigned int)rfa
->load_addr
,
1494 (unsigned int)rfa
->exec_addr
);
1495 de_dbg_indent(c
, 1);
1496 if((rfa
->load_addr
&0xfff00000U
)==0xfff00000U
) {
1497 rfa
->file_type
= (unsigned int)((rfa
->load_addr
&0xfff00)>>8);
1498 rfa
->file_type_known
= 1;
1499 de_dbg(c
, "file type: %03X", rfa
->file_type
);
1501 de_riscos_loadexec_to_timestamp(rfa
->load_addr
, rfa
->exec_addr
, &rfa
->mod_time
);
1502 dbg_timestamp(c
, &rfa
->mod_time
, "timestamp");
1504 de_dbg_indent(c
, -1);
1507 void fmtutil_riscos_read_attribs_field(deark
*c
, dbuf
*f
, struct de_riscos_file_attrs
*rfa
,
1508 i64 pos
, unsigned int flags
)
1510 rfa
->attribs
= (u32
)dbuf_getu32le(f
, pos
);
1511 de_dbg(c
, "attribs: 0x%08x", (unsigned int)rfa
->attribs
);
1512 de_dbg_indent(c
, 1);
1513 rfa
->crc_from_attribs
= rfa
->attribs
>>16;
1514 if(flags
& DE_RISCOS_FLAG_HAS_CRC
) {
1515 de_dbg(c
, "crc (reported): 0x%04x", (unsigned int)rfa
->crc_from_attribs
);
1517 if(flags
& DE_RISCOS_FLAG_HAS_LZWMAXBITS
) {
1518 rfa
->lzwmaxbits
= (unsigned int)((rfa
->attribs
&0xff00)>>8);
1519 de_dbg(c
, "lzw maxbits: %u", rfa
->lzwmaxbits
);
1521 de_dbg_indent(c
, -1);
1528 // Note: Code duplicated in pict.c
1529 static double pict_read_fixed(dbuf
*f
, i64 pos
)
1533 // I think QuickDraw's "Fixed point" numbers are signed, but I don't know
1534 // how negative numbers are handled.
1535 n
= dbuf_geti32be(f
, pos
);
1536 return ((double)n
)/65536.0;
1539 // Read a QuickDraw Rectangle. Caller supplies rect struct.
1540 // Note: Code duplicated in pict.c
1541 static void pict_read_rect(dbuf
*f
, i64 pos
,
1542 struct pict_rect
*rect
, const char *dbgname
)
1544 rect
->t
= dbuf_geti16be(f
, pos
);
1545 rect
->l
= dbuf_geti16be(f
, pos
+2);
1546 rect
->b
= dbuf_geti16be(f
, pos
+4);
1547 rect
->r
= dbuf_geti16be(f
, pos
+6);
1550 de_dbg(f
->c
, "%s: (%d,%d)-(%d,%d)", dbgname
, (int)rect
->l
, (int)rect
->t
,
1551 (int)rect
->r
, (int)rect
->b
);
1555 // Sometimes-present baseAddr field (4 bytes)
1556 void fmtutil_macbitmap_read_baseaddr(deark
*c
, dbuf
*f
, struct fmtutil_macbitmap_info
*bi
, i64 pos
)
1559 de_dbg(c
, "baseAddr part of PixMap, at %d", (int)pos
);
1560 de_dbg_indent(c
, 1);
1561 n
= dbuf_getu32be(f
, pos
);
1562 de_dbg(c
, "baseAddr: 0x%08x", (unsigned int)n
);
1563 de_dbg_indent(c
, -1);
1566 void fmtutil_macbitmap_read_rowbytes_and_bounds(deark
*c
, dbuf
*f
,
1567 struct fmtutil_macbitmap_info
*bi
, i64 pos
)
1569 struct pict_rect tmprect
;
1572 de_dbg(c
, "rowBytes/bounds part of bitmap/PixMap header, at %d", (int)pos
);
1573 de_dbg_indent(c
, 1);
1574 rowbytes_code
= dbuf_getu16be(f
, pos
);
1575 bi
->rowbytes
= rowbytes_code
& 0x7fff;
1576 bi
->pixmap_flag
= (rowbytes_code
& 0x8000)?1:0;
1577 de_dbg(c
, "rowBytes: %d", (int)bi
->rowbytes
);
1578 de_dbg(c
, "pixmap flag: %d", bi
->pixmap_flag
);
1580 pict_read_rect(f
, pos
+2, &tmprect
, "rect");
1581 bi
->npwidth
= tmprect
.r
- tmprect
.l
;
1582 bi
->pdwidth
= bi
->npwidth
; // default
1583 bi
->height
= tmprect
.b
- tmprect
.t
;
1585 de_dbg_indent(c
, -1);
1588 // Pixmap fields that aren't read by read_baseaddr or read_rowbytes_and_bounds
1590 void fmtutil_macbitmap_read_pixmap_only_fields(deark
*c
, dbuf
*f
, struct fmtutil_macbitmap_info
*bi
,
1598 de_dbg(c
, "additional PixMap header fields, at %d", (int)pos
);
1599 de_dbg_indent(c
, 1);
1601 pixmap_version
= dbuf_getu16be(f
, pos
+0);
1602 de_dbg(c
, "pixmap version: %d", (int)pixmap_version
);
1604 bi
->packing_type
= dbuf_getu16be(f
, pos
+2);
1605 de_dbg(c
, "packing type: %d", (int)bi
->packing_type
);
1607 pack_size
= dbuf_getu32be(f
, pos
+4);
1608 de_dbg(c
, "pixel data length: %d", (int)pack_size
);
1610 bi
->hdpi
= pict_read_fixed(f
, pos
+8);
1611 bi
->vdpi
= pict_read_fixed(f
, pos
+12);
1612 de_dbg(c
, "dpi: %.2f"DE_CHAR_TIMES
"%.2f", bi
->hdpi
, bi
->vdpi
);
1614 bi
->pixeltype
= dbuf_getu16be(f
, pos
+16);
1615 bi
->pixelsize
= dbuf_getu16be(f
, pos
+18);
1616 bi
->cmpcount
= dbuf_getu16be(f
, pos
+20);
1617 bi
->cmpsize
= dbuf_getu16be(f
, pos
+22);
1618 de_dbg(c
, "pixel type=%d, bits/pixel=%d, components/pixel=%d, bits/comp=%d",
1619 (int)bi
->pixeltype
, (int)bi
->pixelsize
, (int)bi
->cmpcount
, (int)bi
->cmpsize
);
1621 if(bi
->pixelsize
>0) {
1622 bi
->pdwidth
= (bi
->rowbytes
*8)/bi
->pixelsize
;
1624 if(bi
->pdwidth
< bi
->npwidth
) {
1625 bi
->pdwidth
= bi
->npwidth
;
1628 plane_bytes
= dbuf_getu32be(f
, pos
+24);
1629 de_dbg(c
, "plane bytes: %d", (int)plane_bytes
);
1631 bi
->pmTable
= (u32
)dbuf_getu32be(f
, pos
+28);
1632 de_dbg(c
, "pmTable: 0x%08x", (unsigned int)bi
->pmTable
);
1634 n
= dbuf_getu32be(f
, pos
+32);
1635 de_dbg(c
, "pmReserved: 0x%08x", (unsigned int)n
);
1637 de_dbg_indent(c
, -1);
1640 int fmtutil_macbitmap_read_colortable(deark
*c
, dbuf
*f
,
1641 struct fmtutil_macbitmap_info
*bi
, i64 pos
, i64
*bytes_used
)
1653 de_dbg(c
, "color table at %"I64_FMT
, pos
);
1654 de_dbg_indent(c
, 1);
1656 ct_id
= dbuf_getu32be(f
, pos
);
1657 ct_flags
= (u32
)dbuf_getu16be(f
, pos
+4); // a.k.a. transIndex
1658 ct_size
= dbuf_getu16be(f
, pos
+6);
1659 bi
->num_pal_entries
= ct_size
+1;
1660 de_dbg(c
, "color table id=0x%08x, flags=0x%04x, colors=%d", (unsigned int)ct_id
,
1661 (unsigned int)ct_flags
, (int)bi
->num_pal_entries
);
1663 for(k
=0; k
<bi
->num_pal_entries
; k
++) {
1664 for(z
=0; z
<4; z
++) {
1665 s
[z
] = (u32
)dbuf_getu16be(f
, pos
+8+8*k
+2*z
);
1670 clr
= DE_MAKE_RGB(cr
,cg
,cb
);
1671 de_snprintf(tmps
, sizeof(tmps
), "(%5d,%5d,%5d,idx=%3d) "DE_CHAR_RIGHTARROW
" ",
1672 (int)s
[1], (int)s
[2], (int)s
[3], (int)s
[0]);
1673 de_dbg_pal_entry2(c
, k
, clr
, tmps
, NULL
, NULL
);
1675 // Some files don't have the palette indices set. Most PICT decoders ignore
1676 // the indices if the "device" flag of ct_flags is set, and that seems to
1677 // work (though it's not clearly documented).
1678 if(ct_flags
& 0x8000U
) {
1683 bi
->pal
[s
[0]] = clr
;
1687 de_dbg_indent(c
, -1);
1688 *bytes_used
= 8 + 8*bi
->num_pal_entries
;
1692 // "compressed unsigned short" - a variable-length integer format
1693 // TODO: This is duplicated in shg.c
1694 i64
fmtutil_hlp_get_cus_p(dbuf
*f
, i64
*ppos
)
1698 x1
= (i64
)dbuf_getbyte_p(f
, ppos
);
1700 // If it's even, divide by two.
1703 // If it's odd, divide by two, and add 128 times the value of
1705 x2
= (i64
)dbuf_getbyte_p(f
, ppos
);
1706 return (x1
>>1) | (x2
<<7);
1709 // "compressed signed short"
1710 i64
fmtutil_hlp_get_css_p(dbuf
*f
, i64
*ppos
)
1714 x1
= (i64
)dbuf_getbyte_p(f
, ppos
);
1716 // If it's even, divide by two, and subtract 64
1717 return (x1
>>1) - 64;
1719 // If it's odd, divide by two, add 128 times the value of
1720 // the next byte, and subtract 16384.
1722 x2
= (i64
)dbuf_getbyte_p(f
, ppos
);
1728 // "compressed unsigned long"
1729 i64
fmtutil_hlp_get_cul_p(dbuf
*f
, i64
*ppos
)
1732 x1
= dbuf_getu16le_p(f
, ppos
);
1734 // If it's even, divide by two.
1737 // If it's odd, divide by two, and add 32768 times the value of
1738 // the next two bytes.
1739 x2
= dbuf_getu16le_p(f
, ppos
);
1740 return (x1
>>1) | (x2
<<15);
1743 // "compressed signed long"
1744 i64
fmtutil_hlp_get_csl_p(dbuf
*f
, i64
*ppos
)
1748 x1
= dbuf_getu16le_p(f
, ppos
);
1751 // If it's even, divide by two, and subtract 16384
1752 return (x1
>>1) - 16384;
1754 // If it's odd, divide by two, add 32768 times the value of
1755 // the next two bytes, and subtract 67108864.
1757 x2
= dbuf_getu16le_p(f
, ppos
);