Skip to content

Commit 6cb4160

Browse files
committed
More compact RLE
1 parent 15cf179 commit 6cb4160

File tree

5 files changed

+870
-387
lines changed

5 files changed

+870
-387
lines changed

Marlin/src/lcd/tft/canvas.cpp

+32-43
Original file line numberDiff line numberDiff line change
@@ -126,51 +126,40 @@ void Canvas::addImage(int16_t x, int16_t y, MarlinImage image, uint16_t *colors)
126126
if (color_mode == RLE16) {
127127
uint8_t *bytedata = (uint8_t *)images[image].data;
128128
if (!bytedata) return;
129-
uint8_t overflow = 0;
130-
131-
for (int16_t i = 0; i < image_height; i++) {
132-
int16_t line = y + i;
133-
if (line >= startLine && line < endLine) {
134-
uint16_t *pixel = buffer + x + (line - startLine) * width;
135-
int16_t j=0;
136-
while (j < image_width) {
137-
if ((x + j >= 0) && (x + j < width)) {
138-
uint8_t count = *bytedata;
139-
uint16_t color = ENDIAN_COLOR((bytedata[1]<<8)+bytedata[2]);
140-
if (overflow) {
141-
count = overflow;
142-
overflow = 0;
143-
}
144-
if (j + count > image_width) {
145-
overflow = (j + count) - image_width;
146-
count = count - overflow;
147-
}
148-
for (uint8_t runcount = 0; runcount < count; runcount++) {
149-
*pixel = color;
150-
pixel++;
151-
j++;
152-
}
153-
if (!overflow)
154-
bytedata += 3;
129+
130+
// Loop through the image data advancing the row and column as needed
131+
int16_t row = 0, col = 0, // Image data line and column indexes
132+
outrow = y, outcol = x;
133+
134+
bool done = false;
135+
while (!done) {
136+
uint8_t count = *bytedata++; // Get the count byte
137+
const bool isrle = (count < 0x80); // < 128 is a repeat run; > 128 is a distinct run
138+
count = (count & 0x7F) + 1; // Actual count is 7-bit plus 1
139+
140+
bool getcol = true; // Get at least one color word
141+
while (count--) { // Emit 'count' pixels
142+
143+
uint16_t msb, lsb, color;
144+
if (getcol) {
145+
msb = *bytedata++, lsb = *bytedata++, color = ENDIAN_COLOR((msb << 8) + lsb);
146+
getcol = !isrle;
147+
}
148+
149+
if (outrow >= startLine) { // Dest pixel Y at the canvas yet?
150+
if (WITHIN(outcol, 0, width - 1)) { // Dest pixel X within the canvas?
151+
uint16_t * const pixel = buffer + outcol + (outrow - startLine) * width;
152+
*pixel = color; // Store the color in the pixel
155153
}
156154
}
157-
}
158-
else {
159-
int16_t j=0;
160-
while (j < image_width) {
161-
if ((x + j >= 0) && (x + j < width)) {
162-
uint8_t count = *bytedata;
163-
if (overflow) {
164-
count = overflow;
165-
overflow = 0;
166-
}
167-
if (j + count > image_width) {
168-
overflow = (j + count) - image_width;
169-
count = count - overflow;
170-
}
171-
j += count;
172-
if (!overflow)
173-
bytedata += 3;
155+
156+
++col; ++outcol; // Advance the pixel column
157+
if (col >= image_width) { // Past the right edge of the source image?
158+
++row; ++outrow; // Advance to the next line
159+
col = 0; outcol = x;
160+
if (outrow >= endLine || row >= image_height) {
161+
done = true; // Done once past the end of the canvas
162+
break;
174163
}
175164
}
176165
}

0 commit comments

Comments
 (0)