/* * libptouch — raster right blank trim * * Author: knb * Email: knb@artif.org */ #include "libptouch_internal.h" #include #include libptouch_err_t libptouch_trim_right_blank_columns( libptouch_ctx *ctx, const uint8_t *data, size_t data_len, const libptouch_raster_params_t *in_params, uint16_t right_padding_dots, uint8_t **out_raster, size_t *out_raster_bytes, libptouch_raster_params_t *out_params) { if (!ctx || !data || !in_params || !out_raster || !out_raster_bytes || !out_params) { if (ctx) ptouch_set_error(ctx, LIBPTOUCH_ERR_ARG, "null argument"); return LIBPTOUCH_ERR_ARG; } libptouch_err_t v = libptouch_check_raster(ctx, data, data_len, in_params); if (v != LIBPTOUCH_OK) return v; uint32_t width = in_params->width_dots; uint32_t height = in_params->height_dots; size_t row_bytes = ((size_t)width + 7u) / 8u; int32_t rightmost = -1; for (uint32_t y = 0; y < height; y++) { const uint8_t *row = data + (size_t)y * row_bytes; for (int32_t x = (int32_t)width - 1; x >= 0; x--) { uint8_t b = row[(size_t)x / 8u]; uint8_t bit = (uint8_t)(7u - ((uint32_t)x % 8u)); if (((b >> bit) & 1u) == 0) continue; if (x > rightmost) rightmost = x; break; } } uint32_t new_width = width; if (rightmost >= 0) { uint32_t trimmed = (uint32_t)(rightmost + 1); uint32_t padded = trimmed + (uint32_t)right_padding_dots; if (padded > width) padded = width; if (padded < width) new_width = padded; } size_t new_row_bytes = ((size_t)new_width + 7u) / 8u; size_t total = new_row_bytes * (size_t)height; uint8_t *out = (uint8_t *)calloc(1u, total); if (!out) { ptouch_set_error(ctx, LIBPTOUCH_ERR_NOMEM, "calloc raster failed"); return LIBPTOUCH_ERR_NOMEM; } uint8_t last_mask = 0xFFu; if ((new_width % 8u) != 0u) last_mask = (uint8_t)((0xFFu << (8u - (new_width % 8u))) & 0xFFu); for (uint32_t y = 0; y < height; y++) { const uint8_t *src = data + (size_t)y * row_bytes; uint8_t *dst = out + (size_t)y * new_row_bytes; memcpy(dst, src, new_row_bytes); dst[new_row_bytes - 1u] &= last_mask; } *out_raster = out; *out_raster_bytes = total; out_params->width_dots = new_width; out_params->height_dots = height; out_params->margin_mm = in_params->margin_mm; ptouch_set_error(ctx, LIBPTOUCH_OK, ""); return LIBPTOUCH_OK; }