Created
September 18, 2014 04:38
-
-
Save liuliu/5ee78cb9c5d20a289c87 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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