On-the-fly heatshrink decoding now works.

pull/30/head
Jeroen Domburg 10 years ago
parent 0cd1984fb7
commit 8c04617cb2
  1. 4
      espfstest/Makefile
  2. 21
      user/espfs.c
  3. 25
      user/heatshrink_config_httpd.h
  4. 20
      user/heatshrink_decoder.c

@ -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

@ -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
Loading…
Cancel
Save