1 // This file is part of Deark.
2 // Copyright (C) 2018 Jason Summers
3 // See the file COPYING for terms of use.
7 #include <deark-config.h>
8 #include <deark-private.h>
9 #include <deark-fmtutil.h>
10 DE_DECLARE_MODULE(de_module_flac
);
12 typedef struct localctx_struct
{
16 static const char *get_mdblk_name(u8 blktype
)
18 const char *name
= NULL
;
20 case 0: name
="STREAMINFO"; break;
21 case 1: name
="PADDING"; break;
22 case 2: name
="APPLICATION"; break;
23 case 3: name
="SEEKTABLE"; break;
24 case 4: name
="VORBIS_COMMENT"; break;
25 case 5: name
="CUESHEET"; break;
26 case 6: name
="PICTURE"; break;
31 static void do_metadata_block_vorbiscomment(deark
*c
, lctx
*d
, i64 pos1
, i64 len
)
33 de_dbg(c
, "vorbis comment block at %"I64_FMT
, pos1
);
35 de_run_module_by_id_on_slice2(c
, "ogg", "C", c
->infile
, pos1
, len
);
39 static void do_metadata_block_picture(deark
*c
, lctx
*d
, i64 pos1
, i64 len
)
41 de_dbg(c
, "picture at %"I64_FMT
, pos1
);
43 de_run_module_by_id_on_slice2(c
, "id3", "F", c
->infile
, pos1
, len
);
47 static void do_metadata_block(deark
*c
, lctx
*d
, u8 blktype
, i64 pos1
, i64 len
)
51 do_metadata_block_vorbiscomment(c
, d
, pos1
, len
);
54 do_metadata_block_picture(c
, d
, pos1
, len
);
59 static void run_flac_internal(deark
*c
, lctx
*d
, i64 pos1
, i64 len
)
62 int saved_indent_level
;
64 de_dbg(c
, "signature at %"I64_FMT
, pos
);
67 de_dbg_indent_save(c
, &saved_indent_level
);
75 if(pos
>= pos1
+len
) goto done
;
76 de_dbg(c
, "metadata block at %"I64_FMT
, pos
);
78 b
= de_getbyte_p(&pos
);
79 is_last
= (b
&0x80)!=0;
80 de_dbg(c
, "is-last: %u", (unsigned int)is_last
);
82 blkname
= get_mdblk_name(blktype
);
83 de_dbg(c
, "block type: %u (%s)", (unsigned int)blktype
, blkname
);
84 blklen
= dbuf_getint_ext(c
->infile
, pos
, 3, 0, 0);
86 de_dbg(c
, "block len: %u", (unsigned int)blklen
);
87 do_metadata_block(c
, d
, blktype
, pos
, blklen
);
93 de_dbg(c
, "frames start at %"I64_FMT
, pos
);
96 de_dbg_indent_restore(c
, saved_indent_level
);
99 static void de_run_flac(deark
*c
, de_module_params
*mparams
)
102 struct de_id3info id3i
;
104 d
= de_malloc(c
, sizeof(lctx
));
105 fmtutil_handle_id3(c
, c
->infile
, &id3i
, 0);
106 run_flac_internal(c
, d
, id3i
.main_start
, id3i
.main_end
-id3i
.main_start
);
110 static int de_identify_flac(deark
*c
)
114 if(!c
->detection_data
->id3
.detection_attempted
) {
115 de_err(c
, "flac detection requires id3 module");
119 if(c
->detection_data
->id3
.has_id3v2
) {
120 pos
= (i64
)c
->detection_data
->id3
.bytes_at_start
;
123 if(!dbuf_memcmp(c
->infile
, pos
, "fLaC", 4))
129 void de_module_flac(deark
*c
, struct deark_module_info
*mi
)
133 mi
->run_fn
= de_run_flac
;
134 mi
->identify_fn
= de_identify_flac
;