32 #ifdef SWITCH_HAVE_VPX
33 #include "vpx/vpx_image.h"
34 #if VPX_IMAGE_ABI_VERSION != (4)
35 #error VPX_IMAGE_ABI_VERSION is not (4)
42 #ifdef SWITCH_HAVE_YUV
51 #ifdef SWITCH_HAVE_YUV
63 #ifdef SWITCH_HAVE_YUV
72 #ifdef SWITCH_HAVE_YUV
114 for(i = 0; POS_TABLE[i].
name; i++) {
115 if (!strcasecmp(POS_TABLE[i].name, name)) {
116 r = POS_TABLE[i].
pos;
146 for(i = 0; IMG_FIT_TABLE[i].
name; i++) {
147 if (!strcasecmp(IMG_FIT_TABLE[i].name, name)) {
148 r = IMG_FIT_TABLE[i].
fit;
158 #ifdef SWITCH_HAVE_VPX
159 #ifdef SWITCH_HAVE_YUV
175 #ifdef SWITCH_HAVE_VPX
178 gdImagePtr gd = gdImageCreateTrueColor(d_w, d_h);
180 if (!gd)
return NULL;
209 unsigned char *img_data)
211 #ifdef SWITCH_HAVE_VPX
224 #ifdef SWITCH_HAVE_VPX
233 #ifdef SWITCH_HAVE_YUV
255 (*img)->d_w, (*img)->d_h, (
int)mode);
266 #ifdef SWITCH_HAVE_VPX
270 gdImageDestroy((gdImagePtr)(*img)->user_priv);
282 #define MIN(a,b) ((a) < (b) ? (a) : (b))
286 #define MAX(a,b) ((a) > (b) ? (a) : (b))
292 int xoff = 0, yoff = 0;
297 int max_w =
MIN(img->d_w, IMG->d_w - abs(x));
298 int max_h =
MIN(img->d_h, IMG->d_h - abs(y));
303 for (i = 0; i < max_h; i++) {
304 for (j = 0; j < max_w; j++) {
315 RGB.
r = ((RGB.
r * (255 - alpha)) >> 8) + ((rgb->
r * alpha) >> 8);
316 RGB.
g = ((RGB.
g * (255 - alpha)) >> 8) + ((rgb->
g * alpha) >> 8);
317 RGB.
b = ((RGB.
b * (255 - alpha)) >> 8) + ((rgb->
b * alpha) >> 8);
331 gdImagePtr gd = (gdImagePtr)img->user_priv;
338 if (!gd->trueColor) {
344 for(i = 0; i < img->d_h; i++) {
345 for(j = 0; j < img->d_w; j++) {
346 pixel = gd->tpixels[i][j];
348 rgb_color.r = gdTrueColorGetRed(pixel);
349 rgb_color.g = gdTrueColorGetGreen(pixel);
350 rgb_color.b = gdTrueColorGetBlue(pixel);
370 max_h =
MIN(y + img->d_h - yoff, IMG->d_h);
371 len =
MIN(img->d_w - xoff, IMG->d_w - x);
374 if (x & 0x1) { x++; len--; }
376 if (len <= 0)
return;
378 for (i = y; i < max_h; i++) {
382 if ((len & 1) && (x + len) < img->d_w - 1) len++;
386 for (i = y; i < max_h; i += 2) {
394 #ifdef SWITCH_HAVE_VPX
398 if (x >= img->d_w || y >= img->d_h)
return;
409 w =
MIN(img->d_w - x, w);
410 h =
MIN(img->d_h - y, h);
425 #ifdef SWITCH_HAVE_YUV
428 if (*new_img != NULL) {
429 if (img->fmt != (*new_img)->fmt || img->d_w != (*new_img)->d_w || img->d_h != (*new_img)->d_w) {
434 if (*new_img == NULL) {
464 #ifdef SWITCH_HAVE_YUV
467 if (*new_img != NULL) {
468 if (img->fmt != (*new_img)->fmt || img->d_w != (*new_img)->d_w || img->d_h != (*new_img)->d_w) {
473 if (*new_img == NULL) {
490 img->d_w, img->d_h, (
int)mode);
498 #ifdef SWITCH_HAVE_VPX
504 if (x >= img->d_w || y >= img->d_h)
return NULL;
513 if (!tmp)
return NULL;
515 w =
MIN(img->d_w - x, w);
516 h =
MIN(img->d_h - y, h);
532 #ifdef SWITCH_HAVE_YUV
535 if (x < 0 || y < 0 || x >= img->
d_w || y >= img->
d_h)
return;
538 switch_color_rgb2yuv(color, &yuv);
542 if (((x & 0x1) == 0) && ((y & 0x1) == 0)) {
548 *(alpha ) = color->
a;
549 *(alpha + 1) = color->
r;
550 *(alpha + 2) = color->
g;
551 *(alpha + 3) = color->
b;
558 #ifdef SWITCH_HAVE_YUV
562 if (x < 0 || y < 0 || x >= img->d_w || y >= img->d_h)
return;
565 switch_color_rgb2yuv(color, &yuv_color);
567 max_h =
MIN(y + h, img->d_h);
568 len =
MIN(w, img->d_w - x);
570 if (x & 1) { x++; len--; }
572 if (len <= 0)
return;
574 for (i = y; i < max_h; i++) {
578 if ((len & 1) && (x + len) < img->d_w - 1) len++;
582 for (i = y; i < max_h; i += 2) {
587 for (i = 0; i < img->d_w; i++) {
594 for (i = 1; i < img->d_h; i++) {
602 #ifdef SWITCH_HAVE_YUV
606 if (x < 0 || y < 0 || x >= img->
d_w || y >= img->
d_h)
return;
616 #ifdef SWITCH_HAVE_YUV
617 if (x < 0 || y < 0 || x >= img->
d_w || y >= img->
d_h)
return;
622 switch_img_get_yuv_pixel(img, &yuv, x, y);
623 switch_color_yuv2rgb(&yuv, rgb);
636 int i, j, len, max_h;
638 int xoff = 0, yoff = 0;
639 uint8_t alpha = (int8_t)((255 * percent) / 100);
654 max_h =
MIN(y + img->d_h - yoff, IMG->d_h);
655 len =
MIN(img->d_w - xoff, IMG->d_w - x);
657 if (x & 1) { x++; len--; }
659 if (len <= 0)
return;
661 for (i = y; i < max_h; i++) {
662 for (j = 0; j < len; j++) {
667 c.r = ((RGB.
r * (255 - alpha)) >> 8) + ((rgb.r * alpha) >> 8);
668 c.g = ((RGB.
g * (255 - alpha)) >> 8) + ((rgb.g * alpha) >> 8);
669 c.b = ((RGB.
b * (255 - alpha)) >> 8) + ((rgb.b * alpha) >> 8);
682 {0x00, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x00},
683 {0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00},
684 {0x00, 0x7E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7E, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00},
685 {0x00, 0x7E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7E, 0x00},
686 {0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00},
687 {0x00, 0x7E, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7E, 0x00},
688 {0x00, 0x7E, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x00},
689 {0x00, 0x7E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00},
690 {0x00, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x00},
691 {0x00, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7E, 0x00},
692 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00},
693 {0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
694 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
695 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
698 static void scv_tag(
void *buffer,
int w,
int x,
int y, uint8_t n)
706 for (j=0; j<16; j++) {
707 *( p + (y + j) * w + (x + i)) = (scv_art[n][j] & 0x80 >> i) ? 0xFF : 0x00;
717 if (x > w - 8)
break;
720 case '.': index = 10;
break;
721 case ':': index = 11;
break;
722 case '-': index = 12;
break;
723 case ' ': index = 13;
break;
728 scv_tag(buffer, w, x, y, index);
736 if (
zstr(str))
return;
738 if ((*str) ==
'#' && strlen(str) == 7) {
739 unsigned int r, g, b;
740 sscanf(str,
"#%02x%02x%02x", &r, &g, &b);
745 if (!strcmp(str,
"red")) {
749 }
else if (!strcmp(str,
"green")) {
753 }
else if (!strcmp(str,
"blue")) {
761 #ifdef SWITCH_HAVE_YUV
764 yuv->
y = (uint8_t)(((rgb->
r * 4897) >> 14) + ((rgb->
g * 9611) >> 14) + ((rgb->
b * 1876) >> 14));
765 yuv->
u = (uint8_t)(- ((rgb->
r * 2766) >> 14) - ((5426 * rgb->
g) >> 14) + rgb->
b / 2 + 128);
766 yuv->
v = (uint8_t)(rgb->
r / 2 -((6855 * rgb->
g) >> 14) - ((rgb->
b * 1337) >> 14) + 128);
770 #define CLAMP(val) MAX(0, MIN(val, 255))
772 #ifdef SWITCH_HAVE_YUV
777 int D = yuv->
u - 128;
778 int E = yuv->
v - 128;
780 rgb->
r =
CLAMP((298 * C + 409 * E + 128) >> 8);
781 rgb->
g =
CLAMP((298 * C - 100 * D - 208 * E + 128) >> 8);
782 rgb->
b =
CLAMP((298 * C + 516 * D + 128) >> 8);
786 rgb->
r =
CLAMP( yuv->
y + ((22457 * (yuv->
v-128)) >> 14));
787 rgb->
g =
CLAMP((yuv->
y - ((715 * (yuv->
v-128)) >> 10) - ((5532 * (yuv->
u-128)) >> 14)));
788 rgb->
b =
CLAMP((yuv->
y + ((28384 * (yuv->
u-128)) >> 14)));
794 #ifdef SWITCH_HAVE_YUV
798 switch_color_rgb2yuv(&rgb, color);
802 #if SWITCH_HAVE_FREETYPE
803 #include <ft2build.h>
804 #include FT_FREETYPE_H
808 #define MAX_GRADIENT 8
811 #if SWITCH_HAVE_FREETYPE
837 color->
r = c1->
r + (c2->
r - c1->
r) * i / MAX_GRADIENT;
838 color->
g = c1->
g + (c2->
g - c1->
g) * i / MAX_GRADIENT;
839 color->
b = c1->
b + (c2->
b - c1->
b) * i / MAX_GRADIENT;
856 #if SWITCH_HAVE_FREETYPE
857 if (FT_Init_FreeType(&new_handle->library)) {
867 if (
zstr(font_family)) {
887 new_handle->
angle = angle;
894 *handleP = new_handle;
907 old_handle = *handleP;
909 if (!old_handle)
return;
912 #if SWITCH_HAVE_FREETYPE
913 if (old_handle->library) {
914 FT_Done_FreeType(old_handle->library);
915 old_handle->library = NULL;
918 pool = old_handle->
pool;
928 #if SWITCH_HAVE_FREETYPE
932 FT_Int x_max = x + bitmap->width;
933 FT_Int y_max = y + bitmap->rows;
935 if (bitmap->width == 0)
return;
937 switch (bitmap->pixel_mode) {
938 case FT_PIXEL_MODE_GRAY:
940 case FT_PIXEL_MODE_NONE:
941 case FT_PIXEL_MODE_MONO:
943 for ( j = y, q = 0; j < y_max; j++, q++ ) {
944 for ( i = x, p = 0; i < x_max; i++, p++ ) {
946 int linesize = ((bitmap->width - 1) / 8 + 1) * 8;
948 if ( i < 0 || j < 0 || i >= img->
d_w || j >= img->
d_h)
continue;
950 byte = bitmap->buffer[(q * linesize + p) / 8];
951 if ((byte >> (7 - (p % 8))) & 0x1) {
958 case FT_PIXEL_MODE_GRAY2:
959 case FT_PIXEL_MODE_GRAY4:
960 case FT_PIXEL_MODE_LCD:
961 case FT_PIXEL_MODE_LCD_V:
966 for ( i = x, p = 0; i < x_max; i++, p++ ) {
967 for ( j = y, q = 0; j < y_max; j++, q++ ) {
968 int gradient = bitmap->buffer[q * bitmap->width + p];
969 if ( i < 0 || j < 0 || i >= img->
d_w || j >= img->
d_h)
continue;
978 if (rgb_color.
a > 0) {
979 c.
a = rgb_color.
a * gradient / 255;
980 c.
r = ((rgb_color.
r * (255 - gradient)) >> 8) + ((handle->
color.
r * gradient) >> 8);
981 c.
g = ((rgb_color.
g * (255 - gradient)) >> 8) + ((handle->
color.
g * gradient) >> 8);
982 c.
b = ((rgb_color.
b * (255 - gradient)) >> 8) + ((handle->
color.
b * gradient) >> 8);
999 int x,
int y, const
char *text,
1000 const
char *font_family, const
char *font_color,
1001 const
char *bgcolor, uint16_t font_size,
double angle)
1003 #if SWITCH_HAVE_FREETYPE
1013 int this_x = 0, last_x = 0, space = 0;
1016 if (
zstr(text))
return 0;
1018 if (!handle)
return 0;
1025 font_family = handle->font_family;
1029 handle->font_size = font_size;
1031 font_size = handle->font_size;
1045 handle->angle = angle;
1051 error = FT_New_Face(handle->library, font_family, 0, &face);
1058 error = FT_Set_Char_Size(face, 64 * font_size, 0, 96, 96);
1059 if (error)
return 0;
1063 if (handle->use_bgcolor && slot->bitmap.pixel_mode != FT_PIXEL_MODE_MONO) {
1068 matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
1069 matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
1070 matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
1071 matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
1076 while(*(text + index)) {
1081 pen.y += (font_size + font_size / 4);
1086 FT_Set_Transform(face, &matrix, &pen);
1089 error = FT_Load_Char(face, ch, FT_LOAD_RENDER);
1091 if (error)
continue;
1093 this_x = pen.x + slot->bitmap_left;
1097 draw_bitmap(handle, img, &slot->bitmap, this_x, pen.y - slot->bitmap_top + font_size);
1101 space = this_x - last_x;
1111 pen.x += slot->advance.x >> 6;
1112 pen.y += slot->advance.y >> 6;
1115 ret = width + slot->bitmap.width * 5;
1127 const char *fg =
"#cccccc";
1128 const char *bg =
"#142e55";
1130 const char *font_face = NULL;
1131 const char *fontsz =
"4%";
1132 char *txt =
"Value Optimized Out!";
1134 char *argv[6] = { 0 };
1136 int pre_width = 0, width = 0, font_size = 0, height = 0;
1138 char *duptxt = strdup(text);
1143 if (strchr(text,
':')) {
1146 if (argc > 0 && !
zstr(argv[0])) {
1150 if (argc > 1 && !
zstr(argv[1])) {
1154 if (argc > 2 && !
zstr(argv[2])) {
1155 font_face = argv[2];
1158 if (argc > 3 && !
zstr(argv[3])) {
1165 }
else txt = duptxt;
1167 if (!txt) txt = duptxt;
1169 if (strrchr(fontsz,
'%')) {
1170 font_size = 1 + ((int) (
float)h * (atof(fontsz) / 100.0f));
1172 font_size = atoi(fontsz);
1175 while (*txt ==
' ') txt++;
1180 if (len < 5) len = 5;
1188 font_size / 2, font_size / 2,
1189 txt, NULL, fg, bg, 0, 0);
1191 height = font_size * 2;
1193 if (full && w > width) {
1213 x = (txtimg->
d_w / 2) - (pre_width / 2);
1219 txt, NULL, fg, bg, 0, 0);
1239 len =
MIN(img->d_w, IMG->d_w - x);
1240 if (len <= 0)
return;
1242 for (i = y; i < (y + img->d_h) && i < IMG->d_h; i++) {
1243 if (rect && i >= rect->y && i < (rect->y + rect->h)) {
1244 int size = rect->x > x ? rect->x - x : 0;
1246 size =
MIN(img->d_w - rect->w - size, IMG->d_w - (rect->x + rect->w));
1255 for (i = y; i < (y + img->d_h) && i < IMG->d_h; i += 2) {
1256 if (rect && i > rect->y && i < (rect->y + rect->h)) {
1257 int size = rect->x > x ? rect->x - x : 0;
1262 size =
MIN(img->d_w - rect->w - size, IMG->d_w - (rect->x + rect->w)) / 2;
1272 #define SWITCH_IMG_MAX_WIDTH 1920 * 2
1273 #define SWITCH_IMG_MAX_HEIGHT 1080 * 2
1275 #if !defined(SWITCH_HAVE_YUV)
1276 #undef SWITCH_HAVE_PNG
1279 #ifdef SWITCH_HAVE_PNG
1282 #define PNG_SKIP_SETJMP_CHECK
1286 #ifdef PNG_SIMPLIFIED_READ_SUPPORTED
1288 struct switch_png_opaque_s {
1302 use_png->
pvt->png.version = PNG_IMAGE_VERSION;
1304 if (!png_image_begin_read_from_file(&use_png->
pvt->png, file_name)) {
1309 use_png->
pvt->png.format = PNG_FORMAT_ARGB;
1311 use_png->
pvt->buffer = malloc(PNG_IMAGE_SIZE(use_png->
pvt->png));
1314 if (!png_image_finish_read(&use_png->
pvt->png, NULL, use_png->
pvt->buffer, 0, NULL)) {
1320 use_png->
w = use_png->
pvt->png.width;
1321 use_png->
h = use_png->
pvt->png.height;
1342 png_image_free(&use_png->
pvt->png);
1359 for (i = 0; i < use_png->pvt->png.height; i++) {
1360 for (j = 0; j < use_png->pvt->png.width; j++) {
1362 alpha = use_png->pvt->buffer[i * use_png->pvt->png.width * 4 + j * 4];
1366 rgb_color = (
switch_rgb_color_t *)(use_png->pvt->buffer + i * use_png->pvt->png.width * 4 + j * 4);
1397 #ifdef PNG_SIMPLIFIED_READ_SUPPORTED
1401 png_image png = { 0 };
1402 png_bytep buffer = NULL;
1405 png.version = PNG_IMAGE_VERSION;
1407 if (!png_image_begin_read_from_file(&png, file_name)) {
1413 png.format = PNG_FORMAT_RGB;
1415 png.format = PNG_FORMAT_ARGB;
1421 buffer = malloc(PNG_IMAGE_SIZE(png));
1424 if (!png_image_finish_read(&png, NULL, buffer, 0, NULL)) {
1438 RAWToI420(buffer, png.width * 3,
1442 png.width, png.height);
1444 ARGBToARGB(buffer, png.width * 4,
1446 png.width, png.height);
1450 png_image_free(&png);
1467 png_bytep *row_pointers = NULL;
1471 png_byte color_type;
1474 png_structp png_ptr = NULL;
1475 png_infop info_ptr = NULL;
1478 png_color_8p sig_bit;
1480 png_byte *buffer = NULL;
1491 fp = fopen(file_name,
"rb");
1497 fread(header, 1, 8, fp);
1498 if (png_sig_cmp(header, 0, 8)) {
1503 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1509 info_ptr = png_create_info_struct(png_ptr);
1515 if (setjmp(png_jmpbuf(png_ptr))) {
1520 png_init_io(png_ptr, fp);
1521 png_set_sig_bytes(png_ptr, 8);
1522 png_read_info(png_ptr, info_ptr);
1524 width = png_get_image_width(png_ptr, info_ptr);
1525 height = png_get_image_height(png_ptr, info_ptr);
1526 color_type = png_get_color_type(png_ptr, info_ptr);
1527 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1534 if (color_type == PNG_COLOR_TYPE_PALETTE) {
1535 png_set_expand(png_ptr);
1539 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
1540 png_set_expand(png_ptr);
1544 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
1545 png_set_expand(png_ptr);
1549 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) {
1559 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
1566 if (bit_depth == 16) {
1567 png_set_strip_16(png_ptr);
1573 if (0 && color_type & PNG_COLOR_MASK_COLOR) {
1574 if (png_get_valid(png_ptr, info_ptr, & PNG_INFO_PLTE)) {
1575 png_set_dither(png_ptr, info_ptr->palette,
1576 info_ptr->num_palette, max_screen_colors,
1577 info_ptr->histogram);
1579 png_color std_color_cube[MAX_SCREEN_COLORS] =
1582 png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
1583 MAX_SCREEN_COLORS, NULL);
1589 if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY) {
1593 png_get_sBIT(png_ptr, info_ptr, &sig_bit);
1601 if (bit_depth < 8) {
1602 png_set_packing(png_ptr);
1606 if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
1611 if (bit_depth == 16) {
1612 png_set_swap(png_ptr);
1615 if (0 && color_type & PNG_COLOR_MASK_ALPHA) {
1616 if (setjmp(png_jmpbuf(png_ptr))) {
1621 png_set_strip_alpha(png_ptr);
1624 if (setjmp(png_jmpbuf(png_ptr))) {
1629 if (color_type == PNG_COLOR_TYPE_PALETTE) {
1630 png_set_palette_to_rgb(png_ptr);
1633 png_read_update_info(png_ptr, info_ptr);
1635 color_type = png_get_color_type(png_ptr, info_ptr);
1642 row_bytes = png_get_rowbytes(png_ptr, info_ptr);
1645 row_pointers = (png_bytep*)malloc(
sizeof(png_bytep) * height);
1648 buffer = (png_byte *)malloc(row_bytes * height);
1651 for (y = 0; y < height; y++) {
1652 row_pointers[y] = buffer + row_bytes * y;
1656 if (setjmp(png_jmpbuf(png_ptr))) {
1661 png_read_image(png_ptr, row_pointers);
1663 if (color_type == PNG_COLOR_TYPE_RGBA) {
1664 if (row_bytes > width * 4) {
1665 for(y = 1; y < height; y++) {
1666 memcpy(buffer + y * width * 4, row_pointers[y], width * 4);
1674 ABGRToI420(buffer, width * 4,
1680 ARGBToRGBA(buffer, width * 4,
1684 }
else if (color_type == PNG_COLOR_TYPE_RGB) {
1685 if (row_bytes > width * 3) {
1686 for(y = 1; y < height; y++) {
1687 memcpy(buffer + y * width * 3, row_pointers[y], width * 3);
1699 RAWToI420(buffer, width * 3,
1712 if (info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1720 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
1724 png_image png = { 0 };
1725 png_bytep buffer = NULL;
1728 buffer = malloc(img->d_w * img->d_h * 3);
1734 buffer, img->d_w * 3,
1735 img->d_w, img->d_h);
1737 png.version = PNG_IMAGE_VERSION;
1738 png.format = PNG_FORMAT_RGB;
1739 png.width = img->d_w;
1740 png.height = img->d_h;
1742 if (!png_image_write_to_file(&png, file_name, 0, buffer, 0, NULL)) {
1756 png_byte color_type;
1758 png_structp png_ptr;
1760 png_bytep *row_pointers = NULL;
1763 png_byte *buffer = NULL;
1770 color_type = PNG_COLOR_TYPE_RGB;
1772 fp = fopen(file_name,
"wb");
1778 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1784 info_ptr = png_create_info_struct(png_ptr);
1790 if (setjmp(png_jmpbuf(png_ptr))) {
1795 png_init_io(png_ptr, fp);
1797 if (setjmp(png_jmpbuf(png_ptr))) {
1802 png_set_IHDR(png_ptr, info_ptr, width, height,
1803 bit_depth, color_type, PNG_INTERLACE_NONE,
1804 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
1806 png_write_info(png_ptr, info_ptr);
1808 row_bytes = png_get_rowbytes(png_ptr, info_ptr);
1811 row_pointers = (png_bytep*)malloc(
sizeof(png_bytep) * height);
1814 buffer = (png_byte *)malloc(row_bytes * height);
1817 for (y = 0; y < height; y++) {
1818 row_pointers[y] = buffer + row_bytes * y;
1827 for(y = height - 1; y > 0; y--) {
1829 memcpy(row_pointers[y], buffer + row_bytes * y, width * 3);
1832 if (setjmp(png_jmpbuf(png_ptr))) {
1837 png_write_image(png_ptr, row_pointers);
1839 if (setjmp(png_jmpbuf(png_ptr))) {
1844 png_write_end(png_ptr, NULL);
1853 png_destroy_write_struct(&png_ptr, &info_ptr);
1884 int img_w = 0, img_h = 0;
1885 double screen_aspect = 0, img_aspect = 0;
1894 if (img->d_w == width && img->d_h == height) {
1906 screen_aspect = (double) IMG->
d_w / IMG->
d_h;
1907 img_aspect = (
double) img->d_w / img->d_h;
1910 if (screen_aspect > img_aspect) {
1911 img_w = img_aspect * IMG->
d_h;
1912 x_pos = (IMG->
d_w - img_w) / 2;
1913 }
else if (screen_aspect < img_aspect) {
1914 img_h = IMG->
d_w / img_aspect;
1915 y_pos = (IMG->
d_h - img_h) / 2;
1930 int new_w = 0, new_h = 0;
1937 if (!src || (src->
d_w == width && src->
d_h == height)) {
1951 if (src->
d_w < width && src->
d_h < height) {
1952 float rw = (float)new_w / width;
1953 float rh = (float)new_h / height;
1956 new_h = (int)((
float)new_h / rw);
1959 new_w = (int)((
float)new_w / rh);
1963 while(new_w > width || new_h > height) {
1964 if (new_w > width) {
1965 double m = (double) width / new_w;
1967 new_h = (int) (new_h * m);
1969 double m = (double) height / new_h;
1971 new_w = (int) (new_w * m);
1976 if (new_w && new_h) {
1995 #ifdef SWITCH_HAVE_YUV
2027 default: fourcc = FOURCC_ANY;
2036 #ifdef SWITCH_HAVE_YUV
2043 fourcc = switch_img_fmt2fourcc(fmt);
2045 if (fourcc == FOURCC_ANY) {
2050 ret = ConvertFromI420(src->planes[0], src->stride[0],
2051 src->planes[1], src->stride[1],
2052 src->planes[2], src->stride[2],
2065 #ifdef SWITCH_HAVE_YUV
2069 fourcc = switch_img_fmt2fourcc(fmt);
2071 if (fourcc == FOURCC_ANY) {
2079 if (width == 0 || height == 0) {
2098 ret = ConvertToI420(src, 0,
2099 dest->planes[0], dest->stride[0],
2100 dest->planes[1], dest->stride[1],
2101 dest->planes[2], dest->stride[2],
2115 #ifdef SWITCH_HAVE_YUV
2128 ret = I420Scale(src->planes[0], src->stride[0],
2129 src->planes[1], src->stride[1],
2130 src->planes[2], src->stride[2],
2170 *yP = (sh - ih) / 2;
2177 *xP = (sw - iw) / 2;
2181 *xP = (sw - iw) / 2;
2182 *yP = (sh - ih) / 2;
2185 *xP = (sw - iw) / 2;
2194 *yP = (sh - ih) / 2;
2208 gdImagePtr gd = NULL;
2212 if (!img)
return NULL;
2216 ext = strrchr(file_name,
'.');
2219 fp = fopen(file_name,
"rb");
2222 if (!strcmp(ext,
".png")) {
2223 gd = gdImageCreateFromPng(fp);
2224 }
else if (!strcmp(ext,
".gif")) {
2225 gd = gdImageCreateFromGif(fp);
2226 }
else if (!strcmp(ext,
".jpg") || !strcmp(ext,
".jpeg")) {
2227 gd = gdImageCreateFromJpeg(fp);
2253 const uint8_t *src_u,
int src_stride_u,
2254 const uint8_t *src_v,
int src_stride_v,
2255 uint8_t *dst_y,
int dst_stride_y,
2256 uint8_t *dst_u,
int dst_stride_u,
2257 uint8_t *dst_v,
int dst_stride_v,
2258 int width,
int height)
2260 #ifdef SWITCH_HAVE_YUV
2261 int ret = I420Copy(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
2262 dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v,
2271 uint8_t *dst_planes[],
int dst_stride[],
2272 int width,
int height)
2274 #ifdef SWITCH_HAVE_YUV
2275 int ret = I420Copy(src_planes[
SWITCH_PLANE_Y], src_stride[SWITCH_PLANE_Y],
2278 dst_planes[SWITCH_PLANE_Y], dst_stride[SWITCH_PLANE_Y],
2279 dst_planes[SWITCH_PLANE_U], dst_stride[SWITCH_PLANE_U],
2280 dst_planes[SWITCH_PLANE_V], dst_stride[SWITCH_PLANE_V],
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
void vpx_img_free(vpx_image_t *img)
Close an image descriptor.
switch_bool_t use_bgcolor
#define SWITCH_CHANNEL_LOG
vpx_image_t * vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
static struct pos_el POS_TABLE[]
switch_image_t * switch_img_read_file(const char *file_name)
switch_img_position_t pos
#define SWITCH_IMG_FMT_I444
#define SWITCH_IMG_FMT_RGB24
switch_image_t * switch_img_write_text_img(int w, int h, switch_bool_t full, const char *text)
int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
Set the rectangle identifying the displayed portion of the image.
#define SWITCH_IMG_MAX_HEIGHT
#define SWITCH_IMG_FMT_VPXYV12
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
#define switch_split(_data, _delim, _array)
#define SWITCH_IMG_FMT_I440
#define SWITCH_IMG_FMT_RGB555
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
switch_memory_pool_t * pool
void switch_img_rotate_copy(switch_image_t *img, switch_image_t **new_img, switch_image_rotation_mode_t mode)
Representation of a rectangle on a surface.
#define SWITCH_IMG_FMT_YVYU
switch_status_t switch_img_write_png(switch_image_t *img, char *file_name)
#define SWITCH_PLANE_PACKED
void switch_img_copy(switch_image_t *img, switch_image_t **new_img)
Copy image to a new image.
#define SWITCH_IMG_FMT_ARGB
switch_status_t switch_img_fit(switch_image_t **srcP, int width, int height, switch_img_fit_t fit)
#define SWITCH_IMG_FMT_RGB32
switch_image_t * switch_img_read_png(const char *file_name, switch_img_fmt_t img_fmt)
static void scv_tag(void *buffer, int w, int x, int y, uint8_t n)
#define SWITCH_IMG_FMT_I44416
void switch_img_patch_rect(switch_image_t *IMG, int X, int Y, switch_image_t *img, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
patch part of a small img (x,y,w,h) to a big IMG at position X,Y
switch_img_position_t parse_img_position(const char *name)
void switch_img_free(switch_image_t **img)
Close an image descriptor.
#define SWITCH_IMG_FMT_NONE
void switch_img_txt_handle_destroy(switch_img_txt_handle_t **handleP)
Free a text handle.
void switch_png_free(switch_png_t **pngP)
#define SWITCH_IMG_FMT_YV12
vpx_image_t * vpx_img_wrap(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align, unsigned char *img_data)
Open a descriptor, using existing storage for the underlying image.
switch_status_t switch_img_letterbox(switch_image_t *img, switch_image_t **imgP, int width, int height, const char *color)
switch_status_t switch_img_to_raw(switch_image_t *src, void *dest, switch_size_t size, switch_img_fmt_t fmt)
convert img to raw format
#define SWITCH_IMG_FMT_VPXI420
switch_png_opaque_t * pvt
#define SWITCH_IMG_FMT_RGB565_LE
#define SWITCH_IMG_FMT_GD
switch_memory_pool_t * pool
#define SWITCH_PATH_SEPARATOR
switch_status_t switch_img_patch_png(switch_image_t *img, int x, int y, const char *file_name)
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
#define switch_zmalloc(ptr, len)
unsigned char * planes[4]
void switch_img_rotate(switch_image_t **img, switch_image_rotation_mode_t mode)
Flip the image vertically (top for bottom)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
switch_byte_t switch_byte_t uint32_t switch_bitpack_mode_t mode
#define SWITCH_IMG_FMT_RGB32_LE
switch_image_t * switch_img_wrap(switch_image_t *img, switch_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align, unsigned char *img_data)
Open a descriptor, using existing storage for the underlying image.
#define SWITCH_IMG_FMT_PLANAR
switch_bool_t switch_core_has_video(void)
static struct fit_el IMG_FIT_TABLE[]
static void switch_img_draw_pixel(switch_image_t *img, int x, int y, switch_rgb_color_t *color)
Convert RGB color to YUV.
switch_status_t switch_png_patch_img(switch_png_t *use_png, switch_image_t *img, int x, int y)
uint32_t switch_img_txt_handle_render(switch_img_txt_handle_t *handle, switch_image_t *img, int x, int y, const char *text, const char *font_family, const char *font_color, const char *bgcolor, uint16_t font_size, double angle)
Render text to an img.
int switch_img_set_rect(switch_image_t *img, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
Set the rectangle identifying the displayed portion of the image.
vpx_img_fmt_t switch_img_fmt_t
#define SWITCH_IMG_FMT_I42216
static void switch_img_get_rgb_pixel(switch_image_t *img, switch_rgb_color_t *rgb, int x, int y)
switch_directories SWITCH_GLOBAL_dirs
void switch_img_overlay(switch_image_t *IMG, switch_image_t *img, int x, int y, uint8_t percent)
put a small img over a big IMG at position x,y, with alpha transparency
switch_status_t switch_I420_copy2(uint8_t *src_planes[], int src_stride[], uint8_t *dst_planes[], int dst_stride[], int width, int height)
switch_status_t switch_img_txt_handle_create(switch_img_txt_handle_t **handleP, const char *font_family, const char *font_color, const char *bgcolor, uint16_t font_size, double angle, switch_memory_pool_t *pool)
Created a text handle.
switch_status_t switch_file_exists(const char *filename, switch_memory_pool_t *pool)
void switch_img_add_text(void *buffer, int w, int x, int y, char *s)
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
static void init_gradient_table(switch_img_txt_handle_t *handle)
#define SWITCH_IMG_FMT_ARGB_LE
static uint8_t scv_art[14][16]
switch_status_t switch_png_open(switch_png_t **pngP, const char *file_name)
switch_status_t switch_img_from_raw(switch_image_t *dest, void *src, switch_img_fmt_t fmt, int width, int height)
convert raw memory to switch_img_t
switch_image_t * switch_img_alloc(switch_image_t *img, switch_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
static switch_bool_t switch_is_file_path(const char *file)
#define SWITCH_IMG_FMT_UYVY
#define SWITCH_IMG_FMT_I420
#define SWITCH_IMG_FMT_I44016
switch_img_fit_t parse_img_fit(const char *name)
#define SWITCH_IMG_FMT_BGR24
switch_status_t switch_img_scale(switch_image_t *src, switch_image_t **destP, int width, int height)
void switch_img_patch_hole(switch_image_t *IMG, switch_image_t *img, int x, int y, switch_image_rect_t *rect)
#define SWITCH_IMG_FMT_RGB555_LE
void switch_img_patch(switch_image_t *IMG, switch_image_t *img, int x, int y)
patch a small img to a big IMG at position x,y
uint32_t switch_u8_get_char(char *s, int *i)
struct apr_pool_t switch_memory_pool_t
#define SWITCH_IMG_FMT_444A
switch_status_t switch_I420_copy(const uint8_t *src_y, int src_stride_y, const uint8_t *src_u, int src_stride_u, const uint8_t *src_v, int src_stride_v, uint8_t *dst_y, int dst_stride_y, uint8_t *dst_u, int dst_stride_u, uint8_t *dst_v, int dst_stride_v, int width, int height)
I420 to I420 Copy.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define SWITCH_IMG_FMT_I42016
void switch_color_set_yuv(switch_yuv_color_t *color, const char *str)
Set YUV color with a string.
switch_image_rotation_mode_t
char * switch_core_sprintf(_In_ switch_memory_pool_t *pool, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the pool ...
#define SWITCH_IMG_FMT_RGB565
void switch_img_find_position(switch_img_position_t pos, int sw, int sh, int iw, int ih, int *xP, int *yP)
void switch_color_set_rgb(switch_rgb_color_t *color, const char *str)
Set RGB color with a string.
enum vpx_img_fmt vpx_img_fmt_t
List of supported image formats.
#define SWITCH_IMG_FMT_I422
void switch_img_fill(switch_image_t *img, int x, int y, int w, int h, switch_rgb_color_t *color)
Fill image with color.
#define SWITCH_IMG_MAX_WIDTH
switch_rgb_color_t bgcolor
switch_image_t * switch_img_copy_rect(switch_image_t *img, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
Copy part of an image to a new image.
#define SWITCH_IMG_FMT_YUY2
switch_rgb_color_t gradient_table[MAX_GRADIENT]