summaryrefslogtreecommitdiff
path: root/tests/glean/image.h
blob: 3c6d62c69f4e9ded2cda54b9471e3bb20192691e (plain)
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// BEGIN_COPYRIGHT
// 
// Copyright (C) 1999  Allen Akin   All Rights Reserved.
// 
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the
// Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
// KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ALLEN AKIN BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// 
// END_COPYRIGHT




// image.h:  image data and attributes, image I/O

// This class encapsulates OpenGL information related to images (size,
// format, etc.) and provides utilities for transferring images to and
// from files.


#ifndef __image_h__
#define __image_h__

#include <string>
#include "glwrap.h"
#include "stats.h"

namespace GLEAN {

class Image {

    private:

	GLsizei _width;
	GLsizei _height;
	GLenum _format;
	GLenum _type;
	char* _pixels;
	GLsizei _alignment;
	GLsizei _rowSizeInBytes;
	GLsizei _pixelSizeInBytes;

	enum {				// validation bits, for lazy validation
		vbRowSizeInBytes = 1,
		vbPixelSizeInBytes = 2,
		vbPacker = 4,
		vbUnpacker = 8,
		vbAll = ~0
	};
	int _invalid;
	inline bool invalid(int bit) const { return _invalid & bit; }
	inline bool valid(int bit) const { return !invalid(bit); }
	inline void invalidate(int bits) { _invalid |= bits; }
	inline void validate(int bits) { _invalid &= ~bits; }

	GLsizei validateRowSizeInBytes();
	GLsizei validatePixelSizeInBytes();

	typedef void Unpacker(GLsizei n, double* rgba, char* nextPixel);
	Unpacker* _unpacker;
	Unpacker* validateUnpacker();
	typedef void Packer(GLsizei n, char* nextPixel, double* rgba);
	Packer* _packer;
	Packer* validatePacker();

	// For now, we will require that:
	// 1.  All images are in native byte order (so that byte swapping
	//     at the OpenGL level is unnecessary).
	// 2.  The image width and height above describe the entire image
	//     (so that there is no need to specify row length
	//     independently).
	// 3.  We have no need to specify subimages at this level (so
	//     there is no need for SKIP_ROWS and SKIP_PIXELS attributes).

	// Should construction fix the format and type for all time?
	// That would eliminate synchronization problems between data and
	// descriptive information that might arise when an Image is reused,
	// and might permit use of template functions instead of lots of
	// switches.  Probably not; it would make dynamic type assignment
	// quite awkward.

    public:

	// Exceptions:

	struct Error { };		// Base class for all image errors.
	struct BadFormat: public Error {	// Bad image format.
		GLenum format;
		BadFormat(GLenum f) {format = f;}
	};
	struct BadType: public Error {		// Bad image type.
		GLenum type;
		BadType(GLenum t) {type = t;}
	};
	struct CantOpen: public Error {		// Can't open file.
		const char* filename;
		CantOpen(const char* p) {filename = p;}
	};
	struct RefImageTooLarge: public Error {	// Can't register ref image.
	};

	// Constructors/Destructor:

	Image();
	Image(int aWidth, int aHeight, GLenum aFormat, GLenum aType);
	Image(int aWidth, int aHeight, GLenum aFormat, GLenum aType,
		double r, double g, double b, double a);
	Image(Image& i);
	Image& operator= (Image& i);
	~Image();

	// Reserve space for the pixel array:

	void reserve();

	// Get/Set attributes.  These attributes are useful for calls
	// to glDrawPixels, glTexImage2D, etc.  Note the alignment
	// value; passing it to glPixelStore is essential before using
	// one of the other OpenGL commands.

	inline GLsizei width() const	// Image width, in pixels
		{ return _width; }
	inline void width(GLsizei w)
		{ _width = w; invalidate(vbRowSizeInBytes); }

	inline GLsizei height() const	// Image height, in pixels.
		{ return _height; }
	inline void height(GLsizei h)
		{ _height = h; }

	inline GLenum format() const	// Image format.  Currently
		{ return _format; }	// these formats are supported:
					// GL_LUMINANCE,
					// GL_LUMINANCE_ALPHA,
					// GL_RGB, GL_RGBA.
					// It may be easiest to treat
					// stencil, depth, etc. images
					// as luminance images.
	inline void format(GLenum f) {
		_format = f;
		invalidate(
			  vbRowSizeInBytes
			| vbPixelSizeInBytes
			| vbPacker
			| vbUnpacker);
	}

	inline GLenum type() const	// Pixel data type.  Currently
		{ return _type; }	// these types are supported:
					// GL_BYTE, GL_UNSIGNED_BYTE,
					// GL_SHORT, GL_UNSIGNED_SHORT,
					// GL_INT, GL_UNSIGNED_INT, GL_FLOAT.
	inline void type(GLenum t) {
		_type = t;
		invalidate(
			  vbRowSizeInBytes
			| vbPixelSizeInBytes
			| vbPacker
			| vbUnpacker);
	}

	inline char* pixels() 		// The pixels.
		{ return _pixels; }
	inline const char* pixels() const
		{ return const_cast<const char*>(_pixels); }
	void pixels(char* p);

	inline GLsizei alignment() const	// Alignment.  See glPixelStore.
		{ return _alignment; }
	inline void alignment(GLsizei a)
		{ _alignment = a; invalidate(vbRowSizeInBytes); }

	inline GLsizei rowSizeInBytes() {	// Size of scanline, in bytes
		return valid(vbRowSizeInBytes)?
			_rowSizeInBytes: validateRowSizeInBytes();
	}

	inline GLsizei pixelSizeInBytes() {	// Size of pixel, in bytes
		return valid(vbPixelSizeInBytes)?
			_pixelSizeInBytes: validatePixelSizeInBytes();
	}

	// XXX Utilities to determine component size in bits/bytes?
	// XXX Component range (min neg, max neg, min pos, max pos, eps?)

	// Pixel packing/unpacking utilities:

	void unpack(GLsizei n, double* rgba, char* nextPixel);
	void pack(GLsizei n, char* nextPixel, double* rgba);
	// XXX get(x, y, double* rgba);
	// XXX put(x, y, double* rgba);

	// Image registration.  The utility compares a reference image
	// to the current image (which must be at least as large as the
	// reference image in both dimensions), determines the offset at
	// which the reference image minus the current image has minimum
	// mean absolute error (summed over R, G, B, and A), and returns
	// an object specifying the offset and corresponding statistics.

	struct Registration {
	    	int wOffset;		// offset in width (x)
		int hOffset;		// offset in height (y)
		BasicStats stats[4];	// stats for absolute error in
					// R, G, B, and A
	};
	Registration reg(Image& img);

        // test if images are identical
        bool operator==(const Image &ref) const;

	// GL operation utilities:

	void draw();				// Invoke glDrawPixels.
	void read(GLint x, GLint y);		// Invoke glReadPixels.
	void makeMipmaps(GLenum intFormat);	// Load texture mipmaps.

}; // class Image

} // namespace GLEAN

#endif // __image_h__