Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Readers > Amazon Kindle > Kindle Developer's Corner

Notices

Reply
 
Thread Tools Search this Thread
Old 04-18-2012, 04:37 PM   #16
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 PoP View Post
Are you sure?...
Realy sure?
Sheesh.. just HOW sure do you need to BE that you REALLY want to view a "dead image link"?
geekmaster is offline   Reply With Quote
Old 04-18-2012, 04:55 PM   #17
wolftail
Connoisseur
wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!wolftail will blow your mind, man!
 
wolftail's Avatar
 
Posts: 59
Karma: 57554
Join Date: Jan 2012
Location: Romania
Device: Kindle Touch
Dithermatron 1.1 was very fast but from one point it appeared that it was a bit too fast for the screen to keep up.
The cosmegg one was trippy.
wolftail is offline   Reply With Quote
Advert
Old 04-18-2012, 05:06 PM   #18
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 hawhill View Post
Really nice demos. On my K3, 50% of the CPU time is spent in the Kernel (according to unreliable "top"). Probably, the eink driver could be a bit more optimized...
For the K4 and K5, they eink update calls return immediately, and we have to be careful to not touch the framebuffer until ready, so we wait in a spin-loop. Using a timer to signal an event would save battery in that case, but this is not a long-running background process and that would complicate the code, so a simple spinloop does the job quite nice here.
geekmaster is offline   Reply With Quote
Old 04-18-2012, 05:10 PM   #19
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 wolftail View Post
Dithermatron 1.1 was very fast but from one point it appeared that it was a bit too fast for the screen to keep up.
The cosmegg one was trippy.
Actually, it increases speed while running, and it starts drawing more and more between screen updates, but it does not increase the delay between updates, so at some point the eink drivers cannot keep up and it gets "glitchy". I have another version that I did not post that runs it all at a nice speed (what you would see after the top or bottom of the screen get bumped 10 times. Faster than that and the display updates fall back into "deferred update" mode (which looks rather ugly). I like to run these demos from SSH while in screensaver mode (framework sleeping). Less competition for resources that way and it works nicely for me. Or run it from diags...

You can slow it down by using a different K4DLY selection and recompiling. Cosmegg accepts a command line parameter for msec between display updates. You can change it to 250 for 4 updates/second (./cosmeg 250).

EXPERIMENT: Run multiple "dithermatron &" in the background to see MORE objects.


Last edited by geekmaster; 04-20-2012 at 03:07 PM.
geekmaster is offline   Reply With Quote
Old 04-18-2012, 05:22 PM   #20
PoP
 curly᷂͓̫̙᷊̥̮̾ͯͤͭͬͦͨ ʎʌɹnɔ
PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.PoP ought to be getting tired of karma fortunes by now.
 
PoP's Avatar
 
Posts: 3,002
Karma: 50506927
Join Date: Dec 2010
Location: ♁ ᴺ₄₅°₃₀' ᵂ₇₃°₃₇' ±₆₀"
Device: K3₃.₄.₃ PW3&4₅.₁₃.₃
Quote:
Originally Posted by geekmaster View Post
Sheesh.. just HOW sure do you need to BE that you REALLY want to view a "dead image link"?
Guess I was in a deep hypnotic sleep in my previous post (now fixed).

... and you need to be sure 4 times.

Last edited by PoP; 04-20-2012 at 03:07 PM. Reason: add quote
PoP is offline   Reply With Quote
Advert
Old 04-19-2012, 05:07 AM   #21
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
Arrow palpump - geekmaster palette pump demo

Spoiler:
PHP Code:
//====================================================
// palpump 1.0 - kindle palette pump demo
// 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

//===============================================
// palpump - kindle palette pump demo
// This works on all kindle eink models.   Enjoy!
//-----------------------------------------------
void cosmegg(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 17 32 'Palette Pump 1.0'");
    
system("eips 19 34 'by Geekmaster'");

  for (
j=MX-32;j>80;j-=24) {
    for(
i=j;i>8;i-=8) { tn=mpu+getmsec();
        
palette(i);
        
eupdate(EUPD_UPDATE);    // update display
        
while (tn>getmsec()); // wait until next update time
    
}
    for(
i=8;i<j;i+=8) { tn=mpu+getmsec();
        
palette(i);
        
eupdate(EUPD_UPDATE);    // update display
        
while (tn>getmsec()); // wait until next update time
    
}
  }
    
// 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;
    for (
y=(MX-s)/2;y<(MX+s)/2;y++) for (x=(MX-s)/2;x<(MX+s)/2;x++) {
        
setpx(x,y,(y-(MX-s)/2)*8/s*8+(x-(MX-s)/2)*8/s);
    }
}

//===============================
// 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-64).
// (This works on all eink kindle models.)
//----------------------------------------
inline void setpx(int x,int y,int c) {
    static 
int dt[64] = { 0,32,8,40,2,34,10,42,48,16,56,24,50,18,58,26,12,44,4,
    
36,14,46,6,38,60,28,52,20,62,30,54,22,3,35,11,45,1,33,9,41,51,19,59,27,49,
    
17,57,25,15,47,7,39,13,45,5,37,63,31,55,23,61,29,53,21 }; // dither table
    
fb0[pb*x/8+fs*y]=((128&(c-dt[(7&x)+8*(7&y)]))/128*(blk&(240*(1&~x)|
        
15*(1&x)|fb0[pb*x/8+fs*y])))|((128&(dt[(7&x)+8*(7&y)]-c))/128*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]); }
    
cosmegg(); // do the cosmic egg demo :D
    
return 0;


This started as a test stub to verify the "color palette" dither table values. I now subtracted one from all values so it can get a pure black. Remember that dithering with an 8x8 table gives 65 shades, not 64 as 6-bit colors would give. Anyway, this is an animated "color" palette demo. Not as flashy as the others, but it shows how to use a new function (scaleable palette display). I animate the scaling factor here.

Using this new color palette in some existing programs can make the WHITE value go away, requiring adjustment to the color scale factors in the program.

Remember to clear the screen (eips -c) before running this each time.

The moving palette "wall" appears to be semi-transparent, but that "transparency" is just eink ghosting, which you would not see in a screenshot, but that ghosting looks interesting and contributes to the effect in this demo.
Attached Files
File Type: gz palpump.tar.gz (5.6 KB, 213 views)

Last edited by geekmaster; 04-19-2012 at 05:23 AM.
geekmaster is offline   Reply With Quote
Old 04-20-2012, 01:17 PM   #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
Arrow 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:
Spoiler:
This image has a display gamma of 1.0 needed for kindle eink displays (just like printing on paper). CRT and LCD displays are typically adjusted for gamma 2.2, so this screenshot appears as a well-balanced color spread on the kindle, but viewing this on a CRT or LCD panel will show too many brights and not enough darks. That is to be expected, and adds another complication if you want a program to work on both eink and on LCD panels.

The DARK values are strongly affected by the gamma settings. Compare this image on an LCD panel (like you are probably viewing it on now) with the image displayed on a kindle eink display. Pay careful attention to the top five rows. On a kindle eink display, the entire top five rows of this image are black or "almost black". If you do not see what I am describing, your web browser probably converted the image to grayscale (with gamma correction) if it resized the image. View the image at "original size" and then compare it to the same image on the kindle. When viewed at the correct screen size, it will contain ONLY pure black and white pixels.

Gamma adjustments must be made by selecting dither tables with DIFFERENT threshold values for eink and LCD displays. The proper way to take a screenshot is to re-dither the 256-color image using an LCD dither table, and capture that. The image below uses an eink dither table. I will add another screenshot after I build an LCD dither table for my "paldemo" program.

An image dithered with an LCD dither table will look good on this web page, but will look MUCH TOO DARK on a kindle eink display. You need to use a dither table with threshold values that match your intended display device.

eink gamma 1.0 (linear distribution) dither table:


lcd gamma 2.2 (exponential distribution) dither table:


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:
Attached Files
File Type: gz paldemo.tar.gz (6.8 KB, 206 views)

Last edited by geekmaster; 04-21-2012 at 11:44 AM.
geekmaster is offline   Reply With Quote
Old 04-21-2012, 05:28 AM   #23
kiri87
Member
kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.
 
Posts: 16
Karma: 25544
Join Date: Feb 2012
Device: Kindle 3
Firs of all, thanks for your awesome code, Geekmaster.
I'm a beginner, and I played a bit with your sources. This is a little demo I came up with.
Attached Files
File Type: zip simplePixelDemo.zip (4.6 KB, 187 views)
kiri87 is offline   Reply With Quote
Old 04-21-2012, 08:31 AM   #24
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
Firs of all, thanks for your awesome code, Geekmaster.
I'm a beginner, and I played a bit with your sources. This is a little demo I came up with.
It's alive!

I ran it. It looks like a random walk with pixel timeout and erase. Now I need to go look at the code. This looks interesting. You should add things like a Hilbert Curve to this.

It looks like you pumped the source code through AStyle to reformat it. Unfortunately, AStyle does not have a profile for my condensed coding style that I like (max code per line, max lines per page). White-space lovers probably hate my code anyway. You should change the program name in the comments at the top, and add a revision history that includes your name.

This was worth the "2600 karma" badge of honor. Oops... wrong karma field (I gave you too many points).

WARNING: One thing about the MIT license: This is a derivative of my code, so the copyright FOR THIS SOURCE FILE is still mine. The purpose of the copyright is to support the MIT license so that others can freely use my code, so it does not need multiple copyrights. You removed MY copyright -- you should put that back. It is better to add a revision history to my file to show your name and your changes or additions. If you NEED your own copyright for your function, you should put your function code in a separate .c source file, and put your copyright (and the MIT license or other compatible license such as BSD) in that file. Then link it to mine by putting both files on the compiler command line. I added my original copyright back to the source code (and you should too, and you should edit your post above, to replace the download with a replacement zip file containing properly attributed code. ) Here is the updated code with my copyright line restored (and new title, and additional models tested):
PHP Code:
//====================================================
// simplePixelDemo 1.0 - random walk demo
// Copyright (C) 2012 by geekmaster, with MIT license:
// Copyright (C) 2012 by kiri, 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, 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
#define LENGTH 50000
#define STEP 5000

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);

// global var7
u32 mpu=200;      // 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

void simplePixelDemo(void) {
    
int x,y,tn;
    
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 -c"); //clear screen

    
int currentX MX/2currentY =MY/2//initial point is the center of the screen
    
int choice;
    
int direction 0//the direction: 0 = right, 1 = up, 2 = left, 3 = down
    
long int i;
    
int cu;
    
int pixels[2][LENGTH];

    for (
i=0i<LENGTHi++) {//fill with central pixels
        
pixels[0][i] = currentX;
        
pixels[1][i] = currentY;
    }

    
srand time(NULL) );

    for (
cu=0;cu<100;cu++) {
        
tn=mpu+getmsec();

        for (
i=0i<LENGTH STEPi++) {
            if (
i<STEP)
                
setpx(pixels[0][i], pixels[1][i], 64); //clear some pixels
            // move pixels array to the left
            
pixels[0][i] = pixels[0][STEP];
            
pixels[1][i] = pixels[1][STEP];
        }

        for (
i=0i<STEPi++) {
            
//create some new pixels
            
choice rand()%5;
            if (
choice == 0) {
                
direction += 1;
                
direction %= 4;
            } else if (
choice == 1) {
                
direction -= 1;
                
direction += 4;
                
direction %= 4;
            } else {
                switch(
direction) {
                case 
0:
                    if (
currentX==MX)
                        break;
                    
currentX++;
                    break;
                case 
1:
                    if (
currentY==MY)
                        break;
                    
currentY++;
                    break;
                case 
2:
                    if (
currentX==0)
                        break;
                    
currentX--;
                    break;
                case 
3:
                    if (
currentY==0)
                        break;
                    
currentY--;
                    break;
                }
            }

            
pixels[0][LENGTH STEP i] = currentX;
            
pixels[1][LENGTH STEP i] = currentY;
        }

        for (
i=0i<LENGTHi++) {
            
//display pixels
            
setpx(pixels[0][i], pixels[1][i], 0);
        }

        
eupdate(EUPD_UPDATE); // update display
        
while (tn>getmsec()); // wait until next update time
    
}

    
// 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
}

//===============================
// 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-64).
// (This works on all eink kindle models.)
//----------------------------------------
inline void setpx(int x,int y,int c) {
    static 
int dt[64] = {
         
133,  941,  3351143,
        
4917572551195927,
        
1345,  5371547,  739,
        
6129532163315523,
         
4361244,  2341042,
        
5220602850185826,
        
1648,  8401446,  638,
        
6432562462305422
    
}; // dither table

    
fb0[pb*x/8+fs*y] = ((128&(c-dt[(7&x)+8*(7&y)]))/128*(blk&(240*(1&~x)|
        
15*(1&x)|fb0[pb*x/8+fs*y])))|((128&(dt[(7&x)+8*(7&y)]-c))/128*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]); }
    
simplePixelDemo();
    return 
0;




Last edited by geekmaster; 04-21-2012 at 09:24 AM.
geekmaster is offline   Reply With Quote
Old 04-21-2012, 09:41 AM   #25
kiri87
Member
kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.
 
Posts: 16
Karma: 25544
Join Date: Feb 2012
Device: Kindle 3
Sorry about the license thing. I updated the source file, but I can't manage to edit my post. I attached the updated file to this post.

edit:
It seems that the Edit button appears on this post I just wrote...
Anyways, thanks for the karma.
Attached Files
File Type: zip simplePixelDemo.zip (4.7 KB, 157 views)

Last edited by kiri87; 04-21-2012 at 09:43 AM.
kiri87 is offline   Reply With Quote
Old 04-21-2012, 09:45 AM   #26
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
Sorry about the license thing. I updated the source file, but I can't manage to edit my post. I attached the updated file to this post.

edit:
It seems that the Edit button appears on this post I just wrote...
Anyways, thanks for the karma.
To manage files, you need to go to that post and press Edit / Advanced / Manage files. Is that not working?

Hmm... In your download, somehow my "geekmaster formula 42" got MORE whitespace pollution (it is indented much too far when viewed in Windows Notepad).


Last edited by geekmaster; 04-21-2012 at 09:49 AM.
geekmaster is offline   Reply With Quote
Old 04-21-2012, 09:53 AM   #27
kiri87
Member
kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.kiri87 knows what's going on.
 
Posts: 16
Karma: 25544
Join Date: Feb 2012
Device: Kindle 3
It's very odd. I can still see the Edit button on my previous post, but there's none on the initial post. I think it's automatically hidden after some time, I don't know...
kiri87 is offline   Reply With Quote
Old 04-21-2012, 12:08 PM   #28
jmseight
Zealot
jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'
 
Posts: 130
Karma: 10000
Join Date: Mar 2012
Device: Kindle 3G, Kindle Touch 3G, iRiver Story HD, Sony Reader
Hi kiri87,

I ran the demo and is is very good! My son loves it.

However, I don't think you need to use the dither algorithm because it is all black and white.

Maybe you can modify the demo so it shows dithering...

Thanks,
James
jmseight is offline   Reply With Quote
Old 04-21-2012, 12:40 PM   #29
jmseight
Zealot
jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'
 
Posts: 130
Karma: 10000
Join Date: Mar 2012
Device: Kindle 3G, Kindle Touch 3G, iRiver Story HD, Sony Reader
Hi,

Here is one that uses dithering.

I incremented the color every segment, and made every pixel width 2 to see the dithering.

EDIT: Fixed bug in color.

Code:
//====================================================
// simplePixelDemo 1.0 - random walk demo
// Copyright (C) 2012 by geekmaster, with MIT license:
// Copyright (C) 2012 by kiri, 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, 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
#define LENGTH 25000
#define STEP 1250

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);
void setbx(int,int,int);
int eupdate(int);
int getmsec(void);

// global var7
u32 mpu=200;      // 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
#define bwidth 2 // width of block

void simplePixelDemo(void) {
    int x,y,tn;
    int c=0;
    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/bwidth;  // 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
    
	MY=MY/bwidth;
    
	system("eips -c"); //clear screen

    int currentX = MX/2, currentY =MY/2; //initial point is the center of the screen
    int choice;
    int direction = 0; //the direction: 0 = right, 1 = up, 2 = left, 3 = down
    long int i;
    int cu;
    int pixels[3][LENGTH];

    for (i=0; i<LENGTH; i++) {//fill with central pixels
        pixels[0][i] = currentX;
        pixels[1][i] = currentY;
		pixels[2][i] = c++;  c&=0x3F;
    }

    srand ( time(NULL) );

    for (cu=0; cu<100; cu++) {
        tn=mpu+getmsec();

        for (i=0; i<LENGTH - STEP; i++) {
            if (i<STEP)
                setbx(pixels[0][i], pixels[1][i], 64); //clear some pixels
            // move pixels array to the left
            pixels[0][i] = pixels[0][i + STEP];
            pixels[1][i] = pixels[1][i + STEP];
            pixels[2][i] = pixels[2][i + STEP];
        }

        for (i=0; i<STEP; i++) {
            //create some new pixels
            choice = rand()%5;
            if (choice == 0) {
                direction += 1;
                direction %= 4;
            } else if (choice == 1) {
                direction -= 1;
                direction += 4;
                direction %= 4;
            } else {
                switch(direction) {
                case 0:
                    if (currentX>=MX)
                        break;
                    currentX++;
                    break;
                case 1:
                    if (currentY>=MY)
                        break;
                    currentY++;
                    break;
                case 2:
                    if (currentX<=0)
                        break;
                    currentX--;
                    break;
                case 3:
                    if (currentY<=0)
                        break;
                    currentY--;
                    break;
                }
            }

            pixels[0][LENGTH - STEP + i] = currentX;
            pixels[1][LENGTH - STEP + i] = currentY;
			pixels[2][LENGTH - STEP + i] = c++; c&=0x3F;
        }

        for (i=0; i<LENGTH; i++) {
            //display pixels
            setbx(pixels[0][i], pixels[1][i], pixels[2][i]);
        }

        eupdate(EUPD_UPDATE); // update display
        while (tn>getmsec()); // wait until next update time
    }

    // 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
}

//===============================
// 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;
}

void setbx(int x, int y, int c) {
    int i,j,xx,yy;
	xx=x*bwidth;
	yy=y*bwidth;
    for (i=0; i < bwidth; i++)
	  for (j=0; j < bwidth; j++)
	    setpx (xx+i,yy+j,c);
}


//========================================
// setpx - draw pixel using ordered dither
// x,y: screen coordinates, c: color(0-64).
// (This works on all eink kindle models.)
//----------------------------------------
inline void setpx(int x,int y,int c) {
    static int dt[64] = {
        1, 33,  9, 41,  3, 35, 11, 43,
        49, 17, 57, 25, 51, 19, 59, 27,
        13, 45,  5, 37, 15, 47,  7, 39,
        61, 29, 53, 21, 63, 31, 55, 23,
        4, 36, 12, 44,  2, 34, 10, 42,
        52, 20, 60, 28, 50, 18, 58, 26,
        16, 48,  8, 40, 14, 46,  6, 38,
        64, 32, 56, 24, 62, 30, 54, 22
    }; // dither table

    fb0[pb*x/8+fs*y] = ((128&(c-dt[(7&x)+8*(7&y)]))/128*(blk&(240*(1&~x)|
                        15*(1&x)|fb0[pb*x/8+fs*y])))|((128&(dt[(7&x)+8*(7&y)]-c))/128*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]);
    }
    simplePixelDemo();
    return 0;
}

Last edited by jmseight; 04-21-2012 at 12:54 PM.
jmseight is offline   Reply With Quote
Old 04-21-2012, 04:46 PM   #30
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 jmseight View Post
Hi kiri87,

I ran the demo and is is very good! My son loves it.

However, I don't think you need to use the dither algorithm because it is all black and white.

Maybe you can modify the demo so it shows dithering...

Thanks,
James
Geekmaster formula 42 does a lot more than just dithering. It works on all eink kindles. It works for 4-bit and 8-bit framebuffers. It works for color 0 = white and for color 0 = black. It works on 6-inch and 9.7-inch displays. It has no branches (if else statements) so it is very fast and cache-friendly. It is fine to use it only for black and white. Dithered gray is just an added benefit.

I have a new modified formula 42 that takes color values 0-255 instead of 0-65, so it can be used directly with 8-bit images with no need to pre-scale the color values. It was published as part of "paldemo". It also works with non-linear dither tables, including a LCD 2.2-gamma table (screenshot provided in paldemo post).

I just ran your version. The dithered grays do look interesting on this demo. I like seeing my code grow in unexpected directions that are not on MY "to do" list.

P.S. I am getting an occasional "sementation fault" error on this, which probably means that it tried to write past the end of the framebuffer (y > 799). Although there is no harm in this for a demo, it SHOULD be fixed in the next version (so this error does not end up in other code that borrowed from this, perhaps causing real damage in some other scenario -- better to just do it right).



Last edited by geekmaster; 11-25-2012 at 11:01 PM.
geekmaster is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Troubleshooting Kindle and math formula DrShakalu Amazon Kindle 12 12-11-2011 07:25 AM
Formula Plots PuxyYunm General Discussions 9 05-15-2011 04:19 AM
Demo: Jetbook mini official demo bookwarm Ectaco jetBook 36 09-21-2010 12:18 PM


All times are GMT -4. The time now is 04:18 AM.


MobileRead.com is a privately owned, operated and funded community.