diff --git a/src/xrt/auxiliary/util/CMakeLists.txt b/src/xrt/auxiliary/util/CMakeLists.txt index 567c60985..d14665b40 100644 --- a/src/xrt/auxiliary/util/CMakeLists.txt +++ b/src/xrt/auxiliary/util/CMakeLists.txt @@ -117,6 +117,7 @@ target_link_libraries( aux_util PUBLIC xrt-external-nanopb + xrt-external-bcdec aux-includes aux_generated_bindings aux_os diff --git a/src/xrt/auxiliary/util/u_format.c b/src/xrt/auxiliary/util/u_format.c index 03b19c70b..4bb7f2272 100644 --- a/src/xrt/auxiliary/util/u_format.c +++ b/src/xrt/auxiliary/util/u_format.c @@ -29,6 +29,7 @@ u_format_str(enum xrt_format f) case XRT_FORMAT_YUYV422: return "XRT_FORMAT_YUYV422"; case XRT_FORMAT_UYVY422: return "XRT_FORMAT_UYVY422"; case XRT_FORMAT_MJPEG: return "XRT_FORMAT_MJPEG"; + case XRT_FORMAT_BC4: return "XRT_FORMAT_BC4"; default: assert(!"unsupported format"); return 0; } } @@ -49,6 +50,7 @@ u_format_is_blocks(enum xrt_format f) case XRT_FORMAT_YUV888: case XRT_FORMAT_YUYV422: case XRT_FORMAT_UYVY422: + case XRT_FORMAT_BC4: // Yes return true; case XRT_FORMAT_MJPEG: @@ -80,6 +82,9 @@ u_format_block_width(enum xrt_format f) case XRT_FORMAT_BITMAP_8X1: // Eight pixels per block. return 8; // NOLINT + case XRT_FORMAT_BC4: + // four pixels wide + return 4; default: assert(!"unsupported format"); return 0; } } @@ -104,6 +109,9 @@ u_format_block_height(enum xrt_format f) case XRT_FORMAT_BITMAP_8X8: // Eight pixels high. return 8; + case XRT_FORMAT_BC4: + // four pixels high + return 4; default: assert(!"unsupported format"); return 0; } } @@ -131,8 +139,8 @@ u_format_block_size(enum xrt_format f) case XRT_FORMAT_UYVY422: // Four bytes per two pixels. // 32bit pixel formats. return 4; - case XRT_FORMAT_BITMAP_8X8: // 64 bits. - return 8; + case XRT_FORMAT_BC4: // 64 bits. + case XRT_FORMAT_BITMAP_8X8: return 8; default: assert(!"unsupported format"); return 0; } } diff --git a/src/xrt/auxiliary/util/u_sink_converter.c b/src/xrt/auxiliary/util/u_sink_converter.c index a2fc6bc08..a3fbf48ce 100644 --- a/src/xrt/auxiliary/util/u_sink_converter.c +++ b/src/xrt/auxiliary/util/u_sink_converter.c @@ -22,6 +22,9 @@ #include "jpeglib.h" #endif +#define BCDEC_IMPLEMENTATION +#define BCDEC_BC4BC5_PRECISE +#include "bcdec.h" /* * @@ -390,6 +393,29 @@ from_MJPEG_to_YUV888(struct xrt_frame *dst_frame, size_t size, const uint8_t *da } #endif +/* + * + * BC4 + * + */ + +static void +from_BC4_to_L8(struct xrt_frame *dst_frame, uint32_t w, uint32_t h, size_t stride, const uint8_t *data) +{ + SINK_TRACE_MARKER(); + + assert(w % 4 == 0); + assert(h % 4 == 0); + + const uint8_t *src = data; + for (uint32_t y = 0; y < h; y += 4) { + for (uint32_t x = 0; x < w; x += 4) { + bcdec_bc4(src, dst_frame->data + (y * dst_frame->stride) + x, dst_frame->stride, false); + + src += BCDEC_BC4_BLOCK_SIZE; + } + } +} /* * @@ -485,6 +511,12 @@ convert_frame_l8(struct xrt_frame_sink *xs, struct xrt_frame *xf) struct xrt_frame *converted = NULL; switch (xf->format) { + case XRT_FORMAT_BC4: + if (!create_frame_with_format(xf, XRT_FORMAT_L8, &converted)) { + return; + } + from_BC4_to_L8(converted, xf->width, xf->height, xf->stride, xf->data); + break; case XRT_FORMAT_L8: s->downstream->push_frame(s->downstream, xf); return; case XRT_FORMAT_YUYV422: if (!create_frame_with_format(xf, XRT_FORMAT_L8, &converted)) { @@ -521,6 +553,12 @@ convert_frame_r8g8b8_or_l8(struct xrt_frame_sink *xs, struct xrt_frame *xf) } from_BAYER_GR8_to_R8G8B8(converted, w, h, xf->stride, xf->data); break; + case XRT_FORMAT_BC4: + if (!create_frame_with_format(xf, XRT_FORMAT_L8, &converted)) { + return; + } + from_BC4_to_L8(converted, xf->width, xf->height, xf->stride, xf->data); + break; case XRT_FORMAT_YUYV422: if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) { return; diff --git a/src/xrt/include/xrt/xrt_defines.h b/src/xrt/include/xrt/xrt_defines.h index d3dfad16e..b28ea4c77 100644 --- a/src/xrt/include/xrt/xrt_defines.h +++ b/src/xrt/include/xrt/xrt_defines.h @@ -192,6 +192,8 @@ enum xrt_format XRT_FORMAT_UYVY422, XRT_FORMAT_MJPEG, + + XRT_FORMAT_BC4, }; /*!