home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC-Online 1996 May
/
PCOnline_05_1996.bin
/
linux
/
source
/
contrib
/
seejpeg
/
seejpeg-.4
/
seejpeg-
/
seejpeg-1.4.3
/
cmap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-05
|
2KB
|
115 lines
/*
* cmap.c
*
* Copyright (C) 1993, 1994 Evan Harris
*
* Permission is granted to freely redistribute and modify this code,
* providing the author(s) get credit for having written it.
*/
#include "seejpeg.h"
#include <vga.h>
#define HASHTABLESIZE 1024
#define CMAPSIZE 256
/*
* We probably need a better hash function, but this is better than
* nothing
*/
#define HASH(r, g, b) (((r) << 4) ^ ((g) << 2) ^ (b))
#define NOENTRY 0x80000000
static unsigned long hashtable[HASHTABLESIZE];
static unsigned long last_colour;
static int next_cmap_entry, black_seen;
void
translate_init()
{
int i;
last_colour = 0;
next_cmap_entry = 1;
black_seen = 0;
for (i = 0; i < HASHTABLESIZE; i++) {
hashtable[i] = NOENTRY;
}
}
static JSAMPLE
lookup_colour(JSAMPLE r, JSAMPLE g, JSAMPLE b)
{
unsigned long colour;
int key;
/*
* VGA colours are 18 bit.
*/
r >>= 2;
g >>= 2;
b >>= 2;
colour = ((r << 20) | (g << 14) | (b << 8));
if (colour == (last_colour & 0xffffff00)) {
return (last_colour & 0xff);
}
key = HASH(r, g, b);
while (hashtable[key] != NOENTRY
&& colour != (hashtable[key] & 0xffffff00)) {
if (++key == HASHTABLESIZE) {
key = 0;
}
}
if (hashtable[key] == NOENTRY) {
if (colour == 0) {
hashtable[key] = (colour | 0);
vga_setpalette(0, r, g, b);
black_seen = 1;
} else {
if (next_cmap_entry == CMAPSIZE && !black_seen) {
next_cmap_entry = 0;
} else if (next_cmap_entry == CMAPSIZE || next_cmap_entry == 0) {
error_exit("Colour map full");
}
hashtable[key] = (colour | next_cmap_entry);
vga_setpalette(next_cmap_entry, r, g, b);
if (next_cmap_entry > 0) {
next_cmap_entry++;
}
}
}
last_colour = hashtable[key];
return (last_colour & 0xff);
}
void
translate_row(int width, JSAMPARRAY rgb_row, JSAMPARRAY cmap_row)
{
JSAMPROW inr, ing, inb, out;
int i;
/*
* Assume there are three components in the input and one in the output
*/
inr = rgb_row[0];
ing = rgb_row[1];
inb = rgb_row[2];
out = cmap_row[0];
for (i = 0; i < width; i++) {
*out++ = lookup_colour(*inr++, *ing++, *inb++);
}
}