PageRenderTime 43ms CodeModel.GetById 20ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/FreeImage/Conversion4.cpp

https://bitbucket.org/cabalistic/ogredeps/
C++ | 246 lines | 165 code | 46 blank | 35 comment | 45 complexity | fbcde04e0d0c46d153d69054f536edc3 MD5 | raw file
  1// ==========================================================
  2// Bitmap conversion routines
  3//
  4// Design and implementation by
  5// - Riley McNiff (rmcniff@marexgroup.com)
  6//
  7// This file is part of FreeImage 3
  8//
  9// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
 10// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
 11// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
 12// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
 13// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
 14// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
 15// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
 16// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
 17// THIS DISCLAIMER.
 18//
 19// Use at your own risk!
 20// ==========================================================
 21
 22#include "FreeImage.h"
 23#include "Utilities.h"
 24
 25// ----------------------------------------------------------
 26//  internal conversions X to 4 bits
 27// ----------------------------------------------------------
 28
 29void DLL_CALLCONV
 30FreeImage_ConvertLine1To4(BYTE *target, BYTE *source, int width_in_pixels) {
 31	BOOL hinibble = TRUE;
 32	for (int cols = 0; cols < width_in_pixels; cols++){
 33		if (hinibble == TRUE){
 34			target[cols >> 1] = ((source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 15 : 0) << 4;
 35		} 
 36		else {
 37			target[cols >> 1] |= ((source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 15 : 0);
 38		}
 39
 40		hinibble = !hinibble;
 41	}
 42}
 43
 44void DLL_CALLCONV
 45FreeImage_ConvertLine8To4(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
 46	BOOL hinibble = TRUE;
 47	BYTE index;
 48
 49	for (int cols = 0; cols < width_in_pixels; cols++){
 50		index = GREY(palette[source[cols]].rgbRed, palette[source[cols]].rgbGreen, palette[source[cols]].rgbBlue);
 51		if (hinibble) {
 52			target[cols >> 1] = (index & 0xF0);
 53		} else {
 54			target[cols >> 1] |= (index >> 4);
 55		}
 56
 57		hinibble = !hinibble;
 58	}
 59}
 60
 61void DLL_CALLCONV
 62FreeImage_ConvertLine16To4_555(BYTE *target, BYTE *source, int width_in_pixels) {
 63	WORD *bits = (WORD *)source;
 64	BOOL hinibble = TRUE;
 65
 66	for (int cols = 0; cols < width_in_pixels; cols++) {
 67		if (hinibble) {
 68			target[cols >> 1] = GREY((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F,
 69								(((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
 70								(((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F)
 71								& 0xF0;
 72		} else {
 73			target[cols >> 1] |= GREY((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F,
 74								(((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
 75								(((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F)
 76								>> 4;
 77		}
 78		
 79		hinibble = !hinibble;
 80	}
 81}
 82
 83void DLL_CALLCONV
 84FreeImage_ConvertLine16To4_565(BYTE *target, BYTE *source, int width_in_pixels) {
 85	WORD *bits = (WORD *)source;
 86	BOOL hinibble = TRUE;
 87
 88	for (int cols = 0; cols < width_in_pixels; cols++) {
 89		if (hinibble) {
 90			target[cols >> 1] = GREY((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F,
 91				        (((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
 92						(((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F)
 93						& 0xF0;
 94		} else {
 95			target[cols >> 1] |= GREY((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F,
 96				        (((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
 97						(((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F)
 98						>> 4;
 99		}
100
101		hinibble = !hinibble;
102	}
103}
104
105void DLL_CALLCONV
106FreeImage_ConvertLine24To4(BYTE *target, BYTE *source, int width_in_pixels) {
107	BOOL hinibble = TRUE;
108
109	for (int cols = 0; cols < width_in_pixels; cols++) {
110		if (hinibble) {
111			target[cols >> 1] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]) & 0xF0;
112		} else {
113			target[cols >> 1] |= GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]) >> 4;
114		}
115
116		source += 3;
117		hinibble = !hinibble;
118	}
119}
120
121void DLL_CALLCONV
122FreeImage_ConvertLine32To4(BYTE *target, BYTE *source, int width_in_pixels) {
123	BOOL hinibble = TRUE;
124
125	for (int cols = 0; cols < width_in_pixels; cols++) {
126		if (hinibble) {
127			target[cols >> 1] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]) & 0xF0;
128		} else {
129			target[cols >> 1] |= GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]) >> 4;
130		}
131
132		source += 4;
133		hinibble = !hinibble;
134	}
135}
136
137// ----------------------------------------------------------
138//   smart convert X to 4 bits
139// ----------------------------------------------------------
140
141FIBITMAP * DLL_CALLCONV
142FreeImage_ConvertTo4Bits(FIBITMAP *dib) {
143	if(!FreeImage_HasPixels(dib)) return NULL;
144
145	const int bpp = FreeImage_GetBPP(dib);
146
147	if(bpp != 4) {
148		const int width  = FreeImage_GetWidth(dib);
149		const int height = FreeImage_GetHeight(dib);
150		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 4);
151
152		if(new_dib == NULL) {
153			return NULL;
154		}
155
156		// copy metadata from src to dst
157		FreeImage_CloneMetadata(new_dib, dib);
158
159		// Build a greyscale palette (*always* needed for image processing)
160
161		RGBQUAD *new_pal = FreeImage_GetPalette(new_dib);
162
163		for(int i = 0; i < 16; i++) {
164			new_pal[i].rgbRed	= (BYTE)((i << 4) + i);
165			new_pal[i].rgbGreen = (BYTE)((i << 4) + i);
166			new_pal[i].rgbBlue	= (BYTE)((i << 4) + i);
167		}
168
169		switch(bpp) {
170			case 1:
171			{
172				if(FreeImage_GetColorType(dib) == FIC_PALETTE) {
173
174					// Copy the palette
175
176					RGBQUAD *old_pal = FreeImage_GetPalette(dib);
177					memcpy(&new_pal[0], &old_pal[0], sizeof(RGBQUAD));
178					memcpy(&new_pal[15], &old_pal[1], sizeof(RGBQUAD));
179
180				}
181				else if(FreeImage_GetColorType(dib) == FIC_MINISWHITE) {
182					
183					// Reverse the grayscale palette
184
185					for(int i = 0; i < 16; i++) {
186						new_pal[i].rgbRed = new_pal[i].rgbGreen = new_pal[i].rgbBlue = (BYTE)(255 - ((i << 4) + i));
187					}
188				}
189
190				// Expand and copy the bitmap data
191
192				for (int rows = 0; rows < height; rows++) {
193					FreeImage_ConvertLine1To4(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
194				}
195				return new_dib;
196			}
197
198			case 8 :
199			{
200				// Expand and copy the bitmap data
201
202				for (int rows = 0; rows < height; rows++) {
203					FreeImage_ConvertLine8To4(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
204				}
205				return new_dib;
206			}
207
208			case 16 :
209			{
210				// Expand and copy the bitmap data
211
212				for (int rows = 0; rows < height; rows++) {
213					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
214						FreeImage_ConvertLine16To4_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
215					} else {
216						FreeImage_ConvertLine16To4_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
217					}
218				}
219				
220				return new_dib;
221			}
222
223			case 24 :
224			{
225				// Expand and copy the bitmap data
226
227				for (int rows = 0; rows < height; rows++) {
228					FreeImage_ConvertLine24To4(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);					
229				}
230				return new_dib;
231			}
232
233			case 32 :
234			{
235				// Expand and copy the bitmap data
236
237				for (int rows = 0; rows < height; rows++) {
238					FreeImage_ConvertLine32To4(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
239				}
240				return new_dib;
241			}
242		}
243	}
244
245	return FreeImage_Clone(dib);
246}