The RgbImage C++ class provides the following functionalities:

The class members are described below; it should be straightforward to use them. For examples of programs that use RgbImage, see the TextureBmpModern and FourTexturesModern programs.

I. Constructors and destructor

There are three constructors and one destructor:

	RgbImage();
	RgbImage(const char* filename);
	RgbImage(int numRows, int numCols);	// Allocate a bitmap (uninitialized) of this size.
	~RgbImage();

RgbImage() sets up a null texture map. RgbImage(const char* filename); reads a texture map from the file. The file must be a 24-bit RGB bitmap file. RgbImage(int numRows, int numCols) allocates space for a texture map of the indicated size: its contents are uninitialized. However, use of this third constructor is not recommended (see the discussion below).

II. Reading, writing, allocating, deallocating

	bool LoadBmpFile( const char *filename );	    // Loads the bitmap from the specified file
	bool WriteBmpFile( const char* filename );	    // Write the bitmap to the specified file

	bool LoadFromOpenglBuffer();				    // Load the bitmap from the current OpenGL buffer

    bool AllocateImageData(int numRows, int numCols);  // Allocate a bitmap (uninitialized) of this size.   
	void Reset();									// Frees image data memory

These routines return true if they succeed, but false otherwise; errors can be obtained with GetError().

These routines (and all the routines documented below) are RgbImage member functions; that is, they need to be used with in conjunction with an RgbImage. For example, a file could be loaded by either

    RgbImage texMap("myTexture.bmp");

or

    RgbImage texMap;
    texMap.LoadBmpFile("myTexture.bmp");

The routines LoadBmpFile() and WriteBmpFile read from and write a 24 RGB bitmap file. There is no need to preallocate space for the texture map: the LoadBmpFile always reallocates the image data buffer in the correct size for the texture map contained in the bitmap file.

LoadFromOpenglBuffer reads the RGB image data from the current (front, center) OpenGL frame buffer. This is a great way to save a rendered image to a texture map. If there is no current allocation of memory to hold the texture map, LoadFromOpenglBuffer automatically allocates just enough space to hold the framebuffer contents. If the current row and column dimensions of the texture map allocation do not match the size of the frame buffer, LoadFromOpenglBuffer just loads what will fit.

If you want to use RgbImage without using OpenGL, you should add #define RGBIMAGE_DONT_USE_OPENGL to the header file: this disables the compilation of LoadFromOpenglBuffer.

Reset() deallocates any space used for holding a texture map data.

Use AllocateImageData to allocate space for a texture map of the indicated size. You probably should never call this routine; instead let LoadBmpFile() or LoadFromOpenglBuffer do the allocation for you. AllocateImageData does not deallocate any existing data; to avoid memory leaks, you may need to call Reset() before calling AllocateImageData.

III. Using an RgbImage as an OpenGL texture map

The function ImageData gives you a pointer to the texture map in a format suitable for specifying an OpenGL texture. The function prototype is:

	const void* ImageData() const { return (void*)ImagePtr; }

The RgbImage data is stored with pixels (texels) in row order, one byte per pixel, with row starting on word-aligned positions. As shown in the programs TextureBmpModern and FourTexturesModern, the RgbImage can be loaded into an OpenGL texture map with:

    int textureWidth = texMap.GetNumCols();
    int textureHeight = texMap.GetNumRows();
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureWidth, 0, GL_RGB, GL_UNSIGNED_BYTE, texMap.ImageData());

For more information, see the documentation for TextureBmpModern and FourTexturesModern.

IV. Querying the status of the loaded texture map

The following routines let you query the status of the image data in the texture map:

	long GetNumRows() const { return NumRows; }     // Returns the width of the texture map
	long GetNumCols() const { return NumCols; }     // Returns the height of the texture map
	// Rows are word aligned
	long GetNumBytesPerRow() const { return ((3*NumCols+3)>>2)<<2; }	
	bool ImageLoaded() const { return (ImagePtr!=0); }  // Is an image loaded?

V. Accessing individual pixel (texels) in the texture map

The following routines let you access the image data in the texture map. The texture map pixels (texels) are stored as R,G,B values; each RGB value is an integer between 0 and 255, namely an unsigned char. They can also be set or retrieved as floating point numbers.

	const unsigned char* GetRgbPixel( long row, long col ) const;
	unsigned char* GetRgbPixel( long row, long col );
	void GetRgbPixel( long row, long col, float* red, float* green, float* blue ) const;
	void GetRgbPixel( long row, long col, double* red, double* green, double* blue ) const;

	void SetRgbPixelf( long row, long col, double red, double green, double blue );
	void SetRgbPixelc( long row, long col, 
					   unsigned char red, unsigned char green, unsigned char blue );

VI. Error checking

If an error is encountered, a message is written to stderr. The error codes can also be queried by GetError(). The possible error codes are listed below.

	int GetErrorCode() const { return ErrorCode; }
	enum {
		NoError = 0,
		OpenError = 1,			// Unable to open file for reading
		FileFormatError = 2,	// Not recognized as a 24 bit BMP file
		MemoryError = 3,		// Unable to allocate memory for image data
		ReadError = 4,			// End of file reached prematurely
		WriteError = 5			// Unable to write out data (or no data to write out)
	};