Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
141
Src/bmp/rle.cpp
Normal file
141
Src/bmp/rle.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include "rle.h"
|
||||
static bool CheckOverflow(size_t total_size, int current_position, int read_size)
|
||||
{
|
||||
if (read_size > (int)total_size) // check separate to avoid overflow
|
||||
return true;
|
||||
if (((int)total_size - read_size) < current_position)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void RLE16(const uint8_t *rle, size_t rle_size_bytes, uint16_t *video_frame, size_t video_frame_size, int stride)
|
||||
{
|
||||
int input = 0;
|
||||
int output = 0;
|
||||
video_frame_size >>= 1; // divide by 2 since we're indexing as uint16_t
|
||||
int next_line = output + stride;
|
||||
while (input < (int)rle_size_bytes && output < (int)video_frame_size)
|
||||
{
|
||||
if (CheckOverflow(rle_size_bytes, input, 2)) // we always read at least two bytes
|
||||
break;
|
||||
|
||||
uint8_t b0 = rle[input++];
|
||||
if (b0)
|
||||
{
|
||||
if (CheckOverflow(rle_size_bytes, input, 2))
|
||||
break;
|
||||
|
||||
if (CheckOverflow(video_frame_size, output, b0))
|
||||
{
|
||||
b0 = (uint8_t)(video_frame_size - output);
|
||||
}
|
||||
|
||||
uint16_t pixel = *(uint16_t *)(&rle[input]);
|
||||
input += 2;
|
||||
while (b0--)
|
||||
{
|
||||
memcpy(&video_frame[output], &pixel, 2);
|
||||
output++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t b1 = rle[input++];
|
||||
if (b1 == 0)
|
||||
{
|
||||
output = next_line;
|
||||
next_line = output + stride;
|
||||
}
|
||||
else if (b1 == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (b1 == 2)
|
||||
{
|
||||
if (CheckOverflow(rle_size_bytes, input, 2))
|
||||
break;
|
||||
|
||||
uint8_t p1 = rle[input++];
|
||||
uint8_t p2 = rle[input++];
|
||||
output += p1;
|
||||
output += p2*stride;
|
||||
next_line += p2*stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckOverflow(rle_size_bytes, input, b1*2))
|
||||
break;
|
||||
|
||||
if (CheckOverflow(video_frame_size, output, b1))
|
||||
break;
|
||||
for (uint8_t i=0;i!=b1;i++)
|
||||
{
|
||||
video_frame[output++] = *(uint16_t *)(&rle[input]);
|
||||
input+=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RLE8(const uint8_t *rle, size_t rle_size_bytes, uint8_t *video_frame, size_t video_frame_size, int stride)
|
||||
{
|
||||
int input = 0;
|
||||
int output = 0;
|
||||
int next_line = output + stride;
|
||||
while (input < (int)rle_size_bytes && output < (int)video_frame_size)
|
||||
{
|
||||
if (CheckOverflow(rle_size_bytes, input, 2)) // we always read at least two bytes
|
||||
break;
|
||||
uint8_t b0 = rle[input++];
|
||||
if (b0)
|
||||
{
|
||||
if (CheckOverflow(video_frame_size, output, b0))
|
||||
{
|
||||
b0 = (uint8_t)(video_frame_size - output);
|
||||
}
|
||||
|
||||
uint8_t pixel = rle[input++];
|
||||
memset(&video_frame[output], pixel, b0);
|
||||
output+=b0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t b1 = rle[input++];
|
||||
if (b1 == 0)
|
||||
{
|
||||
output = next_line;
|
||||
next_line = output + stride;
|
||||
}
|
||||
else if (b1 == 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (b1 == 2)
|
||||
{
|
||||
if (CheckOverflow(rle_size_bytes, input, 2))
|
||||
break;
|
||||
|
||||
uint8_t p1 = rle[input++];
|
||||
uint8_t p2 = rle[input++];
|
||||
output += p1;
|
||||
output += p2*stride;
|
||||
next_line += p2*stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckOverflow(rle_size_bytes, input, b1))
|
||||
break;
|
||||
|
||||
if (CheckOverflow(video_frame_size, output, b1))
|
||||
break;
|
||||
memcpy(&video_frame[output], &rle[input], b1);
|
||||
input += b1;
|
||||
output += b1;
|
||||
if (b1 & 1)
|
||||
input++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue