PageRenderTime 29ms CodeModel.GetById 11ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/FreeImage/PixelAccess.cpp

https://bitbucket.org/cabalistic/ogredeps/
C++ | 209 lines | 157 code | 27 blank | 25 comment | 37 complexity | 94d0869683255a20de1c6dd025c57259 MD5 | raw file
  1// ==========================================================
  2// Pixel access 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// - Riley McNiff (rmcniff@marexgroup.com)
  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
 30BYTE * DLL_CALLCONV
 31FreeImage_GetBits(FIBITMAP *dib) {
 32	if(!FreeImage_HasPixels(dib)) {
 33		return NULL;
 34	}
 35	// returns the pixels aligned on a FIBITMAP_ALIGNMENT bytes alignment boundary
 36	size_t lp = (size_t)FreeImage_GetInfoHeader(dib);
 37	lp += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * FreeImage_GetColorsUsed(dib);
 38	lp += (lp % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - lp % FIBITMAP_ALIGNMENT : 0);
 39	return (BYTE *)lp;
 40}
 41
 42BYTE * DLL_CALLCONV
 43FreeImage_GetScanLine(FIBITMAP *dib, int scanline) {
 44	if(!FreeImage_HasPixels(dib)) {
 45		return NULL;
 46	}
 47	return CalculateScanLine(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), scanline);
 48}
 49
 50BOOL DLL_CALLCONV
 51FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
 52	BYTE shift;
 53
 54	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
 55		return FALSE;
 56
 57	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
 58		BYTE *bits = FreeImage_GetScanLine(dib, y);
 59
 60		switch(FreeImage_GetBPP(dib)) {
 61			case 1:
 62				*value = (bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
 63				break;
 64			case 4:
 65				shift = (BYTE)((1 - x % 2) << 2);
 66				*value = (bits[x >> 1] & (0x0F << shift)) >> shift;
 67				break;
 68			case 8:
 69				*value = bits[x];
 70				break;
 71			default:
 72				return FALSE;
 73		}
 74
 75		return TRUE;
 76	}
 77
 78	return FALSE;
 79}
 80
 81BOOL DLL_CALLCONV
 82FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
 83	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
 84		return FALSE;
 85
 86	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
 87		BYTE *bits = FreeImage_GetScanLine(dib, y);
 88
 89		switch(FreeImage_GetBPP(dib)) {
 90			case 16:
 91			{
 92				bits += 2*x;
 93				WORD *pixel = (WORD *)bits;
 94				if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
 95					value->rgbBlue		= (BYTE)((((*pixel & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
 96					value->rgbGreen		= (BYTE)((((*pixel & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
 97					value->rgbRed		= (BYTE)((((*pixel & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
 98					value->rgbReserved	= 0;
 99				} else {
100					value->rgbBlue		= (BYTE)((((*pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
101					value->rgbGreen		= (BYTE)((((*pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
102					value->rgbRed		= (BYTE)((((*pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
103					value->rgbReserved	= 0;
104				}
105				break;
106			}
107			case 24:
108				bits += 3*x;
109				value->rgbBlue		= bits[FI_RGBA_BLUE];	// B
110				value->rgbGreen		= bits[FI_RGBA_GREEN];	// G
111				value->rgbRed		= bits[FI_RGBA_RED];	// R
112				value->rgbReserved	= 0;
113				break;
114			case 32:
115				bits += 4*x;
116				value->rgbBlue		= bits[FI_RGBA_BLUE];	// B
117				value->rgbGreen		= bits[FI_RGBA_GREEN];	// G
118				value->rgbRed		= bits[FI_RGBA_RED];	// R
119				value->rgbReserved	= bits[FI_RGBA_ALPHA];	// A
120				break;
121			default:
122				return FALSE;
123		}
124
125		return TRUE;
126	}
127
128	return FALSE;
129}
130
131BOOL DLL_CALLCONV
132FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
133	BYTE shift;
134
135	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
136		return FALSE;
137
138	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
139		BYTE *bits = FreeImage_GetScanLine(dib, y);
140
141		switch(FreeImage_GetBPP(dib)) {
142			case 1:
143				*value ? bits[x >> 3] |= (0x80 >> (x & 0x7)) : bits[x >> 3] &= (0xFF7F >> (x & 0x7));
144				break;
145			case 4:
146				shift = (BYTE)((1 - x % 2) << 2);
147				bits[x >> 1] &= ~(0x0F << shift);
148				bits[x >> 1] |= ((*value & 0x0F) << shift);
149				break;
150			case 8:
151				bits[x] = *value;
152				break;
153			default:
154				return FALSE;
155		}
156
157		return TRUE;
158	}
159
160	return FALSE;
161}
162
163BOOL DLL_CALLCONV
164FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
165	if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
166		return FALSE;
167
168	if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
169		BYTE *bits = FreeImage_GetScanLine(dib, y);
170
171		switch(FreeImage_GetBPP(dib)) {
172			case 16:
173			{
174				bits += 2*x;
175				WORD *pixel = (WORD *)bits;
176				if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
177					*pixel = ((value->rgbBlue >> 3) << FI16_565_BLUE_SHIFT) |
178						((value->rgbGreen >> 2) << FI16_565_GREEN_SHIFT) |
179						((value->rgbRed >> 3) << FI16_565_RED_SHIFT);
180				} else {
181					*pixel = ((value->rgbBlue >> 3) << FI16_555_BLUE_SHIFT) |
182						((value->rgbGreen >> 3) << FI16_555_GREEN_SHIFT) |
183						((value->rgbRed >> 3) << FI16_555_RED_SHIFT);
184				}
185				break;
186			}
187			case 24:
188				bits += 3*x;
189				bits[FI_RGBA_BLUE]	= value->rgbBlue;	// B
190				bits[FI_RGBA_GREEN] = value->rgbGreen;	// G
191				bits[FI_RGBA_RED]	= value->rgbRed;	// R
192				break;
193			case 32:
194				bits += 4*x;
195				bits[FI_RGBA_BLUE]	= value->rgbBlue;		// B
196				bits[FI_RGBA_GREEN] = value->rgbGreen;		// G
197				bits[FI_RGBA_RED]	= value->rgbRed;		// R
198				bits[FI_RGBA_ALPHA] = value->rgbReserved;	// A
199				break;
200			default:
201				return FALSE;
202		}
203
204		return TRUE;
205	}
206
207	return FALSE;
208}
209