00001 #include <fcntl.h>
00002 #include <linux/cdrom.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <sys/ioctl.h>
00007 #include <sys/stat.h>
00008 #include <time.h>
00009 #include <unistd.h>
00010 #include "funcprotos.h"
00011 #include "quicktime.h"
00012 #include "workarounds.h"
00013
00014
00015
00016 int64_t quicktime_get_file_length(char *path)
00017 {
00018 struct stat64 status;
00019 if(stat64(path, &status))
00020 perror("quicktime_get_file_length stat64:");
00021 return status.st_size;
00022 }
00023
00024 int quicktime_file_open(quicktime_t *file, char *path, int rd, int wr)
00025 {
00026 int exists = 0;
00027 char flags[10];
00028 if(rd && (file->stream = fopen(path, "rb")))
00029 {
00030 exists = 1;
00031 fclose(file->stream);
00032 }
00033
00034 if(rd && !wr) sprintf(flags, "rb");
00035 else
00036 if(!rd && wr) sprintf(flags, "wb");
00037 else
00038 if(rd && wr)
00039 {
00040 if(exists)
00041 sprintf(flags, "rb+");
00042 else
00043 sprintf(flags, "wb+");
00044 }
00045
00046 if(!(file->stream = fopen(path, flags)))
00047 {
00048 perror(__FUNCTION__);
00049 return 1;
00050 }
00051
00052
00053 if(rd && exists)
00054 {
00055 file->total_length = quicktime_get_file_length(path);
00056 }
00057
00058 file->presave_buffer = calloc(1, QUICKTIME_PRESAVE);
00059 return 0;
00060 }
00061
00062 int quicktime_file_close(quicktime_t *file)
00063 {
00064
00065 if(file->presave_size)
00066 {
00067 quicktime_fseek(file, file->presave_position - file->presave_size);
00068 fwrite(file->presave_buffer, 1, file->presave_size, file->stream);
00069 file->presave_size = 0;
00070 }
00071
00072 if(file->stream)
00073 {
00074 fclose(file->stream);
00075 }
00076 file->stream = 0;
00077 return 0;
00078 }
00079
00080
00081
00082 int64_t quicktime_ftell(quicktime_t *file)
00083 {
00084 return file->ftell_position;
00085 }
00086
00087 int quicktime_fseek(quicktime_t *file, int64_t offset)
00088 {
00089 file->ftell_position = offset;
00090 if(offset > file->total_length || offset < 0) return 1;
00091 if(FSEEK(file->stream, file->ftell_position, SEEK_SET))
00092 {
00093
00094 return 1;
00095 }
00096 return 0;
00097 }
00098
00099
00100 static int read_preload(quicktime_t *file, char *data, int64_t size)
00101 {
00102 int64_t selection_start = 0;
00103 int64_t selection_end = 0;
00104 int64_t fragment_start = 0;
00105 int64_t fragment_len = 0;
00106
00107 selection_start = file->file_position;
00108 selection_end = quicktime_add(file->file_position, size);
00109
00110 fragment_start = file->preload_ptr + (selection_start - file->preload_start);
00111 while(fragment_start < 0) fragment_start += file->preload_size;
00112 while(fragment_start >= file->preload_size) fragment_start -= file->preload_size;
00113
00114 while(selection_start < selection_end)
00115 {
00116 fragment_len = selection_end - selection_start;
00117 if(fragment_start + fragment_len > file->preload_size)
00118 fragment_len = file->preload_size - fragment_start;
00119
00120 memcpy(data, file->preload_buffer + fragment_start, fragment_len);
00121 fragment_start += fragment_len;
00122 data += fragment_len;
00123
00124 if(fragment_start >= file->preload_size) fragment_start = (int64_t)0;
00125 selection_start += fragment_len;
00126 }
00127 return 0;
00128 }
00129
00130 int quicktime_read_data(quicktime_t *file, char *data, int64_t size)
00131 {
00132 int result = 1;
00133
00134 if(!file->preload_size)
00135 {
00136 quicktime_fseek(file, file->file_position);
00137 result = fread(data, size, 1, file->stream);
00138 file->ftell_position += size;
00139 }
00140 else
00141 {
00142
00143 int64_t selection_start = file->file_position;
00144 int64_t selection_end = file->file_position + size;
00145 int64_t fragment_start, fragment_len;
00146
00147 if(selection_end - selection_start > file->preload_size)
00148 {
00149
00150 printf("read data Size is larger than preload size. size=%llx preload_size=%llx\n",
00151 selection_end - selection_start, file->preload_size);
00152 quicktime_fseek(file, file->file_position);
00153 result = fread(data, size, 1, file->stream);
00154 file->ftell_position += size;
00155 }
00156 else
00157 if(selection_start >= file->preload_start &&
00158 selection_start < file->preload_end &&
00159 selection_end <= file->preload_end &&
00160 selection_end > file->preload_start)
00161 {
00162
00163 read_preload(file, data, size);
00164 }
00165 else
00166 if(selection_end > file->preload_end &&
00167 selection_end - file->preload_size < file->preload_end)
00168 {
00169
00170
00171 while(selection_end - file->preload_start > file->preload_size)
00172 {
00173 fragment_len = selection_end - file->preload_start - file->preload_size;
00174 if(file->preload_ptr + fragment_len > file->preload_size)
00175 fragment_len = file->preload_size - file->preload_ptr;
00176 file->preload_start += fragment_len;
00177 file->preload_ptr += fragment_len;
00178 if(file->preload_ptr >= file->preload_size) file->preload_ptr = 0;
00179 }
00180
00181
00182 fragment_start = file->preload_ptr + file->preload_end - file->preload_start;
00183 while(fragment_start >= file->preload_size)
00184 fragment_start -= file->preload_size;
00185
00186 while(file->preload_end < selection_end)
00187 {
00188 fragment_len = selection_end - file->preload_end;
00189 if(fragment_start + fragment_len > file->preload_size) fragment_len = file->preload_size - fragment_start;
00190 quicktime_fseek(file, file->preload_end);
00191 result = fread(&(file->preload_buffer[fragment_start]), fragment_len, 1, file->stream);
00192 file->ftell_position += fragment_len;
00193 file->preload_end += fragment_len;
00194 fragment_start += fragment_len;
00195 if(fragment_start >= file->preload_size) fragment_start = 0;
00196 }
00197
00198 read_preload(file, data, size);
00199 }
00200 else
00201 {
00202
00203
00204 quicktime_fseek(file, file->file_position);
00205 result = fread(file->preload_buffer, size, 1, file->stream);
00206 file->ftell_position += size;
00207 file->preload_start = file->file_position;
00208 file->preload_end = file->file_position + size;
00209 file->preload_ptr = 0;
00210 read_preload(file, data, size);
00211 }
00212 }
00213
00214 file->file_position += size;
00215 return result;
00216 }
00217
00218 void quicktime_set_presave(quicktime_t *file, int value)
00219 {
00220
00221 if(!value && file->use_presave)
00222 {
00223 quicktime_fseek(file, file->presave_position - file->presave_size);
00224 fwrite(file->presave_buffer, 1, file->presave_size, file->stream);
00225 file->presave_size = 0;
00226 file->file_position = file->presave_position;
00227 file->ftell_position = file->presave_position;
00228 if(file->total_length < file->ftell_position)
00229 file->total_length = file->ftell_position;
00230 }
00231 else
00232 if(value && !file->use_presave)
00233 {
00234 ;
00235 }
00236
00237 file->use_presave = value;
00238 }
00239
00240 int quicktime_write_data(quicktime_t *file, char *data, int size)
00241 {
00242 int data_offset = 0;
00243 int writes_attempted = 0;
00244 int writes_succeeded = 0;
00245 int iterations = 0;
00246
00247 if(!file->use_presave)
00248 {
00249
00250 quicktime_fseek(file, file->file_position);
00251 writes_attempted = 1;
00252 writes_succeeded = fwrite(data,
00253 size,
00254 1,
00255 file->stream);
00256 file->file_position += size;
00257 file->ftell_position += size;
00258 file->presave_position = file->file_position;
00259 }
00260 else
00261 {
00262
00263 if(file->file_position != file->presave_position)
00264 {
00265 if(file->presave_size)
00266 {
00267 quicktime_fseek(file, file->presave_position - file->presave_size);
00268 writes_succeeded += fwrite(file->presave_buffer, 1, file->presave_size, file->stream);
00269 writes_attempted += file->presave_size;
00270 file->presave_size = 0;
00271 }
00272 file->presave_position = file->file_position;
00273 }
00274
00275
00276 while(size > 0)
00277 {
00278 int fragment_size = QUICKTIME_PRESAVE;
00279 if(fragment_size > size) fragment_size = size;
00280 if(fragment_size + file->presave_size > QUICKTIME_PRESAVE)
00281 fragment_size = QUICKTIME_PRESAVE- file->presave_size;
00282
00283 memcpy(file->presave_buffer + file->presave_size,
00284 data + data_offset,
00285 fragment_size);
00286
00287 file->presave_position += fragment_size;
00288 file->presave_size += fragment_size;
00289 data_offset += fragment_size;
00290 size -= fragment_size;
00291
00292 if(file->presave_size >= QUICKTIME_PRESAVE)
00293 {
00294
00295 quicktime_fseek(file, file->presave_position - file->presave_size);
00296 writes_succeeded += fwrite(file->presave_buffer,
00297 file->presave_size,
00298 1,
00299 file->stream);
00300 writes_attempted += file->presave_size;
00301 file->presave_size = 0;
00302 }
00303 }
00304
00305
00306 file->file_position = file->presave_position;
00307
00308 file->ftell_position = file->presave_position;
00309 }
00310
00311
00312
00313 if(file->total_length < file->ftell_position) file->total_length = file->ftell_position;
00314
00315
00316 if(!writes_succeeded && writes_attempted)
00317 {
00318 return 0;
00319 }
00320 else
00321 if(!size)
00322 return 1;
00323 else
00324 return size;
00325 }
00326
00327 int64_t quicktime_byte_position(quicktime_t *file)
00328 {
00329 return quicktime_position(file);
00330 }
00331
00332
00333 void quicktime_read_pascal(quicktime_t *file, char *data)
00334 {
00335 char len = quicktime_read_char(file);
00336 quicktime_read_data(file, data, len);
00337 data[len] = 0;
00338 }
00339
00340 void quicktime_write_pascal(quicktime_t *file, char *data)
00341 {
00342 char len = strlen(data);
00343 quicktime_write_data(file, &len, 1);
00344 quicktime_write_data(file, data, len);
00345 }
00346
00347 float quicktime_read_fixed32(quicktime_t *file)
00348 {
00349 unsigned long a, b, c, d;
00350 unsigned char data[4];
00351
00352 quicktime_read_data(file, data, 4);
00353 a = data[0];
00354 b = data[1];
00355 c = data[2];
00356 d = data[3];
00357
00358 a = (a << 8) + b;
00359 b = (c << 8) + d;
00360
00361 if(b)
00362 return (float)a + (float)b / 65536;
00363 else
00364 return a;
00365 }
00366
00367 int quicktime_write_fixed32(quicktime_t *file, float number)
00368 {
00369 unsigned char data[4];
00370 int a, b;
00371
00372 a = number;
00373 b = (number - a) * 65536;
00374 data[0] = a >> 8;
00375 data[1] = a & 0xff;
00376 data[2] = b >> 8;
00377 data[3] = b & 0xff;
00378
00379 return quicktime_write_data(file, data, 4);
00380 }
00381
00382 int quicktime_write_int64(quicktime_t *file, int64_t value)
00383 {
00384 unsigned char data[8];
00385
00386 data[0] = (((uint64_t)value) & 0xff00000000000000LL) >> 56;
00387 data[1] = (((uint64_t)value) & 0xff000000000000LL) >> 48;
00388 data[2] = (((uint64_t)value) & 0xff0000000000LL) >> 40;
00389 data[3] = (((uint64_t)value) & 0xff00000000LL) >> 32;
00390 data[4] = (((uint64_t)value) & 0xff000000LL) >> 24;
00391 data[5] = (((uint64_t)value) & 0xff0000LL) >> 16;
00392 data[6] = (((uint64_t)value) & 0xff00LL) >> 8;
00393 data[7] = ((uint64_t)value) & 0xff;
00394
00395 return quicktime_write_data(file, data, 8);
00396 }
00397
00398 int quicktime_write_int64_le(quicktime_t *file, int64_t value)
00399 {
00400 unsigned char data[8];
00401
00402 data[7] = (((uint64_t)value) & 0xff00000000000000LL) >> 56;
00403 data[6] = (((uint64_t)value) & 0xff000000000000LL) >> 48;
00404 data[5] = (((uint64_t)value) & 0xff0000000000LL) >> 40;
00405 data[4] = (((uint64_t)value) & 0xff00000000LL) >> 32;
00406 data[3] = (((uint64_t)value) & 0xff000000LL) >> 24;
00407 data[2] = (((uint64_t)value) & 0xff0000LL) >> 16;
00408 data[1] = (((uint64_t)value) & 0xff00LL) >> 8;
00409 data[0] = ((uint64_t)value) & 0xff;
00410
00411 return quicktime_write_data(file, data, 8);
00412 }
00413
00414 int quicktime_write_int32(quicktime_t *file, long value)
00415 {
00416 unsigned char data[4];
00417
00418 data[0] = (value & 0xff000000) >> 24;
00419 data[1] = (value & 0xff0000) >> 16;
00420 data[2] = (value & 0xff00) >> 8;
00421 data[3] = value & 0xff;
00422
00423 return quicktime_write_data(file, data, 4);
00424 }
00425
00426 int quicktime_write_int32_le(quicktime_t *file, long value)
00427 {
00428 unsigned char data[4];
00429
00430 data[3] = (value & 0xff000000) >> 24;
00431 data[2] = (value & 0xff0000) >> 16;
00432 data[1] = (value & 0xff00) >> 8;
00433 data[0] = value & 0xff;
00434
00435 return quicktime_write_data(file, data, 4);
00436 }
00437
00438 int quicktime_write_char32(quicktime_t *file, char *string)
00439 {
00440 return quicktime_write_data(file, string, 4);
00441 }
00442
00443
00444 float quicktime_read_fixed16(quicktime_t *file)
00445 {
00446 unsigned char data[2];
00447
00448 quicktime_read_data(file, data, 2);
00449
00450 if(data[1])
00451 return (float)data[0] + (float)data[1] / 256;
00452 else
00453 return (float)data[0];
00454 }
00455
00456 int quicktime_write_fixed16(quicktime_t *file, float number)
00457 {
00458 unsigned char data[2];
00459 int a, b;
00460
00461 a = number;
00462 b = (number - a) * 256;
00463 data[0] = a;
00464 data[1] = b;
00465
00466 return quicktime_write_data(file, data, 2);
00467 }
00468
00469 unsigned long quicktime_read_uint32(quicktime_t *file)
00470 {
00471 unsigned long result;
00472 unsigned long a, b, c, d;
00473 char data[4];
00474
00475 quicktime_read_data(file, data, 4);
00476 a = (unsigned char)data[0];
00477 b = (unsigned char)data[1];
00478 c = (unsigned char)data[2];
00479 d = (unsigned char)data[3];
00480
00481 result = (a << 24) | (b << 16) | (c << 8) | d;
00482 return result;
00483 }
00484
00485 long quicktime_read_int32(quicktime_t *file)
00486 {
00487 unsigned long result;
00488 unsigned long a, b, c, d;
00489 char data[4];
00490
00491 quicktime_read_data(file, data, 4);
00492 a = (unsigned char)data[0];
00493 b = (unsigned char)data[1];
00494 c = (unsigned char)data[2];
00495 d = (unsigned char)data[3];
00496
00497 result = (a << 24) | (b << 16) | (c << 8) | d;
00498 return (long)result;
00499 }
00500
00501 long quicktime_read_int32_le(quicktime_t *file)
00502 {
00503 unsigned long result;
00504 unsigned long a, b, c, d;
00505 char data[4];
00506
00507 quicktime_read_data(file, data, 4);
00508 a = (unsigned char)data[0];
00509 b = (unsigned char)data[1];
00510 c = (unsigned char)data[2];
00511 d = (unsigned char)data[3];
00512
00513 result = (d << 24) | (c << 16) | (b << 8) | a;
00514 return (long)result;
00515 }
00516
00517 int64_t quicktime_read_int64(quicktime_t *file)
00518 {
00519 uint64_t result, a, b, c, d, e, f, g, h;
00520 char data[8];
00521
00522 quicktime_read_data(file, data, 8);
00523 a = (unsigned char)data[0];
00524 b = (unsigned char)data[1];
00525 c = (unsigned char)data[2];
00526 d = (unsigned char)data[3];
00527 e = (unsigned char)data[4];
00528 f = (unsigned char)data[5];
00529 g = (unsigned char)data[6];
00530 h = (unsigned char)data[7];
00531
00532 result = (a << 56) |
00533 (b << 48) |
00534 (c << 40) |
00535 (d << 32) |
00536 (e << 24) |
00537 (f << 16) |
00538 (g << 8) |
00539 h;
00540 return (int64_t)result;
00541 }
00542
00543 int64_t quicktime_read_int64_le(quicktime_t *file)
00544 {
00545 uint64_t result, a, b, c, d, e, f, g, h;
00546 char data[8];
00547
00548 quicktime_read_data(file, data, 8);
00549 a = (unsigned char)data[7];
00550 b = (unsigned char)data[6];
00551 c = (unsigned char)data[5];
00552 d = (unsigned char)data[4];
00553 e = (unsigned char)data[3];
00554 f = (unsigned char)data[2];
00555 g = (unsigned char)data[1];
00556 h = (unsigned char)data[0];
00557
00558 result = (a << 56) |
00559 (b << 48) |
00560 (c << 40) |
00561 (d << 32) |
00562 (e << 24) |
00563 (f << 16) |
00564 (g << 8) |
00565 h;
00566 return (int64_t)result;
00567 }
00568
00569
00570 long quicktime_read_int24(quicktime_t *file)
00571 {
00572 unsigned long result;
00573 unsigned long a, b, c;
00574 char data[4];
00575
00576 quicktime_read_data(file, data, 3);
00577 a = (unsigned char)data[0];
00578 b = (unsigned char)data[1];
00579 c = (unsigned char)data[2];
00580
00581 result = (a << 16) | (b << 8) | c;
00582 return (long)result;
00583 }
00584
00585 int quicktime_write_int24(quicktime_t *file, long number)
00586 {
00587 unsigned char data[3];
00588 data[0] = (number & 0xff0000) >> 16;
00589 data[1] = (number & 0xff00) >> 8;
00590 data[2] = (number & 0xff);
00591
00592 return quicktime_write_data(file, data, 3);
00593 }
00594
00595 int quicktime_read_int16(quicktime_t *file)
00596 {
00597 unsigned long result;
00598 unsigned long a, b;
00599 char data[2];
00600
00601 quicktime_read_data(file, data, 2);
00602 a = (unsigned char)data[0];
00603 b = (unsigned char)data[1];
00604
00605 result = (a << 8) | b;
00606 return (int)result;
00607 }
00608
00609 int quicktime_read_int16_le(quicktime_t *file)
00610 {
00611 unsigned long result;
00612 unsigned long a, b;
00613 char data[2];
00614
00615 quicktime_read_data(file, data, 2);
00616 a = (unsigned char)data[0];
00617 b = (unsigned char)data[1];
00618
00619 result = (b << 8) | a;
00620 return (int)result;
00621 }
00622
00623 int quicktime_write_int16(quicktime_t *file, int number)
00624 {
00625 unsigned char data[2];
00626 data[0] = (number & 0xff00) >> 8;
00627 data[1] = (number & 0xff);
00628
00629 return quicktime_write_data(file, data, 2);
00630 }
00631
00632 int quicktime_write_int16_le(quicktime_t *file, int number)
00633 {
00634 unsigned char data[2];
00635 data[1] = (number & 0xff00) >> 8;
00636 data[0] = (number & 0xff);
00637
00638 return quicktime_write_data(file, data, 2);
00639 }
00640
00641 int quicktime_read_char(quicktime_t *file)
00642 {
00643 char output;
00644 quicktime_read_data(file, &output, 1);
00645 return output;
00646 }
00647
00648 int quicktime_write_char(quicktime_t *file, char x)
00649 {
00650 return quicktime_write_data(file, &x, 1);
00651 }
00652
00653 void quicktime_read_char32(quicktime_t *file, char *string)
00654 {
00655 quicktime_read_data(file, string, 4);
00656 }
00657
00658 int64_t quicktime_position(quicktime_t *file)
00659 {
00660 return file->file_position;
00661 }
00662
00663 int quicktime_set_position(quicktime_t *file, int64_t position)
00664 {
00665 file->file_position = position;
00666 if(!file->use_presave)
00667 {
00668 quicktime_fseek(file, position);
00669 file->presave_position = position;
00670 }
00671 return 0;
00672 }
00673
00674 void quicktime_copy_char32(char *output, char *input)
00675 {
00676 *output++ = *input++;
00677 *output++ = *input++;
00678 *output++ = *input++;
00679 *output = *input;
00680 }
00681
00682
00683 void quicktime_print_chars(char *desc, char *input, int len)
00684 {
00685 int i;
00686 printf("%s", desc);
00687 for(i = 0; i < len; i++) printf("%c", input[i]);
00688 printf("\n");
00689 }
00690
00691 unsigned long quicktime_current_time(void)
00692 {
00693 time_t t;
00694 time (&t);
00695 return (t+(66*31536000)+1468800);
00696 }
00697
00698 int quicktime_match_32(char *input, char *output)
00699 {
00700 if(input[0] == output[0] &&
00701 input[1] == output[1] &&
00702 input[2] == output[2] &&
00703 input[3] == output[3])
00704 return 1;
00705 else
00706 return 0;
00707 }
00708
00709 int quicktime_match_24(char *input, char *output)
00710 {
00711 if(input[0] == output[0] &&
00712 input[1] == output[1] &&
00713 input[2] == output[2])
00714 return 1;
00715 else
00716 return 0;
00717 }
00718
00719 int quicktime_quantize16(int number)
00720 {
00721 if(number && (number % 16))
00722 {
00723 number += 16 - (number % 16);
00724 }
00725 return number;
00726 }
00727
00728 int quicktime_quantize32(int number)
00729 {
00730 if(number && (number % 32))
00731 {
00732 number += 32 - (number % 32);
00733 }
00734 return number;
00735 }
00736