/* * soft_geo_tasks_priv.cpp - soft geometry map tasks * * Copyright (c) 2017 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Author: Wind Yuan */ #include "soft_geo_tasks_priv.h" namespace XCam { namespace XCamSoftTasks { XCamReturn GeoMapTask::work_range (const SmartPtr &base, const WorkRange &range) { static const Uchar zero_luma_byte[8] = {0, 0, 0, 0, 0, 0, 0, 0}; static const Uchar2 zero_uv_byte[4] = {{128, 128}, {128, 128}, {128, 128}, {128, 128}}; SmartPtr args = base.dynamic_cast_ptr (); XCAM_ASSERT (args.ptr ()); UcharImage *in_luma = args->in_luma.ptr (), *out_luma = args->out_luma.ptr (); Uchar2Image *in_uv = args->in_uv.ptr (), *out_uv = args->out_uv.ptr (); Float2Image *lut = args->lookup_table.ptr (); XCAM_ASSERT (in_luma && in_uv); XCAM_ASSERT (out_luma && out_uv); XCAM_ASSERT (lut); Float2 factors = args->factors; XCAM_ASSERT ( !XCAM_DOUBLE_EQUAL_AROUND (factors.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (factors.y, 0.0f)); Float2 out_center ((out_luma->get_width () - 1.0f ) / 2.0f, (out_luma->get_height () - 1.0f ) / 2.0f); Float2 lut_center ((lut->get_width () - 1.0f) / 2.0f, (lut->get_height () - 1.0f) / 2.0f); float x_step = 1.0f / factors.x; float y_step = 1.0f / factors.y; #undef OUT_BOUND #define OUT_BOUND(image, first, last) \ (in_pos[first].x >= image->get_width ()) || \ (in_pos[first].y >= image->get_height ()) || \ (in_pos[last].x <= 0.0f) || (in_pos[last].y <= 0.0f) for (uint32_t y = range.pos[1]; y < range.pos[1] + range.pos_len[1]; ++y) for (uint32_t x = range.pos[0]; x < range.pos[0] + range.pos_len[0]; ++x) { // calculate 8x2 luma, center aligned Float2 in_pos[8]; float luma_value[8]; Uchar luma_uc[8]; uint32_t out_x = x * 8, out_y = y * 2; //1st-line luma Float2 out_pos (out_x, out_y); out_pos -= out_center; Float2 first = out_pos / factors; first += lut_center; Float2 lut_pos[8] = { first, Float2(first.x + x_step, first.y), Float2(first.x + x_step * 2, first.y), Float2(first.x + x_step * 3, first.y), Float2(first.x + x_step * 4, first.y), Float2(first.x + x_step * 5, first.y), Float2(first.x + x_step * 6, first.y), Float2(first.x + x_step * 7, first.y) }; lut->read_interpolate_array (lut_pos, in_pos); in_luma->read_interpolate_array (in_pos, luma_value); convert_to_uchar_N (luma_value, luma_uc); if (OUT_BOUND (in_luma, 0, 7)) out_luma->write_array_no_check<8> (out_x, out_y, zero_luma_byte); else out_luma->write_array_no_check<8> (out_x, out_y, luma_uc); //4x1 UV Float2 uv_value[4]; Uchar2 uv_uc[4]; in_pos[0] /= 2.0f; in_pos[1] = in_pos[2] / 2.0f; in_pos[2] = in_pos[4] / 2.0f; in_pos[3] = in_pos[6] / 2.0f; in_uv->read_interpolate_array (in_pos, uv_value); convert_to_uchar2_N (uv_value, uv_uc); if (OUT_BOUND (in_uv, 0, 3)) out_uv->write_array_no_check<4> (x * 4, y, zero_uv_byte); else out_uv->write_array_no_check<4> (x * 4, y, uv_uc); //2nd-line luma lut_pos[0].y = lut_pos[1].y = lut_pos[2].y = lut_pos[3].y = lut_pos[4].y = lut_pos[5].y = lut_pos[6].y = lut_pos[7].y = first.y + y_step; lut->read_interpolate_array (lut_pos, in_pos); in_luma->read_interpolate_array (in_pos, luma_value); convert_to_uchar_N (luma_value, luma_uc); if (OUT_BOUND (in_luma, 0, 7)) out_luma->write_array_no_check<8> (out_x, out_y + 1, zero_luma_byte); else out_luma->write_array_no_check<8> (out_x, out_y + 1, luma_uc); } return XCAM_RETURN_NO_ERROR; } } }