#include "bayer2rgb.h" #include "bayer2rgb-internal.h" #include "convert-internal.hh" #include template static bool reduce_outer1(struct image_info *info, void const *in, void *out, struct image_conversion_info *conv_info) { typedef struct infmt infmt_t; typedef struct infmt outfmt_t; typename infmt_t::bitfmt_t const *in_data = static_cast(in); typename outfmt_t::bitfmt_t *out_data = static_cast(out); unsigned int width = info->w; unsigned int height = info->h; size_t in_stride = info->stride / sizeof *in_data; size_t out_stride = (info->w + sizeof *out_data - 1) / sizeof *out_data; int const rsft = static_cast(infmt_t::bpp) - static_cast(outfmt_t::bpp); if ((info->stride % sizeof *in_data) != 0) { set_fallback_reason(conv_info, "cc: odd input stride"); return false; } for (unsigned int y = 0; y < height; ++y) { for (unsigned int x = 0; x < width; ++x) { unsigned int v = infmt_t::as_uint(in_data[x]); if (rsft < 0) { v <<= -rsft; } else if (rsft > 0) { // round value v += (1u << (rsft - 1)); v >>= rsft; if (v > outfmt_t::max) v = outfmt_t::max; } out_data[x] = outfmt_t::as_bitfmt(v); } in_data += in_stride; out_data += out_stride; } info->stride = out_stride * sizeof *out_data; info->bpp = outfmt_t::bpp; return true; } template static bool reduce_outer0(struct image_info *info, void const *in, void *out, struct image_conversion_info *conv_info) { /* Step 2: split by input bpp */ switch (info->bpp) { case 8: return reduce_outer1(info, in, out, conv_info); case 10: if (info->endian == image_info::BAYER_E_LITTLE) return reduce_outer1(info, in, out, conv_info); else return reduce_outer1(info, in, out, conv_info); case 12: if (info->endian == image_info::BAYER_E_LITTLE) return reduce_outer1(info, in, out, conv_info); else return reduce_outer1(info, in, out, conv_info); case 16: if (info->endian == image_info::BAYER_E_LITTLE) return reduce_outer1(info, in, out, conv_info); else return reduce_outer1(info, in, out, conv_info); default: set_fallback_reason(conv_info, "cc: unsupported input bpp"); return false; } } bool bayer2rgb_reduce_bpp_cc(struct image_info *info, void const *in, void *out, unsigned int out_bpp, struct image_conversion_info *conv_info) { bool handled; if (info->bpp == out_bpp) { if (in != out) memcpy(out, in, info->stride * info->h); return true; } switch (out_bpp) { case 8: handled = reduce_outer0(info, in, out, conv_info); break; default: set_fallback_reason(conv_info, "cc: unsupported output bpp"); handled = false; break; } return handled; }