aboutsummaryrefslogtreecommitdiffstats
path: root/liblss16_encode_from_colour_index.c
diff options
context:
space:
mode:
Diffstat (limited to 'liblss16_encode_from_colour_index.c')
-rw-r--r--liblss16_encode_from_colour_index.c70
1 files changed, 51 insertions, 19 deletions
diff --git a/liblss16_encode_from_colour_index.c b/liblss16_encode_from_colour_index.c
index 95b600b..ae3948e 100644
--- a/liblss16_encode_from_colour_index.c
+++ b/liblss16_encode_from_colour_index.c
@@ -12,11 +12,11 @@
static size_t
flush_buffer(struct liblss16_encoder *encoder, uint8_t *buffer, size_t size)
{
- size_t i;
- for (i = 0; size && encoder->nbuffered - i > 1U; i += 2U, size--)
- buffer[i] = (uint8_t)(encoder->buffered[i + 0] | (encoder->buffered[i + 1] << 4));
- memmove(&encoder->buffered[0], &encoder->buffered[i], encoder->nbuffered - i);
- return i;
+ size_t i = 0, j = 0;
+ for (; size && encoder->nbuffered - i > 1U; i += 2U, size--)
+ buffer[j++] = (uint8_t)(encoder->buffered[i + 0] | (encoder->buffered[i + 1] << 4));
+ memmove(&encoder->buffered[0], &encoder->buffered[i], encoder->nbuffered -= (uint8_t)i);
+ return j;
}
@@ -26,6 +26,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
{
uint8_t *buffer = buffer_;
size_t n;
+ unsigned value;
*written_out = 0;
*nconsumed_out = 0;
@@ -35,7 +36,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
*buffer++ = (uint8_t)0x3DU;
- ++*nconsumed_out;
+ ++*written_out;
encoder->header_position++;
/* fall through */
@@ -43,7 +44,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
*buffer++ = (uint8_t)0xF3U;
- ++*nconsumed_out;
+ ++*written_out;
encoder->header_position++;
/* fall through */
@@ -51,7 +52,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
*buffer++ = (uint8_t)0x13U;
- ++*nconsumed_out;
+ ++*written_out;
encoder->header_position++;
/* fall through */
@@ -59,7 +60,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
*buffer++ = (uint8_t)0x14U;
- ++*nconsumed_out;
+ ++*written_out;
encoder->header_position++;
/* fall through */
@@ -67,7 +68,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
*buffer++ = (uint8_t)encoder->header.width;
- ++*nconsumed_out;
+ ++*written_out;
encoder->header_position++;
/* fall through */
@@ -75,7 +76,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
*buffer++ = (uint8_t)(encoder->header.width >> 8);
- ++*nconsumed_out;
+ ++*written_out;
encoder->header_position++;
/* fall through */
@@ -83,7 +84,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
*buffer++ = (uint8_t)encoder->header.height;
- ++*nconsumed_out;
+ ++*written_out;
encoder->header_position++;
/* fall through */
@@ -91,7 +92,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
*buffer++ = (uint8_t)(encoder->header.height >> 8);
- ++*nconsumed_out;
+ ++*written_out;
encoder->header_position++;
/* fall through */
@@ -102,8 +103,8 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
while (encoder->header_position < 8U + 16U * 3U) {
if (!size--)
return LIBLSS16_ENCODE_RUNNING;
- *buffer++ = ((const uint8_t *)encoder->header.colour_map)[encoder->header_position++];
- ++*nconsumed_out;
+ *buffer++ = ((const uint8_t *)encoder->header.colour_map)[encoder->header_position - 8U];
+ ++*written_out;
encoder->header_position++;
}
@@ -121,8 +122,24 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
}
}
+ if (!encoder->x_rem)
+ goto end_of_image;
+
while (npixels--) {
if (*pixels == encoder->previous) {
+ if (encoder->repetition == 255U + 16U) {
+ encoder->buffered[encoder->nbuffered++] = encoder->previous;
+ encoder->buffered[encoder->nbuffered++] = 0;
+ encoder->buffered[encoder->nbuffered++] = (uint8_t)15U;
+ encoder->buffered[encoder->nbuffered++] = (uint8_t)15U;
+
+ n = flush_buffer(encoder, buffer, size);
+ buffer = &buffer[n];
+ size -= n;
+ *written_out += n;
+
+ encoder->repetition = 0U;
+ }
encoder->repetition++;
} else {
if (!encoder->repetition) {
@@ -131,7 +148,7 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
encoder->buffered[encoder->nbuffered++] = encoder->previous;
encoder->buffered[encoder->nbuffered++] = (uint8_t)encoder->repetition;
} else {
- unsigned value = encoder->repetition - 16U;
+ value = encoder->repetition - 16U;
encoder->buffered[encoder->nbuffered++] = encoder->previous;
encoder->buffered[encoder->nbuffered++] = 0;
encoder->buffered[encoder->nbuffered++] = (uint8_t)(value & 15U);
@@ -145,13 +162,28 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer
buffer = &buffer[n];
size -= n;
*written_out += n;
- if (encoder->nbuffered > 1U)
- return LIBLSS16_ENCODE_RUNNING;
}
++pixels;
++*nconsumed_out;
+ --encoder->x_rem;
+ if (encoder->nbuffered > 1U)
+ return LIBLSS16_ENCODE_RUNNING;
+
+ if (!encoder->x_rem) {
+ end_of_image:
+ if (!encoder->repetition) {
+ /* do nothing */
+ } else if (encoder->repetition < 16U) {
+ encoder->buffered[encoder->nbuffered++] = encoder->previous;
+ encoder->buffered[encoder->nbuffered++] = (uint8_t)encoder->repetition;
+ } else {
+ value = encoder->repetition - 16U;
+ encoder->buffered[encoder->nbuffered++] = encoder->previous;
+ encoder->buffered[encoder->nbuffered++] = 0;
+ encoder->buffered[encoder->nbuffered++] = (uint8_t)(value & 15U);
+ encoder->buffered[encoder->nbuffered++] = (uint8_t)(value >> 4);
+ }
- if (!--encoder->x_rem) {
encoder->previous = 0;
encoder->repetition = 0;
encoder->x_rem = encoder->header.width;