PageRenderTime 238ms CodeModel.GetById 209ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 1ms

/src/FreeImage/Source/FreeImage/Conversion24.cpp

https://bitbucket.org/cabalistic/ogredeps/
C++ | 214 lines | 149 code | 34 blank | 31 comment | 32 complexity | a53123239b8b2ef9528584f4f3aafe28 MD5 | raw file
  1// ==========================================================
  2// Bitmap conversion routines
  3//
  4// Design and implementation by
  5// - Floris van den Berg (flvdberg@wxs.nl)
  6// - Dale Larson (dlarson@norsesoft.com)
  7// - Hervé Drolon (drolon@infonie.fr)
  8// - Jani Kajala (janik@remedy.fi)
  9//
 10// This file is part of FreeImage 3
 11//
 12// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
 13// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
 14// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
 15// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
 16// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
 17// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
 18// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
 19// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
 20// THIS DISCLAIMER.
 21//
 22// Use at your own risk!
 23// ==========================================================
 24
 25#include "FreeImage.h"
 26#include "Utilities.h"
 27
 28// ----------------------------------------------------------
 29//  internal conversions X to 24 bits
 30// ----------------------------------------------------------
 31
 32void DLL_CALLCONV
 33FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
 34	for (int cols = 0; cols < width_in_pixels; cols++) {
 35		BYTE index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
 36
 37		target[FI_RGBA_BLUE] = palette[index].rgbBlue;
 38		target[FI_RGBA_GREEN] = palette[index].rgbGreen;
 39		target[FI_RGBA_RED] = palette[index].rgbRed;
 40
 41		target += 3;
 42	}
 43}
 44
 45void DLL_CALLCONV
 46FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
 47	BOOL low_nibble = FALSE;
 48	int x = 0;
 49
 50	for (int cols = 0; cols < width_in_pixels; ++cols ) {
 51		if (low_nibble) {
 52			target[FI_RGBA_BLUE] = palette[LOWNIBBLE(source[x])].rgbBlue;
 53			target[FI_RGBA_GREEN] = palette[LOWNIBBLE(source[x])].rgbGreen;
 54			target[FI_RGBA_RED] = palette[LOWNIBBLE(source[x])].rgbRed;
 55
 56			x++;
 57		} else {
 58			target[FI_RGBA_BLUE] = palette[HINIBBLE(source[x]) >> 4].rgbBlue;
 59			target[FI_RGBA_GREEN] = palette[HINIBBLE(source[x]) >> 4].rgbGreen;
 60			target[FI_RGBA_RED] = palette[HINIBBLE(source[x]) >> 4].rgbRed;
 61		}
 62
 63		low_nibble = !low_nibble;
 64
 65		target += 3;
 66	}
 67}
 68
 69void DLL_CALLCONV
 70FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
 71	for (int cols = 0; cols < width_in_pixels; cols++) {
 72		target[FI_RGBA_BLUE] = palette[source[cols]].rgbBlue;
 73		target[FI_RGBA_GREEN] = palette[source[cols]].rgbGreen;
 74		target[FI_RGBA_RED] = palette[source[cols]].rgbRed;
 75
 76		target += 3;
 77	}
 78}
 79
 80void DLL_CALLCONV
 81FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels) {
 82	WORD *bits = (WORD *)source;
 83
 84	for (int cols = 0; cols < width_in_pixels; cols++) {
 85		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
 86		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
 87		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
 88
 89		target += 3;
 90	}
 91}
 92
 93void DLL_CALLCONV
 94FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels) {
 95	WORD *bits = (WORD *)source;
 96
 97	for (int cols = 0; cols < width_in_pixels; cols++) {
 98		target[FI_RGBA_RED]   = (BYTE)((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
 99		target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
100		target[FI_RGBA_BLUE]  = (BYTE)((((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
101
102		target += 3;
103	}
104}
105
106void DLL_CALLCONV
107FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels) {
108	for (int cols = 0; cols < width_in_pixels; cols++) {
109		target[FI_RGBA_BLUE] = source[FI_RGBA_BLUE];
110		target[FI_RGBA_GREEN] = source[FI_RGBA_GREEN];
111		target[FI_RGBA_RED] = source[FI_RGBA_RED];
112
113		target += 3;
114		source += 4;
115	}
116}
117
118// ----------------------------------------------------------
119//   smart convert X to 24 bits
120// ----------------------------------------------------------
121
122FIBITMAP * DLL_CALLCONV
123FreeImage_ConvertTo24Bits(FIBITMAP *dib) {
124	if(!FreeImage_HasPixels(dib)) return NULL;
125
126	const unsigned bpp = FreeImage_GetBPP(dib);
127
128	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
129	if((image_type != FIT_BITMAP) && (image_type != FIT_RGB16)) {
130		return NULL;
131	}
132
133	if (bpp != 24) {
134		const int width = FreeImage_GetWidth(dib);
135		const int height = FreeImage_GetHeight(dib);
136		FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
137
138		if(new_dib == NULL) {
139			return NULL;
140		}
141
142		// copy metadata from src to dst
143		FreeImage_CloneMetadata(new_dib, dib);
144
145		switch(bpp) {
146			case 1 :
147			{
148				for (int rows = 0; rows < height; rows++) {
149					FreeImage_ConvertLine1To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));					
150				}
151				return new_dib;
152			}
153
154			case 4 :
155			{
156				for (int rows = 0; rows < height; rows++) {
157					FreeImage_ConvertLine4To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
158				}
159				return new_dib;
160			}
161				
162			case 8 :
163			{
164				for (int rows = 0; rows < height; rows++) {
165					FreeImage_ConvertLine8To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
166				}
167				return new_dib;
168			}
169
170			case 16 :
171			{
172				for (int rows = 0; rows < height; rows++) {
173					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
174						FreeImage_ConvertLine16To24_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
175					} else {
176						// includes case where all the masks are 0
177						FreeImage_ConvertLine16To24_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
178					}
179				}
180				return new_dib;
181			}
182
183			case 32 :
184			{
185				for (int rows = 0; rows < height; rows++) {
186					FreeImage_ConvertLine32To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
187				}
188				return new_dib;
189			}
190
191			case 48:
192			{
193				const unsigned src_pitch = FreeImage_GetPitch(dib);
194				const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
195				const BYTE *src_bits = FreeImage_GetBits(dib);
196				BYTE *dst_bits = FreeImage_GetBits(new_dib);
197				for (int rows = 0; rows < height; rows++) {
198					const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
199					RGBTRIPLE *dst_pixel = (RGBTRIPLE*)dst_bits;
200					for(int cols = 0; cols < width; cols++) {
201						dst_pixel[cols].rgbtRed   = (BYTE)(src_pixel[cols].red   >> 8);
202						dst_pixel[cols].rgbtGreen = (BYTE)(src_pixel[cols].green >> 8);
203						dst_pixel[cols].rgbtBlue  = (BYTE)(src_pixel[cols].blue  >> 8);
204					}
205					src_bits += src_pitch;
206					dst_bits += dst_pitch;
207				}
208				return new_dib;
209			}
210		}
211	}
212
213	return FreeImage_Clone(dib);
214}