/* * cmap.c * * Copyright (C) 1993-1998 Evan Harris * * Permission is granted to freely redistribute and modify this code, * providing the author(s) get credit for having written it. */ /* $Id: cmap.c,v 1.5 1998/10/01 02:52:01 evan Exp $ */ #ifndef lint static char vcid[] = "$Id: cmap.c,v 1.5 1998/10/01 02:52:01 evan Exp $"; #endif /* lint */ #include "seejpeg.h" #include #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(void) { 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; int out_r, out_g, out_b; out_r = gamma_table_shift2[r]; out_g = gamma_table_shift2[g]; out_b = gamma_table_shift2[b]; /* * 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, out_r, out_g, out_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, out_r, out_g, out_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 in, out; int i; /* * Assume there are three components in the input and one in the output */ in = rgb_row[0]; out = cmap_row[0]; for (i = 0; i < width; i++) { *out++ = lookup_colour(*in, *(in + 1), *(in + 2)); in += 3; } }