]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[core] add jpg data_url support with stb_image
authorSeven Du <dujinfang@gmail.com>
Wed, 6 Mar 2019 04:00:15 +0000 (12:00 +0800)
committerAndrey Volk <andywolk@gmail.com>
Sat, 23 Oct 2021 19:00:03 +0000 (22:00 +0300)
src/include/switch_core_video.h
src/switch_core_video.c
tests/unit/switch_core_video.c

index 4fb7d824c0699c361906447efc849d8208fd1d1a..1af0dec7ac05c867577a4f5e50af6e130faacd21 100644 (file)
@@ -395,13 +395,14 @@ SWITCH_DECLARE(switch_status_t) switch_img_write_png(switch_image_t *img, char *
 SWITCH_DECLARE(switch_status_t) switch_png_open(switch_png_t **pngP, const char *file_name);
 SWITCH_DECLARE(void) switch_png_free(switch_png_t **pngP);
 SWITCH_DECLARE(switch_status_t) switch_img_data_url_png(switch_image_t *img, char **urlP);
+SWITCH_DECLARE(switch_status_t) switch_img_data_url(switch_image_t *img, char **urlP, const char *type, int quality);
 
 /*!\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
+* \param[in]    quality   Only used in jpg, 1 ~ 100
 */
 SWITCH_DECLARE(switch_status_t) switch_img_write_to_file(switch_image_t *img, const char* file_name, int quality);
 
index ee44223f641fd840f34f0297fb1232c1881e817b..6a9351cdaad620ec74e1c0393b870f6ab5a4f3bb 100644 (file)
@@ -3211,6 +3211,90 @@ SWITCH_DECLARE(switch_status_t) switch_img_write_to_file(switch_image_t *img, co
        return ret ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
 }
 
+typedef struct data_url_context_s {
+       const char *type;
+       char **urlP;
+} data_url_context_t;
+
+static void data_url_write_func(void *context, void *data, int size)
+{
+       switch_buffer_t *buffer = (switch_buffer_t *)context;
+       switch_buffer_write(buffer, data, size);
+}
+
+SWITCH_DECLARE(switch_status_t) switch_img_data_url(switch_image_t *img, char **urlP, const char *type, int quality)
+{
+       int comp = STBI_rgb;
+       unsigned char *data = NULL;
+       int stride_in_bytes = 0;
+       int ret = 0;
+       switch_buffer_t *buffer = NULL;
+       const char *header = NULL;
+       int header_len = 0;
+
+       if (!type) return SWITCH_STATUS_FALSE;
+
+       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;
+       }
+
+       switch_buffer_create_dynamic(&buffer, 1024, 1024, 0);
+
+       if (!strcmp(type, "png")) {
+               header = "data:image/png;base64,";
+               ret = stbi_write_png_to_func(data_url_write_func, (void *)buffer, img->d_w, img->d_h, comp, (const void *)data, stride_in_bytes);
+       } else if (!strcmp(type, "jpeg") || !strcmp(type, "jpeg")) {
+               header = "data:image/jpeg;base64,";
+               ret = stbi_write_jpg_to_func(data_url_write_func, (void *)buffer, img->d_w, img->d_h, comp, (const void *)data, quality);
+       } else {
+               ret = 0;
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unsupported file format [%s]\n", type);
+       }
+
+       if (ret && switch_buffer_inuse(buffer) > 0) {
+               switch_size_t blen = switch_buffer_inuse(buffer);
+               switch_size_t olen = blen * 4 + strlen(header) + 1;
+               uint8_t *data = switch_buffer_get_head_pointer(buffer);
+               unsigned char *out = NULL;
+
+               switch_zmalloc(out, olen);
+               header_len = strlen(header);
+               memcpy(out, header, header_len);
+               switch_b64_encode(data, blen, out + header_len, olen - header_len);
+               *urlP = (char *)out;
+       }
+
+       free(data);
+       switch_buffer_destroy(&buffer);
+
+       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;
index 219a0acb634550a831b6108ea9d49ad454aa6f62..ec30a43a05bbf7d5d7dac328ef60dec6d3a32376 100644 (file)
@@ -200,6 +200,32 @@ FST_CORE_BEGIN("./conf")
                }
                FST_TEST_END()
 
+               FST_TEST_BEGIN(stb_data_url)
+               {
+                       switch_image_t *img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, 120, 60, 1);
+                       switch_image_t *argb_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_ARGB, 120, 60, 1);
+                       switch_rgb_color_t color = { 0 };
+                       color.r = 255;
+                       // color.g = 255;
+                       // color.b = 255;
+                       char *data_url = NULL;
+
+                       switch_img_fill(img, 0, 0, img->d_w, img->d_h, &color);
+                       switch_img_add_text(img->planes[0], img->d_w, 10, 10, "-1234567890");
+
+                       switch_img_data_url(img, &data_url, "png", 0);
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "PNG: %s\n", data_url);
+                       free(data_url);
+                       data_url = NULL;
+
+                       switch_img_data_url(img, &data_url, "jpeg", 50);
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "JPG: %s\n", data_url);
+
+                       free(data_url);
+                       switch_img_free(&img);
+               }
+               FST_TEST_END()
+
                FST_TEST_BEGIN(read_from_file)
                {
                        switch_image_t *img;