Line data Source code
1 : /* fd_gzip_pack: build-time asset compressor. 2 : Usage: fd_gzip_pack <level> <in> <out> */ 3 : 4 : #include <stdio.h> 5 : #include <stdlib.h> 6 : 7 : #include "../../third_party/zlib/zlib.h" 8 : 9 0 : #define DIE(...) do { fprintf( stderr, __VA_ARGS__ ); fputc( '\n', stderr ); exit( 1 ); } while( 0 ) 10 : 11 : /* zlib is vendored with Z_SOLO (no default allocator) */ 12 0 : static voidpf zalloc_( voidpf o, uInt n, uInt sz ) { (void)o; return calloc( n, sz ); } 13 0 : static void zfree_ ( voidpf o, voidpf p ) { (void)o; free( p ); } 14 : 15 : int 16 : main( int argc, 17 0 : char ** argv ) { 18 0 : if( argc!=4 ) DIE( "usage: %s <level> <in> <out>", argv[0] ); 19 : 20 0 : int level = atoi( argv[1] ); 21 0 : if( level<1 || level>9 ) DIE( "bad level %s", argv[1] ); 22 : 23 0 : FILE * in = fopen( argv[2], "rb" ); if( !in ) DIE( "open %s failed", argv[2] ); 24 0 : FILE * out = fopen( argv[3], "wb" ); if( !out ) DIE( "open %s failed", argv[3] ); 25 : 26 0 : z_stream strm = { .zalloc = zalloc_, .zfree = zfree_ }; 27 : /* windowBits 15+16: deflate with gzip framing (RFC 1952) */ 28 0 : if( deflateInit2( &strm, level, Z_DEFLATED, 15+16, 9, Z_DEFAULT_STRATEGY )!=Z_OK ) DIE( "deflateInit2 failed" ); 29 : 30 0 : static unsigned char ibuf[ 1<<17 ]; 31 0 : static unsigned char obuf[ 1<<17 ]; 32 : 33 0 : for(;;) { 34 0 : size_t rd = fread( ibuf, 1UL, sizeof(ibuf), in ); 35 0 : if( ferror( in ) ) DIE( "read %s failed", argv[2] ); 36 0 : int flush = feof( in ) ? Z_FINISH : Z_NO_FLUSH; 37 : 38 0 : strm.next_in = ibuf; 39 0 : strm.avail_in = (uInt)rd; 40 0 : do { 41 0 : strm.next_out = obuf; 42 0 : strm.avail_out = (uInt)sizeof(obuf); 43 0 : if( deflate( &strm, flush )==Z_STREAM_ERROR ) DIE( "deflate failed" ); 44 0 : size_t wr = sizeof(obuf) - strm.avail_out; 45 0 : if( wr && fwrite( obuf, 1UL, wr, out )!=wr ) DIE( "write %s failed", argv[3] ); 46 0 : } while( !strm.avail_out ); 47 0 : if( flush==Z_FINISH ) break; 48 0 : } 49 : 50 0 : deflateEnd( &strm ); 51 0 : fclose( in ); 52 0 : if( fclose( out ) ) DIE( "close %s failed", argv[3] ); 53 0 : return 0; 54 0 : }