DOSBox-X
|
00001 /* 00002 * Copyright (C) 2018-2020 Jon Campbell 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #ifndef __VIDEOMGRUTIL_RIFF_H 00020 #define __VIDEOMGRUTIL_RIFF_H 00021 00022 #include <stdint.h> 00023 #include <string.h> 00024 #include <stdio.h> 00025 00026 #include "informational.h" 00027 00028 typedef uint32_t riff_fourcc_t; 00029 #define riff_fourcc_const(a,b,c,d) ( (((uint32_t)(a)) << 0U) | (((uint32_t)(b)) << 8U) | (((uint32_t)(c)) << 16U) | (((uint32_t)(d)) << 24U) ) 00030 00031 #define riff_LIST riff_fourcc_const('L','I','S','T') 00032 #define riff_RIFF riff_fourcc_const('R','I','F','F') 00033 00034 #define riff_wav_fmt riff_fourcc_const('f','m','t',' ') 00035 #define riff_wav_data riff_fourcc_const('d','a','t','a') 00036 00037 typedef struct { 00038 int64_t absolute_header_offset; 00039 int64_t absolute_data_offset; 00040 int64_t absolute_offset_next_chunk; 00041 riff_fourcc_t fourcc; 00042 uint32_t data_length; 00043 uint32_t absolute_data_length; 00044 riff_fourcc_t list_fourcc; 00045 int64_t read_offset; 00046 int64_t write_offset; 00047 int wmode; 00048 unsigned char disable_sync; /* 1=riff_stack_pop() will NOT rewrite the header. 00049 caller would use this if using riff_stack_streamwrite() 00050 to blast the data to disk as fast as possible */ 00051 unsigned char placeholder; /* 1=write 0xFFFFFFFF as a placeholder for the actual size 00052 until the header is actually updated. you should really 00053 only set this flag for LIST chunks that are unlikely to 00054 be zero bytes in length. flag is cleared automatically 00055 by riff_stack_pop(). do NOT set if disable_sync is set. */ 00056 } riff_chunk; 00057 00058 static const riff_chunk RIFF_CHUNK_INIT = { 00059 0, 00060 0, 00061 0, 00062 0, 00063 0, 00064 0, 00065 0, 00066 0, 00067 0, 00068 0, 00069 0, 00070 0 00071 }; 00072 00073 typedef struct { 00074 int current,depth; 00075 riff_chunk *stack,*top; 00076 00077 int fd; 00078 int eof; 00079 void* user; 00080 int wmode; 00081 int64_t next_read; 00082 int64_t next_write; 00083 void* buffer; 00084 size_t buflen; 00085 size_t bufofs; 00086 int (*read)(void *a,void *b,size_t c); 00087 int64_t (*seek)(void *a,int64_t offset); 00088 int (*write)(void *a,const void *b,size_t c); 00089 00090 /* flags for controlling some of the optimizations used in this code */ 00091 unsigned char always_lseek; /* 1=always lseek() 00092 0=ignore lseek() if file pointer should be at that point anyway 00093 EXPLANATION: Linux disk I/O caching is more likely to provide better 00094 throughput if we avoid lseek() and write structures and 00095 data using only a continuous series of read() or write() 00096 calls. */ 00097 00098 /* variables provided for the file I/O code */ 00099 int64_t trk_file_pointer; 00100 00101 /* more flags */ 00102 unsigned int fd_owner:1; /* if set, we take ownership of the file descriptor */ 00103 } riff_stack; 00104 00105 int riff_std_read(void *a,void *b,size_t c); 00106 int riff_std_write(void *a,const void *b,size_t c); 00107 int64_t riff_std_seek(void *a,int64_t offset); 00108 00109 riff_stack *riff_stack_create(int depth); 00110 riff_stack *riff_stack_destroy(riff_stack *s); 00111 int riff_stack_is_empty(riff_stack *s); 00112 int riff_stack_empty(riff_stack *s); 00113 riff_chunk *riff_stack_top(riff_stack *s); 00114 riff_chunk *riff_stack_pop(riff_stack *s); 00115 int riff_stack_push(riff_stack *s,riff_chunk *c); 00116 int64_t riff_stack_seek(riff_stack *s,riff_chunk *c,int64_t of); 00117 int riff_stack_read(riff_stack *s,riff_chunk *c,void *buf,size_t len); 00118 int riff_stack_write(riff_stack *s,riff_chunk *c,const void *buf,size_t len); 00119 int riff_stack_streamwrite(riff_stack *s,riff_chunk *c,const void *buf,size_t len); 00120 int64_t riff_stack_current_chunk_offset(riff_stack *s); 00121 int riff_stack_assign_fd(riff_stack *s,int fd); 00122 int riff_stack_assign_fd_ownership(riff_stack *s); 00123 int riff_stack_assign_buffer(riff_stack *s,void *buffer,size_t len); 00124 int riff_stack_chunk_contains_subchunks(riff_chunk *c); 00125 int riff_stack_readchunk(riff_stack *s,riff_chunk *pc,riff_chunk *c); 00126 int riff_stack_set_chunk_data_type(riff_chunk *c,riff_fourcc_t fcc); 00127 int riff_stack_set_chunk_list_type(riff_chunk *c,riff_fourcc_t list,riff_fourcc_t fcc); 00128 void riff_stack_debug_chunk_dump(FILE *fp,riff_stack *riff,riff_chunk *chunk); 00129 void riff_stack_debug_print(FILE *fp,int level,riff_chunk *chunk); 00130 void riff_chunk_improvise(riff_chunk *c,uint64_t ofs,uint32_t size); 00131 void riff_stack_fourcc_to_str(riff_fourcc_t t,char *tmp); 00132 void riff_stack_debug_print_indent(FILE *fp,int level); 00133 int riff_stack_eof(riff_stack *r); 00134 int riff_stack_prepare_for_writing(riff_stack *r,int wmode); 00135 int riff_stack_begin_new_chunk_here(riff_stack *s,riff_chunk *c); 00136 int riff_stack_header_sync(riff_stack *s,riff_chunk *c); 00137 int riff_stack_header_sync_all(riff_stack *s); 00138 int riff_stack_chunk_limit(riff_stack *s,int len); 00139 int riff_stack_enable_placeholder(riff_stack *s,riff_chunk *c); 00140 void riff_stack_writing_sync(riff_stack *s); 00141 00142 #define RIFF_CHUNK_HEADER_LENGTH 8 00143 #define RIFF_LIST_CHUNK_HEADER_LENGTH 12 00144 00145 #endif 00146