Skip to content

Instantly share code, notes, and snippets.

@aisouard
Created June 8, 2015 02:32
Show Gist options
  • Save aisouard/b9b1c1387d9dba7eb971 to your computer and use it in GitHub Desktop.
Save aisouard/b9b1c1387d9dba7eb971 to your computer and use it in GitHub Desktop.
Parseur de fichier de métadonnés
#include <stdio.h>
#include <stdlib.h>
unsigned int swap_uint32(unsigned int num) {
unsigned int swapped;
swapped = ((num >> 24) & 0xff) |
((num << 8) & 0xff0000) |
((num >> 8) & 0xff00) |
((num << 24) & 0xff000000);
return swapped;
}
int swap_int32(int num) {
int swapped;
swapped = ((num >> 24) & 0xff) |
((num << 8) & 0xff0000) |
((num >> 8) & 0xff00) |
((num << 24) & 0xff000000);
return swapped;
}
double swap_float8(double num) {
double swapped;
((unsigned char*)&swapped)[0] = ((unsigned char*)&num)[7];
((unsigned char*)&swapped)[1] = ((unsigned char*)&num)[6];
((unsigned char*)&swapped)[2] = ((unsigned char*)&num)[5];
((unsigned char*)&swapped)[3] = ((unsigned char*)&num)[4];
((unsigned char*)&swapped)[4] = ((unsigned char*)&num)[3];
((unsigned char*)&swapped)[5] = ((unsigned char*)&num)[2];
((unsigned char*)&swapped)[6] = ((unsigned char*)&num)[1];
((unsigned char*)&swapped)[7] = ((unsigned char*)&num)[0];
return swapped;
}
void read_float8(FILE *f, double *out) {
double buffer;
fread(&buffer, sizeof(buffer), 1, f);
*out = swap_float8(buffer);
}
void read_int32(FILE *f, int *out) {
int buffer;
fread(&buffer, sizeof(buffer), 1, f);
*out = swap_int32(buffer);
}
void read_uint32(FILE *f, unsigned int *out) {
unsigned int buffer;
fread(&buffer, sizeof(buffer), 1, f);
*out = swap_uint32(buffer);
}
void read_byte(FILE *f, unsigned char *out) {
unsigned char buffer;
fread(&buffer, sizeof(buffer), 1, f);
}
void read_bytes(FILE *f, unsigned char **out, unsigned int length) {
*out = malloc(length);
fread(*out, length, 1, f);
}
void read_string(FILE *f, char **out) {
int len;
char c;
int pos;
len = 0;
c = 0;
pos = ftell(f);
while (c != EOF) {
c = fgetc(f);
if (c == '\0') {
break;
}
++len;
}
fseek(f, pos, SEEK_SET);
*out = malloc(len + 1);
fread(*out, len + 1, 1, f);
}
typedef struct s_segment {
unsigned int timecode;
unsigned int length;
unsigned int crc32Checksum;
unsigned int numChunks;
unsigned int *chunks;
} t_segment;
void read_segment(FILE *f, t_segment *segment) {
unsigned int i;
read_uint32(f, &segment->timecode);
read_uint32(f, &segment->length);
read_uint32(f, &segment->crc32Checksum);
read_uint32(f, &segment->numChunks);
segment->chunks = malloc(segment->numChunks * sizeof(*segment->chunks));
for (i = 0; i < segment->numChunks; ++i) {
read_uint32(f, &segment->chunks[i]);
}
}
void dump_segment(t_segment *segment) {
unsigned int i;
printf(" Timecode: %d\n"
" Length: %d\n"
" Checksum: 0x%X\n"
" Chunks: %d\n",
segment->timecode,
segment->length,
segment->crc32Checksum,
segment->numChunks);
for (i = 0; i < segment->numChunks; ++i) {
printf(" Chunks[%d]: 0x%X\n", i, segment->chunks[i]);
}
}
typedef struct s_stream {
unsigned char type;
char *mimeType;
unsigned int bandwidth;
int width;
int height;
int numChannels;
int sampleFrequency;
unsigned int chunksize;
unsigned int initLength;
unsigned char *initData;
unsigned int numSegments;
t_segment *segments;
} t_stream;
void read_stream(FILE *f, t_stream *stream) {
unsigned int i;
read_byte(f, &stream->type);
read_string(f, &stream->mimeType);
read_uint32(f, &stream->bandwidth);
read_int32(f, &stream->width);
read_int32(f, &stream->height);
read_int32(f, &stream->numChannels);
read_int32(f, &stream->sampleFrequency);
read_uint32(f, &stream->chunksize);
read_uint32(f, &stream->initLength);
read_bytes(f, &stream->initData, stream->initLength);
read_uint32(f, &stream->numSegments);
stream->segments = malloc(stream->numSegments * sizeof(*stream->segments));
for (i = 0; i < stream->numSegments; ++i) {
read_segment(f, &stream->segments[i]);
}
}
void dump_stream(t_stream *stream) {
unsigned int i;
printf(" Type: %d\n"
" MimeType: {%s}\n"
" Bandwidth: %d\n"
" Width: %d\n"
" Height: %d\n"
" Channels: %d\n"
" Sample Frequency: %d\n"
" Chunk Size: %d\n"
" Init Segment Length: %d\n",
stream->type,
stream->mimeType,
stream->bandwidth,
stream->width,
stream->height,
stream->numChannels,
stream->sampleFrequency,
stream->chunksize,
stream->initLength);
for (i = 0; i < stream->numSegments; ++i) {
printf(" Segment %d\n", i);
dump_segment(&stream->segments[i]);
}
}
typedef struct s_header {
unsigned int magic;
unsigned int version;
char *checksumAlgorithm;
unsigned int timecodeScale;
double duration;
unsigned int numTrackers;
char **trackers;
unsigned int numStreams;
t_stream *streams;
} t_header;
void read_header(FILE *f, t_header *header) {
unsigned int i;
read_uint32(f, &header->magic);
read_uint32(f, &header->version);
read_string(f, &header->checksumAlgorithm);
read_uint32(f, &header->timecodeScale);
read_float8(f, &header->duration);
read_uint32(f, &header->numTrackers);
header->trackers = malloc(header->numTrackers * sizeof(*header->trackers));
for (i = 0; i < header->numTrackers; ++i) {
read_string(f, &header->trackers[i]);
}
read_uint32(f, &header->numStreams);
header->streams = malloc(header->numStreams * sizeof(*header->streams));
for (i = 0; i < header->numStreams; ++i) {
read_stream(f, &header->streams[i]);
}
}
void dump_header(t_header *header) {
unsigned int i;
printf("Magic: %d\n"
"Version: %d\n"
"Checksum Algo: {%s}\n"
"TimecodeScale: %d\n"
"Duration: %f\n"
"Num Trackers: %d\n",
header->magic,
header->version,
header->checksumAlgorithm,
header->timecodeScale,
header->duration,
header->numTrackers);
for (i = 0; i < header->numTrackers; ++i) {
printf("Tracker[%d] = {%s}\n", i, header->trackers[i]);
}
for (i = 0; i < header->numStreams; ++i) {
printf("Stream %d\n", i);
dump_stream(&header->streams[i]);
}
}
int main(int ac, char **av) {
FILE *f;
t_header header;
if (ac < 2) {
printf("usage: %s <peeracleFile>\n", av[0]);
return EXIT_FAILURE;
}
f = fopen(av[1],"rb");
if (f == NULL) {
printf("Can't open %s\n", av[1]);
return EXIT_FAILURE;
}
read_header(f, &header);
dump_header(&header);
fclose(f);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment