7
/* Read entire buffer from the preload buffer */
8
int quicktime_read_preload(quicktime_t *file, char *data, int size)
10
long selection_start = file->file_position;
11
long selection_end = file->file_position + size;
12
long fragment_start, fragment_len, fragment_end;
14
fragment_start = file->preload_ptr + (selection_start - file->preload_start);
15
while(fragment_start < 0) fragment_start += file->preload_size;
16
while(fragment_start >= file->preload_size) fragment_start -= file->preload_size;
18
while(selection_start < selection_end)
20
fragment_len = selection_end - selection_start;
21
if(fragment_start + fragment_len > file->preload_size)
22
fragment_len = file->preload_size - fragment_start;
23
fragment_end = fragment_start + fragment_len;
25
while(fragment_start < fragment_end)
27
*data++ = file->preload_buffer[fragment_start++];
29
if(fragment_start >= file->preload_size) fragment_start = 0;
30
selection_start += fragment_len;
36
int quicktime_read_data(quicktime_t *file, char *data, int size)
39
if(!file->preload_size)
41
if(ftell(file->stream) != file->file_position) fseek(file->stream, file->file_position, SEEK_SET);
42
result = fread(data, size, 1, file->stream);
46
long selection_start = file->file_position;
47
long selection_end = file->file_position + size;
48
long fragment_start, fragment_len, fragment_end;
50
if(selection_end - selection_start > file->preload_size)
52
/* Size is larger than preload size. Should never happen. */
53
if(ftell(file->stream) != file->file_position) fseek(file->stream, file->file_position, SEEK_SET);
54
result = fread(data, size, 1, file->stream);
57
if(selection_start >= file->preload_start &&
58
selection_start < file->preload_end &&
59
selection_end <= file->preload_end &&
60
selection_end > file->preload_start)
62
/* Entire range is in buffer */
63
quicktime_read_preload(file, data, size);
66
if(selection_end > file->preload_end && selection_end - file->preload_size < file->preload_end)
68
/* Range is after buffer */
69
/* Move the preload start to within one preload length of the selection_end */
70
while(selection_end - file->preload_start > file->preload_size)
72
fragment_len = selection_end - file->preload_start - file->preload_size;
73
if(file->preload_ptr + fragment_len > file->preload_size) fragment_len = file->preload_size - file->preload_ptr;
74
file->preload_start += fragment_len;
75
file->preload_ptr += fragment_len;
76
if(file->preload_ptr >= file->preload_size) file->preload_ptr = 0;
79
/* Append sequential data after the preload end to the new end */
80
fragment_start = file->preload_ptr + file->preload_end - file->preload_start;
81
while(fragment_start >= file->preload_size) fragment_start -= file->preload_size;
83
while(file->preload_end < selection_end)
85
fragment_len = selection_end - file->preload_end;
86
if(fragment_start + fragment_len > file->preload_size) fragment_len = file->preload_size - fragment_start;
87
if(ftell(file->stream) != file->preload_end) fseek(file->stream, file->preload_end, SEEK_SET);
88
result = fread(&(file->preload_buffer[fragment_start]), fragment_len, 1, file->stream);
89
file->preload_end += fragment_len;
90
fragment_start += fragment_len;
91
if(fragment_start >= file->preload_size) fragment_start = 0;
94
quicktime_read_preload(file, data, size);
98
/*printf("quicktime_read_data 4 selection_start %ld selection_end %ld preload_start %ld\n", selection_start, selection_end, file->preload_start); */
99
/* Range is before buffer or over a preload_size away from the end of the buffer. */
100
/* Replace entire preload buffer with range. */
101
if(ftell(file->stream) != file->file_position) fseek(file->stream, file->file_position, SEEK_SET);
102
result = fread(file->preload_buffer, size, 1, file->stream);
103
file->preload_start = file->file_position;
104
file->preload_end = file->file_position + size;
105
file->preload_ptr = 0;
106
quicktime_read_preload(file, data, size);
110
file->file_position += size;
114
int quicktime_write_data(quicktime_t *file, char *data, int size)
117
if(ftell(file->stream) != file->file_position) fseek(file->stream, file->file_position, SEEK_SET);
118
result = fwrite(data, size, 1, file->stream);
119
file->file_position += size;
123
int quicktime_test_position(quicktime_t *file)
125
if (quicktime_position(file) < 0)
127
printf("quicktime_test_position: 32 bit overflow\n");
134
int quicktime_read_pascal(quicktime_t *file, char *data)
136
char len = quicktime_read_char(file);
137
quicktime_read_data(file, data, len);
141
int quicktime_write_pascal(quicktime_t *file, char *data)
143
char len = strlen(data);
144
quicktime_write_data(file, &len, 1);
145
quicktime_write_data(file, data, len);
148
float quicktime_read_fixed32(quicktime_t *file)
150
unsigned long a, b, c, d;
151
unsigned char data[4];
153
quicktime_read_data(file, data, 4);
154
/* fread(data, 4, 1, file->stream); */
163
return (float)a + (float)b / 65536;
166
int quicktime_write_fixed32(quicktime_t *file, float number)
168
unsigned char data[4];
172
b = (number - a) * 65536;
178
return quicktime_write_data(file, data, 4);
181
int quicktime_write_int64(quicktime_t *file, u_int64_t value)
183
unsigned char data[8];
186
for (i = 7; i >= 0; i--) {
187
data[i] = value & 0xff;
191
return quicktime_write_data(file, data, 8);
194
int quicktime_write_int32(quicktime_t *file, long value)
196
unsigned char data[4];
198
data[0] = (value & 0xff000000) >> 24;
199
data[1] = (value & 0xff0000) >> 16;
200
data[2] = (value & 0xff00) >> 8;
201
data[3] = value & 0xff;
203
return quicktime_write_data(file, data, 4);
206
int quicktime_write_char32(quicktime_t *file, char *string)
208
return quicktime_write_data(file, string, 4);
212
float quicktime_read_fixed16(quicktime_t *file)
214
unsigned char data[2];
216
quicktime_read_data(file, data, 2);
217
return (float)data[0] + (float)data[1] / 256;
220
int quicktime_write_fixed16(quicktime_t *file, float number)
222
unsigned char data[2];
226
b = (number - a) * 256;
230
return quicktime_write_data(file, data, 2);
233
u_int64_t quicktime_read_int64(quicktime_t *file)
236
u_int64_t result = 0;
239
quicktime_read_data(file, data, 8);
241
for (i = 0; i < 8; i++) {
242
result |= ((u_int64_t)data[i]) << ((7 - i) * 8);
248
long quicktime_read_int32(quicktime_t *file)
250
unsigned long result;
251
unsigned long a, b, c, d;
254
quicktime_read_data(file, data, 4);
255
a = (unsigned char)data[0];
256
b = (unsigned char)data[1];
257
c = (unsigned char)data[2];
258
d = (unsigned char)data[3];
260
result = (a<<24) | (b<<16) | (c<<8) | d;
265
long quicktime_read_int24(quicktime_t *file)
267
unsigned long result;
268
unsigned long a, b, c;
271
quicktime_read_data(file, data, 3);
272
/* fread(data, 3, 1, file->stream); */
273
a = (unsigned char)data[0];
274
b = (unsigned char)data[1];
275
c = (unsigned char)data[2];
277
result = (a<<16) | (b<<8) | c;
281
int quicktime_write_int24(quicktime_t *file, long number)
283
unsigned char data[3];
284
data[0] = (number & 0xff0000) >> 16;
285
data[1] = (number & 0xff00) >> 8;
286
data[2] = (number & 0xff);
288
return quicktime_write_data(file, data, 3);
289
/* return fwrite(data, 3, 1, file->stream); */
292
int quicktime_read_int16(quicktime_t *file)
294
unsigned long result;
298
quicktime_read_data(file, data, 2);
299
/* fread(data, 2, 1, file->stream); */
300
a = (unsigned char)data[0];
301
b = (unsigned char)data[1];
307
int quicktime_write_int16(quicktime_t *file, int number)
309
unsigned char data[2];
310
data[0] = (number & 0xff00) >> 8;
311
data[1] = (number & 0xff);
313
return quicktime_write_data(file, data, 2);
314
/* return fwrite(data, 2, 1, file->stream); */
317
int quicktime_read_char(quicktime_t *file)
320
quicktime_read_data(file, &output, 1);
324
int quicktime_write_char(quicktime_t *file, char x)
326
return quicktime_write_data(file, &x, 1);
329
int quicktime_read_char32(quicktime_t *file, char *string)
331
quicktime_read_data(file, string, 4);
332
/* fread(string, 4, 1, file->stream); */
335
long quicktime_position(quicktime_t *file)
337
return file->file_position;
340
int quicktime_set_position(quicktime_t *file, long position)
342
file->file_position = position;
344
/* fseek(file->stream, position, SEEK_SET); */
347
int quicktime_copy_char32(char *output, char *input)
349
*output++ = *input++;
350
*output++ = *input++;
351
*output++ = *input++;
356
int quicktime_print_chars(char *desc, char *input, int len)
360
for(i = 0; i < len; i++) printf("%c", input[i]);
364
unsigned long quicktime_current_time()
368
return (t+(66*31536000)+1468800);
371
int quicktime_match_32(char *input, char *output)
373
if(input[0] == output[0] &&
374
input[1] == output[1] &&
375
input[2] == output[2] &&
376
input[3] == output[3])
382
int quicktime_read_mp4_descr_length(quicktime_t *file)
385
u_int8_t numBytes = 0;
386
u_int32_t length = 0;
389
b = quicktime_read_char(file);
391
length = (length << 7) | (b & 0x7F);
392
} while ((b & 0x80) && numBytes < 4);
397
int quicktime_write_mp4_descr_length(quicktime_t *file, int length, bool compact)
404
if (length <= 0x7F) {
406
} else if (length <= 0x3FFF) {
408
} else if (length <= 0x1FFFFF) {
417
for (i = numBytes-1; i >= 0; i--) {
418
b = (length >> (i * 7)) & 0x7F;
422
quicktime_write_char(file, b);
428
void quicktime_atom_hexdump(quicktime_t* file, quicktime_atom_t* atom)
433
oldPos = quicktime_position(file);
434
quicktime_set_position(file, atom->start);
435
printf("atom hex dump:\n");
436
for (i = 0; i < atom->size; i++) {
437
printf("%02x ", (u_int8_t)quicktime_read_char(file));
438
if ((i % 16) == 0 && i > 0) {
443
quicktime_set_position(file, oldPos);