Skip to content

Instantly share code, notes, and snippets.

@liuliu
Created September 18, 2014 04:38
Show Gist options
  • Save liuliu/5ee78cb9c5d20a289c87 to your computer and use it in GitHub Desktop.
Save liuliu/5ee78cb9c5d20a289c87 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <zlib.h>
#include <assert.h>
static size_t get_atom_size(uint8_t* atom)
{
return (atom[0] << 24) | (atom[1] << 16) | (atom[2] << 8) | atom[3];
}
static void set_atom_size(uint8_t* atom, size_t atom_size)
{
atom[0] = (atom_size >> 24) & 0xff;
atom[1] = (atom_size >> 16) & 0xff;
atom[2] = (atom_size >> 8) & 0xff;
atom[3] = atom_size & 0xff;
}
int main(int argc, char** argv)
{
FILE *in = fopen(argv[1], "rb");
FILE *out = fopen(argv[2], "wb+");
uint8_t atom[8];
size_t len = fread(atom, sizeof(atom), 1, in);
uint8_t buffer[4096];
while (len > 0)
{
size_t atom_size = get_atom_size(atom);
printf("%d %c%c%c%c\n", (int)atom_size, atom[4], atom[5], atom[6], atom[7]);
if (atom[4] == 'm' && atom[5] == 'o' && atom[6] == 'o' && atom[7] == 'v')
{
// compress the header
// read all the moov header
uint8_t *moov = (uint8_t *)malloc(sizeof(uint8_t) * (atom_size - 8));
size_t bytes_read = fread(moov, 1, atom_size - 8, in);
if (bytes_read != atom_size - 8)
{
// failure, fallback to bypass
fwrite(atom, sizeof(atom), 1, out);
fwrite(moov, 1, bytes_read, out);
} else {
z_stream strm = {
.next_in = (Bytef *)moov,
.avail_in = bytes_read,
.total_out = 0,
.opaque = 0,
.zalloc = Z_NULL,
.zfree = Z_NULL,
};
assert(deflateInit(&strm, 1) == Z_OK);
uint8_t *cmov = (uint8_t *)malloc(sizeof(uint8_t) * (atom_size - 8));
size_t cmov_size = atom_size - 8;
int done = 0;
while (!done)
{
if (strm.total_out >= cmov_size) {
cmov_size += (atom_size - 8 + 1) / 2;
cmov = (uint8_t *)realloc(cmov, cmov_size);
}
strm.next_out = (Bytef *)cmov + strm.total_out;
strm.avail_out = cmov_size - strm.total_out;
int status = deflate(&strm, Z_FINISH);
if (status == Z_STREAM_END)
done = 1;
else if (status != Z_OK)
break;
}
printf("cmov: %d => %d\n", (int)atom_size - 8, (int)strm.total_out);
if (deflateEnd(&strm) == Z_OK && done)
{
set_atom_size(atom, strm.total_out + 40);
fwrite(atom, sizeof(atom), 1, out);
set_atom_size(atom, strm.total_out + 32);
atom[4] = 'c', atom[5] = 'm', atom[6] = 'o', atom[7] = 'v';
fwrite(atom, sizeof(atom), 1, out);
set_atom_size(atom, 12);
atom[4] = 'd', atom[5] = 'c', atom[6] = 'o', atom[7] = 'm';
fwrite(atom, sizeof(atom), 1, out);
uint8_t zlib[4];
zlib[0] = 'z', zlib[1] = 'l', zlib[2] = 'i', zlib[3] = 'b';
fwrite(zlib, sizeof(zlib), 1, out);
set_atom_size(atom, strm.total_out + 12);
atom[4] = 'c', atom[5] = 'm', atom[6] = 'v', atom[7] = 'd';
fwrite(atom, sizeof(atom), 1, out);
set_atom_size(zlib, atom_size);
fwrite(zlib, sizeof(zlib), 1, out);
fwrite(cmov, 1, strm.total_out, out);
} else {
// failure case
fwrite(atom, sizeof(atom), 1, out);
fwrite(moov, 1, bytes_read, out);
}
free(cmov);
}
free(moov);
} else {
// bypass this atom
fwrite(atom, sizeof(atom), 1, out);
int i;
for (i = 0; i < atom_size - 8; i += 4096)
{
size_t bytes_expected = 4096 < atom_size - 8 - i ? 4096 : atom_size - 8 - i;
size_t bytes_read = fread(buffer, 1, bytes_expected, in);
fwrite(buffer, 1, bytes_read, out);
if (bytes_read < bytes_expected)
break;
}
}
len = fread(atom, sizeof(atom), 1, in);
}
fclose(out);
fclose(in);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment