/* * This software is copyrighted as noted below. It may be freely copied, * modified, and redistributed, provided that the copyright notice is * preserved on all copies. * * There is no warranty or other guarantee of fitness for this software, * it is provided solely "as is". Bug reports or fixes may be sent * to the author, who may or may not act on them as he desires. * * You may not include this software in a program or other software product * without supplying the source, or without informing the end-user that the * source is available for no extra charge. * * If you modify this software, you should include a notice giving the * name of the person performing the modification, the date of modification, * and the reason for such modification. */ /* * mask.c - perform transformations using masks. * * Author: Raul Rivero * Mathematics Dept. * University of Oviedo * Date: Mon Jan 6 1992 * Copyright (c) 1992, Raul Rivero * */ #include #include #define BLUETOP 175 #define mvptrs() rb++, gb++, bb++; rm++, gm++, bm++; rs++, gs++, bs++; chroma_mask( base, mask, super, outbitmap ) bitmap_hdr *base, *mask, *super; bitmap_hdr *outbitmap; { byte *rb, *gb, *bb; /* base pointers */ byte *rm, *gm, *bm; /* base mask */ byte *rs, *gs, *bs; /* base super*/ byte *r, *g, *b; byte *end; double position; int totalsize; /* * Fill our new header and allocate memory. */ outbitmap->magic = LUGUSED; outbitmap->xsize = base->xsize; outbitmap->ysize = base->ysize; outbitmap->depth = base->depth; outbitmap->colors = base->colors; totalsize = outbitmap->xsize * outbitmap->ysize; r = outbitmap->r = (byte *) Malloc( totalsize ); g = outbitmap->g = (byte *) Malloc( totalsize ); b = outbitmap->b = (byte *) Malloc( totalsize ); /* * Set the pointers. */ rb = base->r , gb = base->g , bb = base->b; rm = mask->r , gm = mask->g , bm = mask->b; rs = super->r , gs = super->g , bs = super->b; end = r + totalsize; while ( r < end ) { if ( (*rm + *gm + *bm) > CHROMAMASK ) { /* * The current point has red as component, then we * change this point with the super current point. */ *r++ = *rs; *g++ = *gs; *b++ = *bs; mvptrs(); }else { *r++ = *rb; *g++ = *gb; *b++ = *bb; mvptrs(); } } /* No errors */ return 0; } chroma_shadow_mask( base, mask, super, outbitmap ) bitmap_hdr *base, *mask, *super; bitmap_hdr *outbitmap; { byte *rb, *gb, *bb; /* base pointers */ byte *rm, *gm, *bm; /* base mask */ byte *rs, *gs, *bs; /* base super*/ byte *r, *g, *b; byte *end; double position; int totalsize; if ( base->magic != LUGUSED || mask->magic != LUGUSED ) error( 19 ); /* * Fill our new header and allocate memory. */ outbitmap->magic = LUGUSED; outbitmap->xsize = base->xsize; outbitmap->ysize = base->ysize; outbitmap->depth = base->depth; outbitmap->colors = base->colors; totalsize = outbitmap->xsize * outbitmap->ysize; r = outbitmap->r = (byte *) Malloc( totalsize ); g = outbitmap->g = (byte *) Malloc( totalsize ); b = outbitmap->b = (byte *) Malloc( totalsize ); /* * Set the pointers. */ rb = base->r , gb = base->g , bb = base->b; rm = mask->r , gm = mask->g , bm = mask->b; rs = super->r , gs = super->g , bs = super->b; end = r + totalsize; while ( r < end ) { if ( *rm > 0 ) { /* * The current point has red as component, then we * change this point with the super current point. */ *r++ = *rs; *g++ = *gs; *b++ = *bs; mvptrs(); }else { if ( *bm > BLUETOP ) { /* * If the current blue is greater than BLUETOP then * we change this pixel with the current base pixel. */ *r++ = *rb; *g++ = *gb; *b++ = *bb; mvptrs(); }else { /* * Well ... we have a shadow !!!, so we darken * the current base pixel. */ position = *bm / 255.; *r++ = (byte) ( *rb * position ); *g++ = (byte) ( *gb * position ); *b++ = (byte) ( *bb * position ); mvptrs(); } } } /* No errors */ return 0; } mask_change_color( base, mask, outbitmap, newr, newg, newb ) bitmap_hdr *base, *mask, *outbitmap; int newr, newg, newb; { byte *rb, *gb, *bb; /* base pointers */ byte *rm, *gm, *bm; /* base mask */ byte *r, *g, *b; byte *end; int totalsize; double newh, news, newl; double h, s, l; if ( base->xsize != mask->xsize || base->ysize != mask->ysize ) error( 9 ); /* * Translate new color ( rgb ) to hsl format. */ RGB_to_HSL( newr, newg, newb, &newh, &news, &newl ); /* * Fill our new header and allocate memory. */ outbitmap->magic = LUGUSED; outbitmap->xsize = base->xsize; outbitmap->ysize = base->ysize; outbitmap->depth = base->depth; outbitmap->colors = base->colors; totalsize = outbitmap->xsize * outbitmap->ysize; r = outbitmap->r = (byte *) Malloc( totalsize ); g = outbitmap->g = (byte *) Malloc( totalsize ); b = outbitmap->b = (byte *) Malloc( totalsize ); /* * Set the pointers. */ rb = base->r , gb = base->g, bb = base->b; rm = mask->r , gm = mask->g, bm = mask->b; end = r + totalsize; while ( r < end ) { if ( ( (*rm++) + (*gm++) + (*bm++) ) > CHROMAMASK ) { /* * The mask has been actived, so we need change * this pixel with our new color. */ RGB_to_HSL( *rb++, *gb++, *bb++, &h, &s, &l ); HSL_to_RGB( newh, news, l, r++, g++, b++ ); }else { /* * No mask, so we copy the base image. */ *r++ = *rb++; *g++ = *gb++; *b++ = *bb++; } } /* No errors */ return 0; } mask_change_to_bw( base, mask, outbitmap ) bitmap_hdr *base, *mask, *outbitmap; { byte *rb, *gb, *bb; /* base pointers */ byte *rm, *gm, *bm; /* base mask */ byte *r, *g, *b; byte *end; int totalsize; int value; if ( base->xsize != mask->xsize || base->ysize != mask->ysize ) error( 9 ); /* * Fill our new header and allocate memory. */ outbitmap->magic = LUGUSED; outbitmap->xsize = base->xsize; outbitmap->ysize = base->ysize; outbitmap->depth = base->depth; outbitmap->colors = base->colors; totalsize = outbitmap->xsize * outbitmap->ysize; r = outbitmap->r = (byte *) Malloc( totalsize ); g = outbitmap->g = (byte *) Malloc( totalsize ); b = outbitmap->b = (byte *) Malloc( totalsize ); /* * Set the pointers. */ rb = base->r , gb = base->g, bb = base->b; rm = mask->r , gm = mask->g, bm = mask->b; end = r + totalsize; while ( r < end ) { if ( ( (*rm++) + (*gm++) + (*bm++) ) > CHROMAMASK ) { /* * The mask has been actived, so we need change * this pixel with our new color. */ value = RGB_to_BW( *rb++, *gb++, *bb++ ); *r++ = value; *g++ = value; *b++ = value; }else { /* * No mask, so we copy the base image. */ *r++ = *rb++; *g++ = *gb++; *b++ = *bb++; } } /* No errors */ return 0; } mask_darken_color( base, mask, outbitmap ) bitmap_hdr *base, *mask, *outbitmap; { byte *rb, *gb, *bb; /* base pointers */ byte *rm, *gm, *bm; /* base mask */ byte *r, *g, *b; byte *end; int totalsize; double h, s, l; if ( base->xsize != mask->xsize || base->ysize != mask->ysize ) error( 9 ); /* * Fill our new header and allocate memory. */ outbitmap->magic = LUGUSED; outbitmap->xsize = base->xsize; outbitmap->ysize = base->ysize; outbitmap->depth = base->depth; outbitmap->colors = base->colors; totalsize = outbitmap->xsize * outbitmap->ysize; r = outbitmap->r = (byte *) Malloc( totalsize ); g = outbitmap->g = (byte *) Malloc( totalsize ); b = outbitmap->b = (byte *) Malloc( totalsize ); /* * Set the pointers. */ rb = base->r , gb = base->g, bb = base->b; rm = mask->r , gm = mask->g, bm = mask->b; end = r + totalsize; while ( r < end ) { if ( ( (*rm++) + (*gm++) + (*bm++) ) > CHROMAMASK ) { /* * The mask has been actived, so we need change * this pixel with our new color. */ RGB_to_HSL( *rb++, *gb++, *bb++, &h, &s, &l ); HSL_to_RGB( h, s/2., l/1.5, r++, g++, b++ ); }else { /* * No mask, so we copy the base image. */ *r++ = *rb++; *g++ = *gb++; *b++ = *bb++; } } /* No errors */ return 0; } fade_mask( base, super, mask, out ) bitmap_hdr *base, *super, *mask; bitmap_hdr *out; { byte *rb, *gb, *bb; /* base pointers */ byte *rm, *gm, *bm; /* mask pointers */ byte *rs, *gs, *bs; /* super pointers */ byte *ro, *go, *bo; byte *end; double percent, neg_percent; double aux; int totalsize = base->xsize * base->ysize; /* We have images really ? */ if ( base->magic != LUGUSED || super->magic != LUGUSED || mask->magic != LUGUSED ) error( 19 ); /* * Check if the width and height of the input images are the * same. A trick: add all values an multiply one by 3 ( it * no perfect ... but almost ). */ if ( (base->xsize + super->xsize + mask->xsize) != 3 * base->xsize ) error( 12 ); if ( (base->ysize + super->ysize + mask->ysize) != 3 * mask->ysize ) error( 12 ); /* Create the new image ( alloc memory, fill the header, ... ) */ create_solid_image( out, base->xsize, base->ysize, 0, 0, 0 ); /* * Set the pointers. */ rb = base->r , gb = base->g , bb = base->b; rs = super->r , gs = super->g , bs = super->b; rm = mask->r , gm = mask->g , bm = mask->b; ro = out->r , go = out->g , bo = out->b; /* Lets go ! */ end = rb + totalsize; while ( rb < end ) { /* * Calculate the percent of transparency. */ percent = *rm++ / 255.; neg_percent = 1. - percent; /* * Ok, now we know what need from one and another image ( the * percent and negate percent ), so ... */ aux = percent * (double) *rb++ + neg_percent * (double) *rs++; *ro++ = (int) aux; aux = percent * (double) *gb++ + neg_percent * (double) *gs++; *go++ = (int) aux; aux = percent * (double) *bb++ + neg_percent * (double) *bs++; *bo++ = (int) aux; } /* No errors */ return 0; }