PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 16ms RepoModel.GetById 3ms app.codeStats 0ms

/src/FreeImage/Source/Utilities.h

https://bitbucket.org/cabalistic/ogredeps/
C++ Header | 484 lines | 253 code | 75 blank | 156 comment | 27 complexity | d6aead212ee89668d950811ff104a310 MD5 | raw file
  1// ==========================================================
  2// Utility functions
  3//
  4// Design and implementation by
  5// - Floris van den Berg (flvdberg@wxs.nl)
  6// - Hervé Drolon <drolon@infonie.fr>
  7// - Ryan Rubley (ryan@lostreality.org)
  8//
  9// This file is part of FreeImage 3
 10//
 11// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
 12// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
 13// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
 14// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
 15// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
 16// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
 17// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
 18// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
 19// THIS DISCLAIMER.
 20//
 21// Use at your own risk!
 22// ==========================================================
 23
 24#ifndef UTILITIES_H
 25#define UTILITIES_H
 26
 27// ==========================================================
 28//   Standard includes used by the library
 29// ==========================================================
 30
 31#include <math.h>
 32#include <stdlib.h> 
 33#include <memory.h>
 34#include <stdio.h>
 35#include <string.h>
 36#include <stdarg.h>
 37#include <ctype.h>
 38#include <assert.h>
 39#include <errno.h>
 40#include <float.h>
 41#include <limits.h>
 42
 43#include <string>
 44#include <list>
 45#include <map>
 46#include <set>
 47#include <vector>
 48#include <stack>
 49#include <sstream>
 50#include <algorithm>
 51#include <limits>
 52#include <memory>
 53
 54// ==========================================================
 55//   Bitmap palette and pixels alignment
 56// ==========================================================
 57
 58#define FIBITMAP_ALIGNMENT	16	// We will use a 16 bytes alignment boundary
 59
 60// Memory allocation on a specified alignment boundary
 61// defined in BitmapAccess.cpp
 62
 63void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment);
 64void FreeImage_Aligned_Free(void* mem);
 65
 66#if defined(__cplusplus)
 67extern "C" {
 68#endif
 69
 70/**
 71Allocate a FIBITMAP with possibly no pixel data 
 72(i.e. only header data and some or all metadata)
 73@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
 74@param type Image type
 75@param width
 76@param height
 77@param bpp
 78@param red_mask
 79@param green_mask
 80@param blue_mask
 81@see FreeImage_AllocateT
 82*/
 83DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
 84
 85/**
 86Allocate a FIBITMAP of type FIT_BITMAP, with possibly no pixel data 
 87(i.e. only header data and some or all metadata)
 88@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
 89@param width
 90@param height
 91@param bpp
 92@param red_mask
 93@param green_mask
 94@param blue_mask
 95@see FreeImage_Allocate
 96*/
 97DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
 98
 99#if defined(__cplusplus)
100}
101#endif
102
103
104// ==========================================================
105//   File I/O structs
106// ==========================================================
107
108// these structs are for file I/O and should not be confused with similar
109// structs in FreeImage.h which are for in-memory bitmap handling
110
111#ifdef _WIN32
112#pragma pack(push, 1)
113#else
114#pragma pack(1)
115#endif // _WIN32
116
117typedef struct tagFILE_RGBA {
118  unsigned char r,g,b,a;
119} FILE_RGBA;
120
121typedef struct tagFILE_BGRA {
122  unsigned char b,g,r,a;
123} FILE_BGRA;
124
125typedef struct tagFILE_RGB {
126  unsigned char r,g,b;
127} FILE_RGB;
128
129typedef struct tagFILE_BGR {
130  unsigned char b,g,r;
131} FILE_BGR;
132
133#ifdef _WIN32
134#pragma pack(pop)
135#else
136#pragma pack()
137#endif // _WIN32
138
139// ==========================================================
140//   Template utility functions
141// ==========================================================
142
143/// Max function
144template <class T> T MAX(const T &a, const T &b) {
145	return (a > b) ? a: b;
146}
147
148/// Min function
149template <class T> T MIN(const T &a, const T &b) {
150	return (a < b) ? a: b;
151}
152
153/// INPLACESWAP adopted from codeguru.com 
154template <class T> void INPLACESWAP(T& a, T& b) {
155	a ^= b; b ^= a; a ^= b;
156}
157
158/// Clamp function
159template <class T> T CLAMP(const T &value, const T &min_value, const T &max_value) {
160	return ((value < min_value) ? min_value : (value > max_value) ? max_value : value);
161}
162
163/** This procedure computes minimum min and maximum max
164 of n numbers using only (3n/2) - 2 comparisons.
165 min = L[i1] and max = L[i2].
166 ref: Aho A.V., Hopcroft J.E., Ullman J.D., 
167 The design and analysis of computer algorithms, 
168 Addison-Wesley, Reading, 1974.
169*/
170template <class T> void 
171MAXMIN(const T* L, long n, T& max, T& min) {
172	long i1, i2, i, j;
173	T x1, x2;
174	long k1, k2;
175
176	i1 = 0; i2 = 0; min = L[0]; max = L[0]; j = 0;
177	if((n % 2) != 0)  j = 1;
178	for(i = j; i < n; i+= 2) {
179		k1 = i; k2 = i+1;
180		x1 = L[k1]; x2 = L[k2];
181		if(x1 > x2)	{
182			k1 = k2;  k2 = i;
183			x1 = x2;  x2 = L[k2];
184		}
185		if(x1 < min) {
186			min = x1;  i1 = k1;
187		}
188		if(x2 > max) {
189			max = x2;  i2 = k2;
190		}
191	}
192}
193
194// ==========================================================
195//   Utility functions
196// ==========================================================
197
198#ifndef _WIN32
199inline char*
200i2a(unsigned i, char *a, unsigned r) {
201	if (i/r > 0) a = i2a(i/r,a,r);
202	*a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
203	return a+1;
204}
205
206/** 
207 Transforms integer i into an ascii string and stores the result in a; 
208 string is encoded in the base indicated by r.
209 @param i Number to be converted
210 @param a String result
211 @param r Base of value; must be in the range 2 - 36
212 @return Returns a
213*/
214inline char *
215_itoa(int i, char *a, int r) {
216	r = ((r < 2) || (r > 36)) ? 10 : r;
217	if(i < 0) {
218		*a = '-';
219		*i2a(-i, a+1, r) = 0;
220	}
221	else *i2a(i, a, r) = 0;
222	return a;
223}
224
225#endif // !_WIN32
226
227inline unsigned char
228HINIBBLE (unsigned char byte) {
229	return byte & 0xF0;
230}
231
232inline unsigned char
233LOWNIBBLE (unsigned char byte) {
234	return byte & 0x0F;
235}
236
237inline int
238CalculateUsedBits(int bits) {
239	int bit_count = 0;
240	unsigned bit = 1;
241
242	for (unsigned i = 0; i < 32; i++) {
243		if ((bits & bit) == bit) {
244			bit_count++;
245		}
246
247		bit <<= 1;
248	}
249
250	return bit_count;
251}
252
253inline unsigned
254CalculateLine(unsigned width, unsigned bitdepth) {
255	return (unsigned)( ((unsigned long long)width * bitdepth + 7) / 8 );
256}
257
258inline unsigned
259CalculatePitch(unsigned line) {
260	return line + 3 & ~3;
261}
262
263inline unsigned
264CalculateUsedPaletteEntries(unsigned bit_count) {
265	if ((bit_count >= 1) && (bit_count <= 8))
266		return 1 << bit_count;
267
268	return 0;
269}
270
271inline unsigned char *
272CalculateScanLine(unsigned char *bits, unsigned pitch, int scanline) {
273	return (bits + (pitch * scanline));
274}
275
276// ----------------------------------------------------------
277
278/**
279Fast generic assign (faster than for loop)
280@param dst Destination pixel
281@param src Source pixel
282@param bytesperpixel # of bytes per pixel
283*/
284inline void 
285AssignPixel(BYTE* dst, const BYTE* src, unsigned bytesperpixel) {
286	switch (bytesperpixel) {
287		case 1:	// FIT_BITMAP (8-bit)
288			*dst = *src;
289			break;
290
291		case 2: // FIT_UINT16 / FIT_INT16 / 16-bit
292			*(reinterpret_cast<WORD*>(dst)) = *(reinterpret_cast<const WORD*> (src));
293			break;
294
295		case 3: // FIT_BITMAP (24-bit)
296			*(reinterpret_cast<WORD*>(dst)) = *(reinterpret_cast<const WORD*> (src));
297			dst[2] = src[2];
298			break;
299
300		case 4: // FIT_BITMAP (32-bit) / FIT_UINT32 / FIT_INT32 / FIT_FLOAT
301			*(reinterpret_cast<DWORD*>(dst)) = *(reinterpret_cast<const DWORD*> (src));
302			break;
303
304		case 6: // FIT_RGB16 (3 x 16-bit)
305			*(reinterpret_cast<DWORD*>(dst)) = *(reinterpret_cast<const DWORD*> (src));
306			*(reinterpret_cast<WORD*>(dst + 4)) = *(reinterpret_cast<const WORD*> (src + 4));	
307			break;
308
309		// the rest can be speeded up with int64
310			
311		case 8: // FIT_RGBA16 (4 x 16-bit)
312			*(reinterpret_cast<DWORD*>(dst)) = *(reinterpret_cast<const DWORD*> (src));
313			*(reinterpret_cast<DWORD*>(dst + 4)) = *(reinterpret_cast<const DWORD*> (src + 4));	
314			break;
315		
316		case 12: // FIT_RGBF (3 x 32-bit IEEE floating point)
317			*(reinterpret_cast<float*>(dst)) = *(reinterpret_cast<const float*> (src));
318			*(reinterpret_cast<float*>(dst + 4)) = *(reinterpret_cast<const float*> (src + 4));
319			*(reinterpret_cast<float*>(dst + 8)) = *(reinterpret_cast<const float*> (src + 8));
320			break;
321		
322		case 16: // FIT_RGBAF (4 x 32-bit IEEE floating point)
323			*(reinterpret_cast<float*>(dst)) = *(reinterpret_cast<const float*> (src));
324			*(reinterpret_cast<float*>(dst + 4)) = *(reinterpret_cast<const float*> (src + 4));
325			*(reinterpret_cast<float*>(dst + 8)) = *(reinterpret_cast<const float*> (src + 8));
326			*(reinterpret_cast<float*>(dst + 12)) = *(reinterpret_cast<const float*> (src + 12));
327			break;
328			
329		default:
330			assert(FALSE);
331	}
332}
333
334/**
335Swap red and blue channels in a 24- or 32-bit dib. 
336@return Returns TRUE if successful, returns FALSE otherwise
337@see See definition in Conversion.cpp
338*/
339BOOL SwapRedBlue32(FIBITMAP* dib);
340
341/**
342Inplace convert CMYK to RGBA.(8- and 16-bit). 
343Alpha is filled with the first extra channel if any or white otherwise.
344@return Returns TRUE if successful, returns FALSE otherwise
345@see See definition in Conversion.cpp
346*/
347BOOL ConvertCMYKtoRGBA(FIBITMAP* dib);
348
349/**
350Inplace convert CIELab to RGBA (8- and 16-bit).
351@return Returns TRUE if successful, returns FALSE otherwise
352@see See definition in Conversion.cpp
353*/
354BOOL ConvertLABtoRGB(FIBITMAP* dib);
355
356/**
357RGBA to RGB conversion
358@see See definition in Conversion.cpp
359*/
360FIBITMAP* RemoveAlphaChannel(FIBITMAP* dib);
361
362
363// ==========================================================
364//   Big Endian / Little Endian utility functions
365// ==========================================================
366
367inline WORD 
368__SwapUInt16(WORD arg) { 
369#if defined(_MSC_VER) && _MSC_VER >= 1310 
370	return _byteswap_ushort(arg); 
371#elif defined(__i386__) && defined(__GNUC__) 
372	__asm__("xchgb %b0, %h0" : "+q" (arg)); 
373	return arg; 
374#elif defined(__ppc__) && defined(__GNUC__) 
375	WORD result; 
376	__asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&arg), "m" (arg)); 
377	return result; 
378#else 
379	// swap bytes 
380	WORD result;
381	result = ((arg << 8) & 0xFF00) | ((arg >> 8) & 0x00FF); 
382	return result; 
383#endif 
384} 
385 
386inline DWORD 
387__SwapUInt32(DWORD arg) { 
388#if defined(_MSC_VER) && _MSC_VER >= 1310 
389	return _byteswap_ulong(arg); 
390#elif defined(__i386__) && defined(__GNUC__) 
391	__asm__("bswap %0" : "+r" (arg)); 
392	return arg; 
393#elif defined(__ppc__) && defined(__GNUC__) 
394	DWORD result; 
395	__asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&arg), "m" (arg)); 
396	return result; 
397#else 
398	// swap words then bytes
399	DWORD result; 
400	result = ((arg & 0x000000FF) << 24) | ((arg & 0x0000FF00) << 8) | ((arg >> 8) & 0x0000FF00) | ((arg >> 24) & 0x000000FF); 
401	return result; 
402#endif 
403} 
404 
405/**
406for later use ...
407inline uint64_t 
408SwapInt64(uint64_t arg) { 
409#if defined(_MSC_VER) && _MSC_VER >= 1310 
410	return _byteswap_uint64(arg); 
411#else 
412	union Swap { 
413		uint64_t sv; 
414		uint32_t ul[2]; 
415	} tmp, result; 
416	tmp.sv = arg; 
417	result.ul[0] = SwapInt32(tmp.ul[1]);  
418	result.ul[1] = SwapInt32(tmp.ul[0]); 
419	return result.sv; 
420#endif 
421} 
422*/
423
424inline void
425SwapShort(WORD *sp) {
426	*sp = __SwapUInt16(*sp);
427}
428
429inline void
430SwapLong(DWORD *lp) {
431	*lp = __SwapUInt32(*lp);
432}
433
434// ==========================================================
435//   Greyscale and color conversion
436// ==========================================================
437
438/**
439Extract the luminance channel L from a RGBF image. 
440Luminance is calculated from the sRGB model using a D65 white point, using the Rec.709 formula : 
441L = ( 0.2126 * r ) + ( 0.7152 * g ) + ( 0.0722 * b )
442Reference : 
443A Standard Default Color Space for the Internet - sRGB. 
444[online] http://www.w3.org/Graphics/Color/sRGB
445*/
446#define LUMA_REC709(r, g, b)	(0.2126F * r + 0.7152F * g + 0.0722F * b)
447
448#define GREY(r, g, b) (BYTE)LUMA_REC709(r, g, b)
449/*
450#define GREY(r, g, b) (BYTE)(((WORD)r * 77 + (WORD)g * 150 + (WORD)b * 29) >> 8)	// .299R + .587G + .114B
451*/
452/*
453#define GREY(r, g, b) (BYTE)(((WORD)r * 169 + (WORD)g * 256 + (WORD)b * 87) >> 9)	// .33R + 0.5G + .17B
454*/
455
456#define RGB565(b, g, r) ((((b) >> 3) << FI16_565_BLUE_SHIFT) | (((g) >> 2) << FI16_565_GREEN_SHIFT) | (((r) >> 3) << FI16_565_RED_SHIFT))
457#define RGB555(b, g, r) ((((b) >> 3) << FI16_555_BLUE_SHIFT) | (((g) >> 3) << FI16_555_GREEN_SHIFT) | (((r) >> 3) << FI16_555_RED_SHIFT))
458
459#define FORMAT_RGB565(dib) ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) &&(FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) &&(FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK))
460#define RGBQUAD_TO_WORD(dib, color) (FORMAT_RGB565(dib) ? RGB565((color)->rgbBlue, (color)->rgbGreen, (color)->rgbRed) : RGB555((color)->rgbBlue, (color)->rgbGreen, (color)->rgbRed))
461
462#define CREATE_GREYSCALE_PALETTE(palette, entries) \
463	for (unsigned i = 0, v = 0; i < entries; i++, v += 0x00FFFFFF / (entries - 1)) { \
464		((unsigned *)palette)[i] = v; \
465	}
466
467#define CREATE_GREYSCALE_PALETTE_REVERSE(palette, entries) \
468	for (unsigned i = 0, v = 0x00FFFFFF; i < entries; i++, v -= (0x00FFFFFF / (entries - 1))) { \
469		((unsigned *)palette)[i] = v; \
470	}
471
472// ==========================================================
473//   Generic error messages
474// ==========================================================
475
476static const char *FI_MSG_ERROR_MEMORY = "Memory allocation failed";
477static const char *FI_MSG_ERROR_DIB_MEMORY = "DIB allocation failed, maybe caused by an invalid image size or by a lack of memory";
478static const char *FI_MSG_ERROR_PARSING = "Parsing error";
479static const char *FI_MSG_ERROR_MAGIC_NUMBER = "Invalid magic number";
480static const char *FI_MSG_ERROR_UNSUPPORTED_FORMAT = "Unsupported format";
481static const char *FI_MSG_ERROR_UNSUPPORTED_COMPRESSION = "Unsupported compression type";
482static const char *FI_MSG_WARNING_INVALID_THUMBNAIL = "Warning: attached thumbnail cannot be written to output file (invalid format) - Thumbnail saving aborted";
483
484#endif // UTILITIES_H