I'm trying to figure out how to decode screenshots. On my CX running 4.5.0, TiLP takes this screenshot:

However, when trying to decode with this library, I get:

As there's black on the bottom, this isn't a swapping-width-and-length issue, nor is it a color conversion error (or if it is, it's not the main issue) as then there would be patterns of identical colors. My guess is that it's a RLE decoding error, as here's what TiLP does:
switch (format)
{
case CALC_PIXFMT_GRAY_4:
{
uint8_t *q;
uint32_t i, j;
for (i = 0, j = 0, q = dst; i < input_size;)
{
int8_t rec = src[i++];
if (rec >= 0)
{
// Positive count: "repeat 8-bit value" block.
uint8_t cnt = ((uint8_t)rec) + 1;
uint8_t val = src[i++];
if (j + cnt > max_output_size)
{
ret = ERR_INVALID_SCREENSHOT;
break;
}
memset(q, val, cnt);
q += cnt;
j += cnt;
}
else
{
// Negative count: "verbatim" block of 8-bit values.
uint8_t cnt = ((uint8_t)-rec) + 1;
if (j + cnt > max_output_size)
{
ret = ERR_INVALID_SCREENSHOT;
break;
}
memcpy(q, src+i, cnt);
q += cnt;
i += cnt;
j += cnt;
}
}
ret = 0;
}
break;
case CALC_PIXFMT_RGB_565_LE:
{
uint8_t *q;
uint32_t i, j;
for (i = 0, j = 0, q = dst; i < input_size;)
{
int8_t rec = src[i++];
if (rec >= 0)
{
// Positive count: "repeat 32-bit value" block.
uint8_t cnt = ((uint8_t)rec) + 1;
uint32_t val;
uint8_t k;
if (j + cnt * 4 > max_output_size)
{
ret = ERR_INVALID_SCREENSHOT;
break;
}
memcpy(&val, src + i, sizeof(uint32_t));
for (k = 0; k < cnt; k++)
{
memcpy(q, &val, 4);
q += 4;
}
i += 4;
j += cnt * 4;
}
else
{
// Negative count: "verbatim" block of 32-bit values.
uint8_t cnt = ((uint8_t)-rec) + 1;
if (j + cnt * 4 > max_output_size)
{
ret = ERR_INVALID_SCREENSHOT;
break;
}
memcpy(q, src + i, cnt * 4);
q += cnt * 4;
i += cnt * 4;
j += cnt * 4;
}
}
ret = 0;
}
break;
default:
{
ticalcs_critical(_("Unknown pixel format %d\n"), format);
ret = ERR_INVALID_PARAMETER;
}
}
versus this library:
while (in_size > 1 && out_size) {
if (ptr->len < 0) {
len = -(ptr->len) + 1;
len = len < out_size ? len : out_size;
len = len < in_size ? len : in_size;
memcpy(out, &ptr->byte, len);
in_size -= (1 + (len));
ptr = (void*)((unsigned char*)ptr + (1 + (len)));
} else {
len = ptr->len + 1;
len = len < out_size ? len : out_size;
memset(out, ptr->byte, len);
in_size -= sizeof(struct rle);
ptr++;
}
out_size -= len;
out += len;
}
This library doesn't switch between calculator variants and is considerably shorter, so I'd then assume that this library is implemented incorrectly.
I'm trying to figure out how to decode screenshots. On my CX running 4.5.0, TiLP takes this screenshot:


However, when trying to decode with this library, I get:
As there's black on the bottom, this isn't a swapping-width-and-length issue, nor is it a color conversion error (or if it is, it's not the main issue) as then there would be patterns of identical colors. My guess is that it's a RLE decoding error, as here's what TiLP does:
versus this library:
This library doesn't switch between calculator variants and is considerably shorter, so I'd then assume that this library is implemented incorrectly.