~ubuntu-branches/ubuntu/precise/mpeg4ip/precise

« back to all changes in this revision

Viewing changes to lib/mp4/util.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Limonciello
  • Date: 2008-01-12 15:59:56 UTC
  • Revision ID: james.westby@ubuntu.com-20080112155956-1vznw5njidvrh649
Tags: upstream-1.6dfsg
ImportĀ upstreamĀ versionĀ 1.6dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <time.h>
 
2
#include "quicktime.h"
 
3
 
 
4
/* Disk I/O */
 
5
 
 
6
 
 
7
/* Read entire buffer from the preload buffer */
 
8
int quicktime_read_preload(quicktime_t *file, char *data, int size)
 
9
{
 
10
        long selection_start = file->file_position;
 
11
        long selection_end = file->file_position + size;
 
12
        long fragment_start, fragment_len, fragment_end;
 
13
 
 
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;
 
17
 
 
18
        while(selection_start < selection_end)
 
19
        {
 
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;
 
24
 
 
25
                while(fragment_start < fragment_end)
 
26
                {
 
27
                        *data++ = file->preload_buffer[fragment_start++];
 
28
                }
 
29
                if(fragment_start >= file->preload_size) fragment_start = 0;
 
30
                selection_start += fragment_len;
 
31
        }
 
32
        return 0;
 
33
}
 
34
 
 
35
 
 
36
int quicktime_read_data(quicktime_t *file, char *data, int size)
 
37
{
 
38
        int result = 1;
 
39
        if(!file->preload_size)
 
40
        {
 
41
                if(ftell(file->stream) != file->file_position) fseek(file->stream, file->file_position, SEEK_SET);
 
42
                result = fread(data, size, 1, file->stream);
 
43
        }
 
44
        else
 
45
        {
 
46
                long selection_start = file->file_position;
 
47
                long selection_end = file->file_position + size;
 
48
                long fragment_start, fragment_len, fragment_end;
 
49
 
 
50
                if(selection_end - selection_start > file->preload_size)
 
51
                {
 
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);
 
55
                }
 
56
                else
 
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)
 
61
                {
 
62
/* Entire range is in buffer */
 
63
                        quicktime_read_preload(file, data, size);
 
64
                }
 
65
                else
 
66
                if(selection_end > file->preload_end && selection_end - file->preload_size < file->preload_end)
 
67
                {
 
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)
 
71
                        {
 
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;
 
77
                        }
 
78
 
 
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;
 
82
 
 
83
                        while(file->preload_end < selection_end)
 
84
                        {
 
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;
 
92
                        }
 
93
 
 
94
                        quicktime_read_preload(file, data, size);
 
95
                }
 
96
                else
 
97
                {
 
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);
 
107
                }
 
108
        }
 
109
 
 
110
        file->file_position += size;
 
111
        return result;
 
112
}
 
113
 
 
114
int quicktime_write_data(quicktime_t *file, char *data, int size)
 
115
{
 
116
        int result;
 
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;
 
120
        return result;
 
121
}
 
122
 
 
123
int quicktime_test_position(quicktime_t *file)
 
124
{
 
125
        if (quicktime_position(file) < 0)
 
126
        {
 
127
                printf("quicktime_test_position: 32 bit overflow\n");
 
128
                return 1;
 
129
        }
 
130
        else
 
131
        return 0;
 
132
}
 
133
 
 
134
int quicktime_read_pascal(quicktime_t *file, char *data)
 
135
{
 
136
        char len = quicktime_read_char(file);
 
137
        quicktime_read_data(file, data, len);
 
138
        data[len] = 0;
 
139
}
 
140
 
 
141
int quicktime_write_pascal(quicktime_t *file, char *data)
 
142
{
 
143
        char len = strlen(data);
 
144
        quicktime_write_data(file, &len, 1);
 
145
        quicktime_write_data(file, data, len);
 
146
}
 
147
 
 
148
float quicktime_read_fixed32(quicktime_t *file)
 
149
{
 
150
        unsigned long a, b, c, d;
 
151
        unsigned char data[4];
 
152
 
 
153
        quicktime_read_data(file, data, 4);
 
154
/*      fread(data, 4, 1, file->stream); */
 
155
        a = data[0];
 
156
        b = data[1];
 
157
        c = data[2];
 
158
        d = data[3];
 
159
        
 
160
        a = (a << 8) + b;
 
161
        b = (c << 8) + d;
 
162
 
 
163
        return (float)a + (float)b / 65536;
 
164
}
 
165
 
 
166
int quicktime_write_fixed32(quicktime_t *file, float number)
 
167
{
 
168
        unsigned char data[4];
 
169
        int a, b;
 
170
 
 
171
        a = number;
 
172
        b = (number - a) * 65536;
 
173
        data[0] = a >> 8;
 
174
        data[1] = a & 0xff;
 
175
        data[2] = b >> 8;
 
176
        data[3] = b & 0xff;
 
177
 
 
178
        return quicktime_write_data(file, data, 4);
 
179
}
 
180
 
 
181
int quicktime_write_int64(quicktime_t *file, u_int64_t value)
 
182
{
 
183
        unsigned char data[8];
 
184
        int i;
 
185
 
 
186
        for (i = 7; i >= 0; i--) {
 
187
                data[i] = value & 0xff;
 
188
                value >>= 8;
 
189
        }
 
190
 
 
191
        return quicktime_write_data(file, data, 8);
 
192
}
 
193
 
 
194
int quicktime_write_int32(quicktime_t *file, long value)
 
195
{
 
196
        unsigned char data[4];
 
197
 
 
198
        data[0] = (value & 0xff000000) >> 24;
 
199
        data[1] = (value & 0xff0000) >> 16;
 
200
        data[2] = (value & 0xff00) >> 8;
 
201
        data[3] = value & 0xff;
 
202
 
 
203
        return quicktime_write_data(file, data, 4);
 
204
}
 
205
 
 
206
int quicktime_write_char32(quicktime_t *file, char *string)
 
207
{
 
208
        return quicktime_write_data(file, string, 4);
 
209
}
 
210
 
 
211
 
 
212
float quicktime_read_fixed16(quicktime_t *file)
 
213
{
 
214
        unsigned char data[2];
 
215
        
 
216
        quicktime_read_data(file, data, 2);
 
217
        return (float)data[0] + (float)data[1] / 256;
 
218
}
 
219
 
 
220
int quicktime_write_fixed16(quicktime_t *file, float number)
 
221
{
 
222
        unsigned char data[2];
 
223
        int a, b;
 
224
 
 
225
        a = number;
 
226
        b = (number - a) * 256;
 
227
        data[0] = a;
 
228
        data[1] = b;
 
229
        
 
230
        return quicktime_write_data(file, data, 2);
 
231
}
 
232
 
 
233
u_int64_t quicktime_read_int64(quicktime_t *file)
 
234
{
 
235
        u_char data[8];
 
236
        u_int64_t result = 0;
 
237
        int i;
 
238
 
 
239
        quicktime_read_data(file, data, 8);
 
240
 
 
241
        for (i = 0; i < 8; i++) {
 
242
                result |= ((u_int64_t)data[i]) << ((7 - i) * 8);
 
243
        }
 
244
 
 
245
        return result;
 
246
}
 
247
 
 
248
long quicktime_read_int32(quicktime_t *file)
 
249
{
 
250
        unsigned long result;
 
251
        unsigned long a, b, c, d;
 
252
        char data[4];
 
253
        
 
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];
 
259
 
 
260
        result = (a<<24) | (b<<16) | (c<<8) | d;
 
261
        return (long)result;
 
262
}
 
263
 
 
264
 
 
265
long quicktime_read_int24(quicktime_t *file)
 
266
{
 
267
        unsigned long result;
 
268
        unsigned long a, b, c;
 
269
        char data[4];
 
270
        
 
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];
 
276
 
 
277
        result = (a<<16) | (b<<8) | c;
 
278
        return (long)result;
 
279
}
 
280
 
 
281
int quicktime_write_int24(quicktime_t *file, long number)
 
282
{
 
283
        unsigned char data[3];
 
284
        data[0] = (number & 0xff0000) >> 16;
 
285
        data[1] = (number & 0xff00) >> 8;
 
286
        data[2] = (number & 0xff);
 
287
        
 
288
        return quicktime_write_data(file, data, 3);
 
289
/*      return fwrite(data, 3, 1, file->stream); */
 
290
}
 
291
 
 
292
int quicktime_read_int16(quicktime_t *file)
 
293
{
 
294
        unsigned long result;
 
295
        unsigned long a, b;
 
296
        char data[2];
 
297
        
 
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];
 
302
 
 
303
        result = (a<<8) | b;
 
304
        return (int)result;
 
305
}
 
306
 
 
307
int quicktime_write_int16(quicktime_t *file, int number)
 
308
{
 
309
        unsigned char data[2];
 
310
        data[0] = (number & 0xff00) >> 8;
 
311
        data[1] = (number & 0xff);
 
312
        
 
313
        return quicktime_write_data(file, data, 2);
 
314
/*      return fwrite(data, 2, 1, file->stream); */
 
315
}
 
316
 
 
317
int quicktime_read_char(quicktime_t *file)
 
318
{
 
319
        char output;
 
320
        quicktime_read_data(file, &output, 1);
 
321
        return output;
 
322
}
 
323
 
 
324
int quicktime_write_char(quicktime_t *file, char x)
 
325
{
 
326
        return quicktime_write_data(file, &x, 1);
 
327
}
 
328
 
 
329
int quicktime_read_char32(quicktime_t *file, char *string)
 
330
{
 
331
        quicktime_read_data(file, string, 4);
 
332
/*      fread(string, 4, 1, file->stream); */
 
333
}
 
334
 
 
335
long quicktime_position(quicktime_t *file) 
 
336
 
337
        return file->file_position; 
 
338
}
 
339
 
 
340
int quicktime_set_position(quicktime_t *file, long position) 
 
341
{
 
342
        file->file_position = position;
 
343
        return 0;
 
344
/*      fseek(file->stream, position, SEEK_SET);  */
 
345
}
 
346
 
 
347
int quicktime_copy_char32(char *output, char *input)
 
348
{
 
349
        *output++ = *input++;
 
350
        *output++ = *input++;
 
351
        *output++ = *input++;
 
352
        *output = *input;
 
353
}
 
354
 
 
355
 
 
356
int quicktime_print_chars(char *desc, char *input, int len)
 
357
{
 
358
        int i;
 
359
        printf("%s", desc);
 
360
        for(i = 0; i < len; i++) printf("%c", input[i]);
 
361
        printf("\n");
 
362
}
 
363
 
 
364
unsigned long quicktime_current_time()
 
365
{
 
366
        time_t t;
 
367
        time (&t);
 
368
        return (t+(66*31536000)+1468800);
 
369
}
 
370
 
 
371
int quicktime_match_32(char *input, char *output)
 
372
{
 
373
        if(input[0] == output[0] &&
 
374
                input[1] == output[1] &&
 
375
                input[2] == output[2] &&
 
376
                input[3] == output[3])
 
377
                return 1;
 
378
        else 
 
379
                return 0;
 
380
}
 
381
 
 
382
int quicktime_read_mp4_descr_length(quicktime_t *file)
 
383
{
 
384
        u_int8_t b;
 
385
        u_int8_t numBytes = 0;
 
386
        u_int32_t length = 0;
 
387
 
 
388
        do {
 
389
                b = quicktime_read_char(file);
 
390
                numBytes++;
 
391
                length = (length << 7) | (b & 0x7F);
 
392
        } while ((b & 0x80) && numBytes < 4);
 
393
 
 
394
        return length;
 
395
}
 
396
 
 
397
int quicktime_write_mp4_descr_length(quicktime_t *file, int length, bool compact)
 
398
{
 
399
        u_int8_t b;
 
400
        int8_t i;
 
401
        int8_t numBytes;
 
402
 
 
403
        if (compact) {
 
404
                if (length <= 0x7F) {
 
405
                        numBytes = 1;
 
406
                } else if (length <= 0x3FFF) {
 
407
                        numBytes = 2;
 
408
                } else if (length <= 0x1FFFFF) {
 
409
                        numBytes = 3;
 
410
                } else {
 
411
                        numBytes = 4;
 
412
                }
 
413
        } else {
 
414
                numBytes = 4;
 
415
        }
 
416
 
 
417
        for (i = numBytes-1; i >= 0; i--) {
 
418
                b = (length >> (i * 7)) & 0x7F;
 
419
                if (i != 0) {
 
420
                        b |= 0x80;
 
421
                }
 
422
                quicktime_write_char(file, b);
 
423
        }
 
424
 
 
425
        return numBytes; 
 
426
}
 
427
 
 
428
void quicktime_atom_hexdump(quicktime_t* file, quicktime_atom_t* atom)
 
429
{
 
430
        int i;
 
431
        int oldPos;
 
432
 
 
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) {
 
439
                        printf("\n");
 
440
                }
 
441
        }
 
442
        printf("\n");
 
443
        quicktime_set_position(file, oldPos);
 
444
}