Carpe diem, c'est la vie.
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
|
paldemo - kindle 0-255 dithered palette display
UPDATE: The new paldemo version (not yet published) contains a second dither table with gamma 2.2 dither threshold values for LCD and CRT desktop displays. This gives a color palette screenshot that appears correctly balanced (average 50% gray) on desktop displays. See the gamma tutorial below.
This "paldemo" program demonstrates the new "geekmaster formula 42" dithering function adapted for a 0-255 color palette. It can be used to convert a framebuffer containing a grayscale image or antialiased text directly to dithered black and white, so that it can be animated or resized smoothly.
A new dither table is used that spreads the 65 shades of gray evenly through the 0-255 color value range, and a "-1" adjustment was made to a strategic location in the formula to balance the number of pure blacks and pure whites on the ends of the color table for 4-bit pixel displays.
Because 65 is not a power of 2, the threshold columns do not line up in the displayed 16x16 color palette, but this is to be expected for non-integral range conversion.
The display palette onscreen size is adjustable. This demo program calls palette(550) to display a 550x550 pixel palette, but you can change that value to resize the palette.
The screenshot gamma tutorial:
The source: Spoiler:
PHP Code:
//==================================================== // paldemo 1.0 - kindle 0-255 dithered palette display // Copyright (C) 2012 by geekmaster, with MIT license: // http://www.opensource.org/licenses/mit-license.php //---------------------------------------------------- // The speed is limited by the eink device drivers. // Newer kindle models are faster, but need delays. // This was tested on DX,DXG,K3,K4(Mini),K5(Touch). //----------------------------------------------------
#include <stdio.h> // printf #include <stdlib.h> // malloc, free, atoi #include <string.h> // memset, memcpy #include <unistd.h> // usleep #include <fcntl.h> // open, close, write #include <time.h> // time #include <sys/ioctl.h> // ioctl #include <sys/time.h> // gettime #include <sys/mman.h> // mmap, munmap #include <linux/fb.h> // screeninfo
#define FPS 5 // max frames/sec
enum eupd_op { EUPD_OPEN,EUPD_CLOSE,EUPD_UPDATE }; typedef unsigned char u8; typedef unsigned int u32;
// function prototypes inline void setpx(int,int,int); int eupdate(int); int getmsec(void); void palette(int);
// global var7 u32 mpu=100; // msec/update u8 *fb0=NULL; // framebuffer pointer int fdFB=0; // fb0 file descriptor u32 fs=0; // fb0 stride u32 MX=0; // xres (visible) u32 MY=0; // yres (visible) u8 blk=0; // black u8 wht=0; // white u8 pb=0; // pixel bits
//================================================ // paldemo - kindle 0-255 dithered palette display // This works on all kindle eink models. Enjoy! //------------------------------------------------ void paldemo(void) { int x,y,c,tn,i,j; struct fb_var_screeninfo screeninfo; fdFB=open("/dev/fb0",O_RDWR); // eink framebuffer
// calculate model-specific vars ioctl(fdFB,FBIOGET_VSCREENINFO,&screeninfo); MX=screeninfo.xres; // max X+1 MY=screeninfo.yres; // max Y+1 pb=screeninfo.bits_per_pixel; // pixel bits fs=screeninfo.xres_virtual*pb/8; // fb0 stride blk=pb/8-1; // black wht=~blk; // white fb0=(u8 *)mmap(0,MY*fs,PROT_READ|PROT_WRITE,MAP_SHARED,fdFB,0); // map fb0 eupdate(EUPD_OPEN); // open fb0 update proc
system("eips 19 32 '0-255 Palette'"); system("eips 19 34 'by Geekmaster'");
palette(550);
// cleanup - close and free resources eupdate(EUPD_UPDATE); // update display eupdate(EUPD_CLOSE); // close fb0 update proc port munmap(fb0,fs*(MY+1)); // unmap fb0 close(fdFB); // close fb0 }
//========================================= // palette - display scaled "color" palette //----------------------------------------- void palette(int s) { int x,y,c; for (y=(MX-s)/2;y<(MX+s)/2;y++) for (x=(MX-s)/2;x<(MX+s)/2;x++) { c=(y-(MX-s)/2)*16/s*16+(((x-(MX-s)/2)*16)/s); setpx(x,y,c); } }
//=============================== // eupdate - eink update display // op (open, close, update) //------------------------------- int eupdate(int op) { static int fdUpdate=-1; if (EUPD_OPEN==op) { fdUpdate=open("/proc/eink_fb/update_display",O_WRONLY); } else if (EUPD_CLOSE==op) { close(fdUpdate); } else if (EUPD_UPDATE==op) { if (-1==fdUpdate) { system("eips ''"); } else { write(fdUpdate,"1\n",2); } } else { return -1; } // bad op code return fdUpdate; }
//======================================== // setpx - draw pixel using ordered dither // x,y:screen coordinates, c:color(0-255). // (This works on all eink kindle models.) //---------------------------------------- inline void setpx(int x,int y,int c) { static int dt[64] = { 3,129,34,160,10,136,42,168,192,66,223,97,200,73,231,105,50, 176,18,144,58,184,26,152,239,113,207,81,247,121,215,89,14, 140,46,180,7,133,38,164,203,77,235,109,196,70,227,101,62,188, 30,156,54,180,22,148,251,125,219,93,243,117,211,85 }; // 0-255 dither table fb0[pb*x/8+fs*y]=((256&(c-dt[(7&x)+8*(7&y)]-1))/256*(blk&(240*(1&~x)| 15*(1&x)|fb0[pb*x/8+fs*y])))|((256&(dt[(7&x)+8*(7&y)]-c))/256*wht| (blk&((240*(1&x)|15*(1&~x))&fb0[pb*x/8+fs*y]))); // geekmaster formula 42 }
//==================================== // getmsec - get msec since first call // (tick counter wraps every 12 days) //------------------------------------ int getmsec(void) { int tc; static int ts=0; struct timeval tv; gettimeofday(&tv,NULL); tc=tv.tv_usec/1000+1000*(0xFFFFF&tv.tv_sec); if (0==tc) { ts=tc; } return tc-ts; }
//================== // main - start here //------------------ int main(int argc,char **argv) { if (argc>1) { mpu=atoi(argv[1]); } paldemo(); // display 0-255 dithered palette return 0; }
The download:
Last edited by geekmaster; 04-21-2012 at 11:44 AM.
|