[core] add stb_image_write supported image write

This commit is contained in:
Seven Du 2019-03-06 10:28:40 +08:00 committed by Andrey Volk
parent 58d5442dc5
commit 2a87e7b98c
4 changed files with 1718 additions and 2 deletions

1622
libs/stb/stb_image_write.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -398,7 +398,13 @@ SWITCH_DECLARE(switch_status_t) switch_img_data_url_png(switch_image_t *img, cha
/*!\brief Read an image file to switch_image_t */
SWITCH_DECLARE(switch_image_t *) switch_img_read_from_file(const char *file_name, switch_img_fmt_t img_fmt);
/*!\brief Write an image file, supported formats png,jpg,bmp,tga,hdr
* \param[in] img The image descriptor
* \param[in] file_name The file_name to write
* \param[in] quality Only used in jpg, 0 ~ 100
*/
SWITCH_DECLARE(switch_status_t) switch_img_write_to_file(switch_image_t *img, const char* file_name, int quality);
/*!\brief put a small img over a big IMG at position x,y, with alpha transparency
*
* Both IMG and img must be non-NULL

View File

@ -51,6 +51,9 @@
#define STB_IMAGE_IMPLEMENTATION
#include "../libs/stb/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "../libs/stb/stb_image_write.h"
#ifdef SWITCH_HAVE_YUV
static inline void switch_img_get_yuv_pixel(switch_image_t *img, switch_yuv_color_t *yuv, int x, int y);
#endif
@ -3105,7 +3108,7 @@ SWITCH_DECLARE(switch_status_t) switch_img_data_url_png(switch_image_t *img, cha
SWITCH_DECLARE(switch_image_t *) switch_img_read_from_file(const char* file_name, switch_img_fmt_t img_fmt)
{
int width = 0, height = 0, channels = 8;
int width = 0, height = 0, channels = 0;
int comp = STBI_rgb;
unsigned char *data = NULL;
@ -3148,6 +3151,66 @@ SWITCH_DECLARE(switch_image_t *) switch_img_read_from_file(const char* file_name
return NULL;
}
SWITCH_DECLARE(switch_status_t) switch_img_write_to_file(switch_image_t *img, const char* file_name, int quality)
{
int comp = STBI_rgb;
unsigned char *data = NULL;
const char *ext = strrchr(file_name, '.');
int stride_in_bytes = 0;
int ret = 0;
if (!ext) return SWITCH_STATUS_FALSE;
ext++;
if (img->fmt == SWITCH_IMG_FMT_I420) {
comp = STBI_rgb;
stride_in_bytes = img->d_w * 3;
data = malloc(stride_in_bytes * img->d_h);
switch_assert(data);
I420ToRAW(img->planes[SWITCH_PLANE_Y], img->stride[SWITCH_PLANE_Y],
img->planes[SWITCH_PLANE_U], img->stride[SWITCH_PLANE_U],
img->planes[SWITCH_PLANE_V], img->stride[SWITCH_PLANE_V],
data, stride_in_bytes,
img->d_w, img->d_h);
} else if (img->fmt == SWITCH_IMG_FMT_ARGB) {
comp = STBI_rgb_alpha;
stride_in_bytes = img->d_w * 4;
data = malloc(stride_in_bytes * img->d_h);
switch_assert(data);
#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
ARGBToRGBA(img->planes[SWITCH_PLANE_PACKED], stride_in_bytes, data, stride_in_bytes, img->d_w, img->d_h);
#else
ARGBToABGR(img->planes[SWITCH_PLANE_PACKED], stride_in_bytes, data, stride_in_bytes, img->d_w, img->d_h);
#endif
} else {
return SWITCH_STATUS_FALSE;
}
if (!strcasecmp(ext, "png")) {
ret = stbi_write_png(file_name, img->d_w, img->d_h, comp, (const void *)data, stride_in_bytes);
} else if (!strcasecmp(ext, "jpg") || !strcasecmp(ext, "jpeg")) {
ret = stbi_write_jpg(file_name, img->d_w, img->d_h, comp, (const void *)data, quality);
} else if (!strcasecmp(ext, "bmp")) {
ret = stbi_write_bmp(file_name, img->d_w, img->d_h, comp, (const void *)data);
} else if (!strcasecmp(ext, "tga")) {
ret = stbi_write_tga(file_name, img->d_w, img->d_h, comp, (const void *)data);
} else if (!strcasecmp(ext, "hdr")) {
ret = stbi_write_hdr(file_name, img->d_w, img->d_h, comp, (const float *)data);
} else {
ret = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unsupported file format [%s]", ext);
}
free(data);
return ret ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
SWITCH_DECLARE(switch_status_t) switch_img_letterbox(switch_image_t *img, switch_image_t **imgP, int width, int height, const char *color)
{
int img_w = 0, img_h = 0;

View File

@ -220,6 +220,31 @@ FST_CORE_BEGIN("./conf")
switch_img_free(&img);
}
FST_TEST_END()
FST_TEST_BEGIN(write_to_file)
{
switch_image_t *img;
switch_status_t status;
img = switch_img_read_from_file("../../images/cluecon.png", SWITCH_IMG_FMT_I420);
fst_requires(img);
status = switch_img_write_to_file(img, "cluecon-rgb-write.png", 0);
switch_img_free(&img);
fst_check(status == SWITCH_STATUS_SUCCESS);
img = switch_img_read_from_file("../../images/cluecon.png", SWITCH_IMG_FMT_ARGB);
fst_requires(img);
status = switch_img_write_to_file(img, "cluecon-argb-write.png", 0);
switch_img_free(&img);
fst_check(status == SWITCH_STATUS_SUCCESS);
img = switch_img_read_from_file("../../images/cluecon.jpg", SWITCH_IMG_FMT_I420);
fst_requires(img);
status = switch_img_write_to_file(img, "cluecon-jpg-write.jpg", 100);
switch_img_free(&img);
fst_check(status == SWITCH_STATUS_SUCCESS);
}
FST_TEST_END()
}
FST_SUITE_END()
}