/* * Rockchip App * * Copyright (C) 2017 Rockchip Electronics Co., Ltd. * author: hogan.wang@rock-chips.com * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL), available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "draw_rect.h" #ifndef ABS #define ABS(x) (((x)<0) ? -(x) : (x)) #endif static void YUV_SWAP(int *x, int *y) { int tmp = 0; tmp = *x; *x = *y; *y = tmp; } YUV_Color set_yuv_color(COLOR_Type color_type) { YUV_Color color; switch (color_type) { case COLOR_Y: color.Y = 226; color.U = 0; color.V = 149; break; case COLOR_R: color.Y = 76; color.U = 85; color.V = 255; break; case COLOR_G: color.Y = 150; color.U = 44; color.V = 21; break; case COLOR_B: color.Y = 29; color.U = 255; color.V = 107; break; case COLOR_BK: color.Y = 16; color.U = 128; color.V = 128; break; default: color.Y = 128; color.U = 128; color.V = 128; break; } return color; } static int yuv420_draw_point(unsigned char* imgdata, int width, int height, YUV_Point Point, YUV_Color color) { int imgSize; int x, y; if (!imgdata) return -1; if (width < 0 || height < 0) return -1; if (Point.x < 0 || Point.x > width || Point.y < 0 || Point.y > height) return -1; if (Point.x % 2) Point.x--; if (Point.y % 2) Point.y--; imgSize = width * height; x = Point.x; y = Point.y; imgdata[y * width + x] = color.Y; imgdata[imgSize + y * width / 2 + x] = color.U; imgdata[imgSize + y * width / 2 + x + 1] = color.V; return 0; } static int yuv420_draw_vline(void* imgdata, int width, int height, YUV_Point startPoint, YUV_Point endPoint, YUV_Color color) { int ret = 0; int x0, y0, y1; YUV_Point Point; x0 = startPoint.x; y0 = startPoint.y; y1 = endPoint.y; if (y0 > y1) YUV_SWAP(&y0, &y1); Point.x = x0; Point.y = y0; while (Point.y < y1) { Point.y++; ret = yuv420_draw_point((unsigned char *)imgdata, width, height, Point, color); if (ret) return -1; } return 0; } static int yuv420_draw_hline(void* imgdata, int width, int height, YUV_Point startPoint, YUV_Point endPoint, YUV_Color color) { int ret = 0; int x0, y0, x1; YUV_Point Point; x0 = startPoint.x; y0 = startPoint.y; x1 = endPoint.x; if (x0 > x1) YUV_SWAP(&x0, &x1); Point.x = x0; Point.y = y0; while (Point.x < x1) { Point.x++; ret = yuv420_draw_point((unsigned char *)imgdata, width, height, Point, color); if (ret) return -1; } return 0; } static int yuv420_draw_tline(void* imgdata, int width, int height, YUV_Point startPoint, YUV_Point endPoint, YUV_Color color) { int x0, y0, x1, y1; int dx, dy, error; YUV_Point Point; x0 = startPoint.x; y0 = startPoint.y; x1 = endPoint.x; y1 = endPoint.y; if (x0 > x1) { YUV_SWAP(&x0, &x1); YUV_SWAP(&y0, &y1); } dx = x1 - x0; dy = y1 - y0; Point.x = x0; Point.y = y0; if (dx == 0) { yuv420_draw_vline(imgdata, width, height, startPoint, endPoint, color); return 0; } if (dy == 0){ yuv420_draw_hline(imgdata, width, height, startPoint, endPoint, color); return 0; } yuv420_draw_point((unsigned char *)imgdata, width, height, Point, color); if ((dx >= dy) && (dy > 0)) {/* 0 0) { error += (dy - dx) * 2; Point.x++; Point.y++; } else { error += dy * 2; Point.x++; } yuv420_draw_point((unsigned char *)imgdata, width, height, Point, color); } return 0; } if ((dy > dx) && (dy > 0)) {/* k>1 */ error = dy - (dx * 2); while (Point.y < y1) { if (error < 0) { error += (dy - dx) * 2; Point.x++; Point.y++; } else { error += (-dx) * 2; Point.y++; } yuv420_draw_point((unsigned char *)imgdata, width, height, Point, color); } return 0; } if ((dx >= ABS(dy)) && (dy < 0)) { /* -1= dx) && (dy < 0)) { /* k<-1 */ error = dy + (dx * 2); while (Point.y > y1) { if (error > 0) { error += (dy + dx) * 2; Point.x++; Point.y--; } else { error += dx * 2; Point.y--; } yuv420_draw_point((unsigned char *)imgdata, width, height, Point, color); } return 0; } return 0; } void yuv420_draw_line(void* imgdata, int width, int height, YUV_Point startPoint, YUV_Point endPoint, YUV_Color color) { YUV_Point sPoint; YUV_Point ePoint; sPoint.x = startPoint.x - 2; sPoint.y = startPoint.y - 2; ePoint.x = endPoint.x - 2; ePoint.y = endPoint.y - 2; yuv420_draw_tline(imgdata, width, height, sPoint, ePoint, color); sPoint.x = startPoint.x; sPoint.y = startPoint.y; ePoint.x = endPoint.x; ePoint.y = endPoint.y; yuv420_draw_tline(imgdata, width, height, sPoint, ePoint, color); sPoint.x = startPoint.x + 2; sPoint.y = startPoint.y + 2; ePoint.x = endPoint.x + 2; ePoint.y = endPoint.y + 2; yuv420_draw_tline(imgdata, width, height, sPoint, ePoint, color); } void yuv420_draw_rectangle(void* imgdata, int width, int height, YUV_Rect rect_rio, YUV_Color color) { int RoiWidth = rect_rio.width; int RoiHeight = rect_rio.height; int x = rect_rio.x; int y = rect_rio.y; YUV_Point Point[4]; Point[0].x = x; Point[0].y = y; Point[1].x = x + RoiWidth - 2; Point[1].y = y; Point[2].x = x + RoiWidth - 2; Point[2].y = y + RoiHeight - 2; Point[3].x = x; Point[3].y = y + RoiHeight - 2; yuv420_draw_line(imgdata, width, height, Point[0], Point[1], color); yuv420_draw_line(imgdata, width, height, Point[1], Point[2], color); yuv420_draw_line(imgdata, width, height, Point[3], Point[2], color); yuv420_draw_line(imgdata, width, height, Point[0], Point[3], color); }