mirror of https://github.com/ArduPilot/ardupilot
AP_ROMFS: embed raw DEFLATE streams
Saves size not including unnecessary headers or code to parse them.
This commit is contained in:
parent
5d37442f7c
commit
d46cb3fd85
|
@ -7,7 +7,7 @@ Andrew Tridgell
|
||||||
May 2017
|
May 2017
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os, sys, tempfile, gzip
|
import os, sys, zlib
|
||||||
|
|
||||||
def write_encode(out, s):
|
def write_encode(out, s):
|
||||||
out.write(s.encode())
|
out.write(s.encode())
|
||||||
|
@ -28,28 +28,24 @@ def embed_file(out, f, idx, embedded_name, uncompressed):
|
||||||
contents += bytes([0xff]*pad)
|
contents += bytes([0xff]*pad)
|
||||||
print("Padded %u bytes for %s to %u" % (pad, embedded_name, len(contents)))
|
print("Padded %u bytes for %s to %u" % (pad, embedded_name, len(contents)))
|
||||||
|
|
||||||
crc = crc32(bytearray(contents))
|
crc = crc32(contents)
|
||||||
write_encode(out, '__EXTFLASHFUNC__ static const uint8_t ap_romfs_%u[] = {' % idx)
|
write_encode(out, '__EXTFLASHFUNC__ static const uint8_t ap_romfs_%u[] = {' % idx)
|
||||||
|
|
||||||
compressed = tempfile.NamedTemporaryFile()
|
|
||||||
if uncompressed:
|
if uncompressed:
|
||||||
# ensure nul termination
|
# ensure nul termination
|
||||||
if contents[-1] != 0:
|
if contents[-1] != 0:
|
||||||
contents += bytes([0])
|
contents += bytes([0])
|
||||||
compressed.write(contents)
|
b = contents
|
||||||
else:
|
else:
|
||||||
# compress it
|
# compress it (max level, max window size, raw stream, max mem usage)
|
||||||
f = open(compressed.name, "wb")
|
z = zlib.compressobj(level=9, method=zlib.DEFLATED, wbits=-15, memLevel=9)
|
||||||
with gzip.GzipFile(fileobj=f, mode='wb', filename='', compresslevel=9, mtime=0) as g:
|
b = z.compress(contents)
|
||||||
g.write(contents)
|
b += z.flush()
|
||||||
f.close()
|
# append uncompressed length as little-endian bytes
|
||||||
|
l = len(contents)
|
||||||
|
b += bytes([l & 0xFF, (l >> 8) & 0xFF, (l >> 16) & 0xFF, (l >> 24) & 0xFF])
|
||||||
|
|
||||||
compressed.seek(0)
|
write_encode(out, ",".join(str(c) for c in b))
|
||||||
b = bytearray(compressed.read())
|
|
||||||
compressed.close()
|
|
||||||
|
|
||||||
for c in b:
|
|
||||||
write_encode(out, '%u,' % c)
|
|
||||||
write_encode(out, '};\n\n');
|
write_encode(out, '};\n\n');
|
||||||
return crc
|
return crc
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ const uint8_t *AP_ROMFS::find_decompress(const char *name, uint32_t &size)
|
||||||
size = compressed_size;
|
size = compressed_size;
|
||||||
return compressed_data;
|
return compressed_data;
|
||||||
#else
|
#else
|
||||||
// last 4 bytes of gzip file are length of decompressed data
|
// last 4 bytes of compressed data are length of decompressed data
|
||||||
const uint8_t *p = &compressed_data[compressed_size-4];
|
const uint8_t *p = &compressed_data[compressed_size-4];
|
||||||
uint32_t decompressed_size = p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
|
uint32_t decompressed_size = p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
|
||||||
|
|
||||||
|
@ -86,21 +86,10 @@ const uint8_t *AP_ROMFS::find_decompress(const char *name, uint32_t &size)
|
||||||
|
|
||||||
d->source = compressed_data;
|
d->source = compressed_data;
|
||||||
d->source_limit = compressed_data + compressed_size - 4;
|
d->source_limit = compressed_data + compressed_size - 4;
|
||||||
|
|
||||||
// assume gzip format
|
|
||||||
int res = uzlib_gzip_parse_header(d);
|
|
||||||
if (res != TINF_OK) {
|
|
||||||
::free(decompressed_data);
|
|
||||||
::free(d);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->dest = decompressed_data;
|
d->dest = decompressed_data;
|
||||||
d->destSize = decompressed_size;
|
d->destSize = decompressed_size;
|
||||||
|
|
||||||
// we don't check CRC, as it just wastes flash space for constant
|
int res = uzlib_uncompress(d);
|
||||||
// ROMFS data
|
|
||||||
res = uzlib_uncompress(d);
|
|
||||||
|
|
||||||
::free(d);
|
::free(d);
|
||||||
|
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
/*
|
|
||||||
* tinfgzip - tiny gzip decompressor
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
* http://www.ibsensoftware.com/
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014-2016 by Paul Sokolovsky
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express
|
|
||||||
* or implied warranty. In no event will the authors be
|
|
||||||
* held liable for any damages arising from the use of
|
|
||||||
* this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software
|
|
||||||
* for any purpose, including commercial applications,
|
|
||||||
* and to alter it and redistribute it freely, subject to
|
|
||||||
* the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be
|
|
||||||
* misrepresented; you must not claim that you
|
|
||||||
* wrote the original software. If you use this
|
|
||||||
* software in a product, an acknowledgment in
|
|
||||||
* the product documentation would be appreciated
|
|
||||||
* but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked
|
|
||||||
* as such, and must not be misrepresented as
|
|
||||||
* being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from
|
|
||||||
* any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tinf.h"
|
|
||||||
|
|
||||||
#define FTEXT 1
|
|
||||||
#define FHCRC 2
|
|
||||||
#define FEXTRA 4
|
|
||||||
#define FNAME 8
|
|
||||||
#define FCOMMENT 16
|
|
||||||
|
|
||||||
void tinf_skip_bytes(TINF_DATA *d, int num);
|
|
||||||
uint16_t tinf_get_uint16(TINF_DATA *d);
|
|
||||||
|
|
||||||
void tinf_skip_bytes(TINF_DATA *d, int num)
|
|
||||||
{
|
|
||||||
while (num--) uzlib_get_byte(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t tinf_get_uint16(TINF_DATA *d)
|
|
||||||
{
|
|
||||||
unsigned int v = uzlib_get_byte(d);
|
|
||||||
v = (uzlib_get_byte(d) << 8) | v;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uzlib_gzip_parse_header(TINF_DATA *d)
|
|
||||||
{
|
|
||||||
unsigned char flg;
|
|
||||||
|
|
||||||
/* -- check format -- */
|
|
||||||
|
|
||||||
/* check id bytes */
|
|
||||||
if (uzlib_get_byte(d) != 0x1f || uzlib_get_byte(d) != 0x8b) return TINF_DATA_ERROR;
|
|
||||||
|
|
||||||
/* check method is deflate */
|
|
||||||
if (uzlib_get_byte(d) != 8) return TINF_DATA_ERROR;
|
|
||||||
|
|
||||||
/* get flag byte */
|
|
||||||
flg = uzlib_get_byte(d);
|
|
||||||
|
|
||||||
/* check that reserved bits are zero */
|
|
||||||
if (flg & 0xe0) return TINF_DATA_ERROR;
|
|
||||||
|
|
||||||
/* -- find start of compressed data -- */
|
|
||||||
|
|
||||||
/* skip rest of base header of 10 bytes */
|
|
||||||
tinf_skip_bytes(d, 6);
|
|
||||||
|
|
||||||
/* skip extra data if present */
|
|
||||||
if (flg & FEXTRA)
|
|
||||||
{
|
|
||||||
unsigned int xlen = tinf_get_uint16(d);
|
|
||||||
tinf_skip_bytes(d, xlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* skip file name if present */
|
|
||||||
if (flg & FNAME) { while (uzlib_get_byte(d)); }
|
|
||||||
|
|
||||||
/* skip file comment if present */
|
|
||||||
if (flg & FCOMMENT) { while (uzlib_get_byte(d)); }
|
|
||||||
|
|
||||||
/* check header crc if present */
|
|
||||||
if (flg & FHCRC)
|
|
||||||
{
|
|
||||||
/*unsigned int hcrc =*/ tinf_get_uint16(d);
|
|
||||||
|
|
||||||
// TODO: Check!
|
|
||||||
// if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff))
|
|
||||||
// return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize for crc32 checksum */
|
|
||||||
d->checksum_type = TINF_CHKSUM_CRC;
|
|
||||||
d->checksum = ~0;
|
|
||||||
|
|
||||||
return TINF_OK;
|
|
||||||
}
|
|
Loading…
Reference in New Issue