Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
Functions
OOPixMapChannelOperations.m File Reference
#include "OOPixMapChannelOperations.h"
import "OOCPUInfo.h"
+ Include dependency graph for OOPixMapChannelOperations.m:

Go to the source code of this file.

Functions

static void ExtractChannel_4 (OOPixMap *ioPixMap, uint8_t channelIndex)
 
static void ToRGBA_1 (OOPixMap srcPx, OOPixMap dstPx)
 
static void ToRGBA_2 (OOPixMap srcPx, OOPixMap dstPx)
 
static void ModulateUniform_4 (OOPixMap pixMap, uint16_t f0, uint16_t f1, uint16_t f2, uint16_t f3)
 
static void ModulatePixMap_4 (OOPixMap mainPx, OOPixMap otherPx)
 
static void AddPixMap_4 (OOPixMap mainPx, OOPixMap otherPx)
 
BOOL OOExtractPixMapChannel (OOPixMap *ioPixMap, uint8_t channelIndex, BOOL compactWhenDone)
 
BOOL OOPixMapToRGBA (OOPixMap *ioPixMap)
 
BOOL OOPixMapModulateUniform (OOPixMap *ioPixMap, float f0, float f1, float f2, float f3)
 
BOOL OOPixMapModulatePixMap (OOPixMap *ioDstPixMap, OOPixMap otherPixMap)
 
BOOL OOPixMapAddPixMap (OOPixMap *ioDstPixMap, OOPixMap otherPixMap)
 

Function Documentation

◆ AddPixMap_4()

static void AddPixMap_4 ( OOPixMap mainPx,
OOPixMap otherPx )
static

Definition at line 314 of file OOPixMapChannelOperations.m.

315{
316 uint32_t *dst, *other;
317 uint_fast32_t px;
318 uint_fast32_t m02, m13;
319 uint_fast32_t o02, o13;
320 uint_fast32_t xCount, y;
321
322 for (y = 0; y < mainPx.height; y++)
323 {
324 dst = (uint32_t *)((char *)mainPx.pixels + y * mainPx.rowBytes);
325 other = (uint32_t *)((char *)otherPx.pixels + y * otherPx.rowBytes);
326 xCount = mainPx.width;
327
328 do
329 {
330 px = *dst;
331 m02 = (px & 0xFF00FF00) >> 8;
332 m13 = px & 0x00FF00FF;
333
334 px = *other;
335 o02 = (px & 0xFF00FF00) >> 8;
336 o13 = px & 0x00FF00FF;
337
338 /* Saturated adds, two components at a time.
339 By masking out the overflow bits of each component,
340 multiplying them by 0xFF and shifting right one byte, we get a
341 mask that's oxFF for components that overflowed and 0x00 for
342 components that did not, without any conditionals.
343 */
344 m02 += o02;
345 m02 |= ((m02 & 0x01000100) * 0xFF) >> 8;
346 m13 += o13;
347 m13 |= ((m13 & 0x01000100) * 0xFF) >> 8;
348
349 *dst++ = ((m02 << 8) & 0xFF00FF00) | (m13 & 0x00FF00FF);
350 other++;
351 }
352 while (--xCount);
353 }
354}
float y
OOPixMapDimension height
Definition OOPixMap.h:50
size_t rowBytes
Definition OOPixMap.h:52
void * pixels
Definition OOPixMap.h:49
OOPixMapDimension width
Definition OOPixMap.h:50

References OOPixMap::height, OOPixMap::pixels, OOPixMap::rowBytes, OOPixMap::width, and y.

Referenced by OOPixMapAddPixMap().

+ Here is the caller graph for this function:

◆ ExtractChannel_4()

static void ExtractChannel_4 ( OOPixMap * ioPixMap,
uint8_t channelIndex )
static

Definition at line 61 of file OOPixMapChannelOperations.m.

62{
63 NSCParameterAssert(ioPixMap != NULL);
64
65 uint32_t *src;
66 uint8_t *dst;
67 uint_fast8_t shift;
68 uint_fast32_t xCount, y;
69
70 dst = ioPixMap->pixels;
71 shift = 8 * channelIndex;
72
73 for (y = 0; y < ioPixMap->height; y++)
74 {
75 src = (uint32_t *)((char *)ioPixMap->pixels + y * ioPixMap->rowBytes);
76 xCount = ioPixMap->width;
77
78 do
79 {
80 *dst++ = (*src++ >> shift) & 0xFF;
81 }
82 while (--xCount);
83 }
84}

References OOPixMap::height, OOPixMap::pixels, OOPixMap::rowBytes, OOPixMap::width, and y.

Referenced by OOExtractPixMapChannel().

+ Here is the caller graph for this function:

◆ ModulatePixMap_4()

static void ModulatePixMap_4 ( OOPixMap mainPx,
OOPixMap otherPx )
static

Definition at line 255 of file OOPixMapChannelOperations.m.

256{
257 uint32_t *dst, *other;
258 uint_fast32_t px;
259 uint_fast16_t m0, m1, m2, m3;
260 uint_fast16_t o0, o1, o2, o3;
261 uint_fast32_t xCount, y;
262
263 for (y = 0; y < mainPx.height; y++)
264 {
265 dst = (uint32_t *)((char *)mainPx.pixels + y * mainPx.rowBytes);
266 other = (uint32_t *)((char *)otherPx.pixels + y * otherPx.rowBytes);
267 xCount = mainPx.width;
268
269 do
270 {
271 px = *dst;
272 m0 = (px >> 24) & 0xFF;
273 m1 = (px >> 16) & 0xFF;
274 m2 = (px >> 8) & 0xFF;
275 m3 = px & 0xFF;
276
277 px = *other;
278 o0 = (px >> 24) & 0xFF;
279 o1 = (px >> 16) & 0xFF;
280 o2 = (px >> 8) & 0xFF;
281 o3 = px & 0xFF;
282
283 /* Unlike in ModulateUniform(), neither side here goes to 256, so
284 we have to divide by 255 rather than shifting. However, the
285 compiler should be able to optimize this to a multiplication
286 by a magic number.
287 */
288 m0 = (m0 * o0) / 255;
289 m1 = (m1 * o1) / 255;
290 m2 = (m2 * o2) / 255;
291 m3 = (m3 * o3) / 255;
292
293 *dst++ = ((uint_fast32_t)m0 << 24) | ((uint_fast32_t)m1 << 16) | (m2 << 8) | m3;
294 other++;
295 }
296 while (--xCount);
297 }
298}

References OOPixMap::height, OOPixMap::pixels, OOPixMap::rowBytes, OOPixMap::width, and y.

Referenced by OOPixMapModulatePixMap().

+ Here is the caller graph for this function:

◆ ModulateUniform_4()

static void ModulateUniform_4 ( OOPixMap pixMap,
uint16_t f0,
uint16_t f1,
uint16_t f2,
uint16_t f3 )
static

Definition at line 196 of file OOPixMapChannelOperations.m.

197{
198 NSCParameterAssert(OOPixMapBytesPerPixel(pixMap) == 4);
199
200 uint32_t *curr;
201 uint_fast32_t px;
202 uint_fast32_t p0, p1, p2, p3;
203 uint_fast32_t xCount, y;
204
205 for (y = 0; y < pixMap.height; y++)
206 {
207 curr = (uint32_t *)((char *)pixMap.pixels + y * pixMap.rowBytes);
208 xCount = pixMap.width;
209
210 do
211 {
212 px = *curr;
213
214 /* Principle of operation:
215 Each pixel component is in the range 0..0xFF.
216 Each constant factor component is in the range 0..0x100.
217 Multiplying them therefore gives us a result in the range
218 0x0000..0xFF00. The bottom byte is discarded by shifting
219 and masking.
220 */
221
222 p0 = px & 0xFF000000;
223 p0 = ((p0 >> 8) * f0) & 0xFF000000;
224
225 p1 = px & 0x00FF0000;
226 p1 = ((p1 * f1) >> 8) & 0x00FF0000;
227
228 p2 = px & 0x0000FF00;
229 p2 = ((p2 * f2) >> 8) & 0x0000FF00;
230
231 p3 = px & 0x000000FF;
232 p3 = ((p3 * f3) >> 8) & 0x000000FF;
233
234 px = p0 | p1 | p2 | p3;
235 *curr++ = px;
236 }
237 while (--xCount);
238 }
239}
OOINLINE unsigned short OOPixMapBytesPerPixel(OOPixMap pixMap)
Definition OOPixMap.h:132

References OOPixMap::height, OOPixMapBytesPerPixel(), OOPixMap::pixels, OOPixMap::rowBytes, OOPixMap::width, and y.

Referenced by OOPixMapModulateUniform().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ OOExtractPixMapChannel()

BOOL OOExtractPixMapChannel ( OOPixMap * ioPixMap,
uint8_t channelIndex,
BOOL compactWhenDone )

Definition at line 40 of file OOPixMapChannelOperations.m.

41{
42 if (EXPECT_NOT(ioPixMap == NULL || !OOIsValidPixMap(*ioPixMap) || ioPixMap->format != kOOPixMapRGBA || channelIndex > 3))
43 {
44 return NO;
45 }
46
47 ExtractChannel_4(ioPixMap, channelIndex);
48
49 ioPixMap->format = kOOPixMapGrayscale;
50 ioPixMap->rowBytes = ioPixMap->width;
51
52 if (compactWhenDone)
53 {
54 OOCompactPixMap(ioPixMap);
55 }
56
57 return YES;
58}
#define EXPECT_NOT(x)
static void ExtractChannel_4(OOPixMap *ioPixMap, uint8_t channelIndex)
@ kOOPixMapGrayscale
Definition OOPixMap.h:41
@ kOOPixMapRGBA
Definition OOPixMap.h:43
BOOL OOIsValidPixMap(OOPixMap pixMap)
Definition OOPixMap.m:42
OOINLINE void OOCompactPixMap(OOPixMap *ioPixMap)
Definition OOPixMap.h:103
OOPixMapFormat format
Definition OOPixMap.h:51

References EXPECT_NOT, ExtractChannel_4(), OOPixMap::format, kOOPixMapGrayscale, kOOPixMapRGBA, OOCompactPixMap(), OOIsValidPixMap(), OOPixMap::rowBytes, and OOPixMap::width.

+ Here is the call graph for this function:

◆ OOPixMapAddPixMap()

BOOL OOPixMapAddPixMap ( OOPixMap * ioDstPixMap,
OOPixMap otherPixMap )

Definition at line 301 of file OOPixMapChannelOperations.m.

302{
303 if (EXPECT_NOT(ioDstPixMap == NULL || !OOIsValidPixMap(*ioDstPixMap))) return NO;
304 if (EXPECT_NOT(!OOIsValidPixMap(otherPixMap) || otherPixMap.format != kOOPixMapRGBA)) return NO;
305 if (EXPECT_NOT(!OOPixMapToRGBA(ioDstPixMap))) return NO;
306 if (EXPECT_NOT(ioDstPixMap->width != otherPixMap.width || ioDstPixMap->height != otherPixMap.height)) return NO;
307
308 AddPixMap_4(*ioDstPixMap, otherPixMap);
309
310 return YES;
311}
static void AddPixMap_4(OOPixMap mainPx, OOPixMap otherPx)
BOOL OOPixMapToRGBA(OOPixMap *ioPixMap)

References AddPixMap_4(), EXPECT_NOT, OOPixMap::format, OOPixMap::height, kOOPixMapRGBA, OOIsValidPixMap(), OOPixMapToRGBA(), and OOPixMap::width.

+ Here is the call graph for this function:

◆ OOPixMapModulatePixMap()

BOOL OOPixMapModulatePixMap ( OOPixMap * ioDstPixMap,
OOPixMap otherPixMap )

Definition at line 242 of file OOPixMapChannelOperations.m.

243{
244 if (EXPECT_NOT(ioDstPixMap == NULL || !OOIsValidPixMap(*ioDstPixMap))) return NO;
245 if (EXPECT_NOT(!OOIsValidPixMap(otherPixMap) || otherPixMap.format != kOOPixMapRGBA)) return NO;
246 if (EXPECT_NOT(!OOPixMapToRGBA(ioDstPixMap))) return NO;
247 if (EXPECT_NOT(ioDstPixMap->width != otherPixMap.width || ioDstPixMap->height != otherPixMap.height)) return NO;
248
249 ModulatePixMap_4(*ioDstPixMap, otherPixMap);
250
251 return YES;
252}
static void ModulatePixMap_4(OOPixMap mainPx, OOPixMap otherPx)

References EXPECT_NOT, OOPixMap::format, OOPixMap::height, kOOPixMapRGBA, ModulatePixMap_4(), OOIsValidPixMap(), OOPixMapToRGBA(), and OOPixMap::width.

+ Here is the call graph for this function:

◆ OOPixMapModulateUniform()

BOOL OOPixMapModulateUniform ( OOPixMap * ioPixMap,
float f0,
float f1,
float f2,
float f3 )

Definition at line 185 of file OOPixMapChannelOperations.m.

186{
187 if (EXPECT_NOT(ioPixMap == NULL || !OOIsValidPixMap(*ioPixMap))) return NO;
188 if (EXPECT_NOT(!OOPixMapToRGBA(ioPixMap))) return NO;
189
190 ModulateUniform_4(*ioPixMap, f0 * 256.0f, f1 * 256.0f, f2 * 256.0f, f3 * 256.0f);
191
192 return YES;
193}
static void ModulateUniform_4(OOPixMap pixMap, uint16_t f0, uint16_t f1, uint16_t f2, uint16_t f3)

References EXPECT_NOT, ModulateUniform_4(), OOIsValidPixMap(), and OOPixMapToRGBA().

+ Here is the call graph for this function:

◆ OOPixMapToRGBA()

BOOL OOPixMapToRGBA ( OOPixMap * ioPixMap)

Definition at line 87 of file OOPixMapChannelOperations.m.

88{
89 if (EXPECT_NOT(ioPixMap == NULL || !OOIsValidPixMap(*ioPixMap))) return NO;
90 if (ioPixMap->format == kOOPixMapRGBA) return YES;
91
92 OOPixMap temp = OOAllocatePixMap(ioPixMap->width, ioPixMap->height, 4, 0, 0);
93 if (EXPECT_NOT(OOIsNullPixMap(temp))) return NO;
94
95 BOOL OK = NO;
96 switch (ioPixMap->format)
97 {
99 ToRGBA_1(*ioPixMap, temp);
100 OK = YES;
101 break;
102
104 ToRGBA_2(*ioPixMap, temp);
105 OK = YES;
106 break;
107
108 case kOOPixMapRGBA:
110 OK = NO;
111 break;
112 // No default, because -Wswitch-enum is our friend.
113 }
114
115 if (OK)
116 {
117 free(ioPixMap->pixels);
118 *ioPixMap = temp;
119 }
120 else
121 {
122 free(temp.pixels);
123 }
124
125 return OK;
126}
static void ToRGBA_2(OOPixMap srcPx, OOPixMap dstPx)
static void ToRGBA_1(OOPixMap srcPx, OOPixMap dstPx)
@ kOOPixMapInvalidFormat
Definition OOPixMap.h:40
@ kOOPixMapGrayscaleAlpha
Definition OOPixMap.h:42
OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize)
Definition OOPixMap.m:73
OOINLINE BOOL OOIsNullPixMap(OOPixMap pixMap)
Definition OOPixMap.h:60

References EXPECT_NOT, OOPixMap::format, OOPixMap::height, kOOPixMapGrayscale, kOOPixMapGrayscaleAlpha, kOOPixMapInvalidFormat, kOOPixMapRGBA, OOAllocatePixMap(), OOIsNullPixMap(), OOIsValidPixMap(), OOPixMap::pixels, ToRGBA_1(), ToRGBA_2(), and OOPixMap::width.

Referenced by OOPixMapAddPixMap(), OOPixMapModulatePixMap(), and OOPixMapModulateUniform().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ToRGBA_1()

static void ToRGBA_1 ( OOPixMap srcPx,
OOPixMap dstPx )
static

Definition at line 129 of file OOPixMapChannelOperations.m.

130{
131 NSCParameterAssert(OOPixMapBytesPerPixel(srcPx) == 1 && dstPx.format == kOOPixMapRGBA && srcPx.width == dstPx.width && srcPx.height == dstPx.height);
132
133 uint8_t *src;
134 uint32_t *dst;
135 uint_fast32_t xCount, y;
136
137 dst = dstPx.pixels;
138
139 for (y = 0; y < srcPx.height; y++)
140 {
141 src = (uint8_t *)((char *)srcPx.pixels + y * srcPx.rowBytes);
142 xCount = srcPx.width;
143
144 do
145 {
146 *dst++ = (*src++ * 0x00010101) | 0xFF000000;
147 }
148 while (--xCount);
149 }
150}

References OOPixMap::format, OOPixMap::height, kOOPixMapRGBA, OOPixMapBytesPerPixel(), OOPixMap::pixels, OOPixMap::rowBytes, OOPixMap::width, and y.

Referenced by OOPixMapToRGBA().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ToRGBA_2()

static void ToRGBA_2 ( OOPixMap srcPx,
OOPixMap dstPx )
static

Definition at line 153 of file OOPixMapChannelOperations.m.

154{
155 NSCParameterAssert(OOPixMapBytesPerPixel(srcPx) == 2 && dstPx.format == kOOPixMapRGBA && srcPx.width == dstPx.width && srcPx.height == dstPx.height);
156
157 uint16_t *src;
158 uint_fast32_t px;
159 uint32_t *dst;
160 uint_fast32_t xCount, y;
161
162 dst = dstPx.pixels;
163
164 for (y = 0; y < srcPx.height; y++)
165 {
166 src = (uint16_t *)((char *)srcPx.pixels + y * srcPx.rowBytes);
167 xCount = srcPx.width;
168
169 do
170 {
171 px = *src++;
172#if OOLITE_BIG_ENDIAN
173 *dst++ = (((px & 0xFF00) >> 8) * 0x00010101) | ((px & 0x00FF) << 24);
174#elif OOLITE_LITTLE_ENDIAN
175 *dst++ = ((px & 0x00FF) * 0x00010101) | ((px & 0xFF00) << 16);
176#else
177#error Unknown byte order.
178#endif
179 }
180 while (--xCount);
181 }
182}

References OOPixMap::format, OOPixMap::height, kOOPixMapRGBA, OOPixMapBytesPerPixel(), OOPixMap::pixels, OOPixMap::rowBytes, OOPixMap::width, and y.

Referenced by OOPixMapToRGBA().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: