Files
mp4istrunc/mp4istrunc.h
2026-06-13 13:43:26 -05:00

133 lines
2.8 KiB
C

#pragma once
#if defined(__cplusplus)
extern "C"
#endif
#if defined(MP4ISTRUNC_IMPL)
#if defined(_WIN32) || defined(WIN32)
#else
#define _FILE_OFFSET_BITS=64
#endif
#endif
#include <stdio.h>
#define MP4TRUNC_OK 0
#define MP4TRUNC_TRUNC 1
int mp4trunc_istruncf(FILE* f);
int mp4trunc_istrunc(const char* path);
#if defined(MP4ISTRUNC_IMPL)
#include <string.h>
int mp4trunc_istruncf(FILE* f)
{
#if defined(_WIN32) || defined(WIN32)
#if defined(MP4TRUNC_LEGACYWIN32)
fseek(f,0L,SEEK_END);
long long len = (long long)ftell(f);
rewind(f);
#else
_fseeki64(f,0L,SEEK_END);
long long len = (long long)_ftelli64(f);
rewind(f);
#endif
#else
fseeko(f,0L,SEEK_END);
long long len = (long long)ftello(f);
rewind(f);
#endif
unsigned long long fileSizeToThisPoint = 0;
int hadWide = 0;
while(!feof(f))
{
unsigned char hdr[1024];
if(fread(hdr,1,8,f) != 8) return MP4TRUNC_TRUNC;
fileSizeToThisPoint += 8;
unsigned long long atom_len = (unsigned int)hdr[0] << 24 |
(unsigned int)hdr[1] << 16 |
(unsigned int)hdr[2] << 8 |
(unsigned int)hdr[3];
if(atom_len == 0) return MP4TRUNC_OK;
if(memcmp(hdr+4,"wide",4) == 0)
{
hadWide = 1;
continue;
}
int isBig=0;
if(hadWide && atom_len == 1) {
hadWide=0;
isBig=1;
if(fread(hdr+8,1,8,f) != 8) return MP4TRUNC_TRUNC;
fileSizeToThisPoint+=8;
atom_len = (unsigned long)hdr[8] << 56 |
(unsigned long long)hdr[9] << 48 |
(unsigned long long)hdr[10] << 40 |
(unsigned long long)hdr[11] << 32 |
(unsigned long long)hdr[12] << 24 |
(unsigned long long)hdr[13] << 16 |
(unsigned long long)hdr[14] << 8 |
(unsigned long long)hdr[15];
}
if(memcmp(hdr+4,"mdat",4) == 0)
{
if((unsigned long long)len < (atom_len + fileSizeToThisPoint-(isBig?16:8))) return MP4TRUNC_TRUNC;
return MP4TRUNC_OK;
} else {
size_t left = atom_len-(isBig?16:8);
size_t read = 0;
do {
size_t toRead = sizeof(hdr);
if(left < toRead) toRead = left;
read = fread(hdr,1,toRead,f);
left -= read;
fileSizeToThisPoint += read;
if(feof(f) && left != 0) return MP4TRUNC_TRUNC;
} while(read != 0);
}
}
return MP4TRUNC_OK;
}
int mp4trunc_istrunc(const char* path)
{
FILE* f = fopen(path,"rb");
int res = mp4trunc_istruncf(f);
fclose(f);
return res;
}
#endif
#if defined(__cplusplus)
}
#endif