From 6558f56de6fe0233947f073b3312fbaf28414678 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Thu, 28 Apr 2011 01:18:03 -0300 Subject: [PATCH] ubb-vga2: replaced threshold-based color mapping with color cube model - ubb-vga.h (ccube_init, ccube_map), ccube.c: color mapper based on proximity in color cube - grabfb.c (pattern, grabfb), ppmimg.c (pattern, convert): use the color cube mapper instead of inferios threshold-based mapping - ubb-vga2.c (session): initialize the color cube - ubb-vga.h (thres), grabfb.c (thres), ubb-vga2.c (usage, main): removed the threshold along with the option (-l) to set it - Makefile (OBJS): added ccube.o --- ubb-vga/Makefile | 2 +- ubb-vga/ccube.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++ ubb-vga/grabfb.c | 12 +--------- ubb-vga/ppmimg.c | 9 +------ ubb-vga/ubb-vga.h | 7 ++++-- ubb-vga/ubb-vga2.c | 9 +++---- 6 files changed, 69 insertions(+), 28 deletions(-) create mode 100644 ubb-vga/ccube.c diff --git a/ubb-vga/Makefile b/ubb-vga/Makefile index 1674f8a..f5d1fa4 100644 --- a/ubb-vga/Makefile +++ b/ubb-vga/Makefile @@ -3,7 +3,7 @@ CC=mipsel-linux-gcc CFLAGS=-Wall -g -O9 -march=mips32 LDFLAGS=-lm -OBJS=ubb-vga2.o grabfb.o tstimg.o ppm.o ppmimg.o +OBJS=ubb-vga2.o grabfb.o tstimg.o ppm.o ppmimg.o ccube.o .PHONY: all asm sch clean spotless diff --git a/ubb-vga/ccube.c b/ubb-vga/ccube.c new file mode 100644 index 0000000..d8bae88 --- /dev/null +++ b/ubb-vga/ccube.c @@ -0,0 +1,58 @@ +/* + * ccube.c - Color mapper based on color cube model + * + * Written 2011 by Werner Almesberger + * Copyright 2011 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#include + +#include "ubb-vga.h" + + +#define W_RGB (256*0.5) +#define W_Y (256*0.25) +#define W_0 (256*0.125) + + +static struct col { + uint8_t r, g, b; +} col[16]; + + +uint8_t ccube_map(uint8_t r, uint8_t g, uint8_t b) +{ + unsigned best = 0; + int best_i = 0; + unsigned d; + int i; + + for (i = 0; i != 16; i++) { + d = (r-col[i].r)*(r-col[i].r)+ + (g-col[i].g)*(g-col[i].g)+ + (b-col[i].b)*(b-col[i].b); + if (!i || d < best) { + best = d; + best_i = i; + } + } + return best_i; +} + + +void ccube_init(void) +{ + int i; + + for (i = 0; i != 16; i++) { + col[i].r = W_0+(i & R_VAL ? W_RGB : 0)+(i & Y_VAL ? W_Y : 0); + col[i].g = W_0+(i & G_VAL ? W_RGB : 0)+(i & Y_VAL ? W_Y : 0); + col[i].b = W_0+(i & B_VAL ? W_RGB : 0)+(i & Y_VAL ? W_Y : 0); + } +} diff --git a/ubb-vga/grabfb.c b/ubb-vga/grabfb.c index c37b74f..3bd7bb5 100644 --- a/ubb-vga/grabfb.c +++ b/ubb-vga/grabfb.c @@ -17,15 +17,6 @@ #include "ubb-vga.h" -uint8_t thres = 63; - - -static uint8_t pattern(int r, int g, int b) -{ - return ((r ? R_VAL : 0) | (g ? G_VAL : 0) | (b ? B_VAL : 0))*0x11; -} - - void grabfb(void *f, int xres, int yres) { uint32_t *fb = map(0x01d00000, 4*320*240); @@ -42,8 +33,7 @@ void grabfb(void *f, int xres, int yres) r = pix >> 16; g = pix >> 8; b = pix; - p[0] = p[320] = - pattern(r >= thres, g >= thres, b >= thres); + p[0] = p[320] = ccube_map(r, g, b)*0x11; p++; } p += 320; diff --git a/ubb-vga/ppmimg.c b/ubb-vga/ppmimg.c index e475817..9dc2100 100644 --- a/ubb-vga/ppmimg.c +++ b/ubb-vga/ppmimg.c @@ -22,12 +22,6 @@ char *img_name; -static uint8_t pattern(int r, int g, int b) -{ - return (r ? R_VAL : 0) | (g ? G_VAL : 0) | (b ? B_VAL : 0); -} - - static void convert(uint8_t *f, int xres, int yres, uint8_t *ppm) { int x, y; @@ -35,8 +29,7 @@ static void convert(uint8_t *f, int xres, int yres, uint8_t *ppm) for (y = 0; y != yres; y++) for (x = 0; x != xres; x++) { - v = pattern(ppm[0] >= thres, ppm[1] >= thres, - ppm[2] >= thres); + v = ccube_map(ppm[0], ppm[1], ppm[2]); if (x & 1) { *f++ = last | v; } else { diff --git a/ubb-vga/ubb-vga.h b/ubb-vga/ubb-vga.h index 60e2cfe..d0d7b48 100644 --- a/ubb-vga/ubb-vga.h +++ b/ubb-vga/ubb-vga.h @@ -26,9 +26,12 @@ void *map(off_t addr, size_t size); -/* grabfb.c */ +/* ccube.c */ -extern uint8_t thres; +uint8_t ccube_map(uint8_t r, uint8_t g, uint8_t b); +void ccube_init(void); + +/* grabfb.c */ void grabfb(void *f, int xres, int yres); diff --git a/ubb-vga/ubb-vga2.c b/ubb-vga/ubb-vga2.c index 3d836d7..11d41bc 100644 --- a/ubb-vga/ubb-vga2.c +++ b/ubb-vga/ubb-vga2.c @@ -396,6 +396,7 @@ static void session(void (*gen)(void *fb, int xres, int yres), int frames) int i; memset(f, 0, sizeof(f)); + ccube_init(); gen(f, 640, 480); disable_interrupts(); @@ -410,10 +411,9 @@ static void session(void (*gen)(void *fb, int xres, int yres), int frames) static void usage(const char *name) { fprintf(stderr, -"usage: %s [-l threshold] [-t] frames [file]\n\n" +"usage: %s [-t] frames [file]\n\n" " frames number of frames to display\n" " file PPM file\n\n" -" -l threshold channel on/off threshold\n" " -t generate a test image\n" , name); exit(1); @@ -426,11 +426,8 @@ int main(int argc, char *const *argv) int frames; int c; - while ((c = getopt(argc, argv, "l:t")) != EOF) + while ((c = getopt(argc, argv, "t")) != EOF) switch (c) { - case 'l': - thres = atoi(optarg); - break; case 't': gen = tstimg; break;