27void upscaleGrayNearest(
const uint8_t* src, uint16_t sw, uint16_t sh,
42int host_image_info(
const uint8_t* data,
size_t len, uint16_t* out_w, uint16_t* out_h) {
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);
48 LOG_W(
TAG,
"info decode failed: %s", errorKey ? errorKey :
"?");
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) {
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);
68 LOG_W(
TAG,
"render decode failed: %s", errorKey ? errorKey :
"?");
72 uint32_t target_h32 = (
static_cast<uint32_t
>(h) * target_w + w / 2) / w;
73 if (target_h32 == 0) target_h32 = 1;
75 const uint16_t target_h =
static_cast<uint16_t
>(target_h32);
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;
81 const uint8_t* grayForDither = gray.get();
83 if (target_w != w || target_h != h) {
86 if (target_w <= w && target_h <= h) {
87 cdc::image::downscaleGrayBox(gray.get(), w, h, scaled.get(), target_w, target_h);
89 upscaleGrayNearest(gray.get(), w, h, scaled.get(), target_w, target_h);
91 grayForDither = scaled.get();
96 std::memset(out, 0, needed);
97 cdc::image::ditherImage(grayForDither, target_w, target_h, out, scratch.get());
99 *out_stride_bytes = stride;
100 *out_height_px = target_h;
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.