allow ffmpeg video to resample curr_pos, add bluray format
[goodguy/history.git] / cinelerra-5.0 / quicktime / atom.c
1 #include <ctype.h>
2 #include <stdio.h>
3 #include "funcprotos.h"
4 #include "quicktime.h"
5 #include "workarounds.h"
6
7
8
9 static int read_type(char *data, unsigned char *type)
10 {
11         type[0] = data[4];
12         type[1] = data[5];
13         type[2] = data[6];
14         type[3] = data[7];
15         type[4] = 0;
16
17 /*printf("%c%c%c%c ", type[0], type[1], type[2], type[3]); */
18 /* need this for quicktime_check_sig */
19         if(isalpha(type[0]) && isalpha(type[1]) && isalpha(type[2]) && isalpha(type[3]))
20         return 0;
21         else
22         return 1;
23 }
24
25
26 static unsigned long read_size(char *data)
27 {
28         unsigned long result;
29         unsigned long a, b, c, d;
30
31         a = (unsigned char)data[0];
32         b = (unsigned char)data[1];
33         c = (unsigned char)data[2];
34         d = (unsigned char)data[3];
35
36         result = (a << 24) | (b << 16) | (c << 8) | d;
37
38 // extended header is size 1
39 //      if(result < HEADER_LENGTH) result = HEADER_LENGTH;
40         return result;
41 }
42
43 static int64_t read_size64(char *data)
44 {
45         uint64_t result, a, b, c, d, e, f, g, h;
46
47         a = (unsigned char)data[0];
48         b = (unsigned char)data[1];
49         c = (unsigned char)data[2];
50         d = (unsigned char)data[3];
51         e = (unsigned char)data[4];
52         f = (unsigned char)data[5];
53         g = (unsigned char)data[6];
54         h = (unsigned char)data[7];
55
56         result = (a << 56) |
57                 (b << 48) |
58                 (c << 40) |
59                 (d << 32) |
60                 (e << 24) |
61                 (f << 16) |
62                 (g << 8) |
63                 h;
64
65         if(result < HEADER_LENGTH) result = HEADER_LENGTH;
66         return (int64_t)result;
67 }
68
69 static int reset(quicktime_atom_t *atom)
70 {
71         atom->end = 0;
72         atom->type[0] = atom->type[1] = atom->type[2] = atom->type[3] = atom->type[4] = 0;
73         return 0;
74 }
75
76 int quicktime_atom_read_header(quicktime_t *file, quicktime_atom_t *atom)
77 {
78         int result = 0;
79         char header[10];
80         int debug = 0;
81
82         if(file->use_avi)
83         {
84                 reset(atom);
85                 atom->start = quicktime_position(file);
86                 if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
87                 atom->type[0] = header[0];
88                 atom->type[1] = header[1];
89                 atom->type[2] = header[2];
90                 atom->type[3] = header[3];
91                 atom->type[4] = 0;
92                 atom->size =
93                         (((unsigned char)header[4])      ) |
94                         (((unsigned char)header[5]) << 8 ) |
95                         (((unsigned char)header[6]) << 16) |
96                         (((unsigned char)header[7]) << 24);
97                 atom->end = quicktime_add3(atom->start, atom->size, 8);
98         }
99         else
100         {
101                 reset(atom);
102
103                 atom->start = quicktime_position(file);
104
105                 if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
106                 result = read_type(header, atom->type);
107                 atom->size = read_size(header);
108                 atom->end = atom->start + atom->size;
109                 if(debug)
110                         printf("quicktime_atom_read_header 1 %c%c%c%c start=0x%jx"
111                                 " size=0x%jx end=0x%jx ftell %jx %jx\n",
112                                 atom->type[0], atom->type[1], atom->type[2], atom->type[3],
113                                 atom->start, atom->size, atom->end,
114                                 file->file_position,
115                                 (int64_t)FTELL(file->stream));
116
117 /* Skip placeholder atom */
118                 if(quicktime_match_32((char*)atom->type, "wide"))
119                 {
120                         atom->start = quicktime_position(file);
121                         reset(atom);
122                         if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
123                         result = read_type(header, atom->type);
124                         atom->size -= 8;
125                         if(atom->size <= 0)
126                         {
127 /* Wrapper ended.  Get new atom size */
128                                 atom->size = read_size(header);
129                         }
130                         atom->end = atom->start + atom->size;
131                 }
132                 else
133 /* Get extended size */
134                 if(atom->size == 1)
135                 {
136                         if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
137                         atom->size = read_size64(header);
138                         atom->end = atom->start + atom->size;
139 /*
140  * printf("quicktime_atom_read_header 2 %c%c%c%c start %llx size %llx end %llx ftell %llx\n",
141  *      atom->type[0], atom->type[1], atom->type[2], atom->type[3],
142  *      atom->start, atom->size, atom->end,
143  *      file->file_position);
144  */
145                 }
146         }
147
148
149         return result;
150 }
151
152 int quicktime_atom_write_header64(quicktime_t *file, quicktime_atom_t *atom, char *text)
153 {
154         int result = 0;
155         atom->start = quicktime_position(file);
156
157         result = !quicktime_write_int32(file, 1);
158         if(!result) result = !quicktime_write_char32(file, text);
159         if(!result) result = !quicktime_write_int64(file, 0);
160
161         atom->use_64 = 1;
162         return result;
163 }
164
165 int quicktime_atom_write_header(quicktime_t *file,
166         quicktime_atom_t *atom,
167         char *text)
168 {
169         int result = 0;
170
171         if(file->use_avi)
172         {
173                 reset(atom);
174                 atom->start = quicktime_position(file) + 8;
175                 result = !quicktime_write_char32(file, text);
176                 if(!result) result = !quicktime_write_int32_le(file, 0);
177                 atom->use_64 = 0;
178         }
179         else
180         {
181                 atom->start = quicktime_position(file);
182                 result = !quicktime_write_int32(file, 0);
183                 if(!result) result = !quicktime_write_char32(file, text);
184                 atom->use_64 = 0;
185         }
186
187         return result;
188 }
189
190 void quicktime_atom_write_footer(quicktime_t *file, quicktime_atom_t *atom)
191 {
192         atom->end = quicktime_position(file);
193         if(file->use_avi)
194         {
195                 quicktime_set_position(file, atom->start - 4);
196                 quicktime_write_int32_le(file, atom->end - atom->start);
197                 atom->size = atom->end - atom->start;
198         }
199         else
200         {
201                 // We should calculate atom->size here also...  it is used in trak.c FIXME
202                 // I don't know internals of the quicktime to know what is proper calculation - with or wirhout header?
203                 if(atom->use_64)
204                 {
205                         quicktime_set_position(file, atom->start + 8);
206 //printf("quicktime_atom_write_footer %llx %llx %llx %llx\n", file->total_length, file->file_position, atom->start, atom->end);
207                         quicktime_write_int64(file, atom->end - atom->start);
208                 }
209                 else
210                 {
211                         quicktime_set_position(file, atom->start);
212                         quicktime_write_int32(file, atom->end - atom->start);
213                 }
214         }
215         quicktime_set_position(file, atom->end);
216 }
217
218 int quicktime_atom_is(quicktime_atom_t *atom, char *typ)
219 {
220         unsigned char *type = (unsigned char *)typ;
221         return  atom->type[0] == type[0] && atom->type[1] == type[1] &&
222                 atom->type[2] == type[2] && atom->type[3] == type[3] ? 1 : 0;
223 }
224
225 int quicktime_atom_skip(quicktime_t *file, quicktime_atom_t *atom)
226 {
227         if(atom->start == atom->end) atom->end++;
228         return quicktime_set_position(file, atom->end);
229 }