Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
521a9793
提交
521a9793
authored
2月 12, 2015
作者:
Anthony Minessale
提交者:
Michael Jerris
5月 28, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
FS-7500: check in png code and put it in the core to mature
上级
e84d7b8c
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
403 行增加
和
4 行删除
+403
-4
Makefile.am
Makefile.am
+2
-2
configure.ac
configure.ac
+6
-0
switch_core_video.h
src/include/switch_core_video.h
+5
-0
Makefile.am
src/mod/applications/mod_conference/Makefile.am
+1
-1
switch_core_video.c
src/switch_core_video.c
+389
-1
没有找到文件。
Makefile.am
浏览文件 @
521a9793
...
...
@@ -153,9 +153,9 @@ libfreeswitch_spandsp_la_SOURCES = libs/spandsp/src/plc.c libs/spandsp/src/alloc
libfreeswitch_spandsp_la_CFLAGS
=
-Ilibs
/spandsp/src
$(CORE_CFLAGS)
$(AM_CFLAGS)
CORE_LIBS
+=
libfreeswitch_spandsp.la
lib_LTLIBRARIES
=
libfreeswitch.la
libfreeswitch_la_CFLAGS
=
$(CORE_CFLAGS)
$(SQLITE_CFLAGS)
$(FREETYPE_CFLAGS)
$(CURL_CFLAGS)
$(PCRE_CFLAGS)
$(SPEEX_CFLAGS)
$(LIBEDIT_CFLAGS)
$(openssl_CFLAGS)
$(AM_CFLAGS)
libfreeswitch_la_CFLAGS
=
$(CORE_CFLAGS)
$(SQLITE_CFLAGS)
$(
LIBPNG_CFLAGS)
$(
FREETYPE_CFLAGS)
$(CURL_CFLAGS)
$(PCRE_CFLAGS)
$(SPEEX_CFLAGS)
$(LIBEDIT_CFLAGS)
$(openssl_CFLAGS)
$(AM_CFLAGS)
libfreeswitch_la_LDFLAGS
=
-version-info
1:0:0
$(AM_LDFLAGS)
$(PLATFORM_CORE_LDFLAGS)
-no-undefined
libfreeswitch_la_LIBADD
=
$(CORE_LIBS)
$(APR_LIBS)
$(SQLITE_LIBS)
$(FREETYPE_LIBS)
$(CURL_LIBS)
$(PCRE_LIBS)
$(SPEEX_LIBS)
$(LIBEDIT_LIBS)
$(openssl_LIBS)
$(VPX_LIBS)
$(PLATFORM_CORE_LIBS)
libfreeswitch_la_LIBADD
=
$(CORE_LIBS)
$(APR_LIBS)
$(SQLITE_LIBS)
$(
LIBPNG_LIBS)
$(
FREETYPE_LIBS)
$(CURL_LIBS)
$(PCRE_LIBS)
$(SPEEX_LIBS)
$(LIBEDIT_LIBS)
$(openssl_LIBS)
$(VPX_LIBS)
$(PLATFORM_CORE_LIBS)
libfreeswitch_la_DEPENDENCIES
=
$(BUILT_SOURCES)
if
HAVE_ODBC
...
...
configure.ac
浏览文件 @
521a9793
...
...
@@ -755,6 +755,11 @@ if test "x$have_libz" = "xyes" ; then
APR_ADDTO([PLATFORM_CORE_LIBS], [-lz])
fi
AC_CHECK_LIB(yuv, I420Scale, have_libyuv=yes, AC_MSG_ERROR([no usable libyuv; please install libyuv devel package or equivalent]))
if test "x$have_libyuv" = "xyes" ; then
APR_ADDTO([PLATFORM_CORE_LIBS], [-lyuv])
fi
AC_CHECK_LIB(apr-1, apr_pool_mutex_set, use_system_apr=yes, use_system_apr=no)
AM_CONDITIONAL([SYSTEM_APR],[test "${use_system_apr}" = "yes"])
AC_CHECK_LIB(aprutil-1, apr_queue_pop_timeout, use_system_aprutil=yes, use_system_aprutil=no)
...
...
@@ -1192,6 +1197,7 @@ module_enabled() {
grep -v -e "\#" -e "^\$" modules.conf | sed -e "s|^.*/||" | grep "^${1}\$" >/dev/null
}
PKG_CHECK_MODULES([LIBPNG], [libpng12 >= 1.2.49])
PKG_CHECK_MODULES([FREETYPE], [freetype2 >= 2.4.9])
PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.6.20])
PKG_CHECK_MODULES([CURL], [libcurl >= 7.19])
...
...
src/include/switch_core_video.h
浏览文件 @
521a9793
...
...
@@ -191,6 +191,11 @@ SWITCH_DECLARE(switch_status_t) switch_img_txt_handle_render(switch_img_txt_hand
int
x
,
int
y
,
const
char
*
text
,
const
char
*
font_family
,
const
char
*
font_color
,
const
char
*
bgcolor
,
uint16_t
font_size
,
double
angle
);
SWITCH_DECLARE
(
void
)
switch_img_patch_hole
(
switch_image_t
*
IMG
,
switch_image_t
*
img
,
int
x
,
int
y
,
switch_image_rect_t
*
rect
);
SWITCH_DECLARE
(
switch_image_t
*
)
switch_img_read_png
(
char
*
file_name
);
SWITCH_DECLARE
(
void
)
switch_img_write_png
(
switch_image_t
*
img
,
char
*
file_name
);
/** @} */
SWITCH_END_EXTERN_C
...
...
src/mod/applications/mod_conference/Makefile.am
浏览文件 @
521a9793
...
...
@@ -5,7 +5,7 @@ mod_LTLIBRARIES = mod_conference.la
mod_conference_la_SOURCES
=
mod_conference.c
mod_conference_la_CFLAGS
=
$(AM_CFLAGS)
-I
.
mod_conference_la_LIBADD
=
$(switch_builddir)
/libfreeswitch.la
mod_conference_la_LDFLAGS
=
-avoid-version
-module
-no-undefined
-shared
-lyuv
-lfreetype
mod_conference_la_LDFLAGS
=
-avoid-version
-module
-no-undefined
-shared
if
HAVE_OPENAL
mod_conference_la_LDFLAGS
+=
-lopenal
-lm
...
...
src/switch_core_video.c
浏览文件 @
521a9793
...
...
@@ -31,7 +31,7 @@
#include <switch.h>
#include <switch_utf8.h>
#include <libyuv.h>
SWITCH_DECLARE
(
switch_image_t
*
)
switch_img_alloc
(
switch_image_t
*
img
,
switch_img_fmt_t
fmt
,
...
...
@@ -545,6 +545,394 @@ SWITCH_DECLARE(switch_status_t) switch_img_txt_handle_render(switch_img_txt_hand
}
/* WARNING:
patch a big IMG with a rect hole, note this function is WIP ......
It ONLY works when the hole is INSIDE the big IMG and the place the small img will patch to,
more sanity checks need to be decided
*/
SWITCH_DECLARE
(
void
)
switch_img_patch_hole
(
switch_image_t
*
IMG
,
switch_image_t
*
img
,
int
x
,
int
y
,
switch_image_rect_t
*
rect
)
{
int
i
,
len
;
switch_assert
(
img
->
fmt
==
SWITCH_IMG_FMT_I420
);
switch_assert
(
IMG
->
fmt
==
SWITCH_IMG_FMT_I420
);
len
=
MIN
(
img
->
d_w
,
IMG
->
d_w
-
x
);
if
(
len
<=
0
)
return
;
for
(
i
=
y
;
i
<
(
y
+
img
->
d_h
)
&&
i
<
IMG
->
d_h
;
i
++
)
{
if
(
rect
&&
i
>=
rect
->
y
&&
i
<
(
rect
->
y
+
rect
->
h
))
{
int
size
=
rect
->
x
>
x
?
rect
->
x
-
x
:
0
;
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_Y
]
+
IMG
->
stride
[
SWITCH_PLANE_Y
]
*
i
+
x
,
img
->
planes
[
SWITCH_PLANE_Y
]
+
img
->
stride
[
SWITCH_PLANE_Y
]
*
(
i
-
y
),
size
);
size
=
MIN
(
img
->
d_w
-
rect
->
w
-
size
,
IMG
->
d_w
-
(
rect
->
x
+
rect
->
w
));
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_Y
]
+
IMG
->
stride
[
SWITCH_PLANE_Y
]
*
i
+
rect
->
x
+
rect
->
w
,
img
->
planes
[
SWITCH_PLANE_Y
]
+
img
->
stride
[
SWITCH_PLANE_Y
]
*
(
i
-
y
)
+
rect
->
w
+
(
rect
->
x
-
x
),
size
);
}
else
{
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_Y
]
+
IMG
->
stride
[
SWITCH_PLANE_Y
]
*
i
+
x
,
img
->
planes
[
SWITCH_PLANE_Y
]
+
img
->
stride
[
SWITCH_PLANE_Y
]
*
(
i
-
y
),
len
);
}
}
len
/=
2
;
for
(
i
=
y
;
i
<
(
y
+
img
->
d_h
)
&&
i
<
IMG
->
d_h
;
i
+=
2
)
{
if
(
rect
&&
i
>
rect
->
y
&&
i
<
(
rect
->
y
+
rect
->
h
))
{
int
size
=
rect
->
x
>
x
?
rect
->
x
-
x
:
0
;
size
/=
2
;
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_U
]
+
IMG
->
stride
[
SWITCH_PLANE_U
]
*
i
/
2
+
x
/
2
,
img
->
planes
[
SWITCH_PLANE_U
]
+
img
->
stride
[
SWITCH_PLANE_U
]
*
(
i
-
y
)
/
2
,
size
);
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_V
]
+
IMG
->
stride
[
SWITCH_PLANE_V
]
*
i
/
2
+
x
/
2
,
img
->
planes
[
SWITCH_PLANE_V
]
+
img
->
stride
[
SWITCH_PLANE_V
]
*
(
i
-
y
)
/
2
,
size
);
size
=
MIN
(
img
->
d_w
-
rect
->
w
-
size
,
IMG
->
d_w
-
(
rect
->
x
+
rect
->
w
))
/
2
;
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_U
]
+
IMG
->
stride
[
SWITCH_PLANE_U
]
*
i
/
2
+
(
rect
->
x
+
rect
->
w
)
/
2
,
img
->
planes
[
SWITCH_PLANE_U
]
+
img
->
stride
[
SWITCH_PLANE_U
]
*
(
i
-
y
)
/
2
+
(
rect
->
w
+
(
rect
->
x
-
x
))
/
2
,
size
);
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_V
]
+
IMG
->
stride
[
SWITCH_PLANE_V
]
*
i
/
2
+
(
rect
->
x
+
rect
->
w
)
/
2
,
img
->
planes
[
SWITCH_PLANE_V
]
+
img
->
stride
[
SWITCH_PLANE_V
]
*
(
i
-
y
)
/
2
+
(
rect
->
w
+
(
rect
->
x
-
x
))
/
2
,
size
);
}
else
{
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_U
]
+
IMG
->
stride
[
SWITCH_PLANE_U
]
*
i
/
2
+
x
/
2
,
img
->
planes
[
SWITCH_PLANE_U
]
+
img
->
stride
[
SWITCH_PLANE_U
]
*
(
i
-
y
)
/
2
,
len
);
memcpy
(
IMG
->
planes
[
SWITCH_PLANE_V
]
+
IMG
->
stride
[
SWITCH_PLANE_V
]
*
i
/
2
+
x
/
2
,
img
->
planes
[
SWITCH_PLANE_V
]
+
img
->
stride
[
SWITCH_PLANE_V
]
*
(
i
-
y
)
/
2
,
len
);
}
}
}
#define SWITCH_IMG_MAX_WIDTH 1920 * 2
#define SWITCH_IMG_MAX_HEIGHT 1080 * 2
// WIP png functions, need furthur tweak/check to make sure it works on all png files and errors are properly detected and reported
// #define PNG_DEBUG 3
#define PNG_SKIP_SETJMP_CHECK
#include <png.h>
// ref: most are out-dated, man libpng :)
// http://zarb.org/~gc/html/libpng.html
// http://www.libpng.org/pub/png/book/toc.html
// http://www.vias.org/pngguide/chapter01_03_02.html
// http://www.libpng.org/pub/png/libpng-1.2.5-manual.html
// ftp://ftp.oreilly.com/examples/9781565920583/CDROM/SOFTWARE/SOURCE/LIBPNG/EXAMPLE.C
SWITCH_DECLARE
(
switch_image_t
*
)
switch_img_read_png
(
char
*
file_name
)
{
png_byte
header
[
8
];
// 8 is the maximum size that can be checked
png_bytep
*
row_pointers
=
NULL
;
int
y
;
int
width
,
height
;
png_byte
color_type
;
png_byte
bit_depth
;
png_structp
png_ptr
;
png_infop
info_ptr
;
//int number_of_passes;
int
row_bytes
;
png_color_8p
sig_bit
;
// png_color_16 my_background = { 0 }; //{index,r, g, b, grey}
png_color_16
my_background
=
{
0
,
99
,
99
,
99
,
0
};
png_byte
*
buffer
=
NULL
;
switch_image_t
*
img
=
NULL
;
/* open file and test for it being a png */
FILE
*
fp
=
fopen
(
file_name
,
"rb"
);
if
(
!
fp
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"File %s could not be opened for reading"
,
file_name
);
goto
end
;
}
fread
(
header
,
1
,
8
,
fp
);
if
(
png_sig_cmp
(
header
,
0
,
8
))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"File %s is not recognized as a PNG file"
,
file_name
);
goto
end
;
}
png_ptr
=
png_create_read_struct
(
PNG_LIBPNG_VER_STRING
,
NULL
,
NULL
,
NULL
);
if
(
!
png_ptr
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"png_create_read_struct failed"
);
goto
end
;
}
info_ptr
=
png_create_info_struct
(
png_ptr
);
if
(
!
info_ptr
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"png_create_info_struct failed"
);
goto
end
;
}
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Error during init_io"
);
goto
end
;
}
png_init_io
(
png_ptr
,
fp
);
png_set_sig_bytes
(
png_ptr
,
8
);
png_read_info
(
png_ptr
,
info_ptr
);
width
=
png_get_image_width
(
png_ptr
,
info_ptr
);
height
=
png_get_image_height
(
png_ptr
,
info_ptr
);
color_type
=
png_get_color_type
(
png_ptr
,
info_ptr
);
bit_depth
=
png_get_bit_depth
(
png_ptr
,
info_ptr
);
//number_of_passes = png_set_interlace_handling(png_ptr);
/* set up the transformations you want. Note that these are
all optional. Only call them if you want them */
/* expand paletted colors into true rgb */
if
(
color_type
==
PNG_COLOR_TYPE_PALETTE
)
{
png_set_expand
(
png_ptr
);
}
/* expand grayscale images to the full 8 bits */
if
(
color_type
==
PNG_COLOR_TYPE_GRAY
&&
bit_depth
<
8
)
{
png_set_expand
(
png_ptr
);
}
/* expand images with transparency to full alpha channels */
if
(
png_get_valid
(
png_ptr
,
info_ptr
,
PNG_INFO_tRNS
))
{
png_set_expand
(
png_ptr
);
}
/* Set the background color to draw transparent and alpha
images over */
if
(
png_get_valid
(
png_ptr
,
info_ptr
,
PNG_INFO_bKGD
))
{
// png_get_bKGD(png_ptr, info_ptr, &my_background);
// png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
}
else
{
png_set_background
(
png_ptr
,
&
my_background
,
PNG_BACKGROUND_GAMMA_SCREEN
,
0
,
1
.
0
);
}
/* tell libpng to handle the gamma conversion for you */
if
(
png_get_valid
(
png_ptr
,
info_ptr
,
PNG_INFO_gAMA
))
{
// png_set_gamma(png_ptr, screen_gamma, info_ptr->gamma);
}
else
{
// png_set_gamma(png_ptr, screen_gamma, 0.45);
}
/* tell libpng to strip 16 bit depth files down to 8 bits */
if
(
bit_depth
==
16
)
{
png_set_strip_16
(
png_ptr
);
}
#if 0
/* dither rgb files down to 8 bit palettes & reduce palettes
to the number of colors available on your screen */
if (0 && color_type & PNG_COLOR_MASK_COLOR) {
if (png_get_valid(png_ptr, info_ptr, & PNG_INFO_PLTE)) {
png_set_dither(png_ptr, info_ptr->palette,
info_ptr->num_palette, max_screen_colors,
info_ptr->histogram);
} else {
png_color std_color_cube[MAX_SCREEN_COLORS] =
{/* ... colors ... */};
png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
MAX_SCREEN_COLORS, NULL);
}
}
#endif
/* invert monocrome files */
if
(
bit_depth
==
1
&&
color_type
==
PNG_COLOR_TYPE_GRAY
)
{
// png_set_invert(png_ptr);
}
png_get_sBIT
(
png_ptr
,
info_ptr
,
&
sig_bit
);
/* shift the pixels down to their true bit depth */
// if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT) && (bit_depth > (*sig_bit).red)) {
// png_set_shift(png_ptr, sig_bit);
// }
/* pack pixels into bytes */
if
(
bit_depth
<
8
)
{
png_set_packing
(
png_ptr
);
}
/* flip the rgb pixels to bgr */
if
(
color_type
==
PNG_COLOR_TYPE_RGB
||
color_type
==
PNG_COLOR_TYPE_RGB_ALPHA
)
{
// png_set_bgr(png_ptr);
}
/* swap bytes of 16 bit files to least significant bit first */
if
(
bit_depth
==
16
)
{
png_set_swap
(
png_ptr
);
}
if
(
color_type
&
PNG_COLOR_MASK_ALPHA
)
{
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Error!!!!
\n
"
);
goto
end
;
}
png_set_strip_alpha
(
png_ptr
);
}
png_read_update_info
(
png_ptr
,
info_ptr
);
if
(
width
>
SWITCH_IMG_MAX_WIDTH
||
height
>
SWITCH_IMG_MAX_HEIGHT
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"PNG is too large! %dx%d
\n
"
,
width
,
height
);
}
row_bytes
=
png_get_rowbytes
(
png_ptr
,
info_ptr
);
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size: %dx%d row_bytes:%d color_type:%d bit_dept:%d\n", width, height, row_bytes, color_type, bit_depth);
row_pointers
=
(
png_bytep
*
)
malloc
(
sizeof
(
png_bytep
)
*
height
);
switch_assert
(
row_pointers
);
buffer
=
(
png_byte
*
)
malloc
(
row_bytes
*
height
);
switch_assert
(
buffer
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
row_pointers
[
y
]
=
buffer
+
row_bytes
*
y
;
}
if
(
color_type
==
PNG_COLOR_TYPE_PALETTE
)
{
png_set_palette_to_rgb
(
png_ptr
);
}
img
=
switch_img_alloc
(
NULL
,
SWITCH_IMG_FMT_I420
,
width
,
height
,
1
);
switch_assert
(
img
);
/* read file */
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Error during read_image"
);
goto
end
;
}
png_read_image
(
png_ptr
,
row_pointers
);
if
(
png_get_color_type
(
png_ptr
,
info_ptr
)
==
PNG_COLOR_TYPE_RGBA
)
{
// should never get here since we already use png_set_strip_alpha() ?
switch_assert
(
1
==
2
);
switch_assert
(
row_bytes
>=
width
*
4
);
for
(
y
=
1
;
y
<
height
;
y
++
)
{
memcpy
(
buffer
+
y
*
width
*
4
,
row_pointers
[
y
],
width
*
4
);
}
// ABGRToI420(buffer, width * 4,
RGBAToI420
(
buffer
,
width
*
4
,
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
],
width
,
height
);
}
else
if
(
png_get_color_type
(
png_ptr
,
info_ptr
)
==
PNG_COLOR_TYPE_RGB
)
{
switch_assert
(
row_bytes
>=
width
*
3
);
for
(
y
=
1
;
y
<
height
;
y
++
)
{
memcpy
(
buffer
+
y
*
width
*
3
,
row_pointers
[
y
],
width
*
3
);
}
RAWToI420
(
buffer
,
width
*
3
,
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
],
width
,
height
);
}
else
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"unsupported color type: %d
\n
"
,
png_get_color_type
(
png_ptr
,
info_ptr
));
}
end
:
switch_safe_free
(
buffer
);
switch_safe_free
(
row_pointers
);
if
(
fp
)
fclose
(
fp
);
if
(
info_ptr
)
png_destroy_read_struct
(
&
png_ptr
,
&
info_ptr
,
NULL
);
return
img
;
}
SWITCH_DECLARE
(
void
)
switch_img_write_png
(
switch_image_t
*
img
,
char
*
file_name
)
{
int
width
,
height
;
png_byte
color_type
;
png_byte
bit_depth
;
png_structp
png_ptr
;
png_infop
info_ptr
;
png_bytep
*
row_pointers
=
NULL
;
int
row_bytes
;
int
y
;
png_byte
*
buffer
=
NULL
;
FILE
*
fp
=
NULL
;
width
=
img
->
d_w
;
height
=
img
->
d_h
;
bit_depth
=
8
;
color_type
=
PNG_COLOR_TYPE_RGB
;
fp
=
fopen
(
file_name
,
"wb"
);
if
(
!
fp
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"File %s could not be opened for writing"
,
file_name
);
goto
end
;
}
png_ptr
=
png_create_write_struct
(
PNG_LIBPNG_VER_STRING
,
NULL
,
NULL
,
NULL
);
if
(
!
png_ptr
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"png_create_write_struct failed"
);
goto
end
;
}
info_ptr
=
png_create_info_struct
(
png_ptr
);
if
(
!
info_ptr
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"png_create_info_struct failed"
);
goto
end
;
}
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Error during init_io"
);
goto
end
;
}
png_init_io
(
png_ptr
,
fp
);
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Error during writing header"
);
goto
end
;
}
png_set_IHDR
(
png_ptr
,
info_ptr
,
width
,
height
,
bit_depth
,
color_type
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_BASE
,
PNG_FILTER_TYPE_BASE
);
png_write_info
(
png_ptr
,
info_ptr
);
row_bytes
=
png_get_rowbytes
(
png_ptr
,
info_ptr
);
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"size: %dx%d row_bytes:%d color_type:%d bit_dept:%d
\n
"
,
width
,
height
,
row_bytes
,
color_type
,
bit_depth
);
row_pointers
=
(
png_bytep
*
)
malloc
(
sizeof
(
png_bytep
)
*
height
);
switch_assert
(
row_pointers
);
buffer
=
(
png_byte
*
)
malloc
(
row_bytes
*
height
);
switch_assert
(
buffer
);
for
(
y
=
0
;
y
<
height
;
y
++
)
{
row_pointers
[
y
]
=
buffer
+
row_bytes
*
y
;
}
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
],
buffer
,
width
*
3
,
width
,
height
);
for
(
y
=
height
-
1
;
y
>
0
;
y
--
)
{
// todo, check overlaps
memcpy
(
row_pointers
[
y
],
buffer
+
row_bytes
*
y
,
width
*
3
);
}
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Error during writing bytes"
);
goto
end
;
}
png_write_image
(
png_ptr
,
row_pointers
);
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Error during end of write"
);
goto
end
;
}
png_write_end
(
png_ptr
,
NULL
);
end
:
switch_safe_free
(
buffer
);
switch_safe_free
(
row_pointers
);
fclose
(
fp
);
png_destroy_write_struct
(
&
png_ptr
,
&
info_ptr
);
}
/* For Emacs:
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论