Added SPDX to 30 more files - spdx-48

This commit is contained in:
dherrada 2022-02-23 14:28:33 -05:00
parent bfe5427a4a
commit c322561d6f
30 changed files with 856 additions and 735 deletions

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries
//
// SPDX-License-Identifier: MIT
// Test code for Adafruit GPS modules using MTK driver // Test code for Adafruit GPS modules using MTK driver
// such as www.adafruit.com/products/660 (discontinued) // such as www.adafruit.com/products/660 (discontinued)
// For new use see www.adafruit.com/products/746 (needs different code) // For new use see www.adafruit.com/products/746 (needs different code)

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries
//
// SPDX-License-Identifier: MIT
// Arduino "bridge" code between host computer and WS2801-based digital // Arduino "bridge" code between host computer and WS2801-based digital
// RGB LED pixels (e.g. Adafruit product ID #322). Intended for use // RGB LED pixels (e.g. Adafruit product ID #322). Intended for use
// with USB-native boards such as Teensy or Adafruit 32u4 Breakout; // with USB-native boards such as Teensy or Adafruit 32u4 Breakout;

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries
//
// SPDX-License-Identifier: MIT
/***************************************************************************** /*****************************************************************************
Sketch for testing WS2801 LED strands - lights one LED along length of strand. Sketch for testing WS2801 LED strands - lights one LED along length of strand.
Because only one LED is lit at a time, can safely be powered from Arduino +5V. Because only one LED is lit at a time, can safely be powered from Arduino +5V.

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# ATMakers HandUp # ATMakers HandUp
# Listens to the USB Serial port and responds to incoming strings # Listens to the USB Serial port and responds to incoming strings
# Sets appropriate colors on the DotStar LED # Sets appropriate colors on the DotStar LED

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries
#
# SPDX-License-Identifier: MIT
""" """
Paint for PyPortal, PyBadge, PyGamer, and the like. Paint for PyPortal, PyBadge, PyGamer, and the like.

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time import time
import analogio import analogio

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2021 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time import time
import board import board
import simpleio import simpleio

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries
//
// SPDX-License-Identifier: MIT
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
Gemma "Firewalker Lite" sneakers sketch. Gemma "Firewalker Lite" sneakers sketch.
Uses the following Adafruit parts (X2 for two shoes): Uses the following Adafruit parts (X2 for two shoes):

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2018 Phillip Burgess for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# Gemma "Firewalker Lite" sneakers # Gemma "Firewalker Lite" sneakers
# - Uses the following Adafruit parts (X2 for two shoes): # - Uses the following Adafruit parts (X2 for two shoes):
# * Gemma M0 3V microcontroller (#3501) # * Gemma M0 3V microcontroller (#3501)

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time import time
import board import board
import displayio import displayio

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# This file is where you keep secret settings, passwords, and tokens! # This file is where you keep secret settings, passwords, and tokens!
# If you put them in the code you risk committing that info or sharing it # If you put them in the code you risk committing that info or sharing it

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2018 Collin Cunningham for Adafruit Industries
//
// SPDX-License-Identifier: MIT
/* MIDI Solenoid Drummer /* MIDI Solenoid Drummer
* for use with Adafruit Feather + Crickit Featherwing * for use with Adafruit Feather + Crickit Featherwing
* assumes a 5V solenoid connected to each of Crickit's four Drive ports * assumes a 5V solenoid connected to each of Crickit's four Drive ports

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2021 Eva Herrada for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time import time
import math import math
import board import board

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2017 Mikey Sklar for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time import time
import board import board

View file

@ -1,3 +1,8 @@
# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries
# SPDX-FileCopyrightText: 2020 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT
""" """
RGB Matrix Ocean Scroller RGB Matrix Ocean Scroller
Adafruit invests time and resources providing this open source code. Adafruit invests time and resources providing this open source code.

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries
//
// SPDX-License-Identifier: MIT
// On Leonardo/Micro or others with hardware serial, use those! // On Leonardo/Micro or others with hardware serial, use those!
// uncomment this line: // uncomment this line:
// #define pmsSerial Serial1 // #define pmsSerial Serial1

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2020 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time import time
import math import math
import board import board

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2019 Collin Cunningham for Adafruit Industries
#
# SPDX-License-Identifier: MIT
""" """
This code will display a random strategy from strategies.py when the This code will display a random strategy from strategies.py when the
PyPortal screen is pressed. See the original Oblique Strategies PyPortal screen is pressed. See the original Oblique Strategies

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2019 Collin Cunningham for Adafruit Industries
#
# SPDX-License-Identifier: MIT
strategies = [ strategies = [
"Abandon normal instruments", "Abandon normal instruments",
"Accept advice", "Accept advice",

View file

@ -1,222 +1,226 @@
// Bad Apple for ESP32 with OLED SSD1306 | 2018 by Hackerspace-FFM.de | MIT-License. // SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries
// Adapted for Sharp Memory display + Itsy Bitsy M4 - put video.hs on QSPI storage using CircuitPython //
#include "heatshrink_decoder.h" // SPDX-License-Identifier: MIT
#include "SdFat.h" // Bad Apple for ESP32 with OLED SSD1306 | 2018 by Hackerspace-FFM.de | MIT-License.
#include "Adafruit_SPIFlash.h" // Adapted for Sharp Memory display + Itsy Bitsy M4 - put video.hs on QSPI storage using CircuitPython
#include <Adafruit_SharpMem.h> #include "heatshrink_decoder.h"
#define BLACK 0
#define WHITE 1 #include "SdFat.h"
#include "Adafruit_SPIFlash.h"
#define SCALE 3 #include <Adafruit_SharpMem.h>
#define BLACK 0
#define WHITE 1
#if HEATSHRINK_DYNAMIC_ALLOC
#error HEATSHRINK_DYNAMIC_ALLOC must be false for static allocation test suite. #define SCALE 3
#endif
static heatshrink_decoder hsd; #if HEATSHRINK_DYNAMIC_ALLOC
#error HEATSHRINK_DYNAMIC_ALLOC must be false for static allocation test suite.
// global storage for putPixels #endif
int16_t curr_x = 0;
int16_t curr_y = 0; static heatshrink_decoder hsd;
// global storage for decodeRLE // global storage for putPixels
int32_t runlength = -1; int16_t curr_x = 0;
int32_t c_to_dup = -1; int16_t curr_y = 0;
uint32_t lastRefresh = 0; // global storage for decodeRLE
int32_t runlength = -1;
#define SHARP_SS A5 int32_t c_to_dup = -1;
Adafruit_SharpMem display(&SPI, SHARP_SS, 400, 240, 3000000);
#define X_OFFSET (400 - SCALE*128) / 2 uint32_t lastRefresh = 0;
#define Y_OFFSET (240 - SCALE*64) / 2
#define SHARP_SS A5
Adafruit_FlashTransport_QSPI flashTransport; Adafruit_SharpMem display(&SPI, SHARP_SS, 400, 240, 3000000);
Adafruit_SPIFlash flash(&flashTransport); #define X_OFFSET (400 - SCALE*128) / 2
FatFileSystem fatfs; #define Y_OFFSET (240 - SCALE*64) / 2
Adafruit_FlashTransport_QSPI flashTransport;
void putPixels(uint8_t c, int32_t len) { Adafruit_SPIFlash flash(&flashTransport);
static uint8_t color; FatFileSystem fatfs;
uint8_t b = 0;
while(len--) {
b = 128; void putPixels(uint8_t c, int32_t len) {
for (int i=0; i<8; i++) { static uint8_t color;
if (c & b) { uint8_t b = 0;
color = WHITE; while(len--) {
} else { b = 128;
color = BLACK; for (int i=0; i<8; i++) {
} if (c & b) {
b >>= 1; color = WHITE;
if (color == BLACK) { } else {
// we clear the buffer each frame so only black pixels need to be drawn color = BLACK;
display.fillRect(X_OFFSET+curr_x*SCALE, Y_OFFSET+curr_y*SCALE, SCALE, SCALE, color); }
} b >>= 1;
curr_x++; if (color == BLACK) {
if(curr_x >= 128) { // we clear the buffer each frame so only black pixels need to be drawn
curr_x = 0; display.fillRect(X_OFFSET+curr_x*SCALE, Y_OFFSET+curr_y*SCALE, SCALE, SCALE, color);
curr_y++; }
if(curr_y >= 64) { curr_x++;
curr_y = 0; if(curr_x >= 128) {
display.refresh(); curr_x = 0;
display.clearDisplayBuffer(); curr_y++;
// 30 fps target rate if(curr_y >= 64) {
//if(digitalRead(0)) while((millis() - lastRefresh) < 33) ; curr_y = 0;
//lastRefresh = millis(); display.refresh();
} display.clearDisplayBuffer();
} // 30 fps target rate
} //if(digitalRead(0)) while((millis() - lastRefresh) < 33) ;
} //lastRefresh = millis();
} }
}
void decodeRLE(uint8_t c) { }
if(c_to_dup == -1) { }
if((c == 0x55) || (c == 0xaa)) { }
c_to_dup = c;
} else { void decodeRLE(uint8_t c) {
putPixels(c, 1); if(c_to_dup == -1) {
} if((c == 0x55) || (c == 0xaa)) {
} else { c_to_dup = c;
if(runlength == -1) { } else {
if(c == 0) { putPixels(c, 1);
putPixels(c_to_dup & 0xff, 1); }
c_to_dup = -1; } else {
} else if((c & 0x80) == 0) { if(runlength == -1) {
if(c_to_dup == 0x55) { if(c == 0) {
putPixels(0, c); putPixels(c_to_dup & 0xff, 1);
} else { c_to_dup = -1;
putPixels(255, c); } else if((c & 0x80) == 0) {
} if(c_to_dup == 0x55) {
c_to_dup = -1; putPixels(0, c);
} else { } else {
runlength = c & 0x7f; putPixels(255, c);
} }
} else { c_to_dup = -1;
runlength = runlength | (c << 7); } else {
if(c_to_dup == 0x55) { runlength = c & 0x7f;
putPixels(0, runlength); }
} else { } else {
putPixels(255, runlength); runlength = runlength | (c << 7);
} if(c_to_dup == 0x55) {
c_to_dup = -1; putPixels(0, runlength);
runlength = -1; } else {
} putPixels(255, runlength);
} }
} c_to_dup = -1;
runlength = -1;
#define RLEBUFSIZE 4096 }
#define READBUFSIZE 2048 }
void readFile(const char * path){ }
static uint8_t rle_buf[RLEBUFSIZE];
size_t rle_bufhead = 0; #define RLEBUFSIZE 4096
size_t rle_size = 0; #define READBUFSIZE 2048
void readFile(const char * path){
size_t filelen = 0; static uint8_t rle_buf[RLEBUFSIZE];
size_t filesize; size_t rle_bufhead = 0;
static uint8_t compbuf[READBUFSIZE]; size_t rle_size = 0;
Serial.printf("Reading file: %s\n", path); size_t filelen = 0;
File file = fatfs.open(path); size_t filesize;
if(!file || file.isDirectory()){ static uint8_t compbuf[READBUFSIZE];
Serial.println("Failed to open file for reading");
display.println("File open error. Upload video.hs using CircuitPython"); Serial.printf("Reading file: %s\n", path);
display.refresh(); File file = fatfs.open(path);
return; if(!file || file.isDirectory()){
} Serial.println("Failed to open file for reading");
filelen = file.size(); display.println("File open error. Upload video.hs using CircuitPython");
filesize = filelen; display.refresh();
Serial.printf("File size: %d\n", filelen); return;
}
// init display, putPixels and decodeRLE filelen = file.size();
display.clearDisplay(); filesize = filelen;
display.refresh(); Serial.printf("File size: %d\n", filelen);
curr_x = 0;
curr_y = 0; // init display, putPixels and decodeRLE
runlength = -1; display.clearDisplay();
c_to_dup = -1; display.refresh();
lastRefresh = millis(); curr_x = 0;
curr_y = 0;
// init decoder runlength = -1;
heatshrink_decoder_reset(&hsd); c_to_dup = -1;
size_t count = 0; lastRefresh = millis();
uint32_t sunk = 0;
size_t toRead; // init decoder
size_t toSink = 0; heatshrink_decoder_reset(&hsd);
uint32_t sinkHead = 0; size_t count = 0;
uint32_t sunk = 0;
size_t toRead;
// Go through file... size_t toSink = 0;
while(filelen) { uint32_t sinkHead = 0;
if(toSink == 0) {
toRead = filelen;
if(toRead > READBUFSIZE) toRead = READBUFSIZE; // Go through file...
file.read(compbuf, toRead); while(filelen) {
filelen -= toRead; if(toSink == 0) {
toSink = toRead; toRead = filelen;
sinkHead = 0; if(toRead > READBUFSIZE) toRead = READBUFSIZE;
} file.read(compbuf, toRead);
filelen -= toRead;
// uncompress buffer toSink = toRead;
HSD_sink_res sres; sinkHead = 0;
sres = heatshrink_decoder_sink(&hsd, &compbuf[sinkHead], toSink, &count); }
//Serial.print("^^ sinked ");
//Serial.println(count); // uncompress buffer
toSink -= count; HSD_sink_res sres;
sinkHead = count; sres = heatshrink_decoder_sink(&hsd, &compbuf[sinkHead], toSink, &count);
sunk += count; //Serial.print("^^ sinked ");
if (sunk == filesize) { //Serial.println(count);
heatshrink_decoder_finish(&hsd); toSink -= count;
} sinkHead = count;
sunk += count;
HSD_poll_res pres; if (sunk == filesize) {
do { heatshrink_decoder_finish(&hsd);
rle_size = 0; }
pres = heatshrink_decoder_poll(&hsd, rle_buf, RLEBUFSIZE, &rle_size);
//Serial.print("^^ polled "); HSD_poll_res pres;
//Serial.println(rle_size); do {
if(pres < 0) { rle_size = 0;
Serial.print("POLL ERR! "); pres = heatshrink_decoder_poll(&hsd, rle_buf, RLEBUFSIZE, &rle_size);
Serial.println(pres); //Serial.print("^^ polled ");
return; //Serial.println(rle_size);
} if(pres < 0) {
Serial.print("POLL ERR! ");
rle_bufhead = 0; Serial.println(pres);
while(rle_size) { return;
rle_size--; }
if(rle_bufhead >= RLEBUFSIZE) {
Serial.println("RLE_SIZE ERR!"); rle_bufhead = 0;
return; while(rle_size) {
} rle_size--;
decodeRLE(rle_buf[rle_bufhead++]); if(rle_bufhead >= RLEBUFSIZE) {
} Serial.println("RLE_SIZE ERR!");
} while (pres == HSDR_POLL_MORE); return;
} }
file.close(); decodeRLE(rle_buf[rle_bufhead++]);
Serial.println("Done."); }
} } while (pres == HSDR_POLL_MORE);
}
file.close();
Serial.println("Done.");
void setup(){ }
Serial.begin(115200);
//while (!Serial) delay(10);
Serial.println("Bad apple");
void setup(){
flash.begin(); Serial.begin(115200);
// Init file system on the flash //while (!Serial) delay(10);
fatfs.begin(&flash); Serial.println("Bad apple");
display.begin(); flash.begin();
display.clearDisplay(); // Init file system on the flash
display.setTextColor(BLACK, WHITE); fatfs.begin(&flash);
display.setTextSize(2);
display.println("Scaled Bad Apple For SHARP Memory"); display.begin();
display.refresh(); display.clearDisplay();
display.setTextColor(BLACK, WHITE);
readFile("/video.hs"); display.setTextSize(2);
} display.println("Scaled Bad Apple For SHARP Memory");
display.refresh();
void loop(){
readFile("/video.hs");
} }
void loop(){
}

View file

@ -1,20 +1,24 @@
#ifndef HEATSHRINK_H // SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries
#define HEATSHRINK_H //
// SPDX-License-Identifier: MIT
#define HEATSHRINK_AUTHOR "Scott Vokes <vokes.s@gmail.com>"
#define HEATSHRINK_URL "https://github.com/atomicobject/heatshrink" #ifndef HEATSHRINK_H
#define HEATSHRINK_H
/* Version 0.4.1 */
#define HEATSHRINK_VERSION_MAJOR 0 #define HEATSHRINK_AUTHOR "Scott Vokes <vokes.s@gmail.com>"
#define HEATSHRINK_VERSION_MINOR 4 #define HEATSHRINK_URL "https://github.com/atomicobject/heatshrink"
#define HEATSHRINK_VERSION_PATCH 1
/* Version 0.4.1 */
#define HEATSHRINK_MIN_WINDOW_BITS 4 #define HEATSHRINK_VERSION_MAJOR 0
#define HEATSHRINK_MAX_WINDOW_BITS 15 #define HEATSHRINK_VERSION_MINOR 4
#define HEATSHRINK_VERSION_PATCH 1
#define HEATSHRINK_MIN_LOOKAHEAD_BITS 3
#define HEATSHRINK_MIN_WINDOW_BITS 4
#define HEATSHRINK_LITERAL_MARKER 0x01 #define HEATSHRINK_MAX_WINDOW_BITS 15
#define HEATSHRINK_BACKREF_MARKER 0x00
#define HEATSHRINK_MIN_LOOKAHEAD_BITS 3
#endif
#define HEATSHRINK_LITERAL_MARKER 0x01
#define HEATSHRINK_BACKREF_MARKER 0x00
#endif

View file

@ -1,26 +1,30 @@
#ifndef HEATSHRINK_CONFIG_H // SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries
#define HEATSHRINK_CONFIG_H //
// SPDX-License-Identifier: MIT
/* Should functionality assuming dynamic allocation be used? */
#ifndef HEATSHRINK_DYNAMIC_ALLOC #ifndef HEATSHRINK_CONFIG_H
#define HEATSHRINK_DYNAMIC_ALLOC 0 #define HEATSHRINK_CONFIG_H
#endif
/* Should functionality assuming dynamic allocation be used? */
#if HEATSHRINK_DYNAMIC_ALLOC #ifndef HEATSHRINK_DYNAMIC_ALLOC
/* Optional replacement of malloc/free */ #define HEATSHRINK_DYNAMIC_ALLOC 0
#define HEATSHRINK_MALLOC(SZ) malloc(SZ) #endif
#define HEATSHRINK_FREE(P, SZ) free(P)
#else #if HEATSHRINK_DYNAMIC_ALLOC
/* Required parameters for static configuration */ /* Optional replacement of malloc/free */
#define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 2048 #define HEATSHRINK_MALLOC(SZ) malloc(SZ)
#define HEATSHRINK_STATIC_WINDOW_BITS 11 #define HEATSHRINK_FREE(P, SZ) free(P)
#define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4 #else
#endif /* Required parameters for static configuration */
#define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 2048
/* Turn on logging for debugging. */ #define HEATSHRINK_STATIC_WINDOW_BITS 11
#define HEATSHRINK_DEBUGGING_LOGS 0 #define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4
#endif
/* Use indexing for faster compression. (This requires additional space.) */
#define HEATSHRINK_USE_INDEX 1 /* Turn on logging for debugging. */
#define HEATSHRINK_DEBUGGING_LOGS 0
#endif
/* Use indexing for faster compression. (This requires additional space.) */
#define HEATSHRINK_USE_INDEX 1
#endif

View file

@ -1,367 +1,371 @@
#include <stdlib.h> // SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries
#include <string.h> //
#include "heatshrink_decoder.h" // SPDX-License-Identifier: MIT
/* States for the polling state machine. */ #include <stdlib.h>
typedef enum { #include <string.h>
HSDS_TAG_BIT, /* tag bit */ #include "heatshrink_decoder.h"
HSDS_YIELD_LITERAL, /* ready to yield literal byte */
HSDS_BACKREF_INDEX_MSB, /* most significant byte of index */ /* States for the polling state machine. */
HSDS_BACKREF_INDEX_LSB, /* least significant byte of index */ typedef enum {
HSDS_BACKREF_COUNT_MSB, /* most significant byte of count */ HSDS_TAG_BIT, /* tag bit */
HSDS_BACKREF_COUNT_LSB, /* least significant byte of count */ HSDS_YIELD_LITERAL, /* ready to yield literal byte */
HSDS_YIELD_BACKREF, /* ready to yield back-reference */ HSDS_BACKREF_INDEX_MSB, /* most significant byte of index */
} HSD_state; HSDS_BACKREF_INDEX_LSB, /* least significant byte of index */
HSDS_BACKREF_COUNT_MSB, /* most significant byte of count */
#if HEATSHRINK_DEBUGGING_LOGS HSDS_BACKREF_COUNT_LSB, /* least significant byte of count */
#include <stdio.h> HSDS_YIELD_BACKREF, /* ready to yield back-reference */
#include <ctype.h> } HSD_state;
#include <assert.h>
#define LOG(...) fprintf(stderr, __VA_ARGS__) #if HEATSHRINK_DEBUGGING_LOGS
#define ASSERT(X) assert(X) #include <stdio.h>
static const char *state_names[] = { #include <ctype.h>
"tag_bit", #include <assert.h>
"yield_literal", #define LOG(...) fprintf(stderr, __VA_ARGS__)
"backref_index_msb", #define ASSERT(X) assert(X)
"backref_index_lsb", static const char *state_names[] = {
"backref_count_msb", "tag_bit",
"backref_count_lsb", "yield_literal",
"yield_backref", "backref_index_msb",
}; "backref_index_lsb",
#else "backref_count_msb",
#define LOG(...) /* no-op */ "backref_count_lsb",
#define ASSERT(X) /* no-op */ "yield_backref",
#endif };
#else
typedef struct { #define LOG(...) /* no-op */
uint8_t *buf; /* output buffer */ #define ASSERT(X) /* no-op */
size_t buf_size; /* buffer size */ #endif
size_t *output_size; /* bytes pushed to buffer, so far */
} output_info; typedef struct {
uint8_t *buf; /* output buffer */
#define NO_BITS ((uint16_t)-1) size_t buf_size; /* buffer size */
size_t *output_size; /* bytes pushed to buffer, so far */
/* Forward references. */ } output_info;
static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count);
static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte); #define NO_BITS ((uint16_t)-1)
#if HEATSHRINK_DYNAMIC_ALLOC /* Forward references. */
heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count);
uint8_t window_sz2, static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte);
uint8_t lookahead_sz2) {
if ((window_sz2 < HEATSHRINK_MIN_WINDOW_BITS) || #if HEATSHRINK_DYNAMIC_ALLOC
(window_sz2 > HEATSHRINK_MAX_WINDOW_BITS) || heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size,
(input_buffer_size == 0) || uint8_t window_sz2,
(lookahead_sz2 < HEATSHRINK_MIN_LOOKAHEAD_BITS) || uint8_t lookahead_sz2) {
(lookahead_sz2 >= window_sz2)) { if ((window_sz2 < HEATSHRINK_MIN_WINDOW_BITS) ||
return NULL; (window_sz2 > HEATSHRINK_MAX_WINDOW_BITS) ||
} (input_buffer_size == 0) ||
size_t buffers_sz = (1 << window_sz2) + input_buffer_size; (lookahead_sz2 < HEATSHRINK_MIN_LOOKAHEAD_BITS) ||
size_t sz = sizeof(heatshrink_decoder) + buffers_sz; (lookahead_sz2 >= window_sz2)) {
heatshrink_decoder *hsd = HEATSHRINK_MALLOC(sz); return NULL;
if (hsd == NULL) { return NULL; } }
hsd->input_buffer_size = input_buffer_size; size_t buffers_sz = (1 << window_sz2) + input_buffer_size;
hsd->window_sz2 = window_sz2; size_t sz = sizeof(heatshrink_decoder) + buffers_sz;
hsd->lookahead_sz2 = lookahead_sz2; heatshrink_decoder *hsd = HEATSHRINK_MALLOC(sz);
heatshrink_decoder_reset(hsd); if (hsd == NULL) { return NULL; }
LOG("-- allocated decoder with buffer size of %zu (%zu + %u + %u)\n", hsd->input_buffer_size = input_buffer_size;
sz, sizeof(heatshrink_decoder), (1 << window_sz2), input_buffer_size); hsd->window_sz2 = window_sz2;
return hsd; hsd->lookahead_sz2 = lookahead_sz2;
} heatshrink_decoder_reset(hsd);
LOG("-- allocated decoder with buffer size of %zu (%zu + %u + %u)\n",
void heatshrink_decoder_free(heatshrink_decoder *hsd) { sz, sizeof(heatshrink_decoder), (1 << window_sz2), input_buffer_size);
size_t buffers_sz = (1 << hsd->window_sz2) + hsd->input_buffer_size; return hsd;
size_t sz = sizeof(heatshrink_decoder) + buffers_sz; }
HEATSHRINK_FREE(hsd, sz);
(void)sz; /* may not be used by free */ void heatshrink_decoder_free(heatshrink_decoder *hsd) {
} size_t buffers_sz = (1 << hsd->window_sz2) + hsd->input_buffer_size;
#endif size_t sz = sizeof(heatshrink_decoder) + buffers_sz;
HEATSHRINK_FREE(hsd, sz);
void heatshrink_decoder_reset(heatshrink_decoder *hsd) { (void)sz; /* may not be used by free */
size_t buf_sz = 1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd); }
size_t input_sz = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd); #endif
memset(hsd->buffers, 0, buf_sz + input_sz);
hsd->state = HSDS_TAG_BIT; void heatshrink_decoder_reset(heatshrink_decoder *hsd) {
hsd->input_size = 0; size_t buf_sz = 1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd);
hsd->input_index = 0; size_t input_sz = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd);
hsd->bit_index = 0x00; memset(hsd->buffers, 0, buf_sz + input_sz);
hsd->current_byte = 0x00; hsd->state = HSDS_TAG_BIT;
hsd->output_count = 0; hsd->input_size = 0;
hsd->output_index = 0; hsd->input_index = 0;
hsd->head_index = 0; hsd->bit_index = 0x00;
} hsd->current_byte = 0x00;
hsd->output_count = 0;
/* Copy SIZE bytes into the decoder's input buffer, if it will fit. */ hsd->output_index = 0;
HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, hsd->head_index = 0;
uint8_t *in_buf, size_t size, size_t *input_size) { }
if ((hsd == NULL) || (in_buf == NULL) || (input_size == NULL)) {
return HSDR_SINK_ERROR_NULL; /* Copy SIZE bytes into the decoder's input buffer, if it will fit. */
} HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd,
uint8_t *in_buf, size_t size, size_t *input_size) {
size_t rem = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd) - hsd->input_size; if ((hsd == NULL) || (in_buf == NULL) || (input_size == NULL)) {
if (rem == 0) { return HSDR_SINK_ERROR_NULL;
*input_size = 0; }
return HSDR_SINK_FULL;
} size_t rem = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd) - hsd->input_size;
if (rem == 0) {
size = rem < size ? rem : size; *input_size = 0;
LOG("-- sinking %zd bytes\n", size); return HSDR_SINK_FULL;
/* copy into input buffer (at head of buffers) */ }
memcpy(&hsd->buffers[hsd->input_size], in_buf, size);
hsd->input_size += size; size = rem < size ? rem : size;
*input_size = size; LOG("-- sinking %zd bytes\n", size);
return HSDR_SINK_OK; /* copy into input buffer (at head of buffers) */
} memcpy(&hsd->buffers[hsd->input_size], in_buf, size);
hsd->input_size += size;
*input_size = size;
/***************** return HSDR_SINK_OK;
* Decompression * }
*****************/
#define BACKREF_COUNT_BITS(HSD) (HEATSHRINK_DECODER_LOOKAHEAD_BITS(HSD)) /*****************
#define BACKREF_INDEX_BITS(HSD) (HEATSHRINK_DECODER_WINDOW_BITS(HSD)) * Decompression *
*****************/
// States
static HSD_state st_tag_bit(heatshrink_decoder *hsd); #define BACKREF_COUNT_BITS(HSD) (HEATSHRINK_DECODER_LOOKAHEAD_BITS(HSD))
static HSD_state st_yield_literal(heatshrink_decoder *hsd, #define BACKREF_INDEX_BITS(HSD) (HEATSHRINK_DECODER_WINDOW_BITS(HSD))
output_info *oi);
static HSD_state st_backref_index_msb(heatshrink_decoder *hsd); // States
static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd); static HSD_state st_tag_bit(heatshrink_decoder *hsd);
static HSD_state st_backref_count_msb(heatshrink_decoder *hsd); static HSD_state st_yield_literal(heatshrink_decoder *hsd,
static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd); output_info *oi);
static HSD_state st_yield_backref(heatshrink_decoder *hsd, static HSD_state st_backref_index_msb(heatshrink_decoder *hsd);
output_info *oi); static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd);
static HSD_state st_backref_count_msb(heatshrink_decoder *hsd);
HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd);
uint8_t *out_buf, size_t out_buf_size, size_t *output_size) { static HSD_state st_yield_backref(heatshrink_decoder *hsd,
if ((hsd == NULL) || (out_buf == NULL) || (output_size == NULL)) { output_info *oi);
return HSDR_POLL_ERROR_NULL;
} HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd,
*output_size = 0; uint8_t *out_buf, size_t out_buf_size, size_t *output_size) {
if ((hsd == NULL) || (out_buf == NULL) || (output_size == NULL)) {
output_info oi; return HSDR_POLL_ERROR_NULL;
oi.buf = out_buf; }
oi.buf_size = out_buf_size; *output_size = 0;
oi.output_size = output_size;
output_info oi;
while (1) { oi.buf = out_buf;
LOG("-- poll, state is %d (%s), input_size %d\n", oi.buf_size = out_buf_size;
hsd->state, state_names[hsd->state], hsd->input_size); oi.output_size = output_size;
uint8_t in_state = hsd->state;
switch (in_state) { while (1) {
case HSDS_TAG_BIT: LOG("-- poll, state is %d (%s), input_size %d\n",
hsd->state = st_tag_bit(hsd); hsd->state, state_names[hsd->state], hsd->input_size);
break; uint8_t in_state = hsd->state;
case HSDS_YIELD_LITERAL: switch (in_state) {
hsd->state = st_yield_literal(hsd, &oi); case HSDS_TAG_BIT:
break; hsd->state = st_tag_bit(hsd);
case HSDS_BACKREF_INDEX_MSB: break;
hsd->state = st_backref_index_msb(hsd); case HSDS_YIELD_LITERAL:
break; hsd->state = st_yield_literal(hsd, &oi);
case HSDS_BACKREF_INDEX_LSB: break;
hsd->state = st_backref_index_lsb(hsd); case HSDS_BACKREF_INDEX_MSB:
break; hsd->state = st_backref_index_msb(hsd);
case HSDS_BACKREF_COUNT_MSB: break;
hsd->state = st_backref_count_msb(hsd); case HSDS_BACKREF_INDEX_LSB:
break; hsd->state = st_backref_index_lsb(hsd);
case HSDS_BACKREF_COUNT_LSB: break;
hsd->state = st_backref_count_lsb(hsd); case HSDS_BACKREF_COUNT_MSB:
break; hsd->state = st_backref_count_msb(hsd);
case HSDS_YIELD_BACKREF: break;
hsd->state = st_yield_backref(hsd, &oi); case HSDS_BACKREF_COUNT_LSB:
break; hsd->state = st_backref_count_lsb(hsd);
default: break;
return HSDR_POLL_ERROR_UNKNOWN; case HSDS_YIELD_BACKREF:
} hsd->state = st_yield_backref(hsd, &oi);
break;
/* If the current state cannot advance, check if input or output default:
* buffer are exhausted. */ return HSDR_POLL_ERROR_UNKNOWN;
if (hsd->state == in_state) { }
if (*output_size == out_buf_size) { return HSDR_POLL_MORE; }
return HSDR_POLL_EMPTY; /* If the current state cannot advance, check if input or output
} * buffer are exhausted. */
} if (hsd->state == in_state) {
} if (*output_size == out_buf_size) { return HSDR_POLL_MORE; }
return HSDR_POLL_EMPTY;
static HSD_state st_tag_bit(heatshrink_decoder *hsd) { }
uint32_t bits = get_bits(hsd, 1); // get tag bit }
if (bits == NO_BITS) { }
return HSDS_TAG_BIT;
} else if (bits) { static HSD_state st_tag_bit(heatshrink_decoder *hsd) {
return HSDS_YIELD_LITERAL; uint32_t bits = get_bits(hsd, 1); // get tag bit
} else if (HEATSHRINK_DECODER_WINDOW_BITS(hsd) > 8) { if (bits == NO_BITS) {
return HSDS_BACKREF_INDEX_MSB; return HSDS_TAG_BIT;
} else { } else if (bits) {
hsd->output_index = 0; return HSDS_YIELD_LITERAL;
return HSDS_BACKREF_INDEX_LSB; } else if (HEATSHRINK_DECODER_WINDOW_BITS(hsd) > 8) {
} return HSDS_BACKREF_INDEX_MSB;
} } else {
hsd->output_index = 0;
static HSD_state st_yield_literal(heatshrink_decoder *hsd, return HSDS_BACKREF_INDEX_LSB;
output_info *oi) { }
/* Emit a repeated section from the window buffer, and add it (again) }
* to the window buffer. (Note that the repetition can include
* itself.)*/ static HSD_state st_yield_literal(heatshrink_decoder *hsd,
if (*oi->output_size < oi->buf_size) { output_info *oi) {
uint16_t byte = get_bits(hsd, 8); /* Emit a repeated section from the window buffer, and add it (again)
if (byte == NO_BITS) { return HSDS_YIELD_LITERAL; } /* out of input */ * to the window buffer. (Note that the repetition can include
uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; * itself.)*/
uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; if (*oi->output_size < oi->buf_size) {
uint8_t c = byte & 0xFF; uint16_t byte = get_bits(hsd, 8);
LOG("-- emitting literal byte 0x%02x ('%c')\n", c, isprint(c) ? c : '.'); if (byte == NO_BITS) { return HSDS_YIELD_LITERAL; } /* out of input */
buf[hsd->head_index++ & mask] = c; uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)];
push_byte(hsd, oi, c); uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1;
return HSDS_TAG_BIT; uint8_t c = byte & 0xFF;
} else { LOG("-- emitting literal byte 0x%02x ('%c')\n", c, isprint(c) ? c : '.');
return HSDS_YIELD_LITERAL; buf[hsd->head_index++ & mask] = c;
} push_byte(hsd, oi, c);
} return HSDS_TAG_BIT;
} else {
static HSD_state st_backref_index_msb(heatshrink_decoder *hsd) { return HSDS_YIELD_LITERAL;
uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); }
ASSERT(bit_ct > 8); }
uint16_t bits = get_bits(hsd, bit_ct - 8);
LOG("-- backref index (msb), got 0x%04x (+1)\n", bits); static HSD_state st_backref_index_msb(heatshrink_decoder *hsd) {
if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_MSB; } uint8_t bit_ct = BACKREF_INDEX_BITS(hsd);
hsd->output_index = bits << 8; ASSERT(bit_ct > 8);
return HSDS_BACKREF_INDEX_LSB; uint16_t bits = get_bits(hsd, bit_ct - 8);
} LOG("-- backref index (msb), got 0x%04x (+1)\n", bits);
if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_MSB; }
static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd) { hsd->output_index = bits << 8;
uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); return HSDS_BACKREF_INDEX_LSB;
uint16_t bits = get_bits(hsd, bit_ct < 8 ? bit_ct : 8); }
LOG("-- backref index (lsb), got 0x%04x (+1)\n", bits);
if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_LSB; } static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd) {
hsd->output_index |= bits; uint8_t bit_ct = BACKREF_INDEX_BITS(hsd);
hsd->output_index++; uint16_t bits = get_bits(hsd, bit_ct < 8 ? bit_ct : 8);
uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); LOG("-- backref index (lsb), got 0x%04x (+1)\n", bits);
hsd->output_count = 0; if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_LSB; }
return (br_bit_ct > 8) ? HSDS_BACKREF_COUNT_MSB : HSDS_BACKREF_COUNT_LSB; hsd->output_index |= bits;
} hsd->output_index++;
uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd);
static HSD_state st_backref_count_msb(heatshrink_decoder *hsd) { hsd->output_count = 0;
uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); return (br_bit_ct > 8) ? HSDS_BACKREF_COUNT_MSB : HSDS_BACKREF_COUNT_LSB;
ASSERT(br_bit_ct > 8); }
uint16_t bits = get_bits(hsd, br_bit_ct - 8);
LOG("-- backref count (msb), got 0x%04x (+1)\n", bits); static HSD_state st_backref_count_msb(heatshrink_decoder *hsd) {
if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_MSB; } uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd);
hsd->output_count = bits << 8; ASSERT(br_bit_ct > 8);
return HSDS_BACKREF_COUNT_LSB; uint16_t bits = get_bits(hsd, br_bit_ct - 8);
} LOG("-- backref count (msb), got 0x%04x (+1)\n", bits);
if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_MSB; }
static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd) { hsd->output_count = bits << 8;
uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); return HSDS_BACKREF_COUNT_LSB;
uint16_t bits = get_bits(hsd, br_bit_ct < 8 ? br_bit_ct : 8); }
LOG("-- backref count (lsb), got 0x%04x (+1)\n", bits);
if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_LSB; } static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd) {
hsd->output_count |= bits; uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd);
hsd->output_count++; uint16_t bits = get_bits(hsd, br_bit_ct < 8 ? br_bit_ct : 8);
return HSDS_YIELD_BACKREF; LOG("-- backref count (lsb), got 0x%04x (+1)\n", bits);
} if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_LSB; }
hsd->output_count |= bits;
static HSD_state st_yield_backref(heatshrink_decoder *hsd, hsd->output_count++;
output_info *oi) { return HSDS_YIELD_BACKREF;
size_t count = oi->buf_size - *oi->output_size; }
if (count > 0) {
size_t i = 0; static HSD_state st_yield_backref(heatshrink_decoder *hsd,
if (hsd->output_count < count) count = hsd->output_count; output_info *oi) {
uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; size_t count = oi->buf_size - *oi->output_size;
uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; if (count > 0) {
uint16_t neg_offset = hsd->output_index; size_t i = 0;
LOG("-- emitting %zu bytes from -%u bytes back\n", count, neg_offset); if (hsd->output_count < count) count = hsd->output_count;
ASSERT(neg_offset <= mask + 1); uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)];
ASSERT(count <= (size_t)(1 << BACKREF_COUNT_BITS(hsd))); uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1;
uint16_t neg_offset = hsd->output_index;
for (i=0; i<count; i++) { LOG("-- emitting %zu bytes from -%u bytes back\n", count, neg_offset);
uint8_t c = buf[(hsd->head_index - neg_offset) & mask]; ASSERT(neg_offset <= mask + 1);
push_byte(hsd, oi, c); ASSERT(count <= (size_t)(1 << BACKREF_COUNT_BITS(hsd)));
buf[hsd->head_index & mask] = c;
hsd->head_index++; for (i=0; i<count; i++) {
LOG(" -- ++ 0x%02x\n", c); uint8_t c = buf[(hsd->head_index - neg_offset) & mask];
} push_byte(hsd, oi, c);
hsd->output_count -= count; buf[hsd->head_index & mask] = c;
if (hsd->output_count == 0) { return HSDS_TAG_BIT; } hsd->head_index++;
} LOG(" -- ++ 0x%02x\n", c);
return HSDS_YIELD_BACKREF; }
} hsd->output_count -= count;
if (hsd->output_count == 0) { return HSDS_TAG_BIT; }
/* Get the next COUNT bits from the input buffer, saving incremental progress. }
* Returns NO_BITS on end of input, or if more than 15 bits are requested. */ return HSDS_YIELD_BACKREF;
static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count) { }
uint16_t accumulator = 0;
int i = 0; /* Get the next COUNT bits from the input buffer, saving incremental progress.
if (count > 15) { return NO_BITS; } * Returns NO_BITS on end of input, or if more than 15 bits are requested. */
LOG("-- popping %u bit(s)\n", count); static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count) {
uint16_t accumulator = 0;
/* If we aren't able to get COUNT bits, suspend immediately, because we int i = 0;
* don't track how many bits of COUNT we've accumulated before suspend. */ if (count > 15) { return NO_BITS; }
if (hsd->input_size == 0) { LOG("-- popping %u bit(s)\n", count);
if (hsd->bit_index < (1 << (count - 1))) { return NO_BITS; }
} /* If we aren't able to get COUNT bits, suspend immediately, because we
* don't track how many bits of COUNT we've accumulated before suspend. */
for (i = 0; i < count; i++) { if (hsd->input_size == 0) {
if (hsd->bit_index == 0x00) { if (hsd->bit_index < (1 << (count - 1))) { return NO_BITS; }
if (hsd->input_size == 0) { }
LOG(" -- out of bits, suspending w/ accumulator of %u (0x%02x)\n",
accumulator, accumulator); for (i = 0; i < count; i++) {
return NO_BITS; if (hsd->bit_index == 0x00) {
} if (hsd->input_size == 0) {
hsd->current_byte = hsd->buffers[hsd->input_index++]; LOG(" -- out of bits, suspending w/ accumulator of %u (0x%02x)\n",
LOG(" -- pulled byte 0x%02x\n", hsd->current_byte); accumulator, accumulator);
if (hsd->input_index == hsd->input_size) { return NO_BITS;
hsd->input_index = 0; /* input is exhausted */ }
hsd->input_size = 0; hsd->current_byte = hsd->buffers[hsd->input_index++];
} LOG(" -- pulled byte 0x%02x\n", hsd->current_byte);
hsd->bit_index = 0x80; if (hsd->input_index == hsd->input_size) {
} hsd->input_index = 0; /* input is exhausted */
accumulator <<= 1; hsd->input_size = 0;
if (hsd->current_byte & hsd->bit_index) { }
accumulator |= 0x01; hsd->bit_index = 0x80;
if (0) { }
LOG(" -- got 1, accumulator 0x%04x, bit_index 0x%02x\n", accumulator <<= 1;
accumulator, hsd->bit_index); if (hsd->current_byte & hsd->bit_index) {
} accumulator |= 0x01;
} else { if (0) {
if (0) { LOG(" -- got 1, accumulator 0x%04x, bit_index 0x%02x\n",
LOG(" -- got 0, accumulator 0x%04x, bit_index 0x%02x\n", accumulator, hsd->bit_index);
accumulator, hsd->bit_index); }
} } else {
} if (0) {
hsd->bit_index >>= 1; LOG(" -- got 0, accumulator 0x%04x, bit_index 0x%02x\n",
} accumulator, hsd->bit_index);
}
if (count > 1) { LOG(" -- accumulated %08x\n", accumulator); } }
return accumulator; hsd->bit_index >>= 1;
} }
HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd) { if (count > 1) { LOG(" -- accumulated %08x\n", accumulator); }
if (hsd == NULL) { return HSDR_FINISH_ERROR_NULL; } return accumulator;
switch (hsd->state) { }
case HSDS_TAG_BIT:
return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd) {
if (hsd == NULL) { return HSDR_FINISH_ERROR_NULL; }
/* If we want to finish with no input, but are in these states, it's switch (hsd->state) {
* because the 0-bit padding to the last byte looks like a backref case HSDS_TAG_BIT:
* marker bit followed by all 0s for index and count bits. */ return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE;
case HSDS_BACKREF_INDEX_LSB:
case HSDS_BACKREF_INDEX_MSB: /* If we want to finish with no input, but are in these states, it's
case HSDS_BACKREF_COUNT_LSB: * because the 0-bit padding to the last byte looks like a backref
case HSDS_BACKREF_COUNT_MSB: * marker bit followed by all 0s for index and count bits. */
return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; case HSDS_BACKREF_INDEX_LSB:
case HSDS_BACKREF_INDEX_MSB:
/* If the output stream is padded with 0xFFs (possibly due to being in case HSDS_BACKREF_COUNT_LSB:
* flash memory), also explicitly check the input size rather than case HSDS_BACKREF_COUNT_MSB:
* uselessly returning MORE but yielding 0 bytes when polling. */ return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE;
case HSDS_YIELD_LITERAL:
return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; /* If the output stream is padded with 0xFFs (possibly due to being in
* flash memory), also explicitly check the input size rather than
default: * uselessly returning MORE but yielding 0 bytes when polling. */
return HSDR_FINISH_MORE; case HSDS_YIELD_LITERAL:
} return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE;
}
default:
static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte) { return HSDR_FINISH_MORE;
LOG(" -- pushing byte: 0x%02x ('%c')\n", byte, isprint(byte) ? byte : '.'); }
oi->buf[(*oi->output_size)++] = byte; }
(void)hsd;
} static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte) {
LOG(" -- pushing byte: 0x%02x ('%c')\n", byte, isprint(byte) ? byte : '.');
oi->buf[(*oi->output_size)++] = byte;
(void)hsd;
}

View file

@ -1,100 +1,104 @@
#ifndef HEATSHRINK_DECODER_H // SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries
#define HEATSHRINK_DECODER_H //
// SPDX-License-Identifier: MIT
#include <stdint.h>
#include <stddef.h> #ifndef HEATSHRINK_DECODER_H
#include "heatshrink_common.h" #define HEATSHRINK_DECODER_H
#include "heatshrink_config.h"
#include <stdint.h>
typedef enum { #include <stddef.h>
HSDR_SINK_OK, /* data sunk, ready to poll */ #include "heatshrink_common.h"
HSDR_SINK_FULL, /* out of space in internal buffer */ #include "heatshrink_config.h"
HSDR_SINK_ERROR_NULL=-1, /* NULL argument */
} HSD_sink_res; typedef enum {
HSDR_SINK_OK, /* data sunk, ready to poll */
typedef enum { HSDR_SINK_FULL, /* out of space in internal buffer */
HSDR_POLL_EMPTY, /* input exhausted */ HSDR_SINK_ERROR_NULL=-1, /* NULL argument */
HSDR_POLL_MORE, /* more data remaining, call again w/ fresh output buffer */ } HSD_sink_res;
HSDR_POLL_ERROR_NULL=-1, /* NULL arguments */
HSDR_POLL_ERROR_UNKNOWN=-2, typedef enum {
} HSD_poll_res; HSDR_POLL_EMPTY, /* input exhausted */
HSDR_POLL_MORE, /* more data remaining, call again w/ fresh output buffer */
typedef enum { HSDR_POLL_ERROR_NULL=-1, /* NULL arguments */
HSDR_FINISH_DONE, /* output is done */ HSDR_POLL_ERROR_UNKNOWN=-2,
HSDR_FINISH_MORE, /* more output remains */ } HSD_poll_res;
HSDR_FINISH_ERROR_NULL=-1, /* NULL arguments */
} HSD_finish_res; typedef enum {
HSDR_FINISH_DONE, /* output is done */
#if HEATSHRINK_DYNAMIC_ALLOC HSDR_FINISH_MORE, /* more output remains */
#define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(BUF) \ HSDR_FINISH_ERROR_NULL=-1, /* NULL arguments */
((BUF)->input_buffer_size) } HSD_finish_res;
#define HEATSHRINK_DECODER_WINDOW_BITS(BUF) \
((BUF)->window_sz2) #if HEATSHRINK_DYNAMIC_ALLOC
#define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ #define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(BUF) \
((BUF)->lookahead_sz2) ((BUF)->input_buffer_size)
#else #define HEATSHRINK_DECODER_WINDOW_BITS(BUF) \
#define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_) \ ((BUF)->window_sz2)
HEATSHRINK_STATIC_INPUT_BUFFER_SIZE #define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \
#define HEATSHRINK_DECODER_WINDOW_BITS(_) \ ((BUF)->lookahead_sz2)
(HEATSHRINK_STATIC_WINDOW_BITS) #else
#define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ #define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_) \
(HEATSHRINK_STATIC_LOOKAHEAD_BITS) HEATSHRINK_STATIC_INPUT_BUFFER_SIZE
#endif #define HEATSHRINK_DECODER_WINDOW_BITS(_) \
(HEATSHRINK_STATIC_WINDOW_BITS)
typedef struct { #define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \
uint16_t input_size; /* bytes in input buffer */ (HEATSHRINK_STATIC_LOOKAHEAD_BITS)
uint16_t input_index; /* offset to next unprocessed input byte */ #endif
uint16_t output_count; /* how many bytes to output */
uint16_t output_index; /* index for bytes to output */ typedef struct {
uint16_t head_index; /* head of window buffer */ uint16_t input_size; /* bytes in input buffer */
uint8_t state; /* current state machine node */ uint16_t input_index; /* offset to next unprocessed input byte */
uint8_t current_byte; /* current byte of input */ uint16_t output_count; /* how many bytes to output */
uint8_t bit_index; /* current bit index */ uint16_t output_index; /* index for bytes to output */
uint16_t head_index; /* head of window buffer */
#if HEATSHRINK_DYNAMIC_ALLOC uint8_t state; /* current state machine node */
/* Fields that are only used if dynamically allocated. */ uint8_t current_byte; /* current byte of input */
uint8_t window_sz2; /* window buffer bits */ uint8_t bit_index; /* current bit index */
uint8_t lookahead_sz2; /* lookahead bits */
uint16_t input_buffer_size; /* input buffer size */ #if HEATSHRINK_DYNAMIC_ALLOC
/* Fields that are only used if dynamically allocated. */
/* Input buffer, then expansion window buffer */ uint8_t window_sz2; /* window buffer bits */
uint8_t buffers[]; uint8_t lookahead_sz2; /* lookahead bits */
#else uint16_t input_buffer_size; /* input buffer size */
/* Input buffer, then expansion window buffer */
uint8_t buffers[(1 << HEATSHRINK_DECODER_WINDOW_BITS(_)) /* Input buffer, then expansion window buffer */
+ HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_)]; uint8_t buffers[];
#endif #else
} heatshrink_decoder; /* Input buffer, then expansion window buffer */
uint8_t buffers[(1 << HEATSHRINK_DECODER_WINDOW_BITS(_))
#if HEATSHRINK_DYNAMIC_ALLOC + HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_)];
/* Allocate a decoder with an input buffer of INPUT_BUFFER_SIZE bytes, #endif
* an expansion buffer size of 2^WINDOW_SZ2, and a lookahead } heatshrink_decoder;
* size of 2^lookahead_sz2. (The window buffer and lookahead sizes
* must match the settings used when the data was compressed.) #if HEATSHRINK_DYNAMIC_ALLOC
* Returns NULL on error. */ /* Allocate a decoder with an input buffer of INPUT_BUFFER_SIZE bytes,
heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, * an expansion buffer size of 2^WINDOW_SZ2, and a lookahead
uint8_t expansion_buffer_sz2, uint8_t lookahead_sz2); * size of 2^lookahead_sz2. (The window buffer and lookahead sizes
* must match the settings used when the data was compressed.)
/* Free a decoder. */ * Returns NULL on error. */
void heatshrink_decoder_free(heatshrink_decoder *hsd); heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size,
#endif uint8_t expansion_buffer_sz2, uint8_t lookahead_sz2);
/* Reset a decoder. */ /* Free a decoder. */
void heatshrink_decoder_reset(heatshrink_decoder *hsd); void heatshrink_decoder_free(heatshrink_decoder *hsd);
#endif
/* Sink at most SIZE bytes from IN_BUF into the decoder. *INPUT_SIZE is set to
* indicate how many bytes were actually sunk (in case a buffer was filled). */ /* Reset a decoder. */
HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, void heatshrink_decoder_reset(heatshrink_decoder *hsd);
uint8_t *in_buf, size_t size, size_t *input_size);
/* Sink at most SIZE bytes from IN_BUF into the decoder. *INPUT_SIZE is set to
/* Poll for output from the decoder, copying at most OUT_BUF_SIZE bytes into * indicate how many bytes were actually sunk (in case a buffer was filled). */
* OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */ HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd,
HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, uint8_t *in_buf, size_t size, size_t *input_size);
uint8_t *out_buf, size_t out_buf_size, size_t *output_size);
/* Poll for output from the decoder, copying at most OUT_BUF_SIZE bytes into
/* Notify the dencoder that the input stream is finished. * OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */
* If the return value is HSDR_FINISH_MORE, there is still more output, so HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd,
* call heatshrink_decoder_poll and repeat. */ uint8_t *out_buf, size_t out_buf_size, size_t *output_size);
HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd);
/* Notify the dencoder that the input stream is finished.
#endif * If the return value is HSDR_FINISH_MORE, there is still more output, so
* call heatshrink_decoder_poll and repeat. */
HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd);
#endif

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include <FastLED.h> #include <FastLED.h>
#define LED_PIN 0 #define LED_PIN 0

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import board import board
import neopixel import neopixel
import adafruit_fancyled.adafruit_fancyled as fancy import adafruit_fancyled.adafruit_fancyled as fancy

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import serial import serial
# open serial port # open serial port

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import json import json
import serial import serial

View file

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import serial import serial
# how many bytes to read? # how many bytes to read?

View file

@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include <Adafruit_NeoPixel.h> #include <Adafruit_NeoPixel.h>
#include "OPTIGATrustM.h" #include "OPTIGATrustM.h"