annotate 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
rev   line source
tomwalters@0 1 /*
tomwalters@0 2 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
tomwalters@0 3 ===========================================================================
tomwalters@0 4
tomwalters@0 5 Permission to use, copy, modify, and distribute this software without fee
tomwalters@0 6 is hereby granted for research purposes, provided that this copyright
tomwalters@0 7 notice appears in all copies and in all supporting documentation, and that
tomwalters@0 8 the software is not redistributed for any fee (except for a nominal shipping
tomwalters@0 9 charge). Anyone wanting to incorporate all or part of this software in a
tomwalters@0 10 commercial product must obtain a license from the Medical Research Council.
tomwalters@0 11
tomwalters@0 12 The MRC makes no representations about the suitability of this
tomwalters@0 13 software for any purpose. It is provided "as is" without express or implied
tomwalters@0 14 warranty.
tomwalters@0 15
tomwalters@0 16 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
tomwalters@0 17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
tomwalters@0 18 A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
tomwalters@0 19 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
tomwalters@0 20 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
tomwalters@0 21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
tomwalters@0 22 */
tomwalters@0 23
tomwalters@0 24 /*
tomwalters@0 25 grey.c
tomwalters@0 26 ======
tomwalters@0 27
tomwalters@0 28 Greyscale routines for mapping arrays of shorts into
tomwalters@0 29 columns of pixel values (dithered if necessary).
tomwalters@0 30
tomwalters@0 31
tomwalters@0 32 Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit.
tomwalters@0 33
tomwalters@0 34
tomwalters@0 35 Author : John Holdsworth
tomwalters@0 36 Written : 11th May, 1989.
tomwalters@0 37
tomwalters@0 38 Edited :
tomwalters@0 39
tomwalters@0 40 */
tomwalters@0 41 #if defined( NeXT )
tomwalters@0 42 #include <stdlib.h>
tomwalters@0 43 #else
tomwalters@0 44 #include <malloc.h>
tomwalters@0 45 #endif
tomwalters@0 46 #include "grey.h"
tomwalters@0 47
tomwalters@0 48
tomwalters@0 49 #ifndef lint
tomwalters@0 50 static char *sccs_id = "@(#)grey.c 1.9 J. Holdsworth (MRC-APU) 11/8/90" ;
tomwalters@0 51 #endif
tomwalters@0 52
tomwalters@0 53 /* standard recursive dither patterns for grey scales */
tomwalters@0 54
tomwalters@0 55 static int dither(n,x,y)
tomwalters@0 56 int n,x,y;
tomwalters@0 57 {
tomwalters@0 58 static int seed[2][2] = {{ 0, 2 } , { 3, 1 }};
tomwalters@0 59
tomwalters@0 60 if( n==2 )
tomwalters@0 61 return ( seed[y][x] ) ;
tomwalters@0 62 else
tomwalters@0 63 return ( dither(n/2,x%(n/2),y%(n/2))*4 + seed[y%n/(n/2)][x%n/(n/2)] );
tomwalters@0 64
tomwalters@0 65 }
tomwalters@0 66
tomwalters@0 67 int *DitherLine( size, line, length, min, max )
tomwalters@0 68 int size, line, length, min, max ;
tomwalters@0 69 {
tomwalters@0 70 int i, *dither_line = (int *) malloc( (unsigned) length * sizeof ( *dither_line ) ) ;
tomwalters@0 71
tomwalters@0 72 if( dither_line != (int *) 0 ) {
tomwalters@0 73 for( i=0; i < size && i < length ; i++ )
tomwalters@0 74 dither_line[ i ] = min + (double) dither( size, i, line ) * ( max - min ) / ( size * size ) + 0.5 ;
tomwalters@0 75
tomwalters@0 76 /* repeat for rest of line */
tomwalters@0 77
tomwalters@0 78 for( ; i < length ; i++ )
tomwalters@0 79 dither_line[ i ] = dither_line[ i%size ] ;
tomwalters@0 80 }
tomwalters@0 81
tomwalters@0 82 return ( dither_line ) ;
tomwalters@0 83 }
tomwalters@0 84
tomwalters@0 85 int **Dithers( size, length, min, max )
tomwalters@0 86 int size, length, min, max ;
tomwalters@0 87 {
tomwalters@0 88 int i, **diths = (int **) malloc( (unsigned) size * sizeof ( *diths ) ) ;
tomwalters@0 89
tomwalters@0 90 if( diths != (int **) 0 )
tomwalters@0 91 for( i=0 ; i<size ; i++ )
tomwalters@0 92 diths[i] = DitherLine( size, i, length, min, max ) ;
tomwalters@0 93
tomwalters@0 94 return ( diths ) ;
tomwalters@0 95 }
tomwalters@0 96
tomwalters@0 97 void FreeDithers( diths, size )
tomwalters@0 98 int **diths, size ;
tomwalters@0 99 {
tomwalters@0 100 int i ;
tomwalters@0 101
tomwalters@0 102 for( i=0 ; i<size ; i++ )
tomwalters@0 103 free( (char *) diths[i] ) ;
tomwalters@0 104
tomwalters@0 105 free( (char *) diths ) ;
tomwalters@0 106
tomwalters@0 107 return ;
tomwalters@0 108 }
tomwalters@0 109
tomwalters@0 110 /*
tomwalters@0 111
tomwalters@0 112 makeLookup prepares 64k byte lookup table for mapping shorts to pixel values.
tomwalters@0 113 setmap is a routine to be called to locate the window system's color map
tomwalters@0 114 and set it up returning the number of pixels availiable and allocating an
tomwalters@0 115 array containing these values in order of increasing blackness.
tomwalters@0 116
tomwalters@0 117 */
tomwalters@0 118
tomwalters@0 119 #define GREY_DITHER_SIZE 8
tomwalters@0 120
tomwalters@0 121 #define PIXEL_TABLE_SIZE ((1l<<16)-1)
tomwalters@0 122
tomwalters@0 123 struct _lookup *makeLookup( getgreyscale, black, white, height )
tomwalters@0 124 char *(*getgreyscale)() ;
tomwalters@0 125 int black, white ;
tomwalters@0 126 int height ;
tomwalters@0 127 {
tomwalters@0 128 register char *tableptr, *end, pixval ;
tomwalters@0 129 char *greyscale ;
tomwalters@0 130 struct _lookup *lookup ;
tomwalters@0 131 int npixels, pix, min, diff ;
tomwalters@0 132
tomwalters@0 133 if( ( lookup = (struct _lookup *) malloc( (unsigned) sizeof (*lookup) ) ) != 0 &&
tomwalters@0 134 ( lookup->pixeltable = malloc( (unsigned) PIXEL_TABLE_SIZE ) ) != 0 &&
tomwalters@0 135 ( lookup->output = malloc( (unsigned) height + 1 ) ) != 0 ) {
tomwalters@0 136
tomwalters@0 137 /* output null terminated for potential printing out */
tomwalters@0 138
tomwalters@0 139 lookup->output[height] = '\000' ;
tomwalters@0 140
tomwalters@0 141 /* get black to white greyscale */
tomwalters@0 142
tomwalters@0 143 greyscale = getgreyscale( &npixels ) ;
tomwalters@0 144
tomwalters@0 145
tomwalters@0 146 if( black < white ) {
tomwalters@0 147 min = black ;
tomwalters@0 148 diff = white - black ;
tomwalters@0 149 }
tomwalters@0 150 else {
tomwalters@0 151 min = white ;
tomwalters@0 152 diff = black - white ;
tomwalters@0 153 }
tomwalters@0 154
tomwalters@0 155 lookup->dithers = Dithers( GREY_DITHER_SIZE, height, min, min + diff / ( npixels - 1 ) ) ;
tomwalters@0 156
tomwalters@0 157 tableptr = lookup->pixeltable ;
tomwalters@0 158
tomwalters@0 159 for( pix=0 ; pix<npixels ; pix++ ) {
tomwalters@0 160
tomwalters@0 161 if( black < white )
tomwalters@0 162 pixval = greyscale[ pix] ;
tomwalters@0 163 else
tomwalters@0 164 pixval = greyscale[npixels-1-pix] ;
tomwalters@0 165
tomwalters@0 166 if( pix < npixels-1 )
tomwalters@0 167 end = lookup->pixeltable + diff * pix / ( npixels - 1 ) + 1 ;
tomwalters@0 168 else
tomwalters@0 169 end = lookup->pixeltable + PIXEL_TABLE_SIZE ;
tomwalters@0 170
tomwalters@0 171 while( tableptr < end )
tomwalters@0 172 *tableptr++ = pixval ;
tomwalters@0 173 }
tomwalters@0 174
tomwalters@0 175 return ( lookup ) ;
tomwalters@0 176 }
tomwalters@0 177
tomwalters@0 178 return ( 0 ) ;
tomwalters@0 179 }
tomwalters@0 180
tomwalters@0 181 /*
tomwalters@0 182 doLookup just performs the lookup of pixel values to convert an
tomwalters@0 183 array of short values into the corresponding pixels for output.
tomwalters@0 184 when few pixel values are availiable dithering is used to make the
tomwalters@0 185 most of them.
tomwalters@0 186
tomwalters@0 187 */
tomwalters@0 188
tomwalters@0 189 char *lookup( col, lookup, input, match, height )
tomwalters@0 190 int col ;
tomwalters@0 191 struct _lookup *lookup ;
tomwalters@0 192 short *input ;
tomwalters@0 193 int *match, height ;
tomwalters@0 194 {
tomwalters@0 195 register int diff ;
tomwalters@0 196 register int *mptr = match ;
tomwalters@0 197 register int *mend = match + height ;
tomwalters@0 198 register char *dptr = lookup->output ;
tomwalters@0 199 register char *lookuptable = lookup->pixeltable ;
tomwalters@0 200 register int *ditherptr = lookup->dithers[ col%GREY_DITHER_SIZE ] ;
tomwalters@0 201
tomwalters@0 202 while( mptr < mend ) {
tomwalters@0 203
tomwalters@0 204 diff = input[ *mptr++ ] - *ditherptr++ ;
tomwalters@0 205
tomwalters@0 206 if( diff > 0 )
tomwalters@0 207 *dptr++ = lookuptable[ diff ] ;
tomwalters@0 208 else
tomwalters@0 209 *dptr++ = lookuptable[ 0 ] ;
tomwalters@0 210 }
tomwalters@0 211
tomwalters@0 212 return ( lookup->output ) ;
tomwalters@0 213 }
tomwalters@0 214
tomwalters@0 215 void freeLookup( lookup )
tomwalters@0 216 struct _lookup *lookup ;
tomwalters@0 217 {
tomwalters@0 218 if( lookup != 0 ) {
tomwalters@0 219
tomwalters@0 220 free( lookup->pixeltable ) ;
tomwalters@0 221
tomwalters@0 222 free( lookup->output ) ;
tomwalters@0 223
tomwalters@0 224 FreeDithers( lookup->dithers, GREY_DITHER_SIZE ) ;
tomwalters@0 225
tomwalters@0 226 free( (char *) lookup ) ;
tomwalters@0 227 }
tomwalters@0 228 }
tomwalters@0 229
tomwalters@0 230 /* for compattability */
tomwalters@0 231
tomwalters@0 232 void doLookup( col, lookup, input, match, height, data )
tomwalters@0 233 int col ;
tomwalters@0 234 struct _lookup *lookup ;
tomwalters@0 235 short *input ;
tomwalters@0 236 int *match, height ;
tomwalters@0 237 char *data ;
tomwalters@0 238 {
tomwalters@0 239 register int diff ;
tomwalters@0 240 register int *mptr = match ;
tomwalters@0 241 register int *mend = match + height ;
tomwalters@0 242 register char *dptr = data ;
tomwalters@0 243 register char *lookuptable = lookup->pixeltable ;
tomwalters@0 244 register int *ditherptr = lookup->dithers[ col%GREY_DITHER_SIZE ] ;
tomwalters@0 245
tomwalters@0 246 while( mptr < mend ) {
tomwalters@0 247
tomwalters@0 248 diff = input[ *mptr++ ] - *ditherptr++ ;
tomwalters@0 249
tomwalters@0 250 if( diff > 0 )
tomwalters@0 251 *dptr++ = lookuptable[ diff ] ;
tomwalters@0 252 else
tomwalters@0 253 *dptr++ = lookuptable[ 0 ] ;
tomwalters@0 254 }
tomwalters@0 255
tomwalters@0 256 return ;
tomwalters@0 257 }
tomwalters@0 258