tomwalters@0: /* tomwalters@0: Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 tomwalters@0: =========================================================================== tomwalters@0: tomwalters@0: Permission to use, copy, modify, and distribute this software without fee tomwalters@0: is hereby granted for research purposes, provided that this copyright tomwalters@0: notice appears in all copies and in all supporting documentation, and that tomwalters@0: the software is not redistributed for any fee (except for a nominal shipping tomwalters@0: charge). Anyone wanting to incorporate all or part of this software in a tomwalters@0: commercial product must obtain a license from the Medical Research Council. tomwalters@0: tomwalters@0: The MRC makes no representations about the suitability of this tomwalters@0: software for any purpose. It is provided "as is" without express or implied tomwalters@0: warranty. tomwalters@0: tomwalters@0: THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING tomwalters@0: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE tomwalters@0: A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY tomwalters@0: DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN tomwalters@0: AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF tomwalters@0: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. tomwalters@0: */ tomwalters@0: tomwalters@0: /* tomwalters@0: grey.c tomwalters@0: ====== tomwalters@0: tomwalters@0: Greyscale routines for mapping arrays of shorts into tomwalters@0: columns of pixel values (dithered if necessary). tomwalters@0: tomwalters@0: tomwalters@0: Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit. tomwalters@0: tomwalters@0: tomwalters@0: Author : John Holdsworth tomwalters@0: Written : 11th May, 1989. tomwalters@0: tomwalters@0: Edited : tomwalters@0: tomwalters@0: */ tomwalters@0: #if defined( NeXT ) tomwalters@0: #include tomwalters@0: #else tomwalters@0: #include tomwalters@0: #endif tomwalters@0: #include "grey.h" tomwalters@0: tomwalters@0: tomwalters@0: #ifndef lint tomwalters@0: static char *sccs_id = "@(#)grey.c 1.9 J. Holdsworth (MRC-APU) 11/8/90" ; tomwalters@0: #endif tomwalters@0: tomwalters@0: /* standard recursive dither patterns for grey scales */ tomwalters@0: tomwalters@0: static int dither(n,x,y) tomwalters@0: int n,x,y; tomwalters@0: { tomwalters@0: static int seed[2][2] = {{ 0, 2 } , { 3, 1 }}; tomwalters@0: tomwalters@0: if( n==2 ) tomwalters@0: return ( seed[y][x] ) ; tomwalters@0: else tomwalters@0: return ( dither(n/2,x%(n/2),y%(n/2))*4 + seed[y%n/(n/2)][x%n/(n/2)] ); tomwalters@0: tomwalters@0: } tomwalters@0: tomwalters@0: int *DitherLine( size, line, length, min, max ) tomwalters@0: int size, line, length, min, max ; tomwalters@0: { tomwalters@0: int i, *dither_line = (int *) malloc( (unsigned) length * sizeof ( *dither_line ) ) ; tomwalters@0: tomwalters@0: if( dither_line != (int *) 0 ) { tomwalters@0: for( i=0; i < size && i < length ; i++ ) tomwalters@0: dither_line[ i ] = min + (double) dither( size, i, line ) * ( max - min ) / ( size * size ) + 0.5 ; tomwalters@0: tomwalters@0: /* repeat for rest of line */ tomwalters@0: tomwalters@0: for( ; i < length ; i++ ) tomwalters@0: dither_line[ i ] = dither_line[ i%size ] ; tomwalters@0: } tomwalters@0: tomwalters@0: return ( dither_line ) ; tomwalters@0: } tomwalters@0: tomwalters@0: int **Dithers( size, length, min, max ) tomwalters@0: int size, length, min, max ; tomwalters@0: { tomwalters@0: int i, **diths = (int **) malloc( (unsigned) size * sizeof ( *diths ) ) ; tomwalters@0: tomwalters@0: if( diths != (int **) 0 ) tomwalters@0: for( i=0 ; ipixeltable = malloc( (unsigned) PIXEL_TABLE_SIZE ) ) != 0 && tomwalters@0: ( lookup->output = malloc( (unsigned) height + 1 ) ) != 0 ) { tomwalters@0: tomwalters@0: /* output null terminated for potential printing out */ tomwalters@0: tomwalters@0: lookup->output[height] = '\000' ; tomwalters@0: tomwalters@0: /* get black to white greyscale */ tomwalters@0: tomwalters@0: greyscale = getgreyscale( &npixels ) ; tomwalters@0: tomwalters@0: tomwalters@0: if( black < white ) { tomwalters@0: min = black ; tomwalters@0: diff = white - black ; tomwalters@0: } tomwalters@0: else { tomwalters@0: min = white ; tomwalters@0: diff = black - white ; tomwalters@0: } tomwalters@0: tomwalters@0: lookup->dithers = Dithers( GREY_DITHER_SIZE, height, min, min + diff / ( npixels - 1 ) ) ; tomwalters@0: tomwalters@0: tableptr = lookup->pixeltable ; tomwalters@0: tomwalters@0: for( pix=0 ; pixpixeltable + diff * pix / ( npixels - 1 ) + 1 ; tomwalters@0: else tomwalters@0: end = lookup->pixeltable + PIXEL_TABLE_SIZE ; tomwalters@0: tomwalters@0: while( tableptr < end ) tomwalters@0: *tableptr++ = pixval ; tomwalters@0: } tomwalters@0: tomwalters@0: return ( lookup ) ; tomwalters@0: } tomwalters@0: tomwalters@0: return ( 0 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /* tomwalters@0: doLookup just performs the lookup of pixel values to convert an tomwalters@0: array of short values into the corresponding pixels for output. tomwalters@0: when few pixel values are availiable dithering is used to make the tomwalters@0: most of them. tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: char *lookup( col, lookup, input, match, height ) tomwalters@0: int col ; tomwalters@0: struct _lookup *lookup ; tomwalters@0: short *input ; tomwalters@0: int *match, height ; tomwalters@0: { tomwalters@0: register int diff ; tomwalters@0: register int *mptr = match ; tomwalters@0: register int *mend = match + height ; tomwalters@0: register char *dptr = lookup->output ; tomwalters@0: register char *lookuptable = lookup->pixeltable ; tomwalters@0: register int *ditherptr = lookup->dithers[ col%GREY_DITHER_SIZE ] ; tomwalters@0: tomwalters@0: while( mptr < mend ) { tomwalters@0: tomwalters@0: diff = input[ *mptr++ ] - *ditherptr++ ; tomwalters@0: tomwalters@0: if( diff > 0 ) tomwalters@0: *dptr++ = lookuptable[ diff ] ; tomwalters@0: else tomwalters@0: *dptr++ = lookuptable[ 0 ] ; tomwalters@0: } tomwalters@0: tomwalters@0: return ( lookup->output ) ; tomwalters@0: } tomwalters@0: tomwalters@0: void freeLookup( lookup ) tomwalters@0: struct _lookup *lookup ; tomwalters@0: { tomwalters@0: if( lookup != 0 ) { tomwalters@0: tomwalters@0: free( lookup->pixeltable ) ; tomwalters@0: tomwalters@0: free( lookup->output ) ; tomwalters@0: tomwalters@0: FreeDithers( lookup->dithers, GREY_DITHER_SIZE ) ; tomwalters@0: tomwalters@0: free( (char *) lookup ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: /* for compattability */ tomwalters@0: tomwalters@0: void doLookup( col, lookup, input, match, height, data ) tomwalters@0: int col ; tomwalters@0: struct _lookup *lookup ; tomwalters@0: short *input ; tomwalters@0: int *match, height ; tomwalters@0: char *data ; tomwalters@0: { tomwalters@0: register int diff ; tomwalters@0: register int *mptr = match ; tomwalters@0: register int *mend = match + height ; tomwalters@0: register char *dptr = data ; tomwalters@0: register char *lookuptable = lookup->pixeltable ; tomwalters@0: register int *ditherptr = lookup->dithers[ col%GREY_DITHER_SIZE ] ; tomwalters@0: tomwalters@0: while( mptr < mend ) { tomwalters@0: tomwalters@0: diff = input[ *mptr++ ] - *ditherptr++ ; tomwalters@0: tomwalters@0: if( diff > 0 ) tomwalters@0: *dptr++ = lookuptable[ diff ] ; tomwalters@0: else tomwalters@0: *dptr++ = lookuptable[ 0 ] ; tomwalters@0: } tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: