CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
host_api_image.cpp
Go to the documentation of this file.
1
9
11#include "cdc_core/Raii.h"
12#include "cdc_image/Dither.h"
13#include "cdc_image/ImageDecoder.h"
14#include "cdc_log.h"
15
16#include <cstring>
17
18namespace {
19
20const char* TAG = "PLG_IMG";
21
22constexpr uint32_t MAX_PIXELS = 1048576; // decoder input cap (~1 MP)
23constexpr uint16_t MAX_TARGET_W = 1024;
24
25// Nearest-neighbour upscale for targets wider than the source (the cdc_image
26// box filter only downscales).
27void upscaleGrayNearest(const uint8_t* src, uint16_t sw, uint16_t sh,
28 uint8_t* dst, uint16_t dw, uint16_t dh) {
29 for (uint16_t y = 0; y < dh; y++) {
30 const uint8_t* srow = src + static_cast<size_t>(y) * sh / dh * sw;
31 uint8_t* drow = dst + static_cast<size_t>(y) * dw;
32 for (uint16_t x = 0; x < dw; x++) {
33 drow[x] = srow[static_cast<size_t>(x) * sw / dw];
34 }
35 }
36}
37
38} // namespace
39
40extern "C" {
41
42int host_image_info(const uint8_t* data, size_t len, uint16_t* out_w, uint16_t* out_h) {
43 if (!data || len == 0 || !out_w || !out_h) return HOST_ERR_INVALID_ARG;
44 uint16_t w = 0, h = 0;
45 const char* errorKey = nullptr;
46 auto gray = cdc::image::decodeToGray(data, len, MAX_PIXELS, w, h, errorKey);
47 if (!gray) {
48 LOG_W(TAG, "info decode failed: %s", errorKey ? errorKey : "?");
49 return HOST_ERR_GENERIC;
50 }
51 *out_w = w;
52 *out_h = h;
53 return HOST_OK;
54}
55
56int host_image_render(const uint8_t* data, size_t len, uint16_t target_w,
57 uint8_t* out, size_t out_size,
58 uint16_t* out_stride_bytes, uint16_t* out_height_px) {
59 if (!data || len == 0 || !out || !out_stride_bytes || !out_height_px) {
61 }
62 if (target_w == 0 || target_w > MAX_TARGET_W) return HOST_ERR_INVALID_ARG;
63
64 uint16_t w = 0, h = 0;
65 const char* errorKey = nullptr;
66 auto gray = cdc::image::decodeToGray(data, len, MAX_PIXELS, w, h, errorKey);
67 if (!gray) {
68 LOG_W(TAG, "render decode failed: %s", errorKey ? errorKey : "?");
69 return HOST_ERR_GENERIC;
70 }
71
72 uint32_t target_h32 = (static_cast<uint32_t>(h) * target_w + w / 2) / w;
73 if (target_h32 == 0) target_h32 = 1;
74 if (target_h32 > 4096) return HOST_ERR_INVALID_ARG; // absurd aspect ratio
75 const uint16_t target_h = static_cast<uint16_t>(target_h32);
76
77 const uint16_t stride = static_cast<uint16_t>((target_w + 7) / 8);
78 const size_t needed = static_cast<size_t>(stride) * target_h;
79 if (out_size < needed) return HOST_ERR_NO_MEMORY;
80
81 const uint8_t* grayForDither = gray.get();
83 if (target_w != w || target_h != h) {
84 scaled = cdc::core::psramAlloc<uint8_t>(static_cast<size_t>(target_w) * target_h);
85 if (!scaled) return HOST_ERR_NO_MEMORY;
86 if (target_w <= w && target_h <= h) {
87 cdc::image::downscaleGrayBox(gray.get(), w, h, scaled.get(), target_w, target_h);
88 } else {
89 upscaleGrayNearest(gray.get(), w, h, scaled.get(), target_w, target_h);
90 }
91 grayForDither = scaled.get();
92 }
93
94 auto scratch = cdc::core::psramAlloc<int16_t>(cdc::image::Ditherer::scratchCells(target_w));
95 if (!scratch) return HOST_ERR_NO_MEMORY;
96 std::memset(out, 0, needed);
97 cdc::image::ditherImage(grayForDither, target_w, target_h, out, scratch.get());
98
99 *out_stride_bytes = stride;
100 *out_height_px = target_h;
101 return HOST_OK;
102}
103
104} // extern "C"
static const char * TAG
Shared RAII wrappers for firmware resources.
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_W(tag, fmt,...)
Definition cdc_log.h:146
int host_image_info(const uint8_t *data, size_t len, uint16_t *out_w, uint16_t *out_h)
Decode only the image header to get its dimensions.
int host_image_render(const uint8_t *data, size_t len, uint16_t target_w, uint8_t *out, size_t out_size, uint16_t *out_stride_bytes, uint16_t *out_height_px)
Decode, scale to target_w (aspect preserved) and dither to 1-bpp.
CDC Badge OS plugin host API - canonical C ABI contract.
#define HOST_OK
Definition host_api.h:37
#define HOST_ERR_INVALID_ARG
Definition host_api.h:39
#define HOST_ERR_NO_MEMORY
Definition host_api.h:43
#define HOST_ERR_GENERIC
Definition host_api.h:38
std::unique_ptr< T[], CapsFreeDeleter > PsramUniquePtr
Definition Raii.h:44
PsramUniquePtr< T > psramAlloc(std::size_t count) noexcept
Allocate count elements of T in PSRAM (8-bit capable region).
Definition Raii.h:51