Skip to content

Commit 88119aa

Browse files
committed
add example code and library.properties
1 parent 212eca6 commit 88119aa

File tree

6 files changed

+149
-8
lines changed

6 files changed

+149
-8
lines changed

README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# uCompression
2-
uCompression provides RLE compression and decompression functions for microcontrollers implemented as static member functions,
3-
so no instance of the class is required.
2+
Flash memory is valuable resource, especially when using graphical displays on small micro controllers like an ATTiny85 or the ATMega328PB (Arduino UNO). This is where data compression might save the day!
3+
4+
**uCompression** provides fast RLE compression and decompression functions for micro controllers.
5+
It's easy to use, as it is implemented as static member functions, so no instance of the class is required.
6+
7+
*The main design goals were code size and speed.*
48

59
## Compressing data
610

@@ -50,6 +54,9 @@ const uint8_t* uCompression::pgm_RLEdecompress256( const uint8_t* compressedData
5054
is automatically used, resulting in roughly the double decompression Speed.
5155
5256
## Limitiations
57+
The first and most important limitation is, that there is **NO error checking**!
58+
If a target buffer is too small or the chunk sizes for encoding is larger than for decoding, the behaviour is undefined, most likely the MCU will crash or reboot.
59+
5360
RLE algorithms are specialized on efficiently compressing constant data areas. Random data cannot be compressed and will result in the compressed data being slightly larger than the original data.
5461
Under worst case conditions the resulting size will exceed the original data size (by 1 byte for every
5562
63 bytes of source data in a chunk).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//
2+
// Demo code for uCompression
3+
//
4+
// (c)2024 by Lorandil
5+
//
6+
// This code is just a quick demonstration how to use the library and requires
7+
// at least 2kB of RAM and a serial interface to run.
8+
//
9+
// The library itself can even be used on an ATTiny25 when selecting an appropriate chunk size!
10+
//
11+
12+
const uint16_t BUFFER_SIZE = 600;
13+
14+
#include "uCompression.h"
15+
16+
// some simple test data
17+
const uint8_t PROGMEM testData[] =
18+
"****************************************\n"
19+
"* *\n"
20+
"* Welcome to the uCompression library! *\n"
21+
"* *\n"
22+
"* * ******* *\n"
23+
"* *** *** * * *\n"
24+
"* ***** ******* * *** * *\n"
25+
"* ******* ********* * * * * *\n"
26+
"* ********* ******* * *** * *\n"
27+
"* *** *** * * *\n"
28+
"* *** ******* *\n"
29+
"* *\n"
30+
"****************************************\n";
31+
32+
void setup()
33+
{
34+
// wait a moment for the serial port to become ready
35+
delay( 5000 );
36+
// initialize serial transmission
37+
Serial.begin( 115200 );
38+
}
39+
40+
void loop()
41+
{
42+
uint16_t uncompressedSize = sizeof( testData );
43+
44+
// print the uncompressed data
45+
Serial.print(F("Uncompressed data (size = ")); Serial.print( uncompressedSize ); Serial.println(F(")"));
46+
Serial.print( (const __FlashStringHelper *) testData );
47+
48+
// allocate memory for the compressed data
49+
uint8_t compressedData[BUFFER_SIZE];
50+
51+
// compress the test data
52+
Serial.print(F("Compressing data... "));
53+
uint16_t compressedSize = uCompression::pgm_RLEcompress( testData, // pointer to original data
54+
uncompressedSize, // original size
55+
compressedData ); // pointer to result buffer (compressed data)
56+
57+
// print the compressed size
58+
Serial.print(F("size of compressed data is ")); Serial.print( compressedSize ); Serial.println(F(" bytes"));
59+
60+
// allocate buffer for decompressed data (and fill it with '0' to ensure the test data is zero terminated)
61+
uint8_t uncompressedData[BUFFER_SIZE];
62+
memset( uncompressedData, 0, sizeof( uncompressedData ) );
63+
// uncompress the data
64+
uCompression::RLEdecompress( compressedData, // pointer to the compressed data
65+
uncompressedData, // pointer to result buffer (decompressed data)
66+
uncompressedSize ); // original size
67+
68+
// and print the decompressed data for referrence
69+
Serial.println(F("\nDecompressed data"));
70+
Serial.print( (const char *) uncompressedData );
71+
72+
// compare decompressed data to original data
73+
if ( memcmp_P( uncompressedData, testData, uncompressedSize ) == 0 )
74+
{
75+
Serial.println(F("The data has been decompressed correctly!"));
76+
}
77+
else
78+
{
79+
Serial.println(F("*** The decompressed data is different from the original data! ***"));
80+
}
81+
82+
while ( true );
83+
}

keywords.txt

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#######################################
2+
3+
# Syntax Coloring Map For uCompression
4+
5+
#######################################
6+
7+
# Class (KEYWORD1)
8+
9+
#######################################
10+
11+
12+
13+
uCompression KEYWORD1
14+
15+
16+
17+
#######################################
18+
19+
# Methods and Functions (KEYWORD2)
20+
21+
#######################################
22+
23+
24+
RLEcompress KEYWORD2
25+
26+
pgm_RLEcompress KEYWORD2
27+
clearBuffer KEYWORD2
28+
RLEdecompress KEYWORD2
29+
RLEdecompress256 KEYWORD2
30+
pgm_RLEdecompress KEYWORD2
31+
pgm_RLEdecompress256 KEYWORD2
32+
33+
34+
#######################################
35+
# Constants (LITERAL1)
36+
#######################################
37+
38+
39+
RLE_UNCOMPRESSED_DATA LITERAL1
40+
RLE_COMPRESSED_0xFF_DATA LITERAL1
41+
RLE_COMPRESSED_0x00_DATA LITERAL1
42+
RLE_COMPRESSED_DATA LITERAL1
43+
RLE_COMPRESSION_MASK LITERAL1

library.properties

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=uCompression
2+
version=0.1
3+
author=Lorandil
4+
maintainer=Lorandil (Lorandil@gmx.de)
5+
sentence=Simple compression/decompression library.
6+
paragraph=uCompression was designed to compress simple monochrome image data as it is usually used on displays like SSD1306.
7+
category=Data Processing
8+
url=https://github.com/Lorandil/uCompression
9+
architectures=*
10+
depends=

uCompression.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
/*--------------------------------------------------------------*/
44
uint16_t uCompression::RLEcompress( const uint8_t *uncompressedData,
55
uint16_t uncompressedByteCount,
6-
uint8_t *compressedData,
7-
uint16_t compressedBufferSize )
6+
uint8_t *compressedData )
87
{
98
uint16_t compressedByteCount = 0;
109

@@ -98,8 +97,7 @@ uint16_t uCompression::RLEcompress( const uint8_t *uncompressedData,
9897
/*--------------------------------------------------------------*/
9998
uint16_t uCompression::pgm_RLEcompress( const uint8_t *uncompressedData,
10099
uint16_t uncompressedByteCount,
101-
uint8_t *compressedData,
102-
uint16_t compressedBufferSize )
100+
uint8_t *compressedData )
103101
{
104102
uint16_t compressedByteCount = 0;
105103

uCompression.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ class uCompression
2626
public:
2727
uCompression() = default;
2828
static uint16_t RLEcompress( const uint8_t *uncompressedData, uint16_t uncompressedByteCount,
29-
uint8_t *compressedData, uint16_t compressedBufferSize );
29+
uint8_t *compressedData );
3030
static uint16_t pgm_RLEcompress( const uint8_t *uncompressedData, uint16_t uncompressedByteCount,
31-
uint8_t *compressedData, uint16_t compressedBufferSize );
31+
uint8_t *compressedData );
3232
static const uint8_t *RLEdecompress( const uint8_t *compressedData,
3333
uint8_t *uncompressedData, uint16_t uncompressedByteCount );
3434
static const uint8_t *RLEdecompress256( const uint8_t *compressedData,

0 commit comments

Comments
 (0)