Changeset 68 for libmpcdec/branches/zorg/src/mpc_reader.c
- Timestamp:
- 10/06/06 17:14:05 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libmpcdec/branches/zorg/src/mpc_reader.c
r40 r68 32 32 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 33 */ 34 35 34 /// \file mpc_reader.c 36 35 /// Contains implementations for simple file-based mpc_reader 36 #include <mpcdec/reader.h> 37 #include "internal.h" 38 #include <stdio.h> 37 39 38 #include <mpcdec/mpcdec.h> 40 #define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value... 41 typedef struct mpc_reader_stdio_t { 42 FILE *p_file; 43 int file_size; 44 mpc_bool_t is_seekable; 45 mpc_int32_t magic; 46 } mpc_reader_stdio; 39 47 40 48 /// mpc_reader callback implementations 41 49 static mpc_int32_t 42 read_ impl(void *data, void *ptr, mpc_int32_t size)50 read_stdio(mpc_reader *p_reader, void *ptr, mpc_int32_t size) 43 51 { 44 mpc_reader_ file *d = (mpc_reader_file *)data;45 46 return (mpc_int32_t) fread(ptr, 1, size, d->file);52 mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; 53 if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FILE; 54 return (mpc_int32_t) fread(ptr, 1, size, p_stdio->p_file); 47 55 } 48 56 49 57 static mpc_bool_t 50 seek_ impl(void *data, mpc_int32_t offset)58 seek_stdio(mpc_reader *p_reader, mpc_int32_t offset) 51 59 { 52 mpc_reader_ file *d = (mpc_reader_file *)data;53 54 return d->is_seekable ? fseek(d->file, offset, SEEK_SET) == 0 : FALSE;60 mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; 61 if(p_stdio->magic != STDIO_MAGIC) return FALSE; 62 return p_stdio->is_seekable ? fseek(p_stdio->p_file, offset, SEEK_SET) == 0 : FALSE; 55 63 } 56 64 57 65 static mpc_int32_t 58 tell_ impl(void *data)66 tell_stdio(mpc_reader *p_reader) 59 67 { 60 mpc_reader_ file *d = (mpc_reader_file *)data;61 62 return ftell( d->file);68 mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; 69 if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FILE; 70 return ftell(p_stdio->p_file); 63 71 } 64 72 65 73 static mpc_int32_t 66 get_size_ impl(void *data)74 get_size_stdio(mpc_reader *p_reader) 67 75 { 68 mpc_reader_ file *d = (mpc_reader_file *)data;69 70 return d->file_size;76 mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; 77 if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FILE; 78 return p_stdio->file_size; 71 79 } 72 80 73 81 static mpc_bool_t 74 canseek_ impl(void *data)82 canseek_stdio(mpc_reader *p_reader) 75 83 { 76 mpc_reader_file *d = (mpc_reader_file *) data; 84 mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; 85 if(p_stdio->magic != STDIO_MAGIC) return FALSE; 86 return p_stdio->is_seekable; 87 } 77 88 78 return d->is_seekable; 89 mpc_status 90 mpc_reader_setup_file_reader(mpc_reader *p_reader, char *filename) 91 { 92 mpc_reader tmp_reader; mpc_reader_stdio *p_stdio; int err; 93 94 p_stdio = NULL; 95 memset(&tmp_reader, 0, sizeof tmp_reader); 96 p_stdio = malloc(sizeof *p_stdio); 97 if(!p_stdio) return MPC_STATUS_FILE; 98 memset(p_stdio, 0, sizeof *p_stdio); 99 100 p_stdio->magic = STDIO_MAGIC; 101 p_stdio->p_file = fopen(filename, "rb"); 102 if(!p_stdio->p_file) goto clean; 103 p_stdio->is_seekable = TRUE; 104 err = fseek(p_stdio->p_file, 0, SEEK_END); 105 if(err < 0) goto clean; 106 err = ftell(p_stdio->p_file); 107 if(err < 0) goto clean; 108 p_stdio->file_size = err; 109 err = fseek(p_stdio->p_file, 0, SEEK_SET); 110 if(err < 0) goto clean; 111 112 tmp_reader.data = p_stdio; 113 tmp_reader.canseek = canseek_stdio; 114 tmp_reader.get_size = get_size_stdio; 115 tmp_reader.read = read_stdio; 116 tmp_reader.seek = seek_stdio; 117 tmp_reader.tell = tell_stdio; 118 119 *p_reader = tmp_reader; 120 return MPC_STATUS_OK; 121 clean: 122 if(p_stdio && p_stdio->p_file) 123 fclose(p_stdio->p_file); 124 free(p_stdio); 125 return MPC_STATUS_FILE; 79 126 } 80 127 81 128 void 82 mpc_ reader_setup_file_reader(mpc_reader_file *p_reader, FILE *input)129 mpc_exit_stdio_reader(mpc_reader *p_reader) 83 130 { 84 p_reader->reader.seek = seek_impl;85 p_reader->reader.read = read_impl;86 p_reader->reader.tell = tell_impl;87 p_reader->reader.get_size = get_size_impl;88 p_reader-> reader.canseek = canseek_impl;89 p_reader->reader.data = p_reader; // point back to ourselves 131 mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; 132 if(p_stdio->magic != STDIO_MAGIC) return; 133 fclose(p_stdio->p_file); 134 free(p_stdio); 135 p_reader->data = NULL; 136 } 90 137 91 p_reader->file = input; 92 p_reader->is_seekable = TRUE; 93 fseek(input, 0, SEEK_END); 94 p_reader->file_size = ftell(input); 95 fseek(input, 0, SEEK_SET); 138 mpc_int32_t 139 mpc_skip_id3v2(mpc_reader* p_reader) 140 { 141 mpc_uint8_t tmp [10]; 142 mpc_uint32_t unsynchronisation; // ID3v2.4-flag 143 mpc_uint32_t extHeaderPresent; // ID3v2.4-flag 144 mpc_uint32_t experimentalFlag; // ID3v2.4-flag 145 mpc_uint32_t footerPresent; // ID3v2.4-flag 146 mpc_int32_t ret; 147 148 // seek to first byte of mpc data 149 ret = p_reader->seek(p_reader, 0); 150 if(!ret) return 0; 151 152 p_reader->read(p_reader, tmp, sizeof tmp); 153 154 // check id3-tag 155 if ( 0 != memcmp( tmp, "ID3", 3 ) ) 156 return 0; 157 158 // read flags 159 unsynchronisation = tmp[5] & 0x80; 160 extHeaderPresent = tmp[5] & 0x40; 161 experimentalFlag = tmp[5] & 0x20; 162 footerPresent = tmp[5] & 0x10; 163 164 if ( tmp[5] & 0x0F ) 165 return MPC_STATUS_FILE; // not (yet???) allowed 166 if ( (tmp[6] | tmp[7] | tmp[8] | tmp[9]) & 0x80 ) 167 return MPC_STATUS_FILE; // not allowed 168 169 // read headerSize (syncsave: 4 * $0xxxxxxx = 28 significant bits) 170 ret = tmp[6] << 21; 171 ret += tmp[7] << 14; 172 ret += tmp[8] << 7; 173 ret += tmp[9]; 174 ret += 10; 175 if ( footerPresent ) 176 ret += 10; 177 178 return ret; 96 179 }
Note: See TracChangeset
for help on using the changeset viewer.