00001 #include <ctype.h>
00002 #include <stdio.h>
00003 #include "funcprotos.h"
00004 #include "quicktime.h"
00005 #include "workarounds.h"
00006
00007
00008
00009 static int read_type(char *data, char *type)
00010 {
00011 type[0] = data[4];
00012 type[1] = data[5];
00013 type[2] = data[6];
00014 type[3] = data[7];
00015 type[4] = 0;
00016
00017
00018
00019 if(isalpha(type[0]) && isalpha(type[1]) && isalpha(type[2]) && isalpha(type[3]))
00020 return 0;
00021 else
00022 return 1;
00023 }
00024
00025
00026 static unsigned long read_size(char *data)
00027 {
00028 unsigned long result;
00029 unsigned long a, b, c, d;
00030
00031 a = (unsigned char)data[0];
00032 b = (unsigned char)data[1];
00033 c = (unsigned char)data[2];
00034 d = (unsigned char)data[3];
00035
00036 result = (a << 24) | (b << 16) | (c << 8) | d;
00037
00038
00039
00040 return result;
00041 }
00042
00043 static int64_t read_size64(char *data)
00044 {
00045 uint64_t result, a, b, c, d, e, f, g, h;
00046
00047 a = (unsigned char)data[0];
00048 b = (unsigned char)data[1];
00049 c = (unsigned char)data[2];
00050 d = (unsigned char)data[3];
00051 e = (unsigned char)data[4];
00052 f = (unsigned char)data[5];
00053 g = (unsigned char)data[6];
00054 h = (unsigned char)data[7];
00055
00056 result = (a << 56) |
00057 (b << 48) |
00058 (c << 40) |
00059 (d << 32) |
00060 (e << 24) |
00061 (f << 16) |
00062 (g << 8) |
00063 h;
00064
00065 if(result < HEADER_LENGTH) result = HEADER_LENGTH;
00066 return (int64_t)result;
00067 }
00068
00069 static int reset(quicktime_atom_t *atom)
00070 {
00071 atom->end = 0;
00072 atom->type[0] = atom->type[1] = atom->type[2] = atom->type[3] = atom->type[4] = 0;
00073 return 0;
00074 }
00075
00076 int quicktime_atom_read_header(quicktime_t *file, quicktime_atom_t *atom)
00077 {
00078 int result = 0;
00079 char header[10];
00080
00081 if(file->use_avi)
00082 {
00083 reset(atom);
00084 atom->start = quicktime_position(file);
00085 if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
00086 atom->type[0] = header[0];
00087 atom->type[1] = header[1];
00088 atom->type[2] = header[2];
00089 atom->type[3] = header[3];
00090 atom->type[4] = 0;
00091 atom->size =
00092 (((unsigned char)header[4]) ) |
00093 (((unsigned char)header[5]) << 8 ) |
00094 (((unsigned char)header[6]) << 16) |
00095 (((unsigned char)header[7]) << 24);
00096 atom->end = quicktime_add3(atom->start, atom->size, 8);
00097 }
00098 else
00099 {
00100 int64_t size2;
00101
00102 reset(atom);
00103
00104 atom->start = quicktime_position(file);
00105
00106 if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
00107 result = read_type(header, atom->type);
00108 atom->size = read_size(header);
00109 atom->end = atom->start + atom->size;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 if(quicktime_match_32(atom->type, "wide"))
00120 {
00121 atom->start = quicktime_position(file);
00122 reset(atom);
00123 if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
00124 result = read_type(header, atom->type);
00125 atom->size -= 8;
00126 if(atom->size <= 0)
00127 {
00128
00129 atom->size = read_size(header);
00130 }
00131 atom->end = atom->start + atom->size;
00132 }
00133 else
00134
00135 if(atom->size == 1)
00136 {
00137 if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
00138 atom->size = read_size64(header);
00139 atom->end = atom->start + atom->size;
00140
00141
00142
00143
00144
00145
00146 }
00147 }
00148
00149
00150 return result;
00151 }
00152
00153 int quicktime_atom_write_header64(quicktime_t *file, quicktime_atom_t *atom, char *text)
00154 {
00155 int result = 0;
00156 atom->start = quicktime_position(file);
00157
00158 result = !quicktime_write_int32(file, 1);
00159 if(!result) result = !quicktime_write_char32(file, text);
00160 if(!result) result = !quicktime_write_int64(file, 0);
00161
00162 atom->use_64 = 1;
00163 return result;
00164 }
00165
00166 int quicktime_atom_write_header(quicktime_t *file,
00167 quicktime_atom_t *atom,
00168 char *text)
00169 {
00170 int result = 0;
00171
00172 if(file->use_avi)
00173 {
00174 reset(atom);
00175 atom->start = quicktime_position(file) + 8;
00176 result = !quicktime_write_char32(file, text);
00177 if(!result) result = !quicktime_write_int32_le(file, 0);
00178 atom->use_64 = 0;
00179 }
00180 else
00181 {
00182 atom->start = quicktime_position(file);
00183 result = !quicktime_write_int32(file, 0);
00184 if(!result) result = !quicktime_write_char32(file, text);
00185 atom->use_64 = 0;
00186 }
00187
00188 return result;
00189 }
00190
00191 void quicktime_atom_write_footer(quicktime_t *file, quicktime_atom_t *atom)
00192 {
00193 atom->end = quicktime_position(file);
00194 if(file->use_avi)
00195 {
00196 quicktime_set_position(file, atom->start - 4);
00197 quicktime_write_int32_le(file, atom->end - atom->start);
00198 atom->size = atom->end - atom->start;
00199 }
00200 else
00201 {
00202
00203
00204 if(atom->use_64)
00205 {
00206 quicktime_set_position(file, atom->start + 8);
00207
00208 quicktime_write_int64(file, atom->end - atom->start);
00209 }
00210 else
00211 {
00212 quicktime_set_position(file, atom->start);
00213 quicktime_write_int32(file, atom->end - atom->start);
00214 }
00215 }
00216 quicktime_set_position(file, atom->end);
00217 }
00218
00219 int quicktime_atom_is(quicktime_atom_t *atom, unsigned char *type)
00220 {
00221 if(atom->type[0] == type[0] &&
00222 atom->type[1] == type[1] &&
00223 atom->type[2] == type[2] &&
00224 atom->type[3] == type[3])
00225 return 1;
00226 else
00227 return 0;
00228 }
00229
00230 int quicktime_atom_skip(quicktime_t *file, quicktime_atom_t *atom)
00231 {
00232 if(atom->start == atom->end) atom->end++;
00233 return quicktime_set_position(file, atom->end);
00234 }