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;
}