Changeset View
Changeset View
Standalone View
Standalone View
source/blender/io/avi/intern/avi.c
| Show First 20 Lines • Show All 243 Lines • ▼ Show 20 Lines | bool AVI_is_avi(const char *name) | ||||
| movie.header->SuggestedBufferSize = GET_FCC(movie.fp); | movie.header->SuggestedBufferSize = GET_FCC(movie.fp); | ||||
| movie.header->Width = GET_FCC(movie.fp); | movie.header->Width = GET_FCC(movie.fp); | ||||
| movie.header->Height = GET_FCC(movie.fp); | movie.header->Height = GET_FCC(movie.fp); | ||||
| movie.header->Reserved[0] = GET_FCC(movie.fp); | movie.header->Reserved[0] = GET_FCC(movie.fp); | ||||
| movie.header->Reserved[1] = GET_FCC(movie.fp); | movie.header->Reserved[1] = GET_FCC(movie.fp); | ||||
| movie.header->Reserved[2] = GET_FCC(movie.fp); | movie.header->Reserved[2] = GET_FCC(movie.fp); | ||||
| movie.header->Reserved[3] = GET_FCC(movie.fp); | movie.header->Reserved[3] = GET_FCC(movie.fp); | ||||
| fseek(movie.fp, movie.header->size - 14 * 4, SEEK_CUR); | BLI_fseek(movie.fp, movie.header->size - 14 * 4, SEEK_CUR); | ||||
| /* Limit number of streams to some reasonable amount to prevent | /* Limit number of streams to some reasonable amount to prevent | ||||
| * buffer overflow vulnerabilities. */ | * buffer overflow vulnerabilities. */ | ||||
| if (movie.header->Streams < 1 || movie.header->Streams > 65536) { | if (movie.header->Streams < 1 || movie.header->Streams > 65536) { | ||||
| DEBUG_PRINT("Number of streams should be in range 1-65536\n"); | DEBUG_PRINT("Number of streams should be in range 1-65536\n"); | ||||
| fclose(movie.fp); | fclose(movie.fp); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | for (temp = 0; temp < movie.header->Streams; temp++) { | ||||
| movie.streams[temp].sh.SuggestedBufferSize = GET_FCC(movie.fp); | movie.streams[temp].sh.SuggestedBufferSize = GET_FCC(movie.fp); | ||||
| movie.streams[temp].sh.Quality = GET_FCC(movie.fp); | movie.streams[temp].sh.Quality = GET_FCC(movie.fp); | ||||
| movie.streams[temp].sh.SampleSize = GET_FCC(movie.fp); | movie.streams[temp].sh.SampleSize = GET_FCC(movie.fp); | ||||
| movie.streams[temp].sh.left = GET_TCC(movie.fp); | movie.streams[temp].sh.left = GET_TCC(movie.fp); | ||||
| movie.streams[temp].sh.top = GET_TCC(movie.fp); | movie.streams[temp].sh.top = GET_TCC(movie.fp); | ||||
| movie.streams[temp].sh.right = GET_TCC(movie.fp); | movie.streams[temp].sh.right = GET_TCC(movie.fp); | ||||
| movie.streams[temp].sh.bottom = GET_TCC(movie.fp); | movie.streams[temp].sh.bottom = GET_TCC(movie.fp); | ||||
| fseek(movie.fp, movie.streams[temp].sh.size - 14 * 4, SEEK_CUR); | BLI_fseek(movie.fp, movie.streams[temp].sh.size - 14 * 4, SEEK_CUR); | ||||
| if (GET_FCC(movie.fp) != FCC("strf")) { | if (GET_FCC(movie.fp) != FCC("strf")) { | ||||
| DEBUG_PRINT("no stream format information\n"); | DEBUG_PRINT("no stream format information\n"); | ||||
| MEM_freeN(movie.streams); | MEM_freeN(movie.streams); | ||||
| fclose(movie.fp); | fclose(movie.fp); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| Show All 33 Lines | if (movie.streams[temp].sh.Type == FCC("vids")) { | ||||
| else { | else { | ||||
| MEM_freeN(movie.streams); | MEM_freeN(movie.streams); | ||||
| fclose(movie.fp); | fclose(movie.fp); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (j > 0) { | if (j > 0) { | ||||
| fseek(movie.fp, j, SEEK_CUR); | BLI_fseek(movie.fp, j, SEEK_CUR); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| fseek(movie.fp, movie.streams[temp].sf_size, SEEK_CUR); | BLI_fseek(movie.fp, movie.streams[temp].sf_size, SEEK_CUR); | ||||
| } | } | ||||
| /* Walk to the next LIST */ | /* Walk to the next LIST */ | ||||
| while (GET_FCC(movie.fp) != FCC("LIST")) { | while (GET_FCC(movie.fp) != FCC("LIST")) { | ||||
| temp = GET_FCC(movie.fp); | temp = GET_FCC(movie.fp); | ||||
| if (temp < 0 || ftell(movie.fp) > movie.size) { | if (temp < 0 || BLI_ftell(movie.fp) > movie.size) { | ||||
| DEBUG_PRINT("incorrect size in header or error in AVI\n"); | DEBUG_PRINT("incorrect size in header or error in AVI\n"); | ||||
| MEM_freeN(movie.streams); | MEM_freeN(movie.streams); | ||||
| fclose(movie.fp); | fclose(movie.fp); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| fseek(movie.fp, temp, SEEK_CUR); | BLI_fseek(movie.fp, temp, SEEK_CUR); | ||||
| } | } | ||||
| fseek(movie.fp, -4L, SEEK_CUR); | BLI_fseek(movie.fp, -4L, SEEK_CUR); | ||||
| } | } | ||||
| MEM_freeN(movie.streams); | MEM_freeN(movie.streams); | ||||
| fclose(movie.fp); | fclose(movie.fp); | ||||
| /* at least one video track is needed */ | /* at least one video track is needed */ | ||||
| return (movie_tracks != 0); | return (movie_tracks != 0); | ||||
| } | } | ||||
| Show All 38 Lines | AviError AVI_open_movie(const char *name, AviMovie *movie) | ||||
| movie->header->SuggestedBufferSize = GET_FCC(movie->fp); | movie->header->SuggestedBufferSize = GET_FCC(movie->fp); | ||||
| movie->header->Width = GET_FCC(movie->fp); | movie->header->Width = GET_FCC(movie->fp); | ||||
| movie->header->Height = GET_FCC(movie->fp); | movie->header->Height = GET_FCC(movie->fp); | ||||
| movie->header->Reserved[0] = GET_FCC(movie->fp); | movie->header->Reserved[0] = GET_FCC(movie->fp); | ||||
| movie->header->Reserved[1] = GET_FCC(movie->fp); | movie->header->Reserved[1] = GET_FCC(movie->fp); | ||||
| movie->header->Reserved[2] = GET_FCC(movie->fp); | movie->header->Reserved[2] = GET_FCC(movie->fp); | ||||
| movie->header->Reserved[3] = GET_FCC(movie->fp); | movie->header->Reserved[3] = GET_FCC(movie->fp); | ||||
| fseek(movie->fp, movie->header->size - 14 * 4, SEEK_CUR); | BLI_fseek(movie->fp, movie->header->size - 14 * 4, SEEK_CUR); | ||||
| /* Limit number of streams to some reasonable amount to prevent | /* Limit number of streams to some reasonable amount to prevent | ||||
| * buffer overflow vulnerabilities. */ | * buffer overflow vulnerabilities. */ | ||||
| if (movie->header->Streams < 1 || movie->header->Streams > 65536) { | if (movie->header->Streams < 1 || movie->header->Streams > 65536) { | ||||
| DEBUG_PRINT("Number of streams should be in range 1-65536\n"); | DEBUG_PRINT("Number of streams should be in range 1-65536\n"); | ||||
| return AVI_ERROR_FORMAT; | return AVI_ERROR_FORMAT; | ||||
| } | } | ||||
| Show All 39 Lines | for (temp = 0; temp < movie->header->Streams; temp++) { | ||||
| movie->streams[temp].sh.SuggestedBufferSize = GET_FCC(movie->fp); | movie->streams[temp].sh.SuggestedBufferSize = GET_FCC(movie->fp); | ||||
| movie->streams[temp].sh.Quality = GET_FCC(movie->fp); | movie->streams[temp].sh.Quality = GET_FCC(movie->fp); | ||||
| movie->streams[temp].sh.SampleSize = GET_FCC(movie->fp); | movie->streams[temp].sh.SampleSize = GET_FCC(movie->fp); | ||||
| movie->streams[temp].sh.left = GET_TCC(movie->fp); | movie->streams[temp].sh.left = GET_TCC(movie->fp); | ||||
| movie->streams[temp].sh.top = GET_TCC(movie->fp); | movie->streams[temp].sh.top = GET_TCC(movie->fp); | ||||
| movie->streams[temp].sh.right = GET_TCC(movie->fp); | movie->streams[temp].sh.right = GET_TCC(movie->fp); | ||||
| movie->streams[temp].sh.bottom = GET_TCC(movie->fp); | movie->streams[temp].sh.bottom = GET_TCC(movie->fp); | ||||
| fseek(movie->fp, movie->streams[temp].sh.size - 14 * 4, SEEK_CUR); | BLI_fseek(movie->fp, movie->streams[temp].sh.size - 14 * 4, SEEK_CUR); | ||||
| if (GET_FCC(movie->fp) != FCC("strf")) { | if (GET_FCC(movie->fp) != FCC("strf")) { | ||||
| DEBUG_PRINT("no stream format information\n"); | DEBUG_PRINT("no stream format information\n"); | ||||
| return AVI_ERROR_FORMAT; | return AVI_ERROR_FORMAT; | ||||
| } | } | ||||
| movie->streams[temp].sf_size = GET_FCC(movie->fp); | movie->streams[temp].sf_size = GET_FCC(movie->fp); | ||||
| if (movie->streams[temp].sh.Type == FCC("vids")) { | if (movie->streams[temp].sh.Type == FCC("vids")) { | ||||
| Show All 30 Lines | if (movie->streams[temp].sh.Type == FCC("vids")) { | ||||
| movie->streams[temp].format = AVI_FORMAT_MJPEG; | movie->streams[temp].format = AVI_FORMAT_MJPEG; | ||||
| } | } | ||||
| else { | else { | ||||
| return AVI_ERROR_COMPRESSION; | return AVI_ERROR_COMPRESSION; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (j > 0) { | if (j > 0) { | ||||
| fseek(movie->fp, j, SEEK_CUR); | BLI_fseek(movie->fp, j, SEEK_CUR); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| fseek(movie->fp, movie->streams[temp].sf_size, SEEK_CUR); | BLI_fseek(movie->fp, movie->streams[temp].sf_size, SEEK_CUR); | ||||
| } | } | ||||
| /* Walk to the next LIST */ | /* Walk to the next LIST */ | ||||
| while (GET_FCC(movie->fp) != FCC("LIST")) { | while (GET_FCC(movie->fp) != FCC("LIST")) { | ||||
| temp = GET_FCC(movie->fp); | temp = GET_FCC(movie->fp); | ||||
| if (temp < 0 || ftell(movie->fp) > movie->size) { | if (temp < 0 || BLI_ftell(movie->fp) > movie->size) { | ||||
| DEBUG_PRINT("incorrect size in header or error in AVI\n"); | DEBUG_PRINT("incorrect size in header or error in AVI\n"); | ||||
| return AVI_ERROR_FORMAT; | return AVI_ERROR_FORMAT; | ||||
| } | } | ||||
| fseek(movie->fp, temp, SEEK_CUR); | BLI_fseek(movie->fp, temp, SEEK_CUR); | ||||
| } | } | ||||
| fseek(movie->fp, -4L, SEEK_CUR); | BLI_fseek(movie->fp, -4L, SEEK_CUR); | ||||
| } | } | ||||
| while (1) { | while (1) { | ||||
| temp = GET_FCC(movie->fp); | temp = GET_FCC(movie->fp); | ||||
| size = GET_FCC(movie->fp); | size = GET_FCC(movie->fp); | ||||
| if (size == 0) { | if (size == 0) { | ||||
| break; | break; | ||||
| } | } | ||||
| if (temp == FCC("LIST")) { | if (temp == FCC("LIST")) { | ||||
| if (GET_FCC(movie->fp) == FCC("movi")) { | if (GET_FCC(movie->fp) == FCC("movi")) { | ||||
| break; | break; | ||||
| } | } | ||||
| else { | else { | ||||
| fseek(movie->fp, size - 4, SEEK_CUR); | BLI_fseek(movie->fp, size - 4, SEEK_CUR); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| fseek(movie->fp, size, SEEK_CUR); | BLI_fseek(movie->fp, size, SEEK_CUR); | ||||
| } | } | ||||
| if (ftell(movie->fp) > movie->size) { | if (BLI_ftell(movie->fp) > movie->size) { | ||||
| DEBUG_PRINT("incorrect size in header or error in AVI\n"); | DEBUG_PRINT("incorrect size in header or error in AVI\n"); | ||||
| return AVI_ERROR_FORMAT; | return AVI_ERROR_FORMAT; | ||||
| } | } | ||||
| } | } | ||||
| movie->movi_offset = ftell(movie->fp); | movie->movi_offset = BLI_ftell(movie->fp); | ||||
| movie->read_offset = movie->movi_offset; | movie->read_offset = movie->movi_offset; | ||||
| /* Read in the index if the file has one, otherwise create one */ | /* Read in the index if the file has one, otherwise create one */ | ||||
| if (movie->header->Flags & AVIF_HASINDEX) { | if (movie->header->Flags & AVIF_HASINDEX) { | ||||
| fseek(movie->fp, size - 4, SEEK_CUR); | BLI_fseek(movie->fp, size - 4, SEEK_CUR); | ||||
| if (GET_FCC(movie->fp) != FCC("idx1")) { | if (GET_FCC(movie->fp) != FCC("idx1")) { | ||||
| DEBUG_PRINT("bad index informatio\n"); | DEBUG_PRINT("bad index informatio\n"); | ||||
| return AVI_ERROR_FORMAT; | return AVI_ERROR_FORMAT; | ||||
| } | } | ||||
| movie->index_entries = GET_FCC(movie->fp) / sizeof(AviIndexEntry); | movie->index_entries = GET_FCC(movie->fp) / sizeof(AviIndexEntry); | ||||
| if (movie->index_entries == 0) { | if (movie->index_entries == 0) { | ||||
| ▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | while (cur_frame < frame && i < movie->index_entries) { | ||||
| i++; | i++; | ||||
| } | } | ||||
| } | } | ||||
| if (cur_frame != frame) { | if (cur_frame != frame) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| fseek(movie->fp, movie->read_offset + movie->entries[i - 1].Offset, SEEK_SET); | BLI_fseek(movie->fp, movie->read_offset + movie->entries[i - 1].Offset, SEEK_SET); | ||||
| size_t size = GET_FCC(movie->fp); | size_t size = GET_FCC(movie->fp); | ||||
| buffer = MEM_mallocN(size, "readbuffer"); | buffer = MEM_mallocN(size, "readbuffer"); | ||||
| if (fread(buffer, 1, size, movie->fp) != size) { | if (fread(buffer, 1, size, movie->fp) != size) { | ||||
| MEM_freeN(buffer); | MEM_freeN(buffer); | ||||
| return NULL; | return NULL; | ||||
| ▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...) | ||||
| awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | ||||
| list.fcc = FCC("LIST"); | list.fcc = FCC("LIST"); | ||||
| list.size = 0; | list.size = 0; | ||||
| list.ids = FCC("hdrl"); | list.ids = FCC("hdrl"); | ||||
| awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | ||||
| header_pos1 = ftell(movie->fp); | header_pos1 = BLI_ftell(movie->fp); | ||||
| movie->offset_table[0] = ftell(movie->fp); | movie->offset_table[0] = BLI_ftell(movie->fp); | ||||
| awrite(movie, movie->header, 1, sizeof(AviMainHeader), movie->fp, AVI_MAINH); | awrite(movie, movie->header, 1, sizeof(AviMainHeader), movie->fp, AVI_MAINH); | ||||
| for (i = 0; i < movie->header->Streams; i++) { | for (i = 0; i < movie->header->Streams; i++) { | ||||
| list.fcc = FCC("LIST"); | list.fcc = FCC("LIST"); | ||||
| list.size = 0; | list.size = 0; | ||||
| list.ids = FCC("strl"); | list.ids = FCC("strl"); | ||||
| awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | ||||
| stream_pos1 = ftell(movie->fp); | stream_pos1 = BLI_ftell(movie->fp); | ||||
| movie->offset_table[1 + i * 2] = ftell(movie->fp); | movie->offset_table[1 + i * 2] = BLI_ftell(movie->fp); | ||||
| awrite(movie, &movie->streams[i].sh, 1, sizeof(AviStreamHeader), movie->fp, AVI_STREAMH); | awrite(movie, &movie->streams[i].sh, 1, sizeof(AviStreamHeader), movie->fp, AVI_STREAMH); | ||||
| movie->offset_table[1 + i * 2 + 1] = ftell(movie->fp); | movie->offset_table[1 + i * 2 + 1] = BLI_ftell(movie->fp); | ||||
| awrite(movie, movie->streams[i].sf, 1, movie->streams[i].sf_size, movie->fp, AVI_BITMAPH); | awrite(movie, movie->streams[i].sf, 1, movie->streams[i].sf_size, movie->fp, AVI_BITMAPH); | ||||
| stream_pos2 = ftell(movie->fp); | stream_pos2 = BLI_ftell(movie->fp); | ||||
| fseek(movie->fp, stream_pos1 - 8, SEEK_SET); | BLI_fseek(movie->fp, stream_pos1 - 8, SEEK_SET); | ||||
| PUT_FCCN((stream_pos2 - stream_pos1 + 4L), movie->fp); | PUT_FCCN((stream_pos2 - stream_pos1 + 4L), movie->fp); | ||||
| fseek(movie->fp, stream_pos2, SEEK_SET); | BLI_fseek(movie->fp, stream_pos2, SEEK_SET); | ||||
| } | } | ||||
| junk_pos = ftell(movie->fp); | junk_pos = BLI_ftell(movie->fp); | ||||
| if (junk_pos < 2024 - 8) { | if (junk_pos < 2024 - 8) { | ||||
| chunk.fcc = FCC("JUNK"); | chunk.fcc = FCC("JUNK"); | ||||
| chunk.size = 2024 - 8 - (int)junk_pos; | chunk.size = 2024 - 8 - (int)junk_pos; | ||||
| awrite(movie, &chunk, 1, sizeof(AviChunk), movie->fp, AVI_CHUNK); | awrite(movie, &chunk, 1, sizeof(AviChunk), movie->fp, AVI_CHUNK); | ||||
| for (i = 0; i < chunk.size; i++) { | for (i = 0; i < chunk.size; i++) { | ||||
| putc(0, movie->fp); | putc(0, movie->fp); | ||||
| } | } | ||||
| } | } | ||||
| header_pos2 = ftell(movie->fp); | header_pos2 = BLI_ftell(movie->fp); | ||||
| list.fcc = FCC("LIST"); | list.fcc = FCC("LIST"); | ||||
| list.size = 0; | list.size = 0; | ||||
| list.ids = FCC("movi"); | list.ids = FCC("movi"); | ||||
| awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | ||||
| movie->movi_offset = ftell(movie->fp) - 8L; | movie->movi_offset = BLI_ftell(movie->fp) - 8L; | ||||
| fseek(movie->fp, AVI_HDRL_SOFF, SEEK_SET); | BLI_fseek(movie->fp, AVI_HDRL_SOFF, SEEK_SET); | ||||
| PUT_FCCN((header_pos2 - header_pos1 + 4L), movie->fp); | PUT_FCCN((header_pos2 - header_pos1 + 4L), movie->fp); | ||||
| va_end(ap); | va_end(ap); | ||||
| return AVI_ERROR_NONE; | return AVI_ERROR_NONE; | ||||
| } | } | ||||
| Show All 16 Lines | AviError AVI_write_frame(AviMovie *movie, int frame_num, ...) | ||||
| if (frame_num >= movie->index_entries) { | if (frame_num >= movie->index_entries) { | ||||
| const size_t entry_size = (movie->header->Streams + 1) * sizeof(AviIndexEntry); | const size_t entry_size = (movie->header->Streams + 1) * sizeof(AviIndexEntry); | ||||
| movie->entries = (AviIndexEntry *)MEM_recallocN(movie->entries, (frame_num + 1) * entry_size); | movie->entries = (AviIndexEntry *)MEM_recallocN(movie->entries, (frame_num + 1) * entry_size); | ||||
| movie->index_entries = frame_num + 1; | movie->index_entries = frame_num + 1; | ||||
| } | } | ||||
| /* Slap a new record entry onto the end of the file */ | /* Slap a new record entry onto the end of the file */ | ||||
| fseek(movie->fp, 0L, SEEK_END); | BLI_fseek(movie->fp, 0L, SEEK_END); | ||||
| list.fcc = FCC("LIST"); | list.fcc = FCC("LIST"); | ||||
| list.size = 0; | list.size = 0; | ||||
| list.ids = FCC("rec "); | list.ids = FCC("rec "); | ||||
| awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | awrite(movie, &list, 1, sizeof(AviList), movie->fp, AVI_LIST); | ||||
| rec_off = ftell(movie->fp) - 8L; | rec_off = BLI_ftell(movie->fp) - 8L; | ||||
| /* Write a frame for every stream */ | /* Write a frame for every stream */ | ||||
| va_start(ap, frame_num); | va_start(ap, frame_num); | ||||
| for (stream = 0; stream < movie->header->Streams; stream++) { | for (stream = 0; stream < movie->header->Streams; stream++) { | ||||
| unsigned int tbuf = 0; | unsigned int tbuf = 0; | ||||
| format = va_arg(ap, AviFormat); | format = va_arg(ap, AviFormat); | ||||
| buffer = va_arg(ap, void *); | buffer = va_arg(ap, void *); | ||||
| size_t size = va_arg(ap, int); | size_t size = va_arg(ap, int); | ||||
| /* Convert the buffer into the output format */ | /* Convert the buffer into the output format */ | ||||
| buffer = avi_format_convert( | buffer = avi_format_convert( | ||||
| movie, stream, buffer, format, movie->streams[stream].format, &size); | movie, stream, buffer, format, movie->streams[stream].format, &size); | ||||
| /* Write the header info for this data chunk */ | /* Write the header info for this data chunk */ | ||||
| fseek(movie->fp, 0L, SEEK_END); | BLI_fseek(movie->fp, 0L, SEEK_END); | ||||
| chunk.fcc = avi_get_data_id(format, stream); | chunk.fcc = avi_get_data_id(format, stream); | ||||
| chunk.size = size; | chunk.size = size; | ||||
| if (size % 4) { | if (size % 4) { | ||||
| chunk.size += 4 - size % 4; | chunk.size += 4 - size % 4; | ||||
| } | } | ||||
| awrite(movie, &chunk, 1, sizeof(AviChunk), movie->fp, AVI_CHUNK); | awrite(movie, &chunk, 1, sizeof(AviChunk), movie->fp, AVI_CHUNK); | ||||
| /* Write the index entry for this data chunk */ | /* Write the index entry for this data chunk */ | ||||
| movie->entries[frame_num * (movie->header->Streams + 1) + stream + 1].ChunkId = chunk.fcc; | movie->entries[frame_num * (movie->header->Streams + 1) + stream + 1].ChunkId = chunk.fcc; | ||||
| movie->entries[frame_num * (movie->header->Streams + 1) + stream + 1].Flags = AVIIF_KEYFRAME; | movie->entries[frame_num * (movie->header->Streams + 1) + stream + 1].Flags = AVIIF_KEYFRAME; | ||||
| movie->entries[frame_num * (movie->header->Streams + 1) + stream + 1].Offset = | movie->entries[frame_num * (movie->header->Streams + 1) + stream + 1].Offset = | ||||
| (int)(ftell(movie->fp) - 12L - movie->movi_offset); | (int)(BLI_ftell(movie->fp) - 12L - movie->movi_offset); | ||||
| movie->entries[frame_num * (movie->header->Streams + 1) + stream + 1].Size = chunk.size; | movie->entries[frame_num * (movie->header->Streams + 1) + stream + 1].Size = chunk.size; | ||||
| /* Write the chunk */ | /* Write the chunk */ | ||||
| awrite(movie, buffer, 1, size, movie->fp, AVI_RAW); | awrite(movie, buffer, 1, size, movie->fp, AVI_RAW); | ||||
| MEM_freeN(buffer); | MEM_freeN(buffer); | ||||
| if (size % 4) { | if (size % 4) { | ||||
| awrite(movie, &tbuf, 1, 4 - size % 4, movie->fp, AVI_RAW); | awrite(movie, &tbuf, 1, 4 - size % 4, movie->fp, AVI_RAW); | ||||
| } | } | ||||
| /* Update the stream headers length field */ | /* Update the stream headers length field */ | ||||
| movie->streams[stream].sh.Length++; | movie->streams[stream].sh.Length++; | ||||
| fseek(movie->fp, movie->offset_table[1 + stream * 2], SEEK_SET); | BLI_fseek(movie->fp, movie->offset_table[1 + stream * 2], SEEK_SET); | ||||
| awrite(movie, &movie->streams[stream].sh, 1, sizeof(AviStreamHeader), movie->fp, AVI_STREAMH); | awrite(movie, &movie->streams[stream].sh, 1, sizeof(AviStreamHeader), movie->fp, AVI_STREAMH); | ||||
| } | } | ||||
| va_end(ap); | va_end(ap); | ||||
| /* Record the entry for the new record */ | /* Record the entry for the new record */ | ||||
| fseek(movie->fp, 0L, SEEK_END); | BLI_fseek(movie->fp, 0L, SEEK_END); | ||||
| movie->entries[frame_num * (movie->header->Streams + 1)].ChunkId = FCC("rec "); | movie->entries[frame_num * (movie->header->Streams + 1)].ChunkId = FCC("rec "); | ||||
| movie->entries[frame_num * (movie->header->Streams + 1)].Flags = AVIIF_LIST; | movie->entries[frame_num * (movie->header->Streams + 1)].Flags = AVIIF_LIST; | ||||
| movie->entries[frame_num * (movie->header->Streams + 1)].Offset = (int)(rec_off - 8L - | movie->entries[frame_num * (movie->header->Streams + 1)].Offset = (int)(rec_off - 8L - | ||||
| movie->movi_offset); | movie->movi_offset); | ||||
| movie->entries[frame_num * (movie->header->Streams + 1)].Size = (int)(ftell(movie->fp) - | movie->entries[frame_num * (movie->header->Streams + 1)].Size = (int)(BLI_ftell(movie->fp) - | ||||
| (rec_off + 4L)); | (rec_off + 4L)); | ||||
| /* Update the record size */ | /* Update the record size */ | ||||
| fseek(movie->fp, rec_off, SEEK_SET); | BLI_fseek(movie->fp, rec_off, SEEK_SET); | ||||
| PUT_FCCN(movie->entries[frame_num * (movie->header->Streams + 1)].Size, movie->fp); | PUT_FCCN(movie->entries[frame_num * (movie->header->Streams + 1)].Size, movie->fp); | ||||
| /* Update the main header information in the file */ | /* Update the main header information in the file */ | ||||
| movie->header->TotalFrames++; | movie->header->TotalFrames++; | ||||
| fseek(movie->fp, movie->offset_table[0], SEEK_SET); | BLI_fseek(movie->fp, movie->offset_table[0], SEEK_SET); | ||||
| awrite(movie, movie->header, 1, sizeof(AviMainHeader), movie->fp, AVI_MAINH); | awrite(movie, movie->header, 1, sizeof(AviMainHeader), movie->fp, AVI_MAINH); | ||||
| return AVI_ERROR_NONE; | return AVI_ERROR_NONE; | ||||
| } | } | ||||
| AviError AVI_close_compress(AviMovie *movie) | AviError AVI_close_compress(AviMovie *movie) | ||||
| { | { | ||||
| int temp, movi_size, i; | int temp, movi_size, i; | ||||
| if (movie->fp == NULL) { | if (movie->fp == NULL) { | ||||
| /* none of the allocations below were done if the file failed to open */ | /* none of the allocations below were done if the file failed to open */ | ||||
| return AVI_ERROR_FOUND; | return AVI_ERROR_FOUND; | ||||
| } | } | ||||
| fseek(movie->fp, 0L, SEEK_END); | BLI_fseek(movie->fp, 0L, SEEK_END); | ||||
| movi_size = (int)ftell(movie->fp); | movi_size = (int)BLI_ftell(movie->fp); | ||||
| PUT_FCC("idx1", movie->fp); | PUT_FCC("idx1", movie->fp); | ||||
| PUT_FCCN((movie->index_entries * (movie->header->Streams + 1) * 16), movie->fp); | PUT_FCCN((movie->index_entries * (movie->header->Streams + 1) * 16), movie->fp); | ||||
| for (temp = 0; temp < movie->index_entries * (movie->header->Streams + 1); temp++) { | for (temp = 0; temp < movie->index_entries * (movie->header->Streams + 1); temp++) { | ||||
| awrite(movie, &movie->entries[temp], 1, sizeof(AviIndexEntry), movie->fp, AVI_INDEXE); | awrite(movie, &movie->entries[temp], 1, sizeof(AviIndexEntry), movie->fp, AVI_INDEXE); | ||||
| } | } | ||||
| temp = (int)ftell(movie->fp); | temp = (int)BLI_ftell(movie->fp); | ||||
| fseek(movie->fp, AVI_RIFF_SOFF, SEEK_SET); | BLI_fseek(movie->fp, AVI_RIFF_SOFF, SEEK_SET); | ||||
| PUT_FCCN((temp - 8L), movie->fp); | PUT_FCCN((temp - 8L), movie->fp); | ||||
| fseek(movie->fp, movie->movi_offset, SEEK_SET); | BLI_fseek(movie->fp, movie->movi_offset, SEEK_SET); | ||||
| PUT_FCCN((movi_size - (movie->movi_offset + 4L)), movie->fp); | PUT_FCCN((movi_size - (movie->movi_offset + 4L)), movie->fp); | ||||
| fclose(movie->fp); | fclose(movie->fp); | ||||
| for (i = 0; i < movie->header->Streams; i++) { | for (i = 0; i < movie->header->Streams; i++) { | ||||
| if (movie->streams && (movie->streams[i].sf != NULL)) { | if (movie->streams && (movie->streams[i].sf != NULL)) { | ||||
| MEM_freeN(movie->streams[i].sf); | MEM_freeN(movie->streams[i].sf); | ||||
| Show All 16 Lines | |||||