From ace9ea98f70a5d204b5140e6b1288b2f58c2529f Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 28 Nov 2003 20:39:54 +0000 Subject: [PATCH] =?UTF-8?q?=20=20*=20src/bitmap.c:=20=20=20=20=20+=20Dithe?= =?UTF-8?q?r=20chroma=20outside=20of=20rgb2hsv=5Fdefault().=20=20=20=20=20?= =?UTF-8?q?+=20Clip=20fromx=20and=20fromy=20values.=20=20=20*=20NOTES:=20?= =?UTF-8?q?=20=20=20=20+=20Link=20to=20the=20XTerm=20control=20sequences.?= =?UTF-8?q?=20=20=20*=20examples/view.c:=20=20=20=20=20+=20Draw=20status?= =?UTF-8?q?=20bar.=20=20=20=20=20+=20Move=20with=20'h'=20'j'=20'k'=20'l',?= =?UTF-8?q?=20=C3=A0=20la=20vi.=20=20=20=20=20+=20'=3F'=20toggles=20a=20he?= =?UTF-8?q?lp=20menu.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NOTES | 11 ++++++---- examples/view.c | 58 ++++++++++++++++++++++++++++++++++++++++--------- src/bitmap.c | 30 ++++++++++++------------- 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/NOTES b/NOTES index d97a0d9..837a721 100644 --- a/NOTES +++ b/NOTES @@ -17,11 +17,12 @@ $Id$ setab=\E[4%p1%dm, setaf=\E[3%p1%dm From the xterm-16color terminfo: + (http://www.sct.gu.edu.au/~anthony/info/X/Xterm_xf86.terminfo) setab=\E[%?%p1%{8}%<%t%p1%{40}%+%e%p1%{92}%+%;%dm, setaf=\E[%?%p1%{8}%<%t%p1%{30}%+%e%p1%{82}%+%;%dm, - (http://www.sct.gu.edu.au/~anthony/info/X/Xterm_xf86.terminfo) + These values can be simply retrieved with a tigetstr() call. o I tested the following terminals: @@ -75,9 +76,11 @@ $Id$ + gnome-terminal (no bright bg) + konsole (no bright bg, $blink really blinks) - o In an XTerm-compatible terminal, \e[9xm sets bright foreground and - \e[10xm bright background colours. Unfortunately all terminals don't - support these escape sequences. Here is a testcase: + o In an XTerm-compatible terminal, \e[9xm sets bright foreground + and \e[10xm bright background colours. Documentation on this can be + found at http://ftp.xfree86.org/pub/XFree86/4.2.1/doc/ctlseqs.TXT . + Unfortunately all terminals don't support these escape sequences. Here + is a testcase: for fgpre in 3 9; do for fg in 0 4 2 6 1 5 3 7; do for bgpre in 4 10; do diff --git a/examples/view.c b/examples/view.c index 6260e15..4ef7ac7 100644 --- a/examples/view.c +++ b/examples/view.c @@ -24,6 +24,7 @@ #include "config.h" #include +#include #define X_DISPLAY_MISSING 1 #include @@ -40,7 +41,7 @@ const enum caca_dithering dithering_list[] = int main(int argc, char **argv) { - int quit = 0, update = 1; + int quit = 0, update = 1, help = 0; int x, y, w, h, zoom = 0; if(argc != 2) @@ -108,22 +109,34 @@ int main(int argc, char **argv) zoom = 0; update = 1; break; + case CACA_EVENT_KEY_PRESS | 'k': + case CACA_EVENT_KEY_PRESS | 'K': case CACA_EVENT_KEY_PRESS | CACA_KEY_UP: if(zoom > 0) y -= 1 + h / (2 + zoom) / 8; update = 1; break; + case CACA_EVENT_KEY_PRESS | 'j': + case CACA_EVENT_KEY_PRESS | 'J': case CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN: if(zoom > 0) y += 1 + h / (2 + zoom) / 8; update = 1; break; + case CACA_EVENT_KEY_PRESS | 'h': + case CACA_EVENT_KEY_PRESS | 'H': case CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT: if(zoom > 0) x -= 1 + w / (2 + zoom) / 8; update = 1; break; + case CACA_EVENT_KEY_PRESS | 'l': + case CACA_EVENT_KEY_PRESS | 'L': case CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT: if(zoom > 0) x += 1 + w / (2 + zoom) / 8; update = 1; break; + case CACA_EVENT_KEY_PRESS | '?': + help = !help; + update = 1; + break; case CACA_EVENT_KEY_PRESS | 'q': case CACA_EVENT_KEY_PRESS | 'Q': quit = 1; @@ -133,14 +146,17 @@ int main(int argc, char **argv) if(update) { + int ww = caca_get_width(); + int wh = caca_get_height(); + caca_clear(); caca_set_dithering(dithering_list[dithering]); if(zoom < 0) { - int xo = (caca_get_width() - 1) / 2; - int yo = (caca_get_height() - 1) / 2; - int xn = (caca_get_width() - 1) / (2 - zoom); - int yn = (caca_get_height() - 1) / (2 - zoom); + int xo = (ww - 1) / 2; + int yo = (wh - 1) / 2; + int xn = (ww - 1) / (2 - zoom); + int yn = (wh - 1) / (2 - zoom); caca_draw_bitmap(xo - xn, yo - yn, xo + xn, yo + yn, bitmap, pixels); } @@ -154,17 +170,39 @@ int main(int argc, char **argv) if(xn + x > w) x = w - xn; if(yn + y > h) y = h - yn; newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w, - 0x00ff0000, 0x0000ff00, 0x000000ff); - caca_draw_bitmap(0, 0, caca_get_width() - 1, - caca_get_height() - 1, newbitmap, + 0x00ff0000, 0x0000ff00, 0x000000ff); + caca_draw_bitmap(0, 0, ww - 1, wh - 1, newbitmap, pixels + 4 * (x - xn) + 4 * w * (y - yn)); caca_free_bitmap(newbitmap); } else { - caca_draw_bitmap(0, 0, caca_get_width() - 1, - caca_get_height() - 1, bitmap, pixels); + caca_draw_bitmap(0, 0, ww - 1, wh - 1, bitmap, pixels); + } + + caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE); + caca_draw_line(0, 0, ww - 1, 0, ' '); + caca_printf(1, 0, "cacaview %s", VERSION); + caca_putstr(ww - strlen("'?' for help") - 1, 0, + "'?' for help"); + + if(help) + { + caca_putstr(2, 2, " +: zoom in "); + caca_putstr(2, 3, " -: zoom out "); + caca_putstr(2, 4, " x: reset zoom "); + caca_putstr(2, 5, " ------------------- "); + caca_putstr(2, 6, " hjkl: move view "); + caca_putstr(2, 7, " arrows: move view "); + caca_putstr(2, 8, " ------------------- "); + caca_putstr(2, 9, " d: dithering method "); + caca_putstr(2, 10, " ------------------- "); + caca_putstr(2, 11, " ?: help "); + caca_putstr(2, 12, " q: quit "); + + help = 0; } + caca_refresh(); update = 0; } diff --git a/src/bitmap.c b/src/bitmap.c index 59b91bf..4c07ac4 100644 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -221,9 +221,7 @@ static void get_rgb_default(struct caca_bitmap *bitmap, unsigned char *pixels, bits = *(uint32_t *)(pixels + 0); break; case 3: - bits = (pixels[0] << 16) - | (pixels[1] << 8) - | (pixels[2]); + bits = (pixels[0] << 16) | (pixels[1] << 8) | (pixels[2]); break; case 2: bits = *(uint16_t *)(pixels + 0); @@ -256,27 +254,25 @@ static void rgb2hsv_default(int r, int g, int b, int *hue, int *sat, int *val) if(min > g) min = g; if(max < g) max = g; if(min > b) min = b; if(max < b) max = b; - delta = max - min; /* 0 - 65535 */ - *val = max; /* 0 - 65535 */ - *sat = max ? 0x100 * delta / max * 0x100: 0; /* 0 - 65536 */ + delta = max - min; /* 0 - 0xffff */ + *val = max; /* 0 - 0xffff */ - if(*sat > (_get_dither() + 24) * 0x400) + if(delta) { - /* XXX: Values should be between 1 and 6, but since we - * are dithering, there may be overflows, hence our bigger - * *_colors[] tables. */ + *sat = 0x1000 * delta / max * 0x10; /* 0 - 0xffff */ + + /* Generate *hue between 0 and 0x5ffff */ if( r == max ) *hue = 0x10000 + 0x100 * (g - b) / delta * 0x100; else if( g == max ) *hue = 0x30000 + 0x100 * (b - r) / delta * 0x100; else *hue = 0x50000 + 0x100 * (r - g) / delta * 0x100; - - *hue = (*hue + 0x8000 + 0x1000 * _get_dither()) / 0x10000; } else { *sat = 0; + *hue = 0; } } @@ -360,6 +356,10 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2, int fromx = w * (x - x1) / (x2 - x1 + 1); int fromy = h * (y - y1) / (y2 - y1 + 1); + /* Clip values (yuck) */ + if(fromx == 0) fromx = 1; + if(fromy == 0) fromy = 1; + /* First get RGB */ R = 0, G = 0, B = 0; get_rgb_default(bitmap, pixels, fromx, fromy, &r, &g, &b); @@ -377,12 +377,12 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2, /* Now get HSV from RGB */ rgb2hsv_default(R, G, B, &hue, &sat, &val); - if(!sat) + if(sat < 0x6000 + _get_dither() * 0x800) caca_set_color(white_colors[val * 3 / 0x10000], CACA_COLOR_BLACK); else if(val > (_get_dither() + 40) * 0x400) - caca_set_color(light_colors[hue], CACA_COLOR_BLACK); + caca_set_color(light_colors[(hue + 0x8000 + _get_dither() * 0x1000) / 0x10000], CACA_COLOR_BLACK); else - caca_set_color(dark_colors[hue], CACA_COLOR_BLACK); + caca_set_color(dark_colors[(hue + 0x8000 + _get_dither() * 0x1000) / 0x10000], CACA_COLOR_BLACK); /* FIXME: choose better characters! */ ch = (val + 0x200 * _get_dither()) * 10 / 0x10000;