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) ;
}