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