ext/decoders/native/rgb.c in mikunyan-3.9.6 vs ext/decoders/native/rgb.c in mikunyan-3.9.7

- old
+ new

@@ -1,26 +1,102 @@ +#include "rgb.h" +#include <math.h> #include <stdint.h> +#include "color.h" +#include "fp16.h" -static inline int is_system_little() { - int x = 1; - return *(char*)&x == 1; +int decode_a8(const uint8_t *const data, const long size, uint8_t *image) { + const uint8_t *d = data, *d_end = data + size; + for (int i = 0; d < d_end; d++) { + image[i++] = *d; + image[i++] = *d; + image[i++] = *d; + } + return 1; } -void decode_rgb565(const uint16_t* data, const int size, const int is_big_endian, uint8_t* image) { - const uint16_t *d = data; - if (is_big_endian == is_system_little()) { - uint8_t *p = image; - for (int i = 0; i < size; i++, d++, p += 4) { - uint_fast8_t r = *d & 0x00f8; - uint_fast8_t g = (*d & 0x0007) << 5 | (*d & 0xe000) >> 11; - uint_fast8_t b = (*d & 0x1f00) >> 5; - p[0] = r | r >> 5; - p[1] = g | g >> 6; - p[2] = b | b >> 5; - p[3] = 255; +int decode_r8(const uint8_t *const data, const long size, uint8_t *image) { + const uint8_t *d = data, *d_end = data + size; + for (int i = 0; d < d_end; d++) { + image[i++] = *d; + image[i++] = 0; + image[i++] = 0; + } + return 1; +} + +int decode_r16(const uint8_t *const data, const long size, const int endian_big, uint8_t *image) { + const uint8_t *d = endian_big ? data : data + 1; + const uint8_t *d_end = data + size * 2; + for (int i = 0; d < d_end; d += 2) { + image[i++] = *d; + image[i++] = 0; + image[i++] = 0; + } + return 1; +} + +int decode_rgb565(const uint16_t *const data, const long size, const int endian_big, uint8_t *image) { + const uint16_t *d = data, *d_end = data + size; + if (endian_big) + for (; d < d_end; d++, image += 3) + rgb565_bep(*d, image); + else + for (; d < d_end; d++, image += 3) + rgb565_lep(*d, image); + return 1; +} + +static inline uint8_t u16_f16_u8(const uint16_t val) { + float f = fp16_ieee_to_fp32_value(val); + if (!isfinite(f) || f < 0) + return 0; + else if (f > 1) + return 255; + else + return roundf(f * 255); +} + +int decode_rhalf(const uint16_t *data, const long size, const int endian_big, uint8_t *image) { + if (endian_big) { + for (long i = 0; i < size; i++, data++) { + *image++ = u16_f16_u8(bton16(*data)); + *image++ = 0; + *image++ = 0; } } else { - uint32_t *p = (uint32_t*)image; - for (int i = 0; i < size; i++, d++, p++) - *p = (*d & 0xf800) >> 8 | *d >> 13 | (*d & 0x7e0) << 5 | (*d & 0x60) << 3 | *d << 19 | (*d & 0x1c) << 14 | 0xff000000; + for (long i = 0; i < size; i++, data++) { + *image++ = u16_f16_u8(lton16(*data)); + *image++ = 0; + *image++ = 0; + } } + return 1; +} + +int decode_rghalf(const uint16_t *data, const long size, const int endian_big, uint8_t *image) { + if (endian_big) { + for (long i = 0; i < size; i++, data++, image++) { + *image++ = u16_f16_u8(bton16(*data++)); + *image++ = u16_f16_u8(bton16(*data++)); + *image++ = 0; + } + } else { + for (long i = 0; i < size; i++, data++) { + *image++ = u16_f16_u8(lton16(*data++)); + *image++ = u16_f16_u8(lton16(*data++)); + *image++ = 0; + } + } + return 1; +} + +int decode_rgbahalf(const uint16_t *data, const long size, const int endian_big, uint8_t *image) { + long lsize = size * 4; + if (endian_big) + for (long i = 0; i < lsize; i++, data++, image++) + *image = u16_f16_u8(bton16(*data)); + else + for (long i = 0; i < lsize; i++, data++, image++) + *image = u16_f16_u8(lton16(*data)); + return 1; }