Compress base.img using FastLZ library
This commit is contained in:
115
kernel/FastLZ/6unpack_mem.c
Normal file
115
kernel/FastLZ/6unpack_mem.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "hal/hal.h"
|
||||
#include "fastlz.h"
|
||||
|
||||
#define SIXPACK_OK 0
|
||||
#define SIXPACK_ERR_MAGIC -1
|
||||
#define SIXPACK_ERR_CHECKSUM -2
|
||||
#define SIXPACK_ERR_DECOMPRESS -3
|
||||
#define SIXPACK_ERR_BAD_FORMAT -4
|
||||
#define SIXPACK_ERR_NO_SPACE -5
|
||||
|
||||
#define ADLER32_BASE 65521
|
||||
#define BLOCK_SIZE 65536
|
||||
|
||||
static const uint8_t sixpack_magic[8] = {137, '6', 'P', 'K', 13, 10, 26, 10};
|
||||
|
||||
static uint32_t update_adler32(uint32_t checksum, const void *buf, int len) {
|
||||
const uint8_t *ptr = (const uint8_t*)buf;
|
||||
uint32_t s1 = checksum & 0xffff;
|
||||
uint32_t s2 = (checksum >> 16) & 0xffff;
|
||||
|
||||
while (len > 0) {
|
||||
unsigned k = len < 5552 ? len : 5552;
|
||||
len -= k;
|
||||
while (k--) {
|
||||
s1 += *ptr++;
|
||||
if (s1 >= ADLER32_BASE) s1 -= ADLER32_BASE;
|
||||
s2 += s1;
|
||||
if (s2 >= ADLER32_BASE) s2 -= ADLER32_BASE;
|
||||
}
|
||||
}
|
||||
return (s2 << 16) + s1;
|
||||
}
|
||||
|
||||
static uint32_t readU16(const uint8_t *p) {
|
||||
return (uint32_t)p[0] | ((uint32_t)p[1] << 8);
|
||||
}
|
||||
static uint32_t readU32(const uint8_t *p) {
|
||||
return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
|
||||
}
|
||||
|
||||
static void read_chunk_header(const uint8_t *p, int *id, int *opts,
|
||||
uint32_t *size, uint32_t *checksum, uint32_t *extra) {
|
||||
*id = (int)readU16(p);
|
||||
*opts = (int)readU16(p + 2);
|
||||
*size = readU32(p + 4);
|
||||
*checksum = readU32(p + 8);
|
||||
*extra = readU32(p + 12);
|
||||
}
|
||||
|
||||
int sixpack_decompress_mem(const uint8_t *input, size_t in_size,
|
||||
uint8_t *output, size_t out_cap)
|
||||
{
|
||||
if (!input || in_size < 8)
|
||||
return SIXPACK_ERR_BAD_FORMAT;
|
||||
|
||||
/* Check magic */
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (input[i] != sixpack_magic[i])
|
||||
return SIXPACK_ERR_MAGIC;
|
||||
|
||||
size_t pos = 8; /* skip magic */
|
||||
size_t written = 0;
|
||||
|
||||
while (pos + 16 <= in_size) {
|
||||
int chunk_id, opts;
|
||||
uint32_t size, checksum, extra;
|
||||
|
||||
read_chunk_header(input + pos, &chunk_id, &opts, &size, &checksum, &extra);
|
||||
pos += 16;
|
||||
|
||||
if (pos + size > in_size)
|
||||
return SIXPACK_ERR_BAD_FORMAT;
|
||||
|
||||
const uint8_t *chunk_data = input + pos;
|
||||
pos += size;
|
||||
|
||||
/* File header chunk */
|
||||
if (chunk_id == 1) {
|
||||
uint32_t decomp_size = readU32(chunk_data);
|
||||
(void)decomp_size; /* not strictly needed here */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Data chunk */
|
||||
if (chunk_id == 17) {
|
||||
uint32_t cksum = update_adler32(1L, chunk_data, size);
|
||||
if (cksum != checksum)
|
||||
return SIXPACK_ERR_CHECKSUM;
|
||||
|
||||
if (opts == 0) {
|
||||
/* Stored (uncompressed) */
|
||||
if (written + size > out_cap)
|
||||
return SIXPACK_ERR_NO_SPACE;
|
||||
hal_memcpy(output + written, chunk_data, size);
|
||||
written += size;
|
||||
} else if (opts == 1) {
|
||||
/* FastLZ compressed */
|
||||
if (written + extra > out_cap)
|
||||
return SIXPACK_ERR_NO_SPACE;
|
||||
|
||||
int dec = fastlz_decompress(chunk_data, size, output + written, extra);
|
||||
if (dec != (int)extra)
|
||||
return SIXPACK_ERR_DECOMPRESS;
|
||||
|
||||
written += extra;
|
||||
} else {
|
||||
return SIXPACK_ERR_BAD_FORMAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (int)written;
|
||||
}
|
||||
7
kernel/FastLZ/6unpack_mem.h
Normal file
7
kernel/FastLZ/6unpack_mem.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef SIXUNPACK_MEM_H_
|
||||
#define SIXUNPACK_MEM_H_
|
||||
|
||||
int sixpack_decompress_mem(const uint8_t *input, size_t in_size,
|
||||
uint8_t *output, size_t out_cap);
|
||||
|
||||
#endif // SIXUNPACK_MEM_H_
|
||||
1
kernel/FastLZ/fastlz.c
Symbolic link
1
kernel/FastLZ/fastlz.c
Symbolic link
@ -0,0 +1 @@
|
||||
../../FastLZ/fastlz.c
|
||||
1
kernel/FastLZ/fastlz.h
Symbolic link
1
kernel/FastLZ/fastlz.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../FastLZ/fastlz.h
|
||||
Reference in New Issue
Block a user