void Triangulation::calculate_edges() { _VERBOSE("Triangulation::calculate_edges"); Py_XDECREF(_edges); // Create set of all edges, storing them with start point index less than // end point index. typedef std::set<Edge> EdgeSet; EdgeSet edge_set; for (int tri = 0; tri < _ntri; ++tri) { if (!is_masked(tri)) { for (int edge = 0; edge < 3; edge++) { int start = get_triangle_point(tri, edge); int end = get_triangle_point(tri, (edge+1)%3); edge_set.insert(start > end ? Edge(start,end) : Edge(end,start)); } } } // Convert to python _edges array. npy_intp dims[2] = {static_cast<npy_intp>(edge_set.size()), 2}; _edges = (PyArrayObject*)PyArray_SimpleNew(2, dims, PyArray_INT); int* edges_ptr = (int*)PyArray_DATA(_edges); for (EdgeSet::const_iterator it = edge_set.begin(); it != edge_set.end(); ++it) { *edges_ptr++ = it->start; *edges_ptr++ = it->end; } }
std::string Layout::to_string() const { std::string result = ""; if(is_masked()) { result = "[Masked]"; } else { for(int y=1; y<=6; y++) { for(int t=1; t<=5; t++) { int x; LeftRight lr; if(t <= 3) { x = t; lr = Left; } else if(t == 4) { x = 2; lr = Right; } else { x = 1; lr = Right; } int index = convert_cell_to_layout_index(Cell(South,y,x,lr)); if(index == -1) result += "[ ]"; else if(data[index].get_id() == 0) result += "[00]"; else result += "[" + std::to_string(data[index].get_id()) + "]"; result += " "; } // for t in 1..5 result += "\n"; } // for y in 1..6 } // masked ? return result; }
void Layout::swap(int index1, int index2) { assert(!is_masked()); assert(is_able_to_swap(index1, index2)); Piece t = data[index1]; data[index1] = data[index2]; data[index2] = t; }
void Triangulation::calculate_boundaries() { _VERBOSE("Triangulation::calculate_boundaries"); get_neighbors(); // Ensure _neighbors has been created. // Create set of all boundary TriEdges, which are those which do not // have a neighbor triangle. typedef std::set<TriEdge> BoundaryEdges; BoundaryEdges boundary_edges; for (int tri = 0; tri < _ntri; ++tri) { if (!is_masked(tri)) { for (int edge = 0; edge < 3; ++edge) { if (get_neighbor(tri, edge) == -1) { boundary_edges.insert(TriEdge(tri, edge)); } } } } // Take any boundary edge and follow the boundary until return to start // point, removing edges from boundary_edges as they are used. At the same // time, initialise the _tri_edge_to_boundary_map. while (!boundary_edges.empty()) { // Start of new boundary. BoundaryEdges::iterator it = boundary_edges.begin(); int tri = it->tri; int edge = it->edge; _boundaries.push_back(Boundary()); Boundary& boundary = _boundaries.back(); while (true) { boundary.push_back(TriEdge(tri, edge)); boundary_edges.erase(it); _tri_edge_to_boundary_map[TriEdge(tri, edge)] = BoundaryEdge(_boundaries.size()-1, boundary.size()-1); // Move to next edge of current triangle. edge = (edge+1) % 3; // Find start point index of boundary edge. int point = get_triangle_point(tri, edge); // Find next TriEdge by traversing neighbors until find one // without a neighbor. while (get_neighbor(tri, edge) != -1) { tri = get_neighbor(tri, edge); edge = get_edge_in_triangle(tri, point); } if (TriEdge(tri,edge) == boundary.front()) break; // Reached beginning of this boundary, so finished it. else it = boundary_edges.find(TriEdge(tri, edge)); } } }
bool Layout::is_able_to_swap(int index1, int index2) const { assert(!is_masked()); Piece copy[25]; for(int i=0; i<25; i++) copy[i] = data[i]; copy[index1] = data[index2]; copy[index2] = data[index1]; return is_valid_layout(copy); }
int AmPrivacyMaskDPTZ::fill_pm_mem(PRIVACY_MASK_RECT * rect) { int each_row_bytes, num_rows; uint32_t *pm_pixel; int i, j, k; int row_gap_count; PRIVACY_MASK_RECT nearest_block_rect; if ((num_block_x == 0) || (num_block_y == 0)) { INFO("privacy mask block number error \n"); return -1; } if (find_nearest_block_rect(&nearest_block_rect, rect) < 0) { INFO("input rect error \n"); return -1; } pm_color_index = rect->color; //privacy mask dsp mem uses 4 bytes to represent one block, //and width needs to be 32 bytes aligned each_row_bytes = round_up((num_block_x * 4), 32); num_rows = num_block_y; pm_pixel = (uint32_t *)pm_start_addr[pm_buffer_id]; row_gap_count = (each_row_bytes - num_block_x*4)/4; for(i = 0; i < num_rows; i++) { for (j = 0; j < num_block_x; j++) { k = is_masked(j, i, &nearest_block_rect); switch (rect->action) { case PM_ADD_INC: *pm_pixel |= k; break; case PM_ADD_EXC: *pm_pixel &= ~k; break; case PM_REPLACE: *pm_pixel = k; break; case PM_REMOVE_ALL: *pm_pixel = 0; break; default : *pm_pixel = 0; break; } pm_pixel++; } pm_pixel += row_gap_count; } return 0; }
void Triangulation::calculate_neighbors() { _VERBOSE("Triangulation::calculate_neighbors"); Py_XDECREF(_neighbors); // Create _neighbors array with shape (ntri,3) and initialise all to -1. npy_intp dims[2] = {_ntri,3}; _neighbors = (PyArrayObject*)PyArray_SimpleNew(2, dims, PyArray_INT); int* neighbors_ptr = (int*)PyArray_DATA(_neighbors); std::fill(neighbors_ptr, neighbors_ptr + 3*_ntri, -1); // For each triangle edge (start to end point), find corresponding neighbor // edge from end to start point. Do this by traversing all edges and // storing them in a map from edge to TriEdge. If corresponding neighbor // edge is already in the map, don't need to store new edge as neighbor // already found. typedef std::map<Edge, TriEdge> EdgeToTriEdgeMap; EdgeToTriEdgeMap edge_to_tri_edge_map; for (int tri = 0; tri < _ntri; ++tri) { if (!is_masked(tri)) { for (int edge = 0; edge < 3; ++edge) { int start = get_triangle_point(tri, edge); int end = get_triangle_point(tri, (edge+1)%3); EdgeToTriEdgeMap::iterator it = edge_to_tri_edge_map.find(Edge(end,start)); if (it == edge_to_tri_edge_map.end()) { // No neighbor edge exists in the edge_to_tri_edge_map, so // add this edge to it. edge_to_tri_edge_map[Edge(start,end)] = TriEdge(tri,edge); } else { // Neighbor edge found, set the two elements of _neighbors // and remove edge from edge_to_tri_edge_map. neighbors_ptr[3*tri + edge] = it->second.tri; neighbors_ptr[3*it->second.tri + it->second.edge] = tri; edge_to_tri_edge_map.erase(it); } } } } // Note that remaining edges in the edge_to_tri_edge_map correspond to // boundary edges, but the boundaries are calculated separately elsewhere. }
Piece Layout::get(int y, int x, LeftRight lr) const { assert(!is_masked()); return data[convert_cell_to_layout_index(Cell(South,y,x,lr))]; }
Piece Layout::get(int index) const { assert(!is_masked()); return data[index]; }
int AmPrivacyMaskDPTZ::fill_pm_mem(PRIVACY_MASK_RECT * rect) { int each_row_bytes, num_rows; iav_mctf_filter_strength_t *pm_pixel; int i, j, k; int row_gap_count; PRIVACY_MASK_RECT nearest_block_rect; if ((num_block_x == 0) || (num_block_y == 0)) { INFO("privacy mask block number error \n"); return -1; } if (find_nearest_block_rect(&nearest_block_rect, rect) < 0) { INFO("input rect error \n"); return -1; } pm_color_index = rect->color; //privacy mask dsp mem uses 4 bytes to represent one block, //and width needs to be 32 bytes aligned #ifdef CONFIG_ARCH_S2 each_row_bytes = pm_buffer_pitch; #else each_row_bytes = round_up((num_block_x * 4), 32); #endif num_rows = num_block_y; pm_pixel = (iav_mctf_filter_strength_t *)pm_start_addr[pm_buffer_id]; row_gap_count = (each_row_bytes - num_block_x*4)/4; for(i = 0; i < num_rows; i++) { for (j = 0; j < num_block_x; j++) { k = is_masked(j, i, &nearest_block_rect); pm_pixel->u |= NONE_MASK; pm_pixel->v |= NONE_MASK; pm_pixel->y |= NONE_MASK; switch (rect->action) { case PM_ADD_INC: pm_pixel->privacy_mask |= k; break; case PM_ADD_EXC: pm_pixel->privacy_mask &= ~k; break; case PM_REPLACE: pm_pixel->privacy_mask = k; break; case PM_REMOVE_ALL: pm_pixel->privacy_mask = 0; break; default : pm_pixel->privacy_mask = 0; break; } pm_pixel++; } pm_pixel += row_gap_count; } return 0; }
size_t mask_length() const noexcept { return is_masked() ? 4 : 0; }