File: RGBAImage.h

package info (click to toggle)
primrose 6%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,300 kB
  • ctags: 3,385
  • sloc: cpp: 27,318; php: 765; ansic: 636; objc: 272; sh: 136; makefile: 95; perl: 67
file content (186 lines) | stat: -rw-r--r-- 4,664 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
 * 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.
 */
 
 
#ifndef RGBA_IMAGE_INCLUDED
#define RGBA_IMAGE_INCLUDED

#include <stdio.h> 
#include <string.h>
 
#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 channels)
		 * 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();
		
		
		// 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; c<minNumChannels; c++ ) {
		double *inChannel = inImage->getChannel( c );
		
		memcpy( mChannels[c], inChannel, mNumPixels * sizeof( double ) ); 
		}
	}

	
/*	
inline unsigned char *RGBAImage::getRGBABytes() {
	int numBytes = mNumPixels * 4; 
	unsigned char *bytes = new unsigned char[ numBytes ];
	int pixel = 0;
	for( int i=0; i<numBytes; i=i+4 ) {
		bytes[i] = (unsigned char)( mChannels[0][pixel] * 255 );
		bytes[i + 1] = (unsigned char)( mChannels[1][pixel] * 255 );
		bytes[i + 2] = (unsigned char)( mChannels[2][pixel] * 255 );
		bytes[i + 3] = (unsigned char)( mChannels[3][pixel] * 255 );
		pixel++;
		}
	return bytes;
	}
*/

// optimized version
inline unsigned char *RGBAImage::getRGBABytes() {
	int numBytes = mNumPixels * 4; 
	unsigned char *bytes = new unsigned char[ numBytes ];

    double *channelZero = mChannels[0];
    double *channelOne = mChannels[1];
    double *channelTwo = mChannels[2];
    double *channelThree = mChannels[3];
    
    
    register int i = 0;
    for( int p=0; p<mNumPixels; p++ ) {
		bytes[i++] = (unsigned char)( channelZero[p] * 255 );
		bytes[i++] = (unsigned char)( channelOne[p] * 255 );
		bytes[i++] = (unsigned char)( channelTwo[p] * 255 );
		bytes[i++] = (unsigned char)( channelThree[p] * 255 );
		}
	return bytes;
	}

	

inline void RGBAImage::filter( ChannelFilter *inFilter ) {
	// different from standard Image implementation in that we
	// skip the alpha channel when filtering
	for( int i=0; i<mNumChannels-1; i++ ) {
		Image::filter( inFilter, i );
		}	
	}



inline void RGBAImage::filter( ChannelFilter *inFilter, int inChannel ) {
	// provided as a bridge to the Image function, just to
	// get around compile problems.
	Image::filter( inFilter, inChannel );	
	}



inline RGBAImage *RGBAImage::copy() {
	RGBAImage *copiedImage = new RGBAImage( mWide, mHigh );
	copiedImage->paste( this );
	
	return copiedImage;
	}
	
		
#endif