23 OF_ASSUME_NONNULL_BEGIN
26 _OFReadRGB888Pixel(
const uint8_t *pixels,
size_t x,
size_t y,
size_t width,
27 uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *alpha)
29 pixels += (x + y * width) * 3;
38 _OFReadBGR888Pixel(
const uint8_t *pixels,
size_t x,
size_t y,
size_t width,
39 uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *alpha)
41 pixels += (x + y * width) * 3;
50 _OFReadRGBA8888Pixel(
const uint32_t *pixels,
size_t x,
size_t y,
size_t width,
51 uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *alpha)
53 uint32_t value = pixels[x + y * width];
55 *red = (value & 0xFF000000) >> 24;
56 *green = (value & 0x00FF0000) >> 16;
57 *blue = (value & 0x0000FF00) >> 8;
58 *alpha = (value & 0x000000FF);
62 _OFReadARGB8888Pixel(
const uint32_t *pixels,
size_t x,
size_t y,
size_t width,
63 uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *alpha)
65 uint32_t value = pixels[x + y * width];
67 *red = (value & 0x00FF0000) >> 16;
68 *green = (value & 0x0000FF00) >> 8;
69 *blue = (value & 0x000000FF);
70 *alpha = (value & 0xFF000000) >> 24;
74 _OFReadABGR8888Pixel(
const uint32_t *pixels,
size_t x,
size_t y,
size_t width,
75 uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *alpha)
77 uint32_t value = pixels[x + y * width];
79 *red = (value & 0x000000FF);
80 *green = (value & 0x0000FF00) >> 8;
81 *blue = (value & 0x00FF0000) >> 16;
82 *alpha = (value & 0xFF000000) >> 24;
86 _OFReadBGRA8888Pixel(
const uint32_t *pixels,
size_t x,
size_t y,
size_t width,
87 uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *alpha)
89 uint32_t value = pixels[x + y * width];
91 *red = (value & 0x0000FF00) >> 8;
92 *green = (value & 0x00FF0000) >> 16;
93 *blue = (value & 0xFF000000) >> 24;
94 *alpha = (value & 0x000000FF);
98 _OFReadPixelInt8(
const void *pixels, OFPixelFormat format,
size_t x,
size_t y,
99 size_t width, uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *alpha)
102 case OFPixelFormatRGB888:
103 _OFReadRGB888Pixel(pixels, x, y, width, red, green, blue,
106 case OFPixelFormatBGR888:
107 _OFReadBGR888Pixel(pixels, x, y, width, red, green, blue,
110 case OFPixelFormatRGBA8888:
111 _OFReadRGBA8888Pixel(pixels, x, y, width, red, green, blue,
114 case OFPixelFormatARGB8888:
115 _OFReadARGB8888Pixel(pixels, x, y, width, red, green, blue,
118 case OFPixelFormatABGR8888:
119 _OFReadABGR8888Pixel(pixels, x, y, width, red, green, blue,
122 case OFPixelFormatBGRA8888:
123 _OFReadBGRA8888Pixel(pixels, x, y, width, red, green, blue,
131 static OF_INLINE
void 132 _OFReadRGB565Pixel(
const uint16_t *pixels,
size_t x,
size_t y,
size_t width,
133 float *red,
float *green,
float *blue,
float *alpha)
135 uint16_t value = pixels[x + y * width];
137 *red = ((value & 0xF800) >> 11) / 31.0f;
138 *green = ((value & 0x07E0) >> 5) / 63.0f;
139 *blue = (value & 0x001F) / 31.0f;
143 static OF_INLINE
void 144 _OFReadRGBA16161616FPPixel(
const OFFloat16 *pixels,
size_t x,
size_t y,
145 size_t width,
float *red,
float *green,
float *blue,
float *alpha)
147 *red = OFFloat16ToFloat(pixels[(x + y * width) * 4]);
148 *green = OFFloat16ToFloat(pixels[(x + y * width) * 4 + 1]);
149 *blue = OFFloat16ToFloat(pixels[(x + y * width) * 4 + 2]);
150 *alpha = OFFloat16ToFloat(pixels[(x + y * width) * 4 + 3]);
153 static OF_INLINE
void 154 _OFReadRGBA32323232FPPixel(
const float *pixels,
size_t x,
size_t y,
155 size_t width,
float *red,
float *green,
float *blue,
float *alpha)
157 *red = pixels[(x + y * width) * 4];
158 *green = pixels[(x + y * width) * 4 + 1];
159 *blue = pixels[(x + y * width) * 4 + 2];
160 *alpha = pixels[(x + y * width) * 4 + 3];
163 static OF_INLINE
bool 164 _OFReadPixel(
const void *pixels, OFPixelFormat format,
size_t x,
size_t y,
165 size_t width,
float *red,
float *green,
float *blue,
float *alpha)
167 uint8_t redInt8 = 0, greenInt8 = 0, blueInt8 = 0, alphaInt8 = 0;
170 case OFPixelFormatRGB565:
171 _OFReadRGB565Pixel(pixels, x, y, width, red, green, blue,
174 case OFPixelFormatRGBA16161616FP:
175 _OFReadRGBA16161616FPPixel(pixels, x, y, width, red, green,
178 case OFPixelFormatRGBA32323232FP:
179 _OFReadRGBA32323232FPPixel(pixels, x, y, width, red, green,
186 if OF_UNLIKELY (!_OFReadPixelInt8(pixels, format, x, y, width,
187 &redInt8, &greenInt8, &blueInt8, &alphaInt8))
190 *red = redInt8 / 255.0f;
191 *green = greenInt8 / 255.0f;
192 *blue = blueInt8 / 255.0f;
193 *alpha = alphaInt8 / 255.0f;
198 static OF_INLINE
bool 199 _OFReadAveragedPixel(
const void *pixels, OFPixelFormat format,
float x,
float y,
200 size_t width,
size_t clampX,
size_t clampY,
202 float *red,
float *green,
float *blue,
float *alpha)
204 size_t xInt = x, yInt = y, nextXInt = xInt + 1, nextYInt = yInt + 1;
208 if (x == xInt && y == yInt)
209 return _OFReadPixel(pixels, format, xInt, yInt, width,
210 red, green, blue, alpha);
212 if (nextXInt >= clampX || x == xInt)
214 if (nextYInt >= clampY || y == yInt)
217 if (!_OFReadPixel(pixels, format, xInt, yInt, width,
218 &vectors[0].x, &vectors[0].y, &vectors[0].z, &vectors[0].w))
221 if (!_OFReadPixel(pixels, format, nextXInt, yInt, width,
222 &vectors[1].x, &vectors[1].y, &vectors[1].z, &vectors[1].w))
225 if (!_OFReadPixel(pixels, format, xInt, nextYInt, width,
226 &vectors[2].x, &vectors[2].y, &vectors[2].z, &vectors[2].w))
229 if (!_OFReadPixel(pixels, format, nextXInt, nextYInt, width,
230 &vectors[3].x, &vectors[3].y, &vectors[3].z, &vectors[3].w))
233 scales[0] = (1.0f - (x - xInt)) * (1.0f - (y - yInt));
234 scales[1] = (x - xInt) * (1.0f - (y - yInt));
235 scales[2] = (1.0f - (x - xInt)) * (y - yInt);
236 scales[3] = (x - xInt) * (y - yInt);
242 for (uint_fast8_t i = 0; i < 4; i++)
257 static OF_INLINE
void 258 _OFWriteRGB888Pixel(uint8_t *pixels,
size_t x,
size_t y,
size_t width,
259 uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
261 pixels += (x + y * width) * 3;
268 static OF_INLINE
void 269 _OFWriteBGR888Pixel(uint8_t *pixels,
size_t x,
size_t y,
size_t width,
270 uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
272 pixels += (x + y * width) * 3;
279 static OF_INLINE
void 280 _OFWriteRGBA8888Pixel(uint32_t *pixels,
size_t x,
size_t y,
size_t width,
281 uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
283 pixels[x + y * width] = red << 24 | green << 16 | blue << 8 | alpha;
286 static OF_INLINE
void 287 _OFWriteARGB8888Pixel(uint32_t *pixels,
size_t x,
size_t y,
size_t width,
288 uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
290 pixels[x + y * width] = alpha << 24 | red << 16 | green << 8 | blue;
293 static OF_INLINE
void 294 _OFWriteABGR8888Pixel(uint32_t *pixels,
size_t x,
size_t y,
size_t width,
295 uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
297 pixels[x + y * width] = alpha << 24 | blue << 16 | green << 8 | red;
300 static OF_INLINE
void 301 _OFWriteBGRA8888Pixel(uint32_t *pixels,
size_t x,
size_t y,
size_t width,
302 uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
304 pixels[x + y * width] = blue << 24 | green << 16 | red << 8 | alpha;
307 static OF_INLINE
bool 308 _OFWritePixelInt8(
void *pixels, OFPixelFormat format,
size_t x,
size_t y,
309 size_t width, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
312 case OFPixelFormatRGB888:
313 _OFWriteRGB888Pixel(pixels, x, y, width, red, green, blue,
316 case OFPixelFormatRGBA8888:
317 _OFWriteRGBA8888Pixel(pixels, x, y, width, red, green, blue,
320 case OFPixelFormatARGB8888:
321 _OFWriteARGB8888Pixel(pixels, x, y, width, red, green, blue,
324 case OFPixelFormatBGR888:
325 _OFWriteBGR888Pixel(pixels, x, y, width, red, green, blue,
328 case OFPixelFormatABGR8888:
329 _OFWriteABGR8888Pixel(pixels, x, y, width, red, green, blue,
332 case OFPixelFormatBGRA8888:
333 _OFWriteBGRA8888Pixel(pixels, x, y, width, red, green, blue,
341 static OF_INLINE
void 342 _OFWriteRGB565Pixel(uint16_t *pixels,
size_t x,
size_t y,
size_t width,
343 float red,
float green,
float blue,
float alpha)
345 uint8_t redInt, greenInt, blueInt;
347 if OF_UNLIKELY (red > 1.0f)
349 else if OF_UNLIKELY (red < 0.0f)
351 if OF_UNLIKELY (green > 1.0f)
353 else if OF_UNLIKELY (green < 0.0f)
355 if OF_UNLIKELY (blue > 1.0f)
357 else if OF_UNLIKELY (blue < 0.0f)
359 if OF_UNLIKELY (alpha > 1.0f)
362 redInt = roundf(red * 31.0f);
363 greenInt = roundf(green * 63.0f);
364 blueInt = roundf(blue * 31.0f);
366 pixels[x + y * width] = redInt << 11 | greenInt << 5 | blueInt;
369 static OF_INLINE
void 370 _OFWriteRGBA16161616FPPixel(
OFFloat16 *pixels,
size_t x,
size_t y,
size_t width,
371 float red,
float green,
float blue,
float alpha)
373 pixels[(x + y * width) * 4] = OFFloat16FromFloat(red);
374 pixels[(x + y * width) * 4 + 1] = OFFloat16FromFloat(green);
375 pixels[(x + y * width) * 4 + 2] = OFFloat16FromFloat(blue);
376 pixels[(x + y * width) * 4 + 3] = OFFloat16FromFloat(alpha);
379 static OF_INLINE
void 380 _OFWriteRGBA32323232FPPixel(
float *pixels,
size_t x,
size_t y,
size_t width,
381 float red,
float green,
float blue,
float alpha)
383 pixels[(x + y * width) * 4] = red;
384 pixels[(x + y * width) * 4 + 1] = green;
385 pixels[(x + y * width) * 4 + 2] = blue;
386 pixels[(x + y * width) * 4 + 3] = alpha;
389 static OF_INLINE
bool 390 _OFWritePixel(
void *pixels, OFPixelFormat format,
size_t x,
size_t y,
391 size_t width,
float red,
float green,
float blue,
float alpha)
394 case OFPixelFormatRGB565:
395 _OFWriteRGB565Pixel(pixels, x, y, width, red, green, blue,
398 case OFPixelFormatRGBA16161616FP:
399 _OFWriteRGBA16161616FPPixel(pixels, x, y, width, red, green,
402 case OFPixelFormatRGBA32323232FP:
403 _OFWriteRGBA32323232FPPixel(pixels, x, y, width, red, green,
410 if OF_UNLIKELY (red > 1.0f)
412 else if OF_UNLIKELY (red < 0.0f)
414 if OF_UNLIKELY (green > 1.0f)
416 else if OF_UNLIKELY (green < 0.0f)
418 if OF_UNLIKELY (blue > 1.0f)
420 else if OF_UNLIKELY (blue < 0.0f)
422 if OF_UNLIKELY (alpha > 1.0f)
424 else if OF_UNLIKELY (alpha < 0.0f)
427 return _OFWritePixelInt8(pixels, format, x, y, width,
428 roundf(red * 255.0f), roundf(green * 255.0f), roundf(blue * 255.0f),
429 roundf(alpha * 255.0f));
434 - (instancetype)of_init OF_METHOD_FAMILY(
init);
437 OF_ASSUME_NONNULL_END
static OF_INLINE OFVector4D OFMultiplyVector4D(OFVector4D vector, float scalar)
Multiplies the specified vector with a scalar.
Definition: OFObject.h:640
static OF_INLINE OFVector4D OFAddVectors4D(OFVector4D vector1, OFVector4D vector2)
Adds the two specified vectors.
Definition: OFObject.h:612
static OF_INLINE OFVector4D OF_CONST_FUNC OFMakeVector4D(float x, float y, float z, float w)
Creates a new OFVector4D.
Definition: OFObject.h:572
instancetype init()
Initializes an already allocated object.
Definition: OFObject.m:671
__extension__ typedef _Float16 OFFloat16
A type for 16 bit floating point numbers.
Definition: macros.h:961
void(* OFColorSpaceTransferFunction)(OFVector4D *vectors, size_t count)
A transfer function for a color space.
Definition: OFColorSpace.h:42
A vector in 4D space.
Definition: OFObject.h:551
A class representing an image.
Definition: OFImage.h:115