View Single Post
Old 04-30-2012, 01:12 AM   #22
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by kiri87 View Post
...
I did notice, though, there's some unusual issues with the dithering, at least on my Kindle3. That part of code is too complex for me to try fixing it.
First, the dither16 (screen attached, no 2) shows some black where there should be white (on the top, for example)
Second, the dither2 (screen attached, no 3) has a very subtle bug, that can observed easily for grays close to 50%. I attached a resized & cropped a portion of the screenshot to show the bug (screen attached, no 4). Basically, one column in 8 is off by 1 pixel.
After a lot of looking for patterns in different size dither tables, using Karnaugh maps, I figured out a logic function that can generate any size ordered dither table. It works fine up to a 4x4 dither used for 256-color mode, but beyond that it seems to have a subtle bug. Debugging these things is an iterative process, where you keep getting closer until it is "good enough" to do the job intended (and demos do not need to be very accurate). I need to do some speed tests to see whether I should use it during init to create a dither table, or if it is fast enough to use while dithering. At least when compiling with tcc, the dither table wins it would seem (not unexpected, seeing that the recursive dither function calls itself twice for every pixel, and that doubles again at each recursive call). I am impressed by how simple I got that function down to (at least *I* am impressed). I will do a demo eventually.

Anyway, the reason for this post is that this work showed where the "bug" is in dithering as described by kiri87. Dithering works by conditionally rounding the bottom four bits (not used by 4-bit eink hardware) which sometimes adds one to the visible upper 16 bits, depending on the position in the dither matrix. But there is a general problem with dithering in that it converts a 0-255 range to a 0-256 range because 0 sometimes becomes 1, but 255 sometimes becomes 256). And of course, the value 256 white become 0 black when put into an 8-bit pixel. There are two common solutions (often ignored causing the same bug in other code): use a ceiling function to clip values over 255 to 255, or rescale the values *255/256. Rescaling is the mathematically "correct" approach, but consumes more CPU (and therefore more battery).

That "one column in 8 off by 1 pixel" bug mentioned above is also the same range scaling issue due to dithering creating an extra color value. All those extra pixels push up into causing white to dither up into black again. And rescaling to fix the range issues slows down the animation.

EDIT: Rescaling fixed the problems in the dither, and for demos that wait until time for the next eink update, it runs full speed even calculating dither for every pixel and not using a dither table. Cool...



Last edited by geekmaster; 04-30-2012 at 02:14 AM.
geekmaster is offline   Reply With Quote