Mercurial > hg > aim92
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 |