/* * Modification History * * 2000-December-21 Jason Rohrer * Created. * * 2001-January-15 Jason Rohrer * Added an overridden copy() method. * * 2001-January-19 Jason Rohrer * Fixed so that filter( filter, channelNum ) could be called on * this class type. * * 2001-January-31 Jason Rohrer * Fixed a bug in getRGBABytes(). * * 2001-September-15 Jason Rohrer * Added a constructor that copies data from an Image. * * 2006-September-7 Jason Rohrer * Optimized constructor. * * 2010-February-23 Jason Rohrer * Changed default alpha behavior to white instead of black. * * 2010-February-24 Jason Rohrer * Optimized with a static function to avoid needless image copying. */ #ifndef RGBA_IMAGE_INCLUDED #define RGBA_IMAGE_INCLUDED #include #include #include "Image.h" /** * An RGBA extension of Image. * * @author Jason Rohrer */ class RGBAImage : public Image { public: /** * Constructs an RGBA image. All channels are initialized to 0. * * @param inWidth width of image in pixels. * @param inHeight height of image in pixels. */ RGBAImage( int inWidth, int inHeight ); /** * Constructs an RGBAImage by copying a given image. * The image data is truncated or expaned (with black color channels * and white alpha) to fit the 4 channel RGBA model, * and any selection in inImage is ignored. * * @param inImage the image to copy. Copied internally, so must be * destroyed by the caller. */ RGBAImage( Image *inImage ); /** * Gets the pixel data from this image as a byte array. * * @return a byte array containing pixel data for this image. * Stored in row-major order, with each pixel represented * by 4 bytes in the order RGBA. * Must be destroyed by caller. */ virtual unsigned char *getRGBABytes(); // get RGBA a bytes from an image without converting it to an RGBA // image first (faster---found with profiler) // // MUST be a 3- or 4-channel image static unsigned char *getRGBABytes( Image *inImage ); // overrides the Image::filter function virtual void filter( ChannelFilter *inFilter ); virtual void filter( ChannelFilter *inFilter, int inChannel ); // overrides the Image::copy function // since the function is non-virtual in the parent class, // the pointer type should determine which function gets called. RGBAImage *copy(); }; inline RGBAImage::RGBAImage( int inWidth, int inHeight ) : Image( inWidth, inHeight, 4 ) { } inline RGBAImage::RGBAImage( Image *inImage ) // Only init our image's channels to black of inImage doesn't have enough // channels. // This saves time if inImage has 4 or more channels. // Optimization found with profiler. : Image( inImage->getWidth(), inImage->getHeight(), 4, ( inImage->getNumChannels() < 4 ) ) { int minNumChannels = 4; if( inImage->getNumChannels() < minNumChannels ) { minNumChannels = inImage->getNumChannels(); } // if inImage does not have at least 4 channels, // leave our additional channels black // if inImage has extra channels, skip them // copy channels from inImage for( int c=0; cgetChannel( c ); memcpy( mChannels[c], inChannel, mNumPixels * sizeof( double ) ); } if( minNumChannels < 4 ) { // no alpha channel in inImage // set a white one double *alpha = mChannels[3]; for( int i=0; igetWidth() * inImage->getHeight(); int numChannels = inImage->getNumChannels(); int numBytes = numPixels * 4; unsigned char *bytes = new unsigned char[ numBytes ]; double *channelZero = inImage->getChannel( 0 ); double *channelOne = inImage->getChannel( 1 ); double *channelTwo = inImage->getChannel( 2 ); // double-coded branch here to make it faster // (avoid a switch inside the loop if( numChannels > 3 ) { double *channelThree = inImage->getChannel( 3 ); register int i = 0; for( int p=0; ppaste( this ); return copiedImage; } #endif