From 48fa7b7dc0d48c0ecb2e778419c2f7bb5c8cff3a Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 14 Jan 2017 01:37:53 +0100 Subject: [PATCH] Added a few helper functions - open_stream_ext: opens a streamfile based on the filename + ext - find_chunk_be/le: finds chunk_offset in chunked headers --- src/streamfile.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/streamfile.h | 5 +++++ 2 files changed, 58 insertions(+) diff --git a/src/streamfile.c b/src/streamfile.c index 354eebc7..4399e9d8 100644 --- a/src/streamfile.c +++ b/src/streamfile.c @@ -273,6 +273,18 @@ size_t get_streamfile_dos_line(int dst_length, char * dst, off_t offset, } +/** + * Opens an stream using the base streamFile name plus a new extension (ex. for headers in a separate file) + */ +STREAMFILE * open_stream_ext(STREAMFILE *streamFile, const char * ext) { + char filename_ext[PATH_LIMIT]; + + streamFile->get_name(streamFile,filename_ext,sizeof(filename_ext)); + strcpy(filename_ext + strlen(filename_ext) - strlen(filename_extension(filename_ext)), ext); + + return streamFile->open(streamFile,filename_ext,STREAMFILE_DEFAULT_BUFFER_SIZE); +} + /** * open file containing decryption keys and copy to buffer * tries combinations of keynames based on the original filename @@ -419,3 +431,44 @@ int check_extensions(STREAMFILE *streamFile, const char * cmp_exts) { return 0; } + + +/** + * Find a chunk starting from an offset, and save its offset/size (if not NULL), with offset after id/size. + * Works for chunked headers in the form of "chunk_id chunk_size (data)"xN (ex. RIFF). + * The start_offset should be the first actual chunk (not "RIFF" or "WAVE" but "fmt "). + * "full_chunk_size" signals chunk_size includes 4+4+data. + * + * returns 0 on failure + */ +static int find_chunk(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, int size_big_endian, off_t *out_chunk_offset, size_t *out_chunk_size); +int find_chunk_be(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) { + return find_chunk(streamFile, chunk_id, start_offset, full_chunk_size, 1, out_chunk_offset, out_chunk_size); +} +int find_chunk_le(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) { + return find_chunk(streamFile, chunk_id, start_offset, full_chunk_size, 0, out_chunk_offset, out_chunk_size); +} +int find_chunk(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, int size_big_endian, off_t *out_chunk_offset, size_t *out_chunk_size) { + size_t filesize; + off_t current_chunk = start_offset; + + filesize = get_streamfile_size(streamFile); + /* read chunks */ + while (current_chunk < filesize) { + uint32_t chunk_type = read_32bitBE(current_chunk,streamFile); + off_t chunk_size = size_big_endian ? + read_32bitBE(current_chunk+4,streamFile) : + read_32bitLE(current_chunk+4,streamFile); + + if (chunk_type == chunk_id) { + if (out_chunk_offset) *out_chunk_offset = current_chunk+8; + if (out_chunk_size) *out_chunk_size = chunk_size; + return 1; + } + + current_chunk += full_chunk_size ? chunk_size : 4+4+chunk_size; + } + + return 0; +} + diff --git a/src/streamfile.h b/src/streamfile.h index 1127c995..5ad1f3a6 100644 --- a/src/streamfile.h +++ b/src/streamfile.h @@ -148,10 +148,15 @@ static inline STREAMFILE * open_stdio_streamfile(const char * const filename) { size_t get_streamfile_dos_line(int dst_length, char * dst, off_t offset, STREAMFILE * infile, int *line_done_ptr); +STREAMFILE * open_stream_ext(STREAMFILE *streamFile, const char * ext); + int read_key_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile); int read_pos_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile); int check_extensions(STREAMFILE *streamFile, const char * cmp_exts); +int find_chunk_be(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size); +int find_chunk_le(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size); + #endif