1 /*
2 * soft_geo_tasks_priv.cpp - soft geometry map tasks
3 *
4 * Copyright (c) 2017 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 */
20
21 #include "soft_geo_tasks_priv.h"
22
23 namespace XCam {
24
25 namespace XCamSoftTasks {
26
27 XCamReturn
work_range(const SmartPtr<Arguments> & base,const WorkRange & range)28 GeoMapTask::work_range (const SmartPtr<Arguments> &base, const WorkRange &range)
29 {
30 static const Uchar zero_luma_byte[8] = {0, 0, 0, 0, 0, 0, 0, 0};
31 static const Uchar2 zero_uv_byte[4] = {{128, 128}, {128, 128}, {128, 128}, {128, 128}};
32 SmartPtr<GeoMapTask::Args> args = base.dynamic_cast_ptr<GeoMapTask::Args> ();
33 XCAM_ASSERT (args.ptr ());
34 UcharImage *in_luma = args->in_luma.ptr (), *out_luma = args->out_luma.ptr ();
35 Uchar2Image *in_uv = args->in_uv.ptr (), *out_uv = args->out_uv.ptr ();
36 Float2Image *lut = args->lookup_table.ptr ();
37 XCAM_ASSERT (in_luma && in_uv);
38 XCAM_ASSERT (out_luma && out_uv);
39 XCAM_ASSERT (lut);
40
41 Float2 factors = args->factors;
42 XCAM_ASSERT (
43 !XCAM_DOUBLE_EQUAL_AROUND (factors.x, 0.0f) &&
44 !XCAM_DOUBLE_EQUAL_AROUND (factors.y, 0.0f));
45
46 Float2 out_center ((out_luma->get_width () - 1.0f ) / 2.0f, (out_luma->get_height () - 1.0f ) / 2.0f);
47 Float2 lut_center ((lut->get_width () - 1.0f) / 2.0f, (lut->get_height () - 1.0f) / 2.0f);
48 float x_step = 1.0f / factors.x;
49 float y_step = 1.0f / factors.y;
50
51 #undef OUT_BOUND
52 #define OUT_BOUND(image, first, last) \
53 (in_pos[first].x >= image->get_width ()) || \
54 (in_pos[first].y >= image->get_height ()) || \
55 (in_pos[last].x <= 0.0f) || (in_pos[last].y <= 0.0f)
56
57 for (uint32_t y = range.pos[1]; y < range.pos[1] + range.pos_len[1]; ++y)
58 for (uint32_t x = range.pos[0]; x < range.pos[0] + range.pos_len[0]; ++x)
59 {
60 // calculate 8x2 luma, center aligned
61 Float2 in_pos[8];
62 float luma_value[8];
63 Uchar luma_uc[8];
64 uint32_t out_x = x * 8, out_y = y * 2;
65
66 //1st-line luma
67 Float2 out_pos (out_x, out_y);
68 out_pos -= out_center;
69 Float2 first = out_pos / factors;
70 first += lut_center;
71 Float2 lut_pos[8] = {
72 first, Float2(first.x + x_step, first.y),
73 Float2(first.x + x_step * 2, first.y), Float2(first.x + x_step * 3, first.y),
74 Float2(first.x + x_step * 4, first.y), Float2(first.x + x_step * 5, first.y),
75 Float2(first.x + x_step * 6, first.y), Float2(first.x + x_step * 7, first.y)
76 };
77 lut->read_interpolate_array<Float2, 8> (lut_pos, in_pos);
78 in_luma->read_interpolate_array<float, 8> (in_pos, luma_value);
79 convert_to_uchar_N<float, 8> (luma_value, luma_uc);
80 if (OUT_BOUND (in_luma, 0, 7))
81 out_luma->write_array_no_check<8> (out_x, out_y, zero_luma_byte);
82 else
83 out_luma->write_array_no_check<8> (out_x, out_y, luma_uc);
84
85 //4x1 UV
86 Float2 uv_value[4];
87 Uchar2 uv_uc[4];
88 in_pos[0] /= 2.0f;
89 in_pos[1] = in_pos[2] / 2.0f;
90 in_pos[2] = in_pos[4] / 2.0f;
91 in_pos[3] = in_pos[6] / 2.0f;
92 in_uv->read_interpolate_array<Float2, 4> (in_pos, uv_value);
93 convert_to_uchar2_N<Float2, 4> (uv_value, uv_uc);
94 if (OUT_BOUND (in_uv, 0, 3))
95 out_uv->write_array_no_check<4> (x * 4, y, zero_uv_byte);
96 else
97 out_uv->write_array_no_check<4> (x * 4, y, uv_uc);
98
99 //2nd-line luma
100 lut_pos[0].y = lut_pos[1].y = lut_pos[2].y = lut_pos[3].y = lut_pos[4].y = lut_pos[5].y =
101 lut_pos[6].y = lut_pos[7].y = first.y + y_step;
102 lut->read_interpolate_array<Float2, 8> (lut_pos, in_pos);
103 in_luma->read_interpolate_array<float, 8> (in_pos, luma_value);
104 convert_to_uchar_N<float, 8> (luma_value, luma_uc);
105 if (OUT_BOUND (in_luma, 0, 7))
106 out_luma->write_array_no_check<8> (out_x, out_y + 1, zero_luma_byte);
107 else
108 out_luma->write_array_no_check<8> (out_x, out_y + 1, luma_uc);
109 }
110 return XCAM_RETURN_NO_ERROR;
111 }
112
113 }
114
115 }
116
117