1 /*
2 * This software is copyrighted as noted below. It may be freely copied,
3 * modified, and redistributed, provided that the copyright notice is
4 * preserved on all copies.
5 *
6 * There is no warranty or other guarantee of fitness for this software,
7 * it is provided solely "as is". Bug reports or fixes may be sent
8 * to the author, who may or may not act on them as he desires.
9 *
10 * You may not include this software in a program or other software product
11 * without supplying the source, or without informing the end-user that the
12 * source is available for no extra charge.
13 *
14 * If you modify this software, you should include a notice giving the
15 * name of the person performing the modification, the date of modification,
16 * and the reason for such modification.
17 */
18 /*
19 * mask.c - perform transformations using masks.
20 *
21 * Author: Raul Rivero
22 * Mathematics Dept.
23 * University of Oviedo
24 * Date: Mon Jan 6 1992
25 * Copyright (c) 1992, Raul Rivero
26 *
27 */
28
29 #include <lug.h>
30 #include <lugfnts.h>
31 #define BLUETOP 175
32
33 #define mvptrs() rb++, gb++, bb++; rm++, gm++, bm++; rs++, gs++, bs++;
34
chroma_mask(base,mask,super,outbitmap)35 chroma_mask( base, mask, super, outbitmap )
36 bitmap_hdr *base, *mask, *super;
37 bitmap_hdr *outbitmap;
38 {
39 byte *rb, *gb, *bb; /* base pointers */
40 byte *rm, *gm, *bm; /* base mask */
41 byte *rs, *gs, *bs; /* base super*/
42 byte *r, *g, *b;
43 byte *end;
44 double position;
45 int totalsize;
46
47 /*
48 * Fill our new header and allocate memory.
49 */
50 outbitmap->magic = LUGUSED;
51 outbitmap->xsize = base->xsize;
52 outbitmap->ysize = base->ysize;
53 outbitmap->depth = base->depth;
54 outbitmap->colors = base->colors;
55 totalsize = outbitmap->xsize * outbitmap->ysize;
56 r = outbitmap->r = (byte *) Malloc( totalsize );
57 g = outbitmap->g = (byte *) Malloc( totalsize );
58 b = outbitmap->b = (byte *) Malloc( totalsize );
59
60 /*
61 * Set the pointers.
62 */
63 rb = base->r , gb = base->g , bb = base->b;
64 rm = mask->r , gm = mask->g , bm = mask->b;
65 rs = super->r , gs = super->g , bs = super->b;
66
67 end = r + totalsize;
68 while ( r < end ) {
69 if ( (*rm + *gm + *bm) > CHROMAMASK ) {
70 /*
71 * The current point has red as component, then we
72 * change this point with the super current point.
73 */
74 *r++ = *rs;
75 *g++ = *gs;
76 *b++ = *bs;
77 mvptrs();
78 }else {
79 *r++ = *rb;
80 *g++ = *gb;
81 *b++ = *bb;
82 mvptrs();
83 }
84 }
85
86 /* No errors */
87 return 0;
88 }
89
chroma_shadow_mask(base,mask,super,outbitmap)90 chroma_shadow_mask( base, mask, super, outbitmap )
91 bitmap_hdr *base, *mask, *super;
92 bitmap_hdr *outbitmap;
93 {
94 byte *rb, *gb, *bb; /* base pointers */
95 byte *rm, *gm, *bm; /* base mask */
96 byte *rs, *gs, *bs; /* base super*/
97 byte *r, *g, *b;
98 byte *end;
99 double position;
100 int totalsize;
101
102 if ( base->magic != LUGUSED || mask->magic != LUGUSED )
103 error( 19 );
104
105 /*
106 * Fill our new header and allocate memory.
107 */
108 outbitmap->magic = LUGUSED;
109 outbitmap->xsize = base->xsize;
110 outbitmap->ysize = base->ysize;
111 outbitmap->depth = base->depth;
112 outbitmap->colors = base->colors;
113 totalsize = outbitmap->xsize * outbitmap->ysize;
114 r = outbitmap->r = (byte *) Malloc( totalsize );
115 g = outbitmap->g = (byte *) Malloc( totalsize );
116 b = outbitmap->b = (byte *) Malloc( totalsize );
117
118 /*
119 * Set the pointers.
120 */
121 rb = base->r , gb = base->g , bb = base->b;
122 rm = mask->r , gm = mask->g , bm = mask->b;
123 rs = super->r , gs = super->g , bs = super->b;
124
125 end = r + totalsize;
126 while ( r < end ) {
127 if ( *rm > 0 ) {
128 /*
129 * The current point has red as component, then we
130 * change this point with the super current point.
131 */
132 *r++ = *rs;
133 *g++ = *gs;
134 *b++ = *bs;
135 mvptrs();
136 }else {
137 if ( *bm > BLUETOP ) {
138 /*
139 * If the current blue is greater than BLUETOP then
140 * we change this pixel with the current base pixel.
141 */
142 *r++ = *rb;
143 *g++ = *gb;
144 *b++ = *bb;
145 mvptrs();
146 }else {
147 /*
148 * Well ... we have a shadow !!!, so we darken
149 * the current base pixel.
150 */
151 position = *bm / 255.;
152 *r++ = (byte) ( *rb * position );
153 *g++ = (byte) ( *gb * position );
154 *b++ = (byte) ( *bb * position );
155 mvptrs();
156 }
157 }
158 }
159
160 /* No errors */
161 return 0;
162 }
163
mask_change_color(base,mask,outbitmap,newr,newg,newb)164 mask_change_color( base, mask, outbitmap, newr, newg, newb )
165 bitmap_hdr *base, *mask, *outbitmap;
166 int newr, newg, newb;
167 {
168 byte *rb, *gb, *bb; /* base pointers */
169 byte *rm, *gm, *bm; /* base mask */
170 byte *r, *g, *b;
171 byte *end;
172 int totalsize;
173 double newh, news, newl;
174 double h, s, l;
175
176 if ( base->xsize != mask->xsize || base->ysize != mask->ysize )
177 error( 9 );
178
179 /*
180 * Translate new color ( rgb ) to hsl format.
181 */
182 RGB_to_HSL( newr, newg, newb, &newh, &news, &newl );
183
184 /*
185 * Fill our new header and allocate memory.
186 */
187 outbitmap->magic = LUGUSED;
188 outbitmap->xsize = base->xsize;
189 outbitmap->ysize = base->ysize;
190 outbitmap->depth = base->depth;
191 outbitmap->colors = base->colors;
192 totalsize = outbitmap->xsize * outbitmap->ysize;
193 r = outbitmap->r = (byte *) Malloc( totalsize );
194 g = outbitmap->g = (byte *) Malloc( totalsize );
195 b = outbitmap->b = (byte *) Malloc( totalsize );
196
197 /*
198 * Set the pointers.
199 */
200 rb = base->r , gb = base->g, bb = base->b;
201 rm = mask->r , gm = mask->g, bm = mask->b;
202
203 end = r + totalsize;
204 while ( r < end ) {
205 if ( ( (*rm++) + (*gm++) + (*bm++) ) > CHROMAMASK ) {
206 /*
207 * The mask has been actived, so we need change
208 * this pixel with our new color.
209 */
210 RGB_to_HSL( *rb++, *gb++, *bb++, &h, &s, &l );
211 HSL_to_RGB( newh, news, l, r++, g++, b++ );
212 }else {
213 /*
214 * No mask, so we copy the base image.
215 */
216 *r++ = *rb++;
217 *g++ = *gb++;
218 *b++ = *bb++;
219 }
220 }
221
222 /* No errors */
223 return 0;
224 }
225
mask_change_to_bw(base,mask,outbitmap)226 mask_change_to_bw( base, mask, outbitmap )
227 bitmap_hdr *base, *mask, *outbitmap;
228 {
229 byte *rb, *gb, *bb; /* base pointers */
230 byte *rm, *gm, *bm; /* base mask */
231 byte *r, *g, *b;
232 byte *end;
233 int totalsize;
234 int value;
235
236 if ( base->xsize != mask->xsize || base->ysize != mask->ysize )
237 error( 9 );
238
239 /*
240 * Fill our new header and allocate memory.
241 */
242 outbitmap->magic = LUGUSED;
243 outbitmap->xsize = base->xsize;
244 outbitmap->ysize = base->ysize;
245 outbitmap->depth = base->depth;
246 outbitmap->colors = base->colors;
247 totalsize = outbitmap->xsize * outbitmap->ysize;
248 r = outbitmap->r = (byte *) Malloc( totalsize );
249 g = outbitmap->g = (byte *) Malloc( totalsize );
250 b = outbitmap->b = (byte *) Malloc( totalsize );
251
252 /*
253 * Set the pointers.
254 */
255 rb = base->r , gb = base->g, bb = base->b;
256 rm = mask->r , gm = mask->g, bm = mask->b;
257
258 end = r + totalsize;
259 while ( r < end ) {
260 if ( ( (*rm++) + (*gm++) + (*bm++) ) > CHROMAMASK ) {
261 /*
262 * The mask has been actived, so we need change
263 * this pixel with our new color.
264 */
265 value = RGB_to_BW( *rb++, *gb++, *bb++ );
266 *r++ = value;
267 *g++ = value;
268 *b++ = value;
269 }else {
270 /*
271 * No mask, so we copy the base image.
272 */
273 *r++ = *rb++;
274 *g++ = *gb++;
275 *b++ = *bb++;
276 }
277 }
278
279 /* No errors */
280 return 0;
281 }
282
mask_darken_color(base,mask,outbitmap)283 mask_darken_color( base, mask, outbitmap )
284 bitmap_hdr *base, *mask, *outbitmap;
285 {
286 byte *rb, *gb, *bb; /* base pointers */
287 byte *rm, *gm, *bm; /* base mask */
288 byte *r, *g, *b;
289 byte *end;
290 int totalsize;
291 double h, s, l;
292
293 if ( base->xsize != mask->xsize || base->ysize != mask->ysize )
294 error( 9 );
295
296 /*
297 * Fill our new header and allocate memory.
298 */
299 outbitmap->magic = LUGUSED;
300 outbitmap->xsize = base->xsize;
301 outbitmap->ysize = base->ysize;
302 outbitmap->depth = base->depth;
303 outbitmap->colors = base->colors;
304 totalsize = outbitmap->xsize * outbitmap->ysize;
305 r = outbitmap->r = (byte *) Malloc( totalsize );
306 g = outbitmap->g = (byte *) Malloc( totalsize );
307 b = outbitmap->b = (byte *) Malloc( totalsize );
308
309 /*
310 * Set the pointers.
311 */
312 rb = base->r , gb = base->g, bb = base->b;
313 rm = mask->r , gm = mask->g, bm = mask->b;
314
315 end = r + totalsize;
316 while ( r < end ) {
317 if ( ( (*rm++) + (*gm++) + (*bm++) ) > CHROMAMASK ) {
318 /*
319 * The mask has been actived, so we need change
320 * this pixel with our new color.
321 */
322 RGB_to_HSL( *rb++, *gb++, *bb++, &h, &s, &l );
323 HSL_to_RGB( h, s/2., l/1.5, r++, g++, b++ );
324 }else {
325 /*
326 * No mask, so we copy the base image.
327 */
328 *r++ = *rb++;
329 *g++ = *gb++;
330 *b++ = *bb++;
331 }
332 }
333
334 /* No errors */
335 return 0;
336 }
337
fade_mask(base,super,mask,out)338 fade_mask( base, super, mask, out )
339 bitmap_hdr *base, *super, *mask;
340 bitmap_hdr *out;
341 {
342 byte *rb, *gb, *bb; /* base pointers */
343 byte *rm, *gm, *bm; /* mask pointers */
344 byte *rs, *gs, *bs; /* super pointers */
345 byte *ro, *go, *bo;
346 byte *end;
347 double percent, neg_percent;
348 double aux;
349 int totalsize = base->xsize * base->ysize;
350
351 /* We have images really ? */
352 if ( base->magic != LUGUSED ||
353 super->magic != LUGUSED ||
354 mask->magic != LUGUSED )
355 error( 19 );
356
357 /*
358 * Check if the width and height of the input images are the
359 * same. A trick: add all values an multiply one by 3 ( it
360 * no perfect ... but almost ).
361 */
362 if ( (base->xsize + super->xsize + mask->xsize) != 3 * base->xsize )
363 error( 12 );
364 if ( (base->ysize + super->ysize + mask->ysize) != 3 * mask->ysize )
365 error( 12 );
366
367 /* Create the new image ( alloc memory, fill the header, ... ) */
368 create_solid_image( out, base->xsize, base->ysize, 0, 0, 0 );
369
370 /*
371 * Set the pointers.
372 */
373 rb = base->r , gb = base->g , bb = base->b;
374 rs = super->r , gs = super->g , bs = super->b;
375 rm = mask->r , gm = mask->g , bm = mask->b;
376 ro = out->r , go = out->g , bo = out->b;
377
378 /* Lets go ! */
379 end = rb + totalsize;
380 while ( rb < end ) {
381 /*
382 * Calculate the percent of transparency.
383 */
384 percent = *rm++ / 255.;
385 neg_percent = 1. - percent;
386
387 /*
388 * Ok, now we know what need from one and another image ( the
389 * percent and negate percent ), so ...
390 */
391 aux = percent * (double) *rb++ + neg_percent * (double) *rs++;
392 *ro++ = (int) aux;
393 aux = percent * (double) *gb++ + neg_percent * (double) *gs++;
394 *go++ = (int) aux;
395 aux = percent * (double) *bb++ + neg_percent * (double) *bs++;
396 *bo++ = (int) aux;
397 }
398
399 /* No errors */
400 return 0;
401 }
402