Mercurial > hg > aim92
diff glib/grey.c @ 0:5242703e91d3 tip
Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author | tomwalters |
---|---|
date | Fri, 20 May 2011 15:19:45 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glib/grey.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,258 @@ +/* + Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 + =========================================================================== + + Permission to use, copy, modify, and distribute this software without fee + is hereby granted for research purposes, provided that this copyright + notice appears in all copies and in all supporting documentation, and that + the software is not redistributed for any fee (except for a nominal shipping + charge). Anyone wanting to incorporate all or part of this software in a + commercial product must obtain a license from the Medical Research Council. + + The MRC makes no representations about the suitability of this + software for any purpose. It is provided "as is" without express or implied + warranty. + + THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE + A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/* + grey.c + ====== + + Greyscale routines for mapping arrays of shorts into + columns of pixel values (dithered if necessary). + + + Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit. + + + Author : John Holdsworth + Written : 11th May, 1989. + + Edited : + +*/ +#if defined( NeXT ) +#include <stdlib.h> +#else +#include <malloc.h> +#endif +#include "grey.h" + + +#ifndef lint +static char *sccs_id = "@(#)grey.c 1.9 J. Holdsworth (MRC-APU) 11/8/90" ; +#endif + +/* standard recursive dither patterns for grey scales */ + +static int dither(n,x,y) +int n,x,y; +{ + static int seed[2][2] = {{ 0, 2 } , { 3, 1 }}; + + if( n==2 ) + return ( seed[y][x] ) ; + else + return ( dither(n/2,x%(n/2),y%(n/2))*4 + seed[y%n/(n/2)][x%n/(n/2)] ); + +} + +int *DitherLine( size, line, length, min, max ) +int size, line, length, min, max ; +{ + int i, *dither_line = (int *) malloc( (unsigned) length * sizeof ( *dither_line ) ) ; + + if( dither_line != (int *) 0 ) { + for( i=0; i < size && i < length ; i++ ) + dither_line[ i ] = min + (double) dither( size, i, line ) * ( max - min ) / ( size * size ) + 0.5 ; + + /* repeat for rest of line */ + + for( ; i < length ; i++ ) + dither_line[ i ] = dither_line[ i%size ] ; + } + + return ( dither_line ) ; +} + +int **Dithers( size, length, min, max ) +int size, length, min, max ; +{ + int i, **diths = (int **) malloc( (unsigned) size * sizeof ( *diths ) ) ; + + if( diths != (int **) 0 ) + for( i=0 ; i<size ; i++ ) + diths[i] = DitherLine( size, i, length, min, max ) ; + + return ( diths ) ; +} + +void FreeDithers( diths, size ) +int **diths, size ; +{ + int i ; + + for( i=0 ; i<size ; i++ ) + free( (char *) diths[i] ) ; + + free( (char *) diths ) ; + + return ; +} + +/* + + makeLookup prepares 64k byte lookup table for mapping shorts to pixel values. + setmap is a routine to be called to locate the window system's color map + and set it up returning the number of pixels availiable and allocating an + array containing these values in order of increasing blackness. + +*/ + +#define GREY_DITHER_SIZE 8 + +#define PIXEL_TABLE_SIZE ((1l<<16)-1) + +struct _lookup *makeLookup( getgreyscale, black, white, height ) +char *(*getgreyscale)() ; +int black, white ; +int height ; +{ + register char *tableptr, *end, pixval ; + char *greyscale ; + struct _lookup *lookup ; + int npixels, pix, min, diff ; + + if( ( lookup = (struct _lookup *) malloc( (unsigned) sizeof (*lookup) ) ) != 0 && + ( lookup->pixeltable = malloc( (unsigned) PIXEL_TABLE_SIZE ) ) != 0 && + ( lookup->output = malloc( (unsigned) height + 1 ) ) != 0 ) { + + /* output null terminated for potential printing out */ + + lookup->output[height] = '\000' ; + + /* get black to white greyscale */ + + greyscale = getgreyscale( &npixels ) ; + + + if( black < white ) { + min = black ; + diff = white - black ; + } + else { + min = white ; + diff = black - white ; + } + + lookup->dithers = Dithers( GREY_DITHER_SIZE, height, min, min + diff / ( npixels - 1 ) ) ; + + tableptr = lookup->pixeltable ; + + for( pix=0 ; pix<npixels ; pix++ ) { + + if( black < white ) + pixval = greyscale[ pix] ; + else + pixval = greyscale[npixels-1-pix] ; + + if( pix < npixels-1 ) + end = lookup->pixeltable + diff * pix / ( npixels - 1 ) + 1 ; + else + end = lookup->pixeltable + PIXEL_TABLE_SIZE ; + + while( tableptr < end ) + *tableptr++ = pixval ; + } + + return ( lookup ) ; + } + + return ( 0 ) ; +} + +/* + doLookup just performs the lookup of pixel values to convert an + array of short values into the corresponding pixels for output. + when few pixel values are availiable dithering is used to make the + most of them. + +*/ + +char *lookup( col, lookup, input, match, height ) +int col ; +struct _lookup *lookup ; +short *input ; +int *match, height ; +{ + register int diff ; + register int *mptr = match ; + register int *mend = match + height ; + register char *dptr = lookup->output ; + register char *lookuptable = lookup->pixeltable ; + register int *ditherptr = lookup->dithers[ col%GREY_DITHER_SIZE ] ; + + while( mptr < mend ) { + + diff = input[ *mptr++ ] - *ditherptr++ ; + + if( diff > 0 ) + *dptr++ = lookuptable[ diff ] ; + else + *dptr++ = lookuptable[ 0 ] ; + } + + return ( lookup->output ) ; +} + +void freeLookup( lookup ) +struct _lookup *lookup ; +{ + if( lookup != 0 ) { + + free( lookup->pixeltable ) ; + + free( lookup->output ) ; + + FreeDithers( lookup->dithers, GREY_DITHER_SIZE ) ; + + free( (char *) lookup ) ; + } +} + +/* for compattability */ + +void doLookup( col, lookup, input, match, height, data ) +int col ; +struct _lookup *lookup ; +short *input ; +int *match, height ; +char *data ; +{ + register int diff ; + register int *mptr = match ; + register int *mend = match + height ; + register char *dptr = data ; + register char *lookuptable = lookup->pixeltable ; + register int *ditherptr = lookup->dithers[ col%GREY_DITHER_SIZE ] ; + + while( mptr < mend ) { + + diff = input[ *mptr++ ] - *ditherptr++ ; + + if( diff > 0 ) + *dptr++ = lookuptable[ diff ] ; + else + *dptr++ = lookuptable[ 0 ] ; + } + + return ; +} +