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