thomas@utah-gr.UUCP (Spencer W. Thomas) (10/15/84)
Here is a very simple dithering algorithm which will take a 24 bit full color image and turn it into an 8 bit image with a fixed color lookup table. The author is {harpo,ihnp4,decvax}!utah-cs!utah-gr!kitaoka. It is presented here in terms of a complete program, but it should be easy to extract the relevant code as a subroutine. It produces amazingly good images, considering the apparent coarseness of the approximation. =Spencer ================================ cut here ================================ /* * cvt_aed512.c -- convert standard file format to aed format * * Author Shoichi KITAOKA * Computer Science Department * University of Utah * Date April 10 1984 * * Copyright (c) 1984 Shoichi Kitaoka *-------------------------------------------------------------------- * Purpose of the program is convert 24bit images into 8bit image * without changing look up table on each images. * Basic idea is transform 0..255 value into 0..5 value for each RGB. * To randomize this procedure 4*4 threshold matrix (dither matrix) * is used. *-------------------------------------------------------------------- * USAGE : cvt_aed512 < *.std > *.aed * Here *.std means standard format image file which consists of * 512*480*24 bit data. (First 512 byte of Red value for first scanline comes * then 512 byte of Green value, 512 byte of Blue value, then next scanline * data and so on.) * *.aed means AED512 format data which actually 8bit/pixel image. (512* * 480*8 bit = 512*480 bytes) * Each byte of *.aed file means the look up table number. * Look up table value should be set up as following: * * (I assume look up each look up table can contain 8bit for each RGB. * And SETC(n,r,g,b) means set n-th look up table with RGB value (r,g,b). ) * * for (i=0;i<6;i++) * for (j=0;j<6;j++) * for (k=0;k<6;k++) * SETC (i+j*6+k*36,i*51,j*51,k*51) ; *----------------------------------------------------------------------- * Since this program assign 0..5 value for each RGB value, 216 look up * tables are used and 40 tables are not used. * Also since the look up table is fixed, if the original image has * some special tendency (ex. alomost all pixel is red.), only few of * look up tbale are used. *------------------------------------------------------------------------ */ #include <stdio.h> #define XMAX 512 #define YMAX 480 /* threshold matrix for coloe value 0..51 (255 / 5 = 51) */ int dm[4][4] = { 0 , 37 , 9 , 47 , 25 , 12 , 35 , 22 , 6 , 44 , 3 , 41 , 31 , 19 , 28 , 16} ; /* buffers for one scanline */ char image_red[512],image_gre[512],image_blu[512] ; /* original image */ char image_aed[512] ; /* converted image */ /*----------------------------------------------------------------*/ main() { int i,j ; for (i=0;i<YMAX;i++) { /* read original images */ fread( image_red,sizeof(char),XMAX,stdin) ; fread( image_gre,sizeof(char),XMAX,stdin) ; fread( image_blu,sizeof(char),XMAX,stdin) ; /* convert */ for (j=0;j<XMAX;j++) image_aed[j] = dmap((short)image_red[j],j,i) + dmap((short)image_gre[j],j,i) * 6 + dmap((short)image_blu[j],j,i) * 36 ; /* output */ fwrite( image_aed,sizeof(char),XMAX,stdout) ; } } /* get the 'randomized' value for the pixel(x,y) */ dmap(v,x,y) short v ; int x,y ; { int d ; if (v<0) v += 256 ; d = dm[x%4][y%4] ; /* threshold value */ if ((v%51)>d) return (v/51)+1 ; else return (v/51) ; }