On-the-fly heatshrink decoding now works.
This commit is contained in:
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
CFLAGS=-I../lib/heatshrink -I../user -I../include -std=gnu99
|
CFLAGS=-I../lib/heatshrink -I../user -I../include -std=gnu99
|
||||||
|
|
||||||
espfs.o: espfs.c ../user/espfs.c
|
|
||||||
|
|
||||||
espfstest: main.o espfs.o heatshrink_decoder.o
|
espfstest: main.o espfs.o heatshrink_decoder.o
|
||||||
$(CC) -o $@ $^
|
$(CC) -o $@ $^
|
||||||
|
|
||||||
|
espfs.o: espfs.c ../user/espfs.c
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o espfstest
|
rm -f *.o espfstest
|
||||||
|
|||||||
+10
-11
@@ -36,6 +36,9 @@ extern char* espFsData;
|
|||||||
#include "heatshrink_decoder.h"
|
#include "heatshrink_decoder.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct EspFsFile {
|
struct EspFsFile {
|
||||||
EspFsHeader *header;
|
EspFsHeader *header;
|
||||||
char decompressor;
|
char decompressor;
|
||||||
@@ -46,7 +49,8 @@ struct EspFsFile {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Available locations, at least in my flash, with boundaries partially guessed:
|
Available locations, at least in my flash, with boundaries partially guessed. This
|
||||||
|
is using 0.9.1 SDK on a not-too-new module.
|
||||||
0x00000 (0x10000): Code/data (RAM data?)
|
0x00000 (0x10000): Code/data (RAM data?)
|
||||||
0x10000 (0x02000): Gets erased by something?
|
0x10000 (0x02000): Gets erased by something?
|
||||||
0x12000 (0x2E000): Free (filled with zeroes) (parts used by ESPCloud and maybe SSL)
|
0x12000 (0x2E000): Free (filled with zeroes) (parts used by ESPCloud and maybe SSL)
|
||||||
@@ -62,7 +66,7 @@ a memory exception, crashing the program.
|
|||||||
|
|
||||||
|
|
||||||
//Copies len bytes over from dst to src, but does it using *only*
|
//Copies len bytes over from dst to src, but does it using *only*
|
||||||
//aligned 32-bit reads.
|
//aligned 32-bit reads. Yes, it's no too optimized but it's short and sweet and it works.
|
||||||
void ICACHE_FLASH_ATTR memcpyAligned(char *dst, char *src, int len) {
|
void ICACHE_FLASH_ATTR memcpyAligned(char *dst, char *src, int len) {
|
||||||
int x;
|
int x;
|
||||||
int w, b;
|
int w, b;
|
||||||
@@ -120,12 +124,14 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
|
|||||||
#ifdef EFS_HEATSHRINK
|
#ifdef EFS_HEATSHRINK
|
||||||
} else if (h.compression==COMPRESS_HEATSHRINK) {
|
} else if (h.compression==COMPRESS_HEATSHRINK) {
|
||||||
char parm;
|
char parm;
|
||||||
|
heatshrink_decoder *dec;
|
||||||
//Decoder params are stored in 1st byte.
|
//Decoder params are stored in 1st byte.
|
||||||
memcpyAligned(&parm, r->posComp, 1);
|
memcpyAligned(&parm, r->posComp, 1);
|
||||||
r->posComp++;
|
r->posComp++;
|
||||||
os_printf("Heatshrink compressed file; decode parms = %x\n", parm);
|
os_printf("Heatshrink compressed file; decode parms = %x\n", parm);
|
||||||
r->decompData=(heatshrink_decoder *)heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf);
|
dec=heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf);
|
||||||
os_printf("Decompressor allocated.\n");
|
heatshrink_decoder_reset(dec);
|
||||||
|
r->decompData=dec;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
os_printf("Invalid compression: %d\n", h.compression);
|
os_printf("Invalid compression: %d\n", h.compression);
|
||||||
@@ -160,28 +166,21 @@ int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) {
|
|||||||
int decoded=0;
|
int decoded=0;
|
||||||
int elen, rlen, r;
|
int elen, rlen, r;
|
||||||
char ebuff[16];
|
char ebuff[16];
|
||||||
os_printf("heatshrink: reading\n");
|
|
||||||
heatshrink_decoder *dec=(heatshrink_decoder *)fh->decompData;
|
heatshrink_decoder *dec=(heatshrink_decoder *)fh->decompData;
|
||||||
while(decoded<len) {
|
while(decoded<len) {
|
||||||
//Feed data into the decompressor
|
//Feed data into the decompressor
|
||||||
elen=flen-(fh->posComp - fh->posStart);
|
elen=flen-(fh->posComp - fh->posStart);
|
||||||
if (elen==0) return decoded; //file is read
|
if (elen==0) return decoded; //file is read
|
||||||
if (elen>0) {
|
if (elen>0) {
|
||||||
os_printf("heatshrink: feeding decoder (%d comp bytes left)\n", elen);
|
|
||||||
memcpyAligned(ebuff, fh->posComp, 16);
|
memcpyAligned(ebuff, fh->posComp, 16);
|
||||||
for (r=0; r<16; r++) os_printf("%02hhx ", ebuff[r]);
|
|
||||||
os_printf("\n");
|
|
||||||
r=heatshrink_decoder_sink(dec, ebuff, (elen>16)?16:elen, &rlen);
|
r=heatshrink_decoder_sink(dec, ebuff, (elen>16)?16:elen, &rlen);
|
||||||
os_printf("heatshrink: decoder ate %d bytes (code %d)\n", rlen, r);
|
|
||||||
fh->posComp+=rlen;
|
fh->posComp+=rlen;
|
||||||
if (rlen==elen) {
|
if (rlen==elen) {
|
||||||
os_printf("heatshrink: finish\n");
|
|
||||||
heatshrink_decoder_finish(dec);
|
heatshrink_decoder_finish(dec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Grab decompressed data and put into buff
|
//Grab decompressed data and put into buff
|
||||||
r=heatshrink_decoder_poll(dec, buff, len-decoded, &rlen);
|
r=heatshrink_decoder_poll(dec, buff, len-decoded, &rlen);
|
||||||
os_printf("heatshrink: decoder emitted %d bytes (code %d)\n", rlen, r);
|
|
||||||
fh->posDecomp+=rlen;
|
fh->posDecomp+=rlen;
|
||||||
buff+=rlen;
|
buff+=rlen;
|
||||||
decoded+=rlen;
|
decoded+=rlen;
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef HEATSHRINK_CONFIG_H
|
||||||
|
#define HEATSHRINK_CONFIG_H
|
||||||
|
|
||||||
|
/* Should functionality assuming dynamic allocation be used? */
|
||||||
|
#define HEATSHRINK_DYNAMIC_ALLOC 1
|
||||||
|
|
||||||
|
#if HEATSHRINK_DYNAMIC_ALLOC
|
||||||
|
/* Optional replacement of malloc/free */
|
||||||
|
#define HEATSHRINK_MALLOC(SZ) os_malloc(SZ)
|
||||||
|
#define HEATSHRINK_FREE(P, SZ) os_free(P)
|
||||||
|
#else
|
||||||
|
/* Required parameters for static configuration */
|
||||||
|
#define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 32
|
||||||
|
#define HEATSHRINK_STATIC_WINDOW_BITS 8
|
||||||
|
#define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Turn on logging for debugging. */
|
||||||
|
#define HEATSHRINK_DEBUGGING_LOGS 0
|
||||||
|
|
||||||
|
/* Use indexing for faster compression. (This requires additional space.) */
|
||||||
|
#define HEATSHRINK_USE_INDEX 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#include "httpdconfig.h"
|
||||||
|
#ifdef EFS_HEATSHRINK
|
||||||
|
//Stupid wrapper so we don't have to move c-files around
|
||||||
|
//Also loads httpd-specific config.
|
||||||
|
|
||||||
|
#define _STDLIB_H_
|
||||||
|
#define _STRING_H_
|
||||||
|
#define _STDDEF_H
|
||||||
|
#define _STDINT_H
|
||||||
|
|
||||||
|
#include "c_types.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "osapi.h"
|
||||||
|
#include "heatshrink_config_httpd.h"
|
||||||
|
#define malloc(x) os_malloc(x)
|
||||||
|
#define memset(x,y,z) os_memset(x,y,z)
|
||||||
|
#define memcpy(x,y,z) os_memcpy(x,y,z)
|
||||||
|
#include "../lib/heatshrink/heatshrink_decoder.c"
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user