r606: convert ODDLEADS to TOP_FIRST and EVENLEADS to BOTTOM_FIRST
[cinelerra_cv/mob.git] / quicktime / stsdtable.c
blob00697d2286ae90c95a999828294055df354db08c
1 #include "funcprotos.h"
2 #include "quicktime.h"
5 void quicktime_mjqt_init(quicktime_mjqt_t *mjqt)
9 void quicktime_mjqt_delete(quicktime_mjqt_t *mjqt)
13 void quicktime_mjqt_dump(quicktime_mjqt_t *mjqt)
18 void quicktime_mjht_init(quicktime_mjht_t *mjht)
22 void quicktime_mjht_delete(quicktime_mjht_t *mjht)
26 void quicktime_mjht_dump(quicktime_mjht_t *mjht)
30 // Set esds header to a copy of the argument
31 void quicktime_set_mpeg4_header(quicktime_stsd_table_t *table,
32 unsigned char *data,
33 int size)
35 if(table->mpeg4_header)
37 free(table->mpeg4_header);
40 table->mpeg4_header = calloc(1, size);
41 memcpy(table->mpeg4_header, data, size);
42 table->mpeg4_header_size = size;
45 static void read_wave(quicktime_t *file,
46 quicktime_stsd_table_t *table,
47 quicktime_atom_t *parent_atom)
49 quicktime_atom_t leaf_atom;
50 while(quicktime_position(file) < parent_atom->end)
52 quicktime_atom_read_header(file, &leaf_atom);
53 if(quicktime_atom_is(&leaf_atom, "esds"))
55 quicktime_read_esds(file, &leaf_atom, table);
57 else
58 quicktime_atom_skip(file, &leaf_atom);
62 void quicktime_read_stsd_audio(quicktime_t *file, quicktime_stsd_table_t *table, quicktime_atom_t *parent_atom)
64 quicktime_atom_t leaf_atom;
66 table->version = quicktime_read_int16(file);
67 table->revision = quicktime_read_int16(file);
68 quicktime_read_data(file, table->vendor, 4);
69 table->channels = quicktime_read_int16(file);
70 table->sample_size = quicktime_read_int16(file);
71 table->compression_id = quicktime_read_int16(file);
72 table->packet_size = quicktime_read_int16(file);
73 table->sample_rate = quicktime_read_fixed32(file);
75 // Kluge for fixed32 limitation
76 if(table->sample_rate + 65536 == 96000 ||
77 table->sample_rate + 65536 == 88200) table->sample_rate += 65536;
80 // Version 1 fields
81 if(table->version == 1)
83 table->samples_per_packet = quicktime_read_int32(file);
84 table->bytes_per_packet = quicktime_read_int32(file);
85 table->bytes_per_frame = quicktime_read_int32(file);
86 table->bytes_per_sample = quicktime_read_int32(file);
87 while(quicktime_position(file) < parent_atom->end)
89 quicktime_atom_read_header(file, &leaf_atom);
90 if(quicktime_atom_is(&leaf_atom, "wave"))
92 read_wave(file, table, &leaf_atom);
94 else
95 quicktime_atom_skip(file, &leaf_atom);
100 void quicktime_write_stsd_audio(quicktime_t *file, quicktime_stsd_table_t *table)
102 quicktime_write_int16(file, table->version);
103 quicktime_write_int16(file, table->revision);
104 quicktime_write_data(file, table->vendor, 4);
105 quicktime_write_int16(file, table->channels);
106 quicktime_write_int16(file, table->sample_size);
107 quicktime_write_int16(file, table->compression_id);
108 quicktime_write_int16(file, table->packet_size);
109 quicktime_write_fixed32(file, table->sample_rate);
112 // Lifted from mplayer and changed a bit
113 struct __attribute__((__packed__)) ImageDescription {
114 // int32_t idSize; /* total size of ImageDescription including extra data ( CLUTs and other per sequence data ) */
115 char cType[4]; /* what kind of codec compressed this data */
116 int32_t resvd1; /* reserved for Apple use */
117 int16_t resvd2; /* reserved for Apple use */
118 int16_t dataRefIndex; /* set to zero */
119 int16_t version; /* which version is this data */
120 int16_t revisionLevel; /* what version of that codec did this */
121 char vendor[4]; /* whose codec compressed this data */
122 uint32_t temporalQuality; /* what was the temporal quality factor */
123 uint32_t spatialQuality; /* what was the spatial quality factor */
124 int16_t width; /* how many pixels wide is this data */
125 int16_t height; /* how many pixels high is this data */
126 int32_t hRes; /* horizontal resolution */
127 int32_t vRes; /* vertical resolution */
128 int32_t dataSize; /* if known, the size of data for this image descriptor */
129 int16_t frameCount; /* number of frames this description applies to */
130 char name[32]; /* name of codec ( in case not installed ) */
131 int16_t depth; /* what depth is this data (1-32) or ( 33-40 grayscale ) */
132 int16_t clutID; /* clut id or if 0 clut follows or -1 if no clut */
136 void quicktime_read_stsd_video(quicktime_t *file,
137 quicktime_stsd_table_t *table,
138 quicktime_atom_t *parent_atom)
140 quicktime_atom_t leaf_atom;
141 int len;
143 table->version = quicktime_read_int16(file);
144 table->revision = quicktime_read_int16(file);
145 quicktime_read_data(file, table->vendor, 4);
146 table->temporal_quality = quicktime_read_int32(file);
147 table->spatial_quality = quicktime_read_int32(file);
148 table->width = quicktime_read_int16(file);
149 table->height = quicktime_read_int16(file);
150 table->dpi_horizontal = quicktime_read_fixed32(file);
151 table->dpi_vertical = quicktime_read_fixed32(file);
152 table->data_size = quicktime_read_int32(file);
153 table->frames_per_sample = quicktime_read_int16(file);
154 len = quicktime_read_char(file);
155 quicktime_read_data(file, table->compressor_name, 31);
156 table->depth = quicktime_read_int16(file);
157 table->ctab_id = quicktime_read_int16(file);
160 /* The data needed for SVQ3 codec and maybe some others ? */
161 struct ImageDescription *id;
162 int stsd_size,fourcc,c,d;
163 stsd_size = parent_atom->end - parent_atom->start;
164 table->extradata_size = stsd_size - 4;
165 id = (struct ImageDescription *) malloc(table->extradata_size); // we do not include size
166 table->extradata = (char *) id;
168 memcpy(id->cType, table->format, 4); // Fourcc
169 id->version = table->version;
170 id->revisionLevel = table->revision;
171 memcpy(id->vendor, table->vendor, 4); // I think mplayer screws up on this one, it turns bytes around! :)
172 id->temporalQuality = table->temporal_quality;
173 id->spatialQuality = table->spatial_quality;
174 id->width = table->width;
175 id->height = table->height;
176 id->hRes = table->dpi_horizontal;
177 id->vRes = table->dpi_vertical;
178 id->dataSize = table->data_size;
179 id->frameCount = table->frames_per_sample;
180 id->name[0] = len;
181 memcpy(&(id->name[1]), table->compressor_name, 31);
182 id->depth = table->depth;
183 id->clutID = table->ctab_id;
184 if (quicktime_position(file) < parent_atom->end)
186 int position = quicktime_position(file); // remember position
187 int datalen = parent_atom->end - position;
188 quicktime_read_data(file, ((char*)&id->clutID)+2, datalen);
189 quicktime_set_position(file, position); // return to previous position so parsing can go on
193 while(quicktime_position(file) < parent_atom->end)
195 quicktime_atom_read_header(file, &leaf_atom);
196 //printf("quicktime_read_stsd_video 1 %llx %llx %llx\n", leaf_atom.start, leaf_atom.end, quicktime_position(file));
199 if(quicktime_atom_is(&leaf_atom, "esds"))
201 quicktime_read_esds(file, &leaf_atom, table);
203 else
204 if(quicktime_atom_is(&leaf_atom, "ctab"))
206 quicktime_read_ctab(file, &(table->ctab));
208 else
209 if(quicktime_atom_is(&leaf_atom, "gama"))
211 table->gamma = quicktime_read_fixed32(file);
213 else
214 if(quicktime_atom_is(&leaf_atom, "fiel"))
216 table->fields = quicktime_read_char(file);
217 table->field_dominance = quicktime_read_char(file);
219 else
220 quicktime_atom_skip(file, &leaf_atom);
223 /* if(quicktime_atom_is(&leaf_atom, "mjqt")) */
224 /* { */
225 /* quicktime_read_mjqt(file, &(table->mjqt)); */
226 /* } */
227 /* else */
228 /* if(quicktime_atom_is(&leaf_atom, "mjht")) */
229 /* { */
230 /* quicktime_read_mjht(file, &(table->mjht)); */
231 /* } */
232 /* else */
234 //printf("quicktime_read_stsd_video 2\n");
237 void quicktime_write_stsd_video(quicktime_t *file, quicktime_stsd_table_t *table)
239 quicktime_write_int16(file, table->version);
240 quicktime_write_int16(file, table->revision);
241 quicktime_write_data(file, table->vendor, 4);
242 quicktime_write_int32(file, table->temporal_quality);
243 quicktime_write_int32(file, table->spatial_quality);
244 quicktime_write_int16(file, table->width);
245 quicktime_write_int16(file, table->height);
246 quicktime_write_fixed32(file, table->dpi_horizontal);
247 quicktime_write_fixed32(file, table->dpi_vertical);
248 quicktime_write_int32(file, table->data_size);
249 quicktime_write_int16(file, table->frames_per_sample);
250 quicktime_write_char(file, strlen(table->compressor_name));
251 quicktime_write_data(file, table->compressor_name, 31);
252 quicktime_write_int16(file, table->depth);
253 quicktime_write_int16(file, table->ctab_id);
256 // Write field order for mjpa
257 if(table->fields)
259 quicktime_atom_t atom;
261 quicktime_atom_write_header(file, &atom, "fiel");
262 quicktime_write_char(file, table->fields);
263 quicktime_write_char(file, table->field_dominance);
264 quicktime_atom_write_footer(file, &atom);
267 // Write header for mp4v
268 if(table->mpeg4_header_size && table->mpeg4_header)
270 quicktime_write_esds(file, table, 1, 0);
274 void quicktime_read_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table)
276 quicktime_atom_t leaf_atom;
278 quicktime_atom_read_header(file, &leaf_atom);
280 table->format[0] = leaf_atom.type[0];
281 table->format[1] = leaf_atom.type[1];
282 table->format[2] = leaf_atom.type[2];
283 table->format[3] = leaf_atom.type[3];
284 quicktime_read_data(file, table->reserved, 6);
285 table->data_reference = quicktime_read_int16(file);
287 if(minf->is_audio) quicktime_read_stsd_audio(file, table, &leaf_atom);
288 if(minf->is_video) quicktime_read_stsd_video(file, table, &leaf_atom);
291 void quicktime_stsd_table_init(quicktime_stsd_table_t *table)
293 int i;
294 table->format[0] = 'y';
295 table->format[1] = 'u';
296 table->format[2] = 'v';
297 table->format[3] = '2';
298 for(i = 0; i < 6; i++) table->reserved[i] = 0;
299 table->data_reference = 1;
301 table->version = 0;
302 table->revision = 0;
303 table->vendor[0] = 'l';
304 table->vendor[1] = 'n';
305 table->vendor[2] = 'u';
306 table->vendor[3] = 'x';
308 table->temporal_quality = 100;
309 table->spatial_quality = 258;
310 table->width = 0;
311 table->height = 0;
312 table->dpi_horizontal = 72;
313 table->dpi_vertical = 72;
314 table->data_size = 0;
315 table->frames_per_sample = 1;
316 for(i = 0; i < 32; i++) table->compressor_name[i] = 0;
317 sprintf(table->compressor_name, "Quicktime for Linux");
318 table->depth = 24;
319 table->ctab_id = 65535;
320 quicktime_ctab_init(&(table->ctab));
321 table->gamma = 0;
322 table->fields = 0;
323 table->field_dominance = 1;
324 quicktime_mjqt_init(&(table->mjqt));
325 quicktime_mjht_init(&(table->mjht));
327 table->channels = 0;
328 table->sample_size = 0;
329 table->compression_id = 0;
330 table->packet_size = 0;
331 table->sample_rate = 0;
333 table->mpeg4_header = 0;
334 table->mpeg4_header_size = 0;
336 table->extradata = 0;
337 table->extradata_size = 0;
341 void quicktime_stsd_table_delete(quicktime_stsd_table_t *table)
343 quicktime_ctab_delete(&(table->ctab));
344 quicktime_mjqt_delete(&(table->mjqt));
345 quicktime_mjht_delete(&(table->mjht));
346 if(table->mpeg4_header) free(table->mpeg4_header);
347 if(table->extradata) free(table->extradata);
350 void quicktime_stsd_video_dump(quicktime_stsd_table_t *table)
352 printf(" version %d\n", table->version);
353 printf(" revision %d\n", table->revision);
354 printf(" vendor %c%c%c%c\n", table->vendor[0], table->vendor[1], table->vendor[2], table->vendor[3]);
355 printf(" temporal_quality %ld\n", table->temporal_quality);
356 printf(" spatial_quality %ld\n", table->spatial_quality);
357 printf(" width %d\n", table->width);
358 printf(" height %d\n", table->height);
359 printf(" dpi_horizontal %f\n", table->dpi_horizontal);
360 printf(" dpi_vertical %f\n", table->dpi_vertical);
361 printf(" data_size %ld\n", table->data_size);
362 printf(" frames_per_sample %d\n", table->frames_per_sample);
363 printf(" compressor_name %s\n", table->compressor_name);
364 printf(" depth %d\n", table->depth);
365 printf(" ctab_id %d\n", table->ctab_id);
366 printf(" gamma %f\n", table->gamma);
367 if(table->fields)
369 printf(" fields %d\n", table->fields);
370 printf(" field dominance %d\n", table->field_dominance);
372 if(!table->ctab_id) quicktime_ctab_dump(&(table->ctab));
373 quicktime_mjqt_dump(&(table->mjqt));
374 quicktime_mjht_dump(&(table->mjht));
377 void quicktime_stsd_audio_dump(quicktime_stsd_table_t *table)
379 printf(" version %d\n", table->version);
380 printf(" revision %d\n", table->revision);
381 printf(" vendor %c%c%c%c\n", table->vendor[0], table->vendor[1], table->vendor[2], table->vendor[3]);
382 printf(" channels %d\n", table->channels);
383 printf(" sample_size %d\n", table->sample_size);
384 printf(" compression_id %d\n", table->compression_id);
385 printf(" packet_size %d\n", table->packet_size);
386 printf(" sample_rate %f\n", table->sample_rate);
387 if(table->version == 1)
389 printf(" samples_per_packet %d\n", table->samples_per_packet);
390 printf(" bytes_per_packet %d\n", table->bytes_per_packet);
391 printf(" bytes_per_frame %d\n", table->bytes_per_frame);
392 printf(" bytes_per_sample %d\n", table->bytes_per_sample);
396 void quicktime_stsd_table_dump(void *minf_ptr, quicktime_stsd_table_t *table)
398 quicktime_minf_t *minf = minf_ptr;
399 printf(" format %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]);
400 quicktime_print_chars(" reserved ", table->reserved, 6);
401 printf(" data_reference %d\n", table->data_reference);
403 if(minf->is_audio) quicktime_stsd_audio_dump(table);
404 if(minf->is_video) quicktime_stsd_video_dump(table);
407 void quicktime_write_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table)
409 quicktime_atom_t atom;
410 quicktime_atom_write_header(file, &atom, table->format);
411 /*printf("quicktime_write_stsd_table %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]); */
412 quicktime_write_data(file, table->reserved, 6);
413 quicktime_write_int16(file, table->data_reference);
415 if(minf->is_audio) quicktime_write_stsd_audio(file, table);
416 if(minf->is_video) quicktime_write_stsd_video(file, table);
418 quicktime_atom_write_footer(file, &atom);