Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
858f38cf
Commit
858f38cf
authored
Feb 14, 2014
by
Tristan Matthews
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
png: add encoder
parent
453264d4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
194 additions
and
6 deletions
+194
-6
modules/codec/png.c
modules/codec/png.c
+194
-6
No files found.
modules/codec/png.c
View file @
858f38cf
...
...
@@ -33,12 +33,31 @@
#include <vlc_codec.h>
#include <png.h>
/* PNG_SYS_COMMON_MEMBERS:
* members common to encoder and decoder descriptors
*/
#define PNG_SYS_COMMON_MEMBERS \
/**@{*/
\
bool b_error; \
vlc_object_t *p_obj; \
/**@}*/
\
/*
* png common descriptor
*/
struct
png_sys_t
{
PNG_SYS_COMMON_MEMBERS
};
typedef
struct
png_sys_t
png_sys_t
;
/*****************************************************************************
* decoder_sys_t : png decoder descriptor
*****************************************************************************/
struct
decoder_sys_t
{
bool
b_error
;
PNG_SYS_COMMON_MEMBERS
};
/*****************************************************************************
...
...
@@ -49,6 +68,20 @@ static void CloseDecoder ( vlc_object_t * );
static
picture_t
*
DecodeBlock
(
decoder_t
*
,
block_t
**
);
/*
* png encoder descriptor
*/
struct
encoder_sys_t
{
PNG_SYS_COMMON_MEMBERS
int
i_blocksize
;
};
static
int
OpenEncoder
(
vlc_object_t
*
);
static
void
CloseEncoder
(
vlc_object_t
*
);
static
block_t
*
EncodeBlock
(
encoder_t
*
,
picture_t
*
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
...
...
@@ -59,6 +92,14 @@ vlc_module_begin ()
set_capability
(
"decoder"
,
1000
)
set_callbacks
(
OpenDecoder
,
CloseDecoder
)
add_shortcut
(
"png"
)
/* encoder submodule */
add_submodule
()
add_shortcut
(
"png"
)
set_section
(
N_
(
"Encoding"
),
NULL
)
set_description
(
N_
(
"PNG video encoder"
))
set_capability
(
"encoder"
,
1000
)
set_callbacks
(
OpenEncoder
,
CloseEncoder
)
vlc_module_end
()
/*****************************************************************************
...
...
@@ -78,6 +119,8 @@ static int OpenDecoder( vlc_object_t *p_this )
if
(
(
p_dec
->
p_sys
=
malloc
(
sizeof
(
decoder_sys_t
))
)
==
NULL
)
return
VLC_ENOMEM
;
p_dec
->
p_sys
->
p_obj
=
p_this
;
/* Set output properties */
p_dec
->
fmt_out
.
i_cat
=
VIDEO_ES
;
p_dec
->
fmt_out
.
i_codec
=
VLC_CODEC_RGBA
;
...
...
@@ -101,17 +144,40 @@ static void user_read( png_structp p_png, png_bytep data, png_size_t i_length )
p_block
->
i_buffer
-=
i_length
;
}
static
void
user_flush
(
png_structp
p_png
)
{
/* noop */
(
void
)
p_png
;
}
static
void
user_write
(
png_structp
p_png
,
png_bytep
data
,
png_size_t
i_length
)
{
block_t
*
p_block
=
(
block_t
*
)
png_get_io_ptr
(
p_png
);
if
(
i_length
>
p_block
->
i_buffer
)
{
char
err_str
[
64
];
snprintf
(
err_str
,
sizeof
(
err_str
),
"block size %zu too small for %zu encoded bytes"
,
p_block
->
i_buffer
,
i_length
);
png_error
(
p_png
,
err_str
);
return
;
}
memcpy
(
p_block
->
p_buffer
,
data
,
i_length
);
p_block
->
p_buffer
+=
i_length
;
p_block
->
i_buffer
-=
i_length
;
}
static
void
user_error
(
png_structp
p_png
,
png_const_charp
error_msg
)
{
decoder_t
*
p_dec
=
(
decoder
_t
*
)
png_get_error_ptr
(
p_png
);
p_
dec
->
p_
sys
->
b_error
=
true
;
msg_Err
(
p_
dec
,
"%s"
,
error_msg
);
png_sys_t
*
p_sys
=
(
png_sys
_t
*
)
png_get_error_ptr
(
p_png
);
p_sys
->
b_error
=
true
;
msg_Err
(
p_
sys
->
p_obj
,
"%s"
,
error_msg
);
}
static
void
user_warning
(
png_structp
p_png
,
png_const_charp
warning_msg
)
{
decoder_t
*
p_dec
=
(
decoder
_t
*
)
png_get_error_ptr
(
p_png
);
msg_Warn
(
p_
dec
,
"%s"
,
warning_msg
);
png_sys_t
*
p_sys
=
(
png_sys
_t
*
)
png_get_error_ptr
(
p_png
);
msg_Warn
(
p_
sys
->
p_obj
,
"%s"
,
warning_msg
);
}
/****************************************************************************
...
...
@@ -253,3 +319,125 @@ static void CloseDecoder( vlc_object_t *p_this )
free
(
p_sys
);
}
static
int
OpenEncoder
(
vlc_object_t
*
p_this
)
{
encoder_t
*
p_enc
=
(
encoder_t
*
)
p_this
;
if
(
p_enc
->
fmt_out
.
i_codec
!=
VLC_CODEC_PNG
)
return
VLC_EGENERIC
;
/* Allocate the memory needed to store the encoder's structure */
p_enc
->
p_sys
=
malloc
(
sizeof
(
encoder_sys_t
)
);
if
(
p_enc
->
p_sys
==
NULL
)
return
VLC_ENOMEM
;
p_enc
->
p_sys
->
p_obj
=
p_this
;
p_enc
->
p_sys
->
i_blocksize
=
3
*
p_enc
->
fmt_in
.
video
.
i_visible_width
*
p_enc
->
fmt_in
.
video
.
i_visible_height
;
p_enc
->
fmt_in
.
i_codec
=
VLC_CODEC_RGB24
;
p_enc
->
fmt_in
.
video
.
i_rmask
=
0x000000ff
;
p_enc
->
fmt_in
.
video
.
i_gmask
=
0x0000ff00
;
p_enc
->
fmt_in
.
video
.
i_bmask
=
0x00ff0000
;
p_enc
->
pf_encode_video
=
EncodeBlock
;
return
VLC_SUCCESS
;
}
/*
* EncodeBlock
*/
static
block_t
*
EncodeBlock
(
encoder_t
*
p_enc
,
picture_t
*
p_pic
)
{
encoder_sys_t
*
p_sys
=
p_enc
->
p_sys
;
if
(
unlikely
(
!
p_pic
)
)
{
return
NULL
;
}
block_t
*
p_block
=
block_Alloc
(
p_sys
->
i_blocksize
);
if
(
p_block
==
NULL
)
{
return
NULL
;
}
png_structp
p_png
=
png_create_write_struct
(
PNG_LIBPNG_VER_STRING
,
0
,
0
,
0
);
if
(
p_png
==
NULL
)
{
block_Release
(
p_block
);
return
NULL
;
}
/* save buffer start */
uint8_t
*
p_start
=
p_block
->
p_buffer
;
size_t
i_start
=
p_block
->
i_buffer
;
p_sys
->
b_error
=
false
;
png_infop
p_info
=
NULL
;
/* libpng longjmp's there in case of error */
if
(
setjmp
(
png_jmpbuf
(
p_png
)
)
)
goto
error
;
png_set_write_fn
(
p_png
,
p_block
,
user_write
,
user_flush
);
png_set_error_fn
(
p_png
,
p_enc
,
user_error
,
user_warning
);
p_info
=
png_create_info_struct
(
p_png
);
if
(
p_info
==
NULL
)
goto
error
;
png_infop
p_end_info
=
png_create_info_struct
(
p_png
);
if
(
p_end_info
==
NULL
)
goto
error
;
const
unsigned
i_width
=
p_enc
->
fmt_in
.
video
.
i_visible_width
;
const
unsigned
i_height
=
p_enc
->
fmt_in
.
video
.
i_visible_height
;
png_set_IHDR
(
p_png
,
p_info
,
i_width
,
i_height
,
8
,
PNG_COLOR_TYPE_RGB
,
PNG_INTERLACE_NONE
,
PNG_COMPRESSION_TYPE_DEFAULT
,
PNG_FILTER_TYPE_DEFAULT
);
if
(
p_sys
->
b_error
)
goto
error
;
png_write_info
(
p_png
,
p_info
);
if
(
p_sys
->
b_error
)
goto
error
;
/* Encode picture */
for
(
unsigned
i
=
0
;
i
<
i_height
;
i
++
)
{
png_write_row
(
p_png
,
p_pic
->
p
->
p_pixels
+
(
i_width
*
i
*
3
));
if
(
p_sys
->
b_error
)
goto
error
;
}
png_write_end
(
p_png
,
p_end_info
);
if
(
p_sys
->
b_error
)
goto
error
;
png_destroy_write_struct
(
&
p_png
,
&
p_info
);
/* restore original buffer position */
p_block
->
p_buffer
=
p_start
;
p_block
->
i_buffer
=
i_start
;
return
p_block
;
error:
png_destroy_write_struct
(
&
p_png
,
p_info
?
&
p_info
:
NULL
);
block_Release
(
p_block
);
return
NULL
;
}
/*****************************************************************************
* CloseEncoder: png encoder destruction
*****************************************************************************/
static
void
CloseEncoder
(
vlc_object_t
*
p_this
)
{
encoder_t
*
p_enc
=
(
encoder_t
*
)
p_this
;
encoder_sys_t
*
p_sys
=
p_enc
->
p_sys
;
free
(
p_sys
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment