|
#include "drawing.h" |
|
#include "string.h" |
|
|
|
#define max(a, b) (((a) > (b)) ? (a) : (b)) |
|
#define min(a, b) (((a) < (b)) ? (a) : (b)) |
|
|
|
void draw_rectangle_c1(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness) |
|
{ |
|
const unsigned char* pen_color = (const unsigned char*)&color; |
|
|
|
if (thickness == -1) |
|
{ |
|
|
|
for (int y = ry; y < ry + rh; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx; x < rx + rw; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x] = pen_color[0]; |
|
} |
|
} |
|
|
|
return; |
|
} |
|
|
|
const int t0 = thickness / 2; |
|
const int t1 = thickness - t0; |
|
|
|
|
|
{ |
|
for (int y = ry - t0; y < ry + t1; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x] = pen_color[0]; |
|
} |
|
} |
|
} |
|
|
|
|
|
{ |
|
for (int y = ry + rh - t0; y < ry + rh + t1; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x] = pen_color[0]; |
|
} |
|
} |
|
} |
|
|
|
|
|
for (int x = rx - t0; x < rx + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
for (int y = ry + t1; y < ry + rh - t0; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
p[x] = pen_color[0]; |
|
} |
|
} |
|
|
|
|
|
for (int x = rx + rw - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
for (int y = ry + t1; y < ry + rh - t0; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
p[x] = pen_color[0]; |
|
} |
|
} |
|
} |
|
|
|
void draw_rectangle_c2(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness) |
|
{ |
|
const unsigned char* pen_color = (const unsigned char*)&color; |
|
|
|
if (thickness == -1) |
|
{ |
|
|
|
for (int y = ry; y < ry + rh; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx; x < rx + rw; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 2 + 0] = pen_color[0]; |
|
p[x * 2 + 1] = pen_color[1]; |
|
} |
|
} |
|
|
|
return; |
|
} |
|
|
|
const int t0 = thickness / 2; |
|
const int t1 = thickness - t0; |
|
|
|
|
|
{ |
|
for (int y = ry - t0; y < ry + t1; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 2 + 0] = pen_color[0]; |
|
p[x * 2 + 1] = pen_color[1]; |
|
} |
|
} |
|
} |
|
|
|
|
|
{ |
|
for (int y = ry + rh - t0; y < ry + rh + t1; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 2 + 0] = pen_color[0]; |
|
p[x * 2 + 1] = pen_color[1]; |
|
} |
|
} |
|
} |
|
|
|
|
|
for (int x = rx - t0; x < rx + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
for (int y = ry + t1; y < ry + rh - t0; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
p[x * 2 + 0] = pen_color[0]; |
|
p[x * 2 + 1] = pen_color[1]; |
|
} |
|
} |
|
|
|
|
|
for (int x = rx + rw - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
for (int y = ry + t1; y < ry + rh - t0; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
p[x * 2 + 0] = pen_color[0]; |
|
p[x * 2 + 1] = pen_color[1]; |
|
} |
|
} |
|
} |
|
|
|
void draw_rectangle_c3(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness) |
|
{ |
|
const unsigned char* pen_color = (const unsigned char*)&color; |
|
|
|
if (thickness == -1) |
|
{ |
|
|
|
for (int y = ry; y < ry + rh; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx; x < rx + rw; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 3 + 0] = pen_color[0]; |
|
p[x * 3 + 1] = pen_color[1]; |
|
p[x * 3 + 2] = pen_color[2]; |
|
} |
|
} |
|
|
|
return; |
|
} |
|
|
|
const int t0 = thickness / 2; |
|
const int t1 = thickness - t0; |
|
|
|
|
|
{ |
|
for (int y = ry - t0; y < ry + t1; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 3 + 0] = pen_color[0]; |
|
p[x * 3 + 1] = pen_color[1]; |
|
p[x * 3 + 2] = pen_color[2]; |
|
} |
|
} |
|
} |
|
|
|
|
|
{ |
|
for (int y = ry + rh - t0; y < ry + rh + t1; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 3 + 0] = pen_color[0]; |
|
p[x * 3 + 1] = pen_color[1]; |
|
p[x * 3 + 2] = pen_color[2]; |
|
} |
|
} |
|
} |
|
|
|
|
|
for (int x = rx - t0; x < rx + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
for (int y = ry + t1; y < ry + rh - t0; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
p[x * 3 + 0] = pen_color[0]; |
|
p[x * 3 + 1] = pen_color[1]; |
|
p[x * 3 + 2] = pen_color[2]; |
|
} |
|
} |
|
|
|
|
|
for (int x = rx + rw - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
for (int y = ry + t1; y < ry + rh - t0; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
p[x * 3 + 0] = pen_color[0]; |
|
p[x * 3 + 1] = pen_color[1]; |
|
p[x * 3 + 2] = pen_color[2]; |
|
} |
|
} |
|
} |
|
|
|
void draw_rectangle_c4(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness) |
|
{ |
|
const unsigned char* pen_color = (const unsigned char*)&color; |
|
|
|
if (thickness == -1) |
|
{ |
|
|
|
for (int y = ry; y < ry + rh; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx; x < rx + rw; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 4 + 0] = pen_color[0]; |
|
p[x * 4 + 1] = pen_color[1]; |
|
p[x * 4 + 2] = pen_color[2]; |
|
p[x * 4 + 3] = pen_color[3]; |
|
} |
|
} |
|
|
|
return; |
|
} |
|
|
|
const int t0 = thickness / 2; |
|
const int t1 = thickness - t0; |
|
|
|
|
|
{ |
|
for (int y = ry - t0; y < ry + t1; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 4 + 0] = pen_color[0]; |
|
p[x * 4 + 1] = pen_color[1]; |
|
p[x * 4 + 2] = pen_color[2]; |
|
p[x * 4 + 3] = pen_color[3]; |
|
} |
|
} |
|
} |
|
|
|
|
|
{ |
|
for (int y = ry + rh - t0; y < ry + rh + t1; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
for (int x = rx - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
p[x * 4 + 0] = pen_color[0]; |
|
p[x * 4 + 1] = pen_color[1]; |
|
p[x * 4 + 2] = pen_color[2]; |
|
p[x * 4 + 3] = pen_color[3]; |
|
} |
|
} |
|
} |
|
|
|
|
|
for (int x = rx - t0; x < rx + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
for (int y = ry + t1; y < ry + rh - t0; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
p[x * 4 + 0] = pen_color[0]; |
|
p[x * 4 + 1] = pen_color[1]; |
|
p[x * 4 + 2] = pen_color[2]; |
|
p[x * 4 + 3] = pen_color[3]; |
|
} |
|
} |
|
|
|
|
|
for (int x = rx + rw - t0; x < rx + rw + t1; x++) |
|
{ |
|
if (x < 0) |
|
continue; |
|
|
|
if (x >= w) |
|
break; |
|
|
|
for (int y = ry + t1; y < ry + rh - t0; y++) |
|
{ |
|
if (y < 0) |
|
continue; |
|
|
|
if (y >= h) |
|
break; |
|
|
|
unsigned char* p = pixels + stride * y; |
|
|
|
p[x * 4 + 0] = pen_color[0]; |
|
p[x * 4 + 1] = pen_color[1]; |
|
p[x * 4 + 2] = pen_color[2]; |
|
p[x * 4 + 3] = pen_color[3]; |
|
} |
|
} |
|
} |
|
|
|
void draw_rectangle_yuv420sp(unsigned char* yuv420sp, int w, int h, int rx, int ry, int rw, int rh, unsigned int color, int thickness) |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const unsigned char* pen_color = (const unsigned char*)&color; |
|
|
|
unsigned int v_y; |
|
unsigned int v_uv; |
|
unsigned char* pen_color_y = (unsigned char*)&v_y; |
|
unsigned char* pen_color_uv = (unsigned char*)&v_uv; |
|
pen_color_y[0] = pen_color[0]; |
|
pen_color_uv[0] = pen_color[1]; |
|
pen_color_uv[1] = pen_color[2]; |
|
|
|
unsigned char* Y = yuv420sp; |
|
draw_rectangle_c1(Y, w, h, w, rx, ry, rw, rh, v_y, thickness); |
|
|
|
unsigned char* UV = yuv420sp + w * h; |
|
int thickness_uv = thickness == -1 ? thickness : max(thickness / 2, 1); |
|
draw_rectangle_c2(UV, w / 2, h / 2, w, rx / 2, ry / 2, rw / 2, rh / 2, v_uv, thickness_uv); |
|
} |
|
|
|
|
|
void draw_image_yuv420sp(unsigned char* yuv420sp, int w, int h, unsigned char* draw_img, int rx, int ry, int rw, int rh) { |
|
for (int i = 0; i < rh; i++) { |
|
memcpy(yuv420sp + (ry+i) * w + rx, draw_img + i * rw, rw); |
|
} |
|
for (int i = 0; i < rh/2; i++) { |
|
memcpy(yuv420sp + w*h + (ry/2+i) * w+ rx, draw_img + rw*rh + i*rw, rw); |
|
} |
|
} |