davidgfnet / wifi_display

E-ink wireless display
244 stars 36 forks source link

RLE code might be wrong #3

Open X-Ryl669 opened 8 years ago

X-Ryl669 commented 8 years ago

There is no escape code in the RLE encoding code in PHP if the "pixel/color" to be encoded has a value higher than 0x80 and happens only once. In that case, the PHP code will output the pixel -as-is-. However, when decoding, it'll be skipped because it'll be seen as "RLE length" code, and will repeat the next pixel (pix & 0x7F) times.

Also, to speed up the PHP image encoding code, it'll be better to preallocate the output array and access it with iterators, instead of constantly growing it.

davidgfnet commented 8 years ago

Can you provide an input that can exploit that? I'm not seeing what you say sorry, I might be too tired. And yes, the routine is massively slow and I have a couple of ideas on how to speed it up, I'll fix it in the coming days (since it makes my screen to time out when my server is doing other stuff and PHP gets CPU bottlenecked). Thanks!

X-Ryl669 commented 8 years ago

This is what I get: Code

$buf = [255, 255, 255, 128, 120, 112, 0, 0, 0, 0, 0, 230, 0, 30, 32, 32, 33, 33, 33, 34, 34, 34, 34, 128, 128, 128, 128, 128];
echo "In\n";
foreach($buf as $b)
   printf("%02x ", $b);
echo "\n";

echo "Out\n";
$out = img_compress($buf);
foreach($out as $b)
   printf("%02x ", $b);
echo "\n";

Result

In
ff ff ff 80 78 70 00 00 00 00 00 e6 00 1e 20 20 21 21 21 22 22 22 22 80 80 80 80 80
Out
85 ff ff ff 80 78 70 04 00 87 e6 00 1e 20 20 21 21 21 03 22 04 80

Then, looking at the output stream, I see many missed opportunities to compress, ideal with the decoder expectations would be:

02 ff 82 80 78 70 04 00 84 e6 00 1e 20 20 02 21 03 22 04 80

If the first bytes in the input picture are not repeating at least 4 times, then the first byte in the output stream is wrong.

TLDR: I'm not sure about the line $encoderle = ($bytec > 3); which should read, $encoderle = ($bytec > 2); to me, which gives the best output and does decompress to the input sequence too.

davidgfnet commented 8 years ago

So let me get this clear: You are just saying that the compressor is not optimal, but it works, right? Cause your original post seemed to imply that the compressor/decompressor would break under certain circumstances (inputs). But yeah you are right, the "> 3" should be a ">= 3", that's a typo there that generates suboptimal encodings. Also since we don't bother to encode 1 or 2 bytes repeated sequences (for obvious reasons) we could expand the encoding lenght by subtracting a 2 and therefore allowing 129 byte RLEs (that might improve compression for large uniform colors). Also note that the PHP always outputs a 60KB image regardless of the compression level (pads with zeros) due to the fact that the image doesn't have a header with the content length. That's definetly an improvement we could add to the STM32 firmware.

X-Ryl669 commented 8 years ago

First question, yes it works suboptimal. The first test I give it was with quasi random picture, and it failed but because it overflowed, but the error was between the keyboard and the chair. Second remark, yes it could be a definitive improvement since it takes time to transmit it to both CPU (ESP is limited by STM32 SPI's speed anyway).