void ResizeImagePeriodicMirror(const cv::Mat& src_img, const int h_off, const int w_off, cv::Mat* dst_img) { const int h_src = src_img.rows; const int w_src = src_img.cols; const int h_dst = dst_img->rows; const int w_dst = dst_img->cols; const int num_channels = src_img.channels(); CHECK_EQ(num_channels, dst_img->channels()) << "number of channels of source and destimation images have to be equal"; CHECK_NE(dst_img, &src_img) << "doesn't support in place calculation"; for (int h = 0; h < h_dst; ++h) { uchar* ptr_dst = dst_img->ptr<uchar>(h); const uchar* ptr_src = src_img.ptr<uchar>( (floor_div(h-h_off, h_src))%2 == 0 ? positive_mod(h-h_off, h_src) : h_src-1-positive_mod(h-h_off, h_src)); int index_dst = 0; for (int w = 0; w < w_dst; ++w) { int index_src = positive_mod(w-w_off, w_src); index_src = (floor_div(w-w_off, w_src))%2 == 0 ? index_src : w_src-1-index_src; index_src *= num_channels; for (int c = 0; c < num_channels; ++c) { ptr_dst[index_dst++] = ptr_src[index_src++]; } } } }
size_t process(univector<T, Tag>& output, univector_ref<const T> input) { const itype required_input_size = input_size_for_output(output.size()); const itype input_size = input.size(); for (size_t i = 0; i < output.size(); i++) { const itype intermediate_index = output_position_to_intermediate(static_cast<itype>(i) + output_position); const itype intermediate_start = intermediate_index - taps + 1; const std::lldiv_t input_pos = floor_div(intermediate_start + interpolation_factor - 1, interpolation_factor); const itype input_start = input_pos.quot; // first input sample const itype tap_start = interpolation_factor - 1 - input_pos.rem; const univector_ref<T> tap_ptr = filter.slice(static_cast<size_t>(tap_start * depth)); if (input_start >= input_position + input_size) { output[i] = T(0); } else if (input_start >= input_position) { output[i] = dotproduct(input.slice(input_start - input_position, depth), tap_ptr); } else { const itype prev_count = input_position - input_start; output[i] = dotproduct(delay.slice(size_t(depth - prev_count)), tap_ptr) + dotproduct(input.slice(0, size_t(depth - prev_count)), tap_ptr.slice(size_t(prev_count), size_t(depth - prev_count))); } } if (required_input_size >= depth) { delay.slice(0, delay.size()) = padded(input.slice(size_t(required_input_size - depth))); } else { delay.truncate(size_t(depth - required_input_size)) = delay.slice(size_t(required_input_size)); delay.slice(size_t(depth - required_input_size)) = padded(input); } input_position += required_input_size; output_position += output.size(); return required_input_size; }
numeric read_numeric(char* val) { enum { decimal_digits_per_nbase = 4 }; // decimal digits per word short* s = reinterpret_cast<short*>(val); u_short const words_count = ntohs(*s); s++; signed short first_word_weight = ntohs(*s); s++; u_short const sign = ntohs(*s); s++; u_short display_scale = ntohs(*s); s++; assert(display_scale >= 0); std::clog << "X: nwords=" << words_count << " weight=" << first_word_weight << " sign=" << sign << " dscale=" << display_scale << std::endl; numeric n; if (sign == numeric::positive) { n.mode = numeric::positive; n.sign = 0; } else if (sign == numeric::negative) { n.mode = numeric::negative; n.sign = 1; } else if (sign == numeric::NaN) { n.mode = numeric::NaN; return n; } else { throw std::invalid_argument("invalid sign"); } std::vector<short> digits; int exp = 0; if (words_count == 0) { exp = -display_scale; digits.push_back(0); } else { assert(words_count > 0); std::vector<short> words(words_count); for (auto i = 0U; i < words_count; ++i) { words[i] = ntohs(*s); s++; } std::array<short, 4> const shifts = { 1000, 100, 10, 1 }; for(auto it(words.cbegin()); it != words.cend(); ++it) { for (std::size_t si = 0; si < shifts.size(); ++si) { double const fd = floor_div(*it, shifts[si]); short const digit = static_cast<int>(fd) % 10; assert(digit < 10); if (!digits.empty() || digit != 0) digits.push_back(digit); } } // There are weight + 1 digits before the decimal point. exp = (first_word_weight + 1 - words_count) * decimal_digits_per_nbase; if (0 < exp && exp < 20) { std::fill_n(std::back_inserter(digits), exp, 0); exp = 0; } if (display_scale > 0) { int const zerofill = display_scale + exp; if (zerofill < 0) { auto last = digits.cbegin() + (digits.size() + zerofill); digits.erase(last, digits.cend()); exp -= zerofill; } else if (zerofill > 0) { std::fill_n(std::back_inserter(digits), zerofill, 0); exp -= zerofill; } } } assert(!digits.empty()); n.digits = digits; n.exp = exp; return n; }
KFR_MEM_INTRINSIC itype output_position_to_input(itype out_pos) const { return floor_div(output_position_to_intermediate(out_pos), interpolation_factor).quot; }
KFR_MEM_INTRINSIC itype input_position_to_output(itype in_pos) const { return floor_div(input_position_to_intermediate(in_pos), decimation_factor).quot; }