mirror of
https://github.com/ioquake/jedi-outcast.git
synced 2024-11-10 07:11:42 +00:00
1810 lines
26 KiB
C
1810 lines
26 KiB
C
|
/**
|
||
|
|
||
|
** $Header: /roq/libim/imvfbadjust.c 1 11/02/99 4:38p Zaphod $
|
||
|
|
||
|
** Copyright (c) 1989-1995 San Diego Supercomputer Center (SDSC)
|
||
|
|
||
|
** a division of General Atomics, San Diego, California, USA
|
||
|
|
||
|
**
|
||
|
|
||
|
** Users and possessors of this source code are hereby granted a
|
||
|
|
||
|
** nonexclusive, royalty-free copyright and design patent license to
|
||
|
|
||
|
** use this code in individual software. License is not granted for
|
||
|
|
||
|
** commercial resale, in whole or in part, without prior written
|
||
|
|
||
|
** permission from SDSC. This source is provided "AS IS" without express
|
||
|
|
||
|
** or implied warranty of any kind.
|
||
|
|
||
|
**
|
||
|
|
||
|
** For further information contact:
|
||
|
|
||
|
** E-Mail: info@sds.sdsc.edu
|
||
|
|
||
|
**
|
||
|
|
||
|
** Surface Mail: Information Center
|
||
|
|
||
|
** San Diego Supercomputer Center
|
||
|
|
||
|
** P.O. Box 85608
|
||
|
|
||
|
** San Diego, CA 92138-5608
|
||
|
|
||
|
** (619) 534-5000
|
||
|
|
||
|
**/
|
||
|
|
||
|
|
||
|
|
||
|
#define HEADER " $Header: /roq/libim/imvfbadjust.c 1 11/02/99 4:38p Zaphod $"
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
|
||
|
** FILE
|
||
|
|
||
|
** imvfbadjust.c - adjust a VFB
|
||
|
|
||
|
**
|
||
|
|
||
|
** PROJECT
|
||
|
|
||
|
** libim - SDSC image manipulation library
|
||
|
|
||
|
**
|
||
|
|
||
|
** DESCRIPTION
|
||
|
|
||
|
** imvfbadjust.c contains routines for adjusting components of pixels in a VFB
|
||
|
|
||
|
**
|
||
|
|
||
|
** PUBLIC CONTENTS
|
||
|
|
||
|
** d =defined constant
|
||
|
|
||
|
** f =function
|
||
|
|
||
|
** m =defined macro
|
||
|
|
||
|
** t =typedef/struct/union
|
||
|
|
||
|
** v =variable
|
||
|
|
||
|
** ? =other
|
||
|
|
||
|
**
|
||
|
|
||
|
** ImVfbAdjust f adjust the field values of a virtual frame buffer
|
||
|
|
||
|
**
|
||
|
|
||
|
** PRIVATE CONTENTS
|
||
|
|
||
|
** imAdjustPixel m adjust a pixel component
|
||
|
|
||
|
** imCheckField m check that a field value is within legal range
|
||
|
|
||
|
** IM_ERROR m return an error
|
||
|
|
||
|
**
|
||
|
|
||
|
** HISTORY
|
||
|
|
||
|
** $Log: /roq/libim/imvfbadjust.c $
|
||
|
*
|
||
|
* 1 11/02/99 4:38p Zaphod
|
||
|
|
||
|
** Revision 1.7 1995/06/29 00:28:04 bduggan
|
||
|
|
||
|
** updated copyright year
|
||
|
|
||
|
**
|
||
|
|
||
|
** Revision 1.6 1994/10/03 11:29:45 nadeau
|
||
|
|
||
|
** Updated to ANSI C and C++ compatibility.
|
||
|
|
||
|
** Removed all use of register keyword.
|
||
|
|
||
|
** Minimized use of custom SDSC types (e.g., uchar vs. unsigned char)
|
||
|
|
||
|
** Changed all float arguments to double.
|
||
|
|
||
|
** Added forward declarations.
|
||
|
|
||
|
** Added misc. casts to passify SGI and DEC compilers.
|
||
|
|
||
|
** Changed all macros and defined constants to have names
|
||
|
|
||
|
** starting with IM.
|
||
|
|
||
|
** Updated comments.
|
||
|
|
||
|
** Updated indenting on some code.
|
||
|
|
||
|
** Updated copyright message.
|
||
|
|
||
|
**
|
||
|
|
||
|
** Revision 1.5 92/12/03 01:53:59 nadeau
|
||
|
|
||
|
** Changed names of ImRgbHsi and ImHsiRgb to new names.
|
||
|
|
||
|
**
|
||
|
|
||
|
** Revision 1.4 92/09/01 20:11:06 vle
|
||
|
|
||
|
** Updated copyright notice.
|
||
|
|
||
|
**
|
||
|
|
||
|
** Revision 1.3 92/09/01 12:24:45 nadeau
|
||
|
|
||
|
** Rearranged and rewrote much of the code to add in additional
|
||
|
|
||
|
** error checks, support keying off of non-RGB images when given
|
||
|
|
||
|
** RGB or HSI key fields, support monochrome, write protect,
|
||
|
|
||
|
** Z-buffer, integer data, and float data fields.
|
||
|
|
||
|
**
|
||
|
|
||
|
** Revision 1.2 92/08/26 12:45:45 groening
|
||
|
|
||
|
** minor error corrections
|
||
|
|
||
|
**
|
||
|
|
||
|
** Revision 1.1 92/08/10 08:52:09 groening
|
||
|
|
||
|
** Initial revision
|
||
|
|
||
|
**
|
||
|
|
||
|
**
|
||
|
|
||
|
**/
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
|
||
|
** CODE CREDITS
|
||
|
|
||
|
** Custom development, Chris Groening, San Diego Supercomputer Center, 1992.
|
||
|
|
||
|
** Custom development, Dave Nadeau, San Diego Supercomputer Center, 1992.
|
||
|
|
||
|
**/
|
||
|
|
||
|
#include "iminternal.h"
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* MACRO
|
||
|
|
||
|
* imAdjustPixel - adjust a pixel component
|
||
|
|
||
|
*
|
||
|
|
||
|
* DESCRIPTION
|
||
|
|
||
|
* Used by each of the adjustment operators of ImVfbAdjust(),
|
||
|
|
||
|
* this macro queries a pixel's component value, adjusts it as
|
||
|
|
||
|
* requested, checks that it is a legal value, then saves it
|
||
|
|
||
|
* back to the VFB.
|
||
|
|
||
|
*
|
||
|
|
||
|
* The macro is provide to encapsulate an algorithm that is
|
||
|
|
||
|
* nearly identical for each adjustment operator. Note that
|
||
|
|
||
|
* the 'op' argument is a C operator, like "+=" or "*=" that
|
||
|
|
||
|
* is substituted into the code. It is not a variable and is
|
||
|
|
||
|
* not a character string. This macro should be invoked with
|
||
|
|
||
|
* a statement like:
|
||
|
|
||
|
*
|
||
|
|
||
|
* imAdjustPixel( += )
|
||
|
|
||
|
*
|
||
|
|
||
|
* in order to implement an ADD operation. Pretty tricky, huh?
|
||
|
|
||
|
*/
|
||
|
|
||
|
#define imAdjustPixel(op) \
|
||
|
{ \
|
||
|
float hsi[3]; \
|
||
|
int rgb[3]; \
|
||
|
switch ( adjustField ) \
|
||
|
{ \
|
||
|
case IMRED: \
|
||
|
pixel = ImVfbQRed( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
if ( pixel > 255 ) pixel = 255; \
|
||
|
if ( pixel < 0 ) pixel = 0; \
|
||
|
ImVfbSRed( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMGREEN: \
|
||
|
pixel = ImVfbQGreen( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
if ( pixel > 255 ) pixel = 255; \
|
||
|
if ( pixel < 0 ) pixel = 0; \
|
||
|
ImVfbSGreen( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMBLUE: \
|
||
|
pixel = ImVfbQBlue( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
if ( pixel > 255 ) pixel = 255; \
|
||
|
if ( pixel < 0 ) pixel = 0; \
|
||
|
ImVfbSBlue( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMINDEX8: \
|
||
|
pixel = ImVfbQIndex8( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
if ( pixel > 255 ) pixel = 255; \
|
||
|
if ( pixel < 0 ) pixel = 0; \
|
||
|
ImVfbSIndex8( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMINDEX16: \
|
||
|
pixel = ImVfbQIndex16( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
if ( pixel > 65535 ) pixel = 65535; \
|
||
|
if ( pixel < 0 ) pixel = 0; \
|
||
|
ImVfbSIndex16( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMMONO: \
|
||
|
pixel = ImVfbQMono( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
if ( pixel > 1 ) pixel = 1; \
|
||
|
if ( pixel < 0 ) pixel = 0; \
|
||
|
ImVfbSMono( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMHUE: \
|
||
|
case IMSATURATION: \
|
||
|
case IMINTENSITY: \
|
||
|
rgb[0] = ImVfbQRed( dstVfb, pDst ); \
|
||
|
rgb[1] = ImVfbQGreen( dstVfb, pDst ); \
|
||
|
rgb[2] = ImVfbQBlue( dstVfb, pDst ); \
|
||
|
ImRgbToHsi( rgb, hsi ); \
|
||
|
if ( adjustField == IMHUE ) hsi[0] op value;\
|
||
|
else if ( adjustField == IMSATURATION) hsi[1] op value;\
|
||
|
else hsi[2] op value;\
|
||
|
ImHsiToRgb( hsi, rgb ); \
|
||
|
ImVfbSRed( dstVfb, pDst, rgb[0] ); \
|
||
|
ImVfbSGreen( dstVfb, pDst, rgb[1] ); \
|
||
|
ImVfbSBlue( dstVfb, pDst, rgb[2] ); \
|
||
|
break; \
|
||
|
case IMALPHA: \
|
||
|
pixel = ImVfbQAlpha( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
if ( pixel > 255 ) pixel = 255; \
|
||
|
if ( pixel < 0 ) pixel = 0; \
|
||
|
ImVfbSAlpha( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMWPROT: \
|
||
|
pixel = ImVfbQWProt( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
if ( pixel > 255 ) pixel = 255; \
|
||
|
if ( pixel < 0 ) pixel = 0; \
|
||
|
ImVfbSWProt( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMZ: \
|
||
|
pixel = ImVfbQZ( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
ImVfbSZ( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
case IMFDATA: \
|
||
|
pixel = ImVfbQFData( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
ImVfbSFData( dstVfb, pDst, pixel ); \
|
||
|
break; \
|
||
|
case IMIDATA: \
|
||
|
pixel = ImVfbQIData( dstVfb, pDst ); \
|
||
|
pixel op value; \
|
||
|
ImVfbSIData( dstVfb, pDst, (int)pixel ); \
|
||
|
break; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* MACRO
|
||
|
|
||
|
* IM_ERROR - return an error code
|
||
|
|
||
|
*
|
||
|
|
||
|
* DESCRIPTION
|
||
|
|
||
|
* This macro encapsulates setting ImErrNo and returning and is
|
||
|
|
||
|
* used just to make the code shorter and easier to read.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#define IM_ERROR(errnum) \
|
||
|
{ \
|
||
|
ImErrNo = (errnum); \
|
||
|
return( IMVFBNULL ); \
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* MACRO
|
||
|
|
||
|
* imCheckField - check that a value is within a legal range
|
||
|
|
||
|
*
|
||
|
|
||
|
* DESCRIPTION
|
||
|
|
||
|
* This macro is used to check each of the key and adjust values
|
||
|
|
||
|
* to make sure they are within acceptable ranges.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#define imCheckField(extent,error) \
|
||
|
{ \
|
||
|
switch ( operation ) \
|
||
|
{ \
|
||
|
case IMADD: \
|
||
|
case IMSUBTRACT: \
|
||
|
if ( adjustLow < -(extent) || adjustHigh > (extent) ) \
|
||
|
IM_ERROR( error ); \
|
||
|
break; \
|
||
|
case IMMULTIPLY: \
|
||
|
if ( adjustLow < 0 ) \
|
||
|
IM_ERROR( error ); \
|
||
|
break; \
|
||
|
case IMDIVIDE: \
|
||
|
if ( adjustLow <= 0 ) \
|
||
|
IM_ERROR( error ); \
|
||
|
break; \
|
||
|
case IMSET: \
|
||
|
if ( adjustLow < 0 || adjustHigh > (extent) ) \
|
||
|
IM_ERROR( error ); \
|
||
|
break; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* FUNCTION
|
||
|
|
||
|
* ImVfbAdjust - adjust the fields in a virtual frame buffer.
|
||
|
|
||
|
*
|
||
|
|
||
|
* DESCRIPTION
|
||
|
|
||
|
* The source image's pixels are adjusted and written to the destination
|
||
|
|
||
|
* image. Adjustements are performed on pixels selected by the 'key'
|
||
|
|
||
|
* arguments and modify those pixel's 'adjust' fields using the given
|
||
|
|
||
|
* operation.
|
||
|
|
||
|
*
|
||
|
|
||
|
* The majority of the code here is just to check that all the incomming
|
||
|
|
||
|
* arguments make sense. Whew!
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef __STDC__
|
||
|
|
||
|
ImVfb * /* Returns filled destination vfb */
|
||
|
|
||
|
ImVfbAdjust( ImVfb *srcVfb, int keyField, double keyStart, double keyEnd, int operation,
|
||
|
|
||
|
int adjustField, double adjustStart, double adjustEnd, ImVfb *dstVfb )
|
||
|
|
||
|
#else
|
||
|
|
||
|
ImVfb * /* Returns filled destination vfb */
|
||
|
|
||
|
ImVfbAdjust( srcVfb, keyField, keyStart, keyEnd, operation,
|
||
|
|
||
|
adjustField, adjustStart, adjustEnd, dstVfb)
|
||
|
|
||
|
ImVfb *srcVfb; /* incoming vfb */
|
||
|
|
||
|
int keyField; /* what field to change */
|
||
|
|
||
|
double keyStart; /* Start range of field to change */
|
||
|
|
||
|
double keyEnd; /* End range of field to change */
|
||
|
|
||
|
int operation; /* What operation to perform on field */
|
||
|
|
||
|
int adjustField; /* what field to adjust */
|
||
|
|
||
|
double adjustStart; /* Start range of field to adjust */
|
||
|
|
||
|
double adjustEnd; /* End range of field to adjust */
|
||
|
|
||
|
ImVfb *dstVfb; /* Destination vfb */
|
||
|
|
||
|
#endif
|
||
|
|
||
|
{
|
||
|
|
||
|
int x,y; /* Width and height of image */
|
||
|
|
||
|
int i,j; /* Counters */
|
||
|
|
||
|
float factor; /* Replacement value factor */
|
||
|
|
||
|
int fields; /* Fields of source VFB */
|
||
|
|
||
|
int pixelRgb[3]; /* RGB pixel value */
|
||
|
|
||
|
float pixelHsi[3]; /* HSI pixel value */
|
||
|
|
||
|
float pixel; /* Pixel value */
|
||
|
|
||
|
float value; /* Value with which to modify pixel */
|
||
|
|
||
|
ImClt *clt; /* Image's color lookup table */
|
||
|
|
||
|
ImVfbPtr pDst; /* Pointer to destination VFB */
|
||
|
|
||
|
float keyLow; /* Low key value */
|
||
|
|
||
|
float keyHigh; /* High key value */
|
||
|
|
||
|
float adjustLow; /* Low adjust value */
|
||
|
|
||
|
float adjustHigh; /* High adjust value */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Check for legal key and adjust values. This is made a bit
|
||
|
|
||
|
* tricky because of the following:
|
||
|
|
||
|
*
|
||
|
|
||
|
* 1. Different field types have different legal key value
|
||
|
|
||
|
* ranges.
|
||
|
|
||
|
*
|
||
|
|
||
|
* 2. Replace value ranges depend on the operation being
|
||
|
|
||
|
* performed, as well as upon the adjust field's type.
|
||
|
|
||
|
*
|
||
|
|
||
|
* Key fields are restricted as follows:
|
||
|
|
||
|
* mono: 0 to 1
|
||
|
|
||
|
* red, green, blue, alpha, index8, wprot: 0 to 255
|
||
|
|
||
|
* index16: 0 to 65535
|
||
|
|
||
|
* z: 0 to maxint
|
||
|
|
||
|
* idata: any int
|
||
|
|
||
|
* fdata: any float
|
||
|
|
||
|
* hue: 0 to 360.0
|
||
|
|
||
|
* saturation, intensity: 0 to 1.0
|
||
|
|
||
|
*
|
||
|
|
||
|
* Adjust fields are restricted as follows:
|
||
|
|
||
|
*
|
||
|
|
||
|
* Add and subtract:
|
||
|
|
||
|
* It doesn't make much sense to add more, or subtract more
|
||
|
|
||
|
* than the max or min field value. Doing so puts the result
|
||
|
|
||
|
* beyond the max or min, and will just get clamped back to
|
||
|
|
||
|
* the max or min anyway.
|
||
|
|
||
|
* mono: -1 to 1
|
||
|
|
||
|
* red, green, blue, alpha, index8, wprot: -255 to 255
|
||
|
|
||
|
* index16: -65535 to 65535
|
||
|
|
||
|
* z, idata, fdata: anything
|
||
|
|
||
|
* hue: -360.0 to 360.0
|
||
|
|
||
|
* saturation, intensity: -1.0 to 1.0
|
||
|
|
||
|
*
|
||
|
|
||
|
* Multiply:
|
||
|
|
||
|
* Multiplication factors can be anything except negative.
|
||
|
|
||
|
* Negative factors would produce negative results, which
|
||
|
|
||
|
* would just get clamped back to 0 anyway.
|
||
|
|
||
|
* mono: 0 to 1
|
||
|
|
||
|
* red, green, blue, alpha, index8, wprot: 0 to anything
|
||
|
|
||
|
* index16: 0 to anything
|
||
|
|
||
|
* z: 0 to anything
|
||
|
|
||
|
* idata, fdata: anything
|
||
|
|
||
|
* hue: 0 to anything
|
||
|
|
||
|
* saturation, intensity: 0 to anything
|
||
|
|
||
|
*
|
||
|
|
||
|
* Divide:
|
||
|
|
||
|
* Division factors can be anything except zero or negative.
|
||
|
|
||
|
* Zero causes horrible things. Negative values would produce
|
||
|
|
||
|
* negative results, which would just get clamped back to
|
||
|
|
||
|
* 0 anyway.
|
||
|
|
||
|
* mono: >0 to 1
|
||
|
|
||
|
* red, green, blue, alpha, index8, wprot: >0 to anything
|
||
|
|
||
|
* index16: >0 to anything
|
||
|
|
||
|
* z: >0 to anything
|
||
|
|
||
|
* idata, fdata: !=0, anything
|
||
|
|
||
|
* hue: >0 to anything
|
||
|
|
||
|
* saturation, intensity: >0 to anything
|
||
|
|
||
|
*
|
||
|
|
||
|
* Set:
|
||
|
|
||
|
* Set can be anything legal for the field.
|
||
|
|
||
|
* mono: 0 to 1
|
||
|
|
||
|
* red, green, blue, alpha, index8, wprot: 0 to 255
|
||
|
|
||
|
* index16: 0 to 65535
|
||
|
|
||
|
* z: 0 to anything
|
||
|
|
||
|
* idata, fdata: anything
|
||
|
|
||
|
* hue: 0 to 360.0
|
||
|
|
||
|
* saturation, intensity: 0 to 1.0
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Get the low and high key and adjust values to make testing
|
||
|
|
||
|
* extent faster.
|
||
|
|
||
|
*/
|
||
|
|
||
|
if ( keyStart < keyEnd )
|
||
|
|
||
|
{
|
||
|
|
||
|
keyLow = keyStart;
|
||
|
|
||
|
keyHigh = keyEnd;
|
||
|
|
||
|
}
|
||
|
|
||
|
else
|
||
|
|
||
|
{
|
||
|
|
||
|
keyHigh = keyStart;
|
||
|
|
||
|
keyLow = keyEnd;
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( adjustStart < adjustEnd )
|
||
|
|
||
|
{
|
||
|
|
||
|
adjustLow = adjustStart;
|
||
|
|
||
|
adjustHigh = adjustEnd;
|
||
|
|
||
|
}
|
||
|
|
||
|
else
|
||
|
|
||
|
{
|
||
|
|
||
|
adjustHigh = adjustStart;
|
||
|
|
||
|
adjustLow = adjustEnd;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Make sure the key field and key range are good.
|
||
|
|
||
|
*/
|
||
|
|
||
|
switch ( keyField )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMMONO:
|
||
|
|
||
|
if ( keyLow < 0.0 || keyHigh > 1.0 )
|
||
|
|
||
|
IM_ERROR( IMEKEY );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMRED:
|
||
|
|
||
|
case IMGREEN:
|
||
|
|
||
|
case IMBLUE:
|
||
|
|
||
|
case IMALPHA:
|
||
|
|
||
|
case IMINDEX8:
|
||
|
|
||
|
case IMWPROT:
|
||
|
|
||
|
if ( keyLow < 0.0 || keyHigh > 255.0 )
|
||
|
|
||
|
IM_ERROR( IMEKEY );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMINDEX16:
|
||
|
|
||
|
if ( keyLow < 0.0 || keyHigh > 65535.0 )
|
||
|
|
||
|
IM_ERROR( IMEKEY );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMHUE:
|
||
|
|
||
|
if ( keyLow < 0.0 || keyHigh > 360.0 )
|
||
|
|
||
|
IM_ERROR( IMEKEY );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMSATURATION:
|
||
|
|
||
|
case IMINTENSITY:
|
||
|
|
||
|
if ( keyLow < 0.0 || keyHigh > 1.0 )
|
||
|
|
||
|
IM_ERROR( IMEKEY );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMZ:
|
||
|
|
||
|
if ( keyLow < 0.0 )
|
||
|
|
||
|
IM_ERROR( IMEKEY );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMIDATA:
|
||
|
|
||
|
case IMFDATA:
|
||
|
|
||
|
/* All values allowed. */
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
default:
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Make sure the operation is good.
|
||
|
|
||
|
*/
|
||
|
|
||
|
switch ( operation )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMADD:
|
||
|
|
||
|
case IMSUBTRACT:
|
||
|
|
||
|
case IMMULTIPLY:
|
||
|
|
||
|
case IMDIVIDE:
|
||
|
|
||
|
case IMSET:
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
IM_ERROR( IMEOPERATION );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Make sure the adjust field and adjust range are good.
|
||
|
|
||
|
*/
|
||
|
|
||
|
switch ( adjustField )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMMONO:
|
||
|
|
||
|
imCheckField( 1.0, IMEADJUST );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMRED:
|
||
|
|
||
|
case IMGREEN:
|
||
|
|
||
|
case IMBLUE:
|
||
|
|
||
|
case IMALPHA:
|
||
|
|
||
|
case IMINDEX8:
|
||
|
|
||
|
case IMWPROT:
|
||
|
|
||
|
imCheckField( 255.0, IMEADJUST );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMINDEX16:
|
||
|
|
||
|
imCheckField( 65535.0, IMEADJUST );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMZ:
|
||
|
|
||
|
switch ( operation )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMADD:
|
||
|
|
||
|
case IMSUBTRACT:
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMMULTIPLY:
|
||
|
|
||
|
case IMSET:
|
||
|
|
||
|
if ( adjustLow < 0.0 )
|
||
|
|
||
|
IM_ERROR( IMEADJUST );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMDIVIDE:
|
||
|
|
||
|
if ( adjustLow == 0.0 || adjustHigh == 0.0 )
|
||
|
|
||
|
IM_ERROR( IMEADJUST );
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMIDATA:
|
||
|
|
||
|
case IMFDATA:
|
||
|
|
||
|
if ( operation == IMDIVIDE &&
|
||
|
|
||
|
( adjustLow == 0.0 || adjustHigh == 0.0 ) )
|
||
|
|
||
|
IM_ERROR( IMEADJUST );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMHUE:
|
||
|
|
||
|
imCheckField( 360.0, IMEADJUST );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMSATURATION:
|
||
|
|
||
|
case IMINTENSITY:
|
||
|
|
||
|
imCheckField( 1.0, IMEADJUST );
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Check that the source VFB has the fields we need to do the
|
||
|
|
||
|
* adjustment.
|
||
|
|
||
|
*
|
||
|
|
||
|
* Key fields:
|
||
|
|
||
|
* red, green, blue: source may have any color field type
|
||
|
|
||
|
* hue, saturation, inten: source may have any color field type
|
||
|
|
||
|
* mono: source must have MONO
|
||
|
|
||
|
* index8: source must have INDEX8
|
||
|
|
||
|
* index16: source must have INDEX16
|
||
|
|
||
|
* alpha: source must have ALPHA
|
||
|
|
||
|
* wprot: source must have WPROT
|
||
|
|
||
|
* z: source must have Z
|
||
|
|
||
|
* idata: source must have IDATA
|
||
|
|
||
|
* fdata: source must have FDATA
|
||
|
|
||
|
*
|
||
|
|
||
|
* Replace fields:
|
||
|
|
||
|
* red, green, blue: destination must have RGB.
|
||
|
|
||
|
* hue, saturation, inten: destination must have RGB.
|
||
|
|
||
|
* index8: destination must have INDEX8.
|
||
|
|
||
|
* index16: destination must have INDEX16.
|
||
|
|
||
|
* alpha: destination must have ALPHA.
|
||
|
|
||
|
* wprot: destination must have WPROT
|
||
|
|
||
|
* z: destination must have Z
|
||
|
|
||
|
* idata: destination must have IDATA
|
||
|
|
||
|
* fdata: destination must have FDATA
|
||
|
|
||
|
*/
|
||
|
|
||
|
fields = ImVfbQFields( srcVfb );
|
||
|
|
||
|
switch ( keyField )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMMONO:
|
||
|
|
||
|
if ( !(fields & IMVFBMONO) )
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMRED:
|
||
|
|
||
|
case IMGREEN:
|
||
|
|
||
|
case IMBLUE:
|
||
|
|
||
|
case IMHUE:
|
||
|
|
||
|
case IMSATURATION:
|
||
|
|
||
|
case IMINTENSITY:
|
||
|
|
||
|
if ( !(fields&(IMVFBRGB|IMVFBINDEX8|IMVFBINDEX16|IMVFBMONO)))
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMINDEX8:
|
||
|
|
||
|
if ( !(fields & IMVFBINDEX8) )
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMINDEX16:
|
||
|
|
||
|
if ( !(fields & IMVFBINDEX16) )
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMALPHA:
|
||
|
|
||
|
if ( !(fields & IMVFBALPHA) )
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMWPROT:
|
||
|
|
||
|
if ( !(fields & IMVFBWPROT) )
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMZ:
|
||
|
|
||
|
if ( !(fields & IMVFBZ) )
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMIDATA:
|
||
|
|
||
|
if ( !(fields & IMVFBIDATA) )
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMFDATA:
|
||
|
|
||
|
if ( !(fields & IMVFBFDATA) )
|
||
|
|
||
|
IM_ERROR( IMEKEYFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
switch ( adjustField )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMMONO:
|
||
|
|
||
|
if ( !(fields & IMVFBMONO) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMRED:
|
||
|
|
||
|
case IMGREEN:
|
||
|
|
||
|
case IMBLUE:
|
||
|
|
||
|
case IMHUE:
|
||
|
|
||
|
case IMSATURATION:
|
||
|
|
||
|
case IMINTENSITY:
|
||
|
|
||
|
if ( !(fields & IMVFBRGB) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMINDEX8:
|
||
|
|
||
|
if ( !(fields & IMVFBINDEX8) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMINDEX16:
|
||
|
|
||
|
if ( !(fields & IMVFBINDEX16) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMALPHA:
|
||
|
|
||
|
if ( !(fields & IMVFBALPHA) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMWPROT:
|
||
|
|
||
|
if ( !(fields & IMVFBWPROT) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMZ:
|
||
|
|
||
|
if ( !(fields & IMVFBZ) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMIDATA:
|
||
|
|
||
|
if ( !(fields & IMVFBIDATA) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
|
||
|
case IMFDATA:
|
||
|
|
||
|
if ( !(fields & IMVFBFDATA) )
|
||
|
|
||
|
IM_ERROR( IMEADJUSTFIELD );
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Copy the source into the destination, creating a new destination
|
||
|
|
||
|
* if needed. ImVfbCopy() will catch problems where the given
|
||
|
|
||
|
* destination VFB (if not IMVFBNEW) doesn't have the same fields as
|
||
|
|
||
|
* the source, or isn't at least as large as the source.
|
||
|
|
||
|
*/
|
||
|
|
||
|
x = ImVfbQWidth( srcVfb );
|
||
|
|
||
|
y = ImVfbQHeight( srcVfb );
|
||
|
|
||
|
if ( srcVfb == IMVFBNULL )
|
||
|
|
||
|
IM_ERROR( IMENOVFB );
|
||
|
|
||
|
if ( srcVfb != dstVfb )
|
||
|
|
||
|
{
|
||
|
|
||
|
dstVfb = ImVfbCopy( srcVfb, 0, 0, x, y, fields, dstVfb, 0,0);
|
||
|
|
||
|
if ( dstVfb == IMVFBNULL )
|
||
|
|
||
|
return ( IMVFBNULL ); /* ImErrNo already set */
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Prepare to adjust the image.
|
||
|
|
||
|
*/
|
||
|
|
||
|
if ( keyEnd != keyStart )
|
||
|
|
||
|
factor = (adjustEnd - adjustStart) / (keyEnd - keyStart);
|
||
|
|
||
|
else
|
||
|
|
||
|
factor = 0;
|
||
|
|
||
|
|
||
|
|
||
|
clt = ImVfbQClt( dstVfb ); /* Might be IMCLTNULL */
|
||
|
|
||
|
pDst = ImVfbQFirst( dstVfb );
|
||
|
|
||
|
fields = ImVfbQFields( dstVfb );
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Simplify the field mask to the single key field we care about.
|
||
|
|
||
|
*/
|
||
|
|
||
|
switch ( keyField )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMRED:
|
||
|
|
||
|
case IMGREEN:
|
||
|
|
||
|
case IMBLUE:
|
||
|
|
||
|
case IMHUE:
|
||
|
|
||
|
case IMSATURATION:
|
||
|
|
||
|
case IMINTENSITY:
|
||
|
|
||
|
fields &= IMVFBIMAGEMASK;
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
fields = keyField;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Adjust the image.
|
||
|
|
||
|
*
|
||
|
|
||
|
* Note that there are a lot of checks in the innermost pixel scan
|
||
|
|
||
|
* loop that are loop-invariant. It would certainly speed things
|
||
|
|
||
|
* up if they were moved out of the loop. Unfortunately, this
|
||
|
|
||
|
* considerably increases the amount of the code since it requires
|
||
|
|
||
|
* duplicating the loop for each combination of:
|
||
|
|
||
|
*
|
||
|
|
||
|
* keyField
|
||
|
|
||
|
* red 4 combinations of dst VFB fields
|
||
|
|
||
|
* green 4 combinations of dst VFB fields
|
||
|
|
||
|
* blue 4 combinations of dst VFB fields
|
||
|
|
||
|
* hue 4 combinations of dst VFB fields
|
||
|
|
||
|
* saturation 4 combinations of dst VFB fields
|
||
|
|
||
|
* intensity 4 combinations of dst VFB fields
|
||
|
|
||
|
* index8 2 combinations of dst CLT existance
|
||
|
|
||
|
* index16 2 combinations of dst CLT existance
|
||
|
|
||
|
* mono 1 combination
|
||
|
|
||
|
* alpha 1 combination
|
||
|
|
||
|
* wprot 1 combination
|
||
|
|
||
|
* z 1 combination
|
||
|
|
||
|
* idata 1 combination
|
||
|
|
||
|
* fdata 1 combination
|
||
|
|
||
|
* --
|
||
|
|
||
|
* subtotal 34
|
||
|
|
||
|
*
|
||
|
|
||
|
* operator 5 possible values
|
||
|
|
||
|
* adjustField 10 possible values
|
||
|
|
||
|
* ---
|
||
|
|
||
|
* TOTAL 34 * 5 * 10 = 1700 variants
|
||
|
|
||
|
*
|
||
|
|
||
|
* Things clearly get out of hand quick. Additionally, the basic
|
||
|
|
||
|
* algorithm gets spread out all over everywhere, even with liberal
|
||
|
|
||
|
* use of macros.
|
||
|
|
||
|
*
|
||
|
|
||
|
* So, we'll pay the speed penalty in order to get less code and
|
||
|
|
||
|
* easier maintenance.
|
||
|
|
||
|
*/
|
||
|
|
||
|
for ( i = 0; i < y; i++ )
|
||
|
|
||
|
{
|
||
|
|
||
|
for ( j = 0; j < x; j++ )
|
||
|
|
||
|
{
|
||
|
|
||
|
/* Get the pixel value depending upon keyfield. */
|
||
|
|
||
|
switch ( keyField )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMRED:
|
||
|
|
||
|
/* Get pixel value from VFB depending upon fields. */
|
||
|
|
||
|
switch ( fields )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMVFBRGB:
|
||
|
|
||
|
pixel = ImVfbQRed( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBINDEX8:
|
||
|
|
||
|
pixel = ImVfbQIndex8( dstVfb, pDst );
|
||
|
|
||
|
if ( clt != IMCLTNULL )
|
||
|
|
||
|
pixel = ImCltQRed( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBINDEX16:
|
||
|
|
||
|
pixel = ImVfbQIndex16( dstVfb, pDst );
|
||
|
|
||
|
if ( clt != IMCLTNULL )
|
||
|
|
||
|
pixel = ImCltQRed( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
else
|
||
|
|
||
|
pixel /= 255;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBMONO:
|
||
|
|
||
|
pixel = ImVfbQMono( dstVfb, pDst ) * 255;
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMGREEN:
|
||
|
|
||
|
/* Get pixel value from VFB depending upon fields. */
|
||
|
|
||
|
switch ( fields )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMVFBRGB:
|
||
|
|
||
|
pixel = ImVfbQGreen( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBINDEX8:
|
||
|
|
||
|
pixel = ImVfbQIndex8( dstVfb, pDst );
|
||
|
|
||
|
if ( clt != IMCLTNULL )
|
||
|
|
||
|
pixel = ImCltQGreen( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBINDEX16:
|
||
|
|
||
|
pixel = ImVfbQIndex16( dstVfb, pDst );
|
||
|
|
||
|
if ( clt != IMCLTNULL )
|
||
|
|
||
|
pixel = ImCltQGreen( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
else
|
||
|
|
||
|
pixel /= 255;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBMONO:
|
||
|
|
||
|
pixel = ImVfbQMono( dstVfb, pDst ) * 255;
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMBLUE:
|
||
|
|
||
|
/* Get pixel value from VFB depending upon fields. */
|
||
|
|
||
|
switch ( fields )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMVFBRGB:
|
||
|
|
||
|
pixel = ImVfbQBlue( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBINDEX8:
|
||
|
|
||
|
pixel = ImVfbQIndex8( dstVfb, pDst );
|
||
|
|
||
|
if ( clt != IMCLTNULL )
|
||
|
|
||
|
pixel = ImCltQBlue( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBINDEX16:
|
||
|
|
||
|
pixel = ImVfbQIndex16( dstVfb, pDst );
|
||
|
|
||
|
if ( clt != IMCLTNULL )
|
||
|
|
||
|
pixel = ImCltQBlue( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
else
|
||
|
|
||
|
pixel /= 255;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBMONO:
|
||
|
|
||
|
pixel = ImVfbQMono( dstVfb, pDst ) * 255;
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMINDEX8:
|
||
|
|
||
|
pixel = ImVfbQIndex8( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMINDEX16:
|
||
|
|
||
|
pixel = ImVfbQIndex16( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMMONO:
|
||
|
|
||
|
pixel = ImVfbQMono( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMALPHA:
|
||
|
|
||
|
pixel = ImVfbQAlpha( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMWPROT:
|
||
|
|
||
|
pixel = ImVfbQWProt( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMZ:
|
||
|
|
||
|
pixel = ImVfbQZ( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMIDATA:
|
||
|
|
||
|
pixel = ImVfbQIData( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMFDATA:
|
||
|
|
||
|
pixel = ImVfbQFData( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMHUE:
|
||
|
|
||
|
case IMSATURATION:
|
||
|
|
||
|
case IMINTENSITY:
|
||
|
|
||
|
/* Get pixel value from VFB depending upon fields. */
|
||
|
|
||
|
switch ( fields )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMVFBRGB:
|
||
|
|
||
|
pixelRgb[0] = ImVfbQRed( dstVfb, pDst );
|
||
|
|
||
|
pixelRgb[1] = ImVfbQGreen( dstVfb, pDst );
|
||
|
|
||
|
pixelRgb[2] = ImVfbQBlue( dstVfb, pDst );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBINDEX8:
|
||
|
|
||
|
pixel = ImVfbQIndex8( dstVfb, pDst );
|
||
|
|
||
|
if ( clt != IMCLTNULL )
|
||
|
|
||
|
{
|
||
|
|
||
|
pixelRgb[0] = ImCltQRed( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
pixelRgb[1] = ImCltQGreen( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
pixelRgb[2] = ImCltQBlue( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
}
|
||
|
|
||
|
else
|
||
|
|
||
|
{
|
||
|
|
||
|
pixelRgb[0] = (int)pixel;
|
||
|
|
||
|
pixelRgb[1] = (int)pixel;
|
||
|
|
||
|
pixelRgb[2] = (int)pixel;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBINDEX16:
|
||
|
|
||
|
pixel = ImVfbQIndex16( dstVfb, pDst );
|
||
|
|
||
|
if ( clt != IMCLTNULL )
|
||
|
|
||
|
{
|
||
|
|
||
|
pixelRgb[0] = ImCltQRed( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
pixelRgb[1] = ImCltQGreen( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
pixelRgb[2] = ImCltQBlue( ImCltQPtr( clt, (int)pixel));
|
||
|
|
||
|
}
|
||
|
|
||
|
else
|
||
|
|
||
|
{
|
||
|
|
||
|
pixelRgb[0] = (int)pixel / 255;
|
||
|
|
||
|
pixelRgb[1] = (int)pixel / 255;
|
||
|
|
||
|
pixelRgb[2] = (int)pixel / 255;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMVFBMONO:
|
||
|
|
||
|
pixel = ImVfbQMono( dstVfb, pDst ) * 255;
|
||
|
|
||
|
pixelRgb[0] = (int)pixel;
|
||
|
|
||
|
pixelRgb[1] = (int)pixel;
|
||
|
|
||
|
pixelRgb[2] = (int)pixel;
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
ImRgbToHsi( pixelRgb, pixelHsi );
|
||
|
|
||
|
switch ( keyField )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMHUE: pixel = pixelHsi[0]; break;
|
||
|
|
||
|
case IMSATURATION: pixel = pixelHsi[1]; break;
|
||
|
|
||
|
case IMINTENSITY: pixel = pixelHsi[2]; break;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* Check if the pixel is within the key range. */
|
||
|
|
||
|
if ( !(pixel >= keyStart && pixel <= keyEnd) )
|
||
|
|
||
|
{
|
||
|
|
||
|
/* Nope! */
|
||
|
|
||
|
ImVfbSInc( dstVfb, pDst );
|
||
|
|
||
|
continue;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* Compute the value to add, subtract, etc. */
|
||
|
|
||
|
value = adjustStart + factor * (pixel - keyStart);
|
||
|
|
||
|
|
||
|
|
||
|
/* Update the pixel depending upon the operation. */
|
||
|
|
||
|
switch ( operation )
|
||
|
|
||
|
{
|
||
|
|
||
|
case IMADD:
|
||
|
|
||
|
imAdjustPixel( += );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMSUBTRACT:
|
||
|
|
||
|
imAdjustPixel( -= );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMMULTIPLY:
|
||
|
|
||
|
imAdjustPixel( *= );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMDIVIDE:
|
||
|
|
||
|
imAdjustPixel( /= );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IMSET:
|
||
|
|
||
|
imAdjustPixel( = );
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
ImVfbSInc( dstVfb, pDst );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
return( dstVfb);
|
||
|
|
||
|
}
|
||
|
|