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