Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
85a57296
Commit
85a57296
authored
Feb 04, 2003
by
Fabrice Bellard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
yes, PNG can be simpler :-)
Originally committed as revision 1545 to
svn://svn.ffmpeg.org/ffmpeg/trunk
parent
838dec44
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
402 additions
and
156 deletions
+402
-156
Makefile
libavformat/Makefile
+1
-1
png.c
libavformat/png.c
+401
-155
No files found.
libavformat/Makefile
View file @
85a57296
...
@@ -20,7 +20,7 @@ OBJS+= asf.o
...
@@ -20,7 +20,7 @@ OBJS+= asf.o
endif
endif
# image formats
# image formats
OBJS
+=
pnm.o yuv.o png.o
libpng/png.o libpng/pngread.o libpng/pngrutil.o libpng/pngwrite.o libpng/pngwutil.o
jpeg.o gifdec.o
OBJS
+=
pnm.o yuv.o png.o jpeg.o gifdec.o
# file I/O
# file I/O
OBJS
+=
avio.o aviobuf.o file.o
OBJS
+=
avio.o aviobuf.o file.o
OBJS
+=
framehook.o
OBJS
+=
framehook.o
...
...
libavformat/png.c
View file @
85a57296
...
@@ -18,216 +18,462 @@
...
@@ -18,216 +18,462 @@
*/
*/
#include "avformat.h"
#include "avformat.h"
#include "libpng/png.h"
#include <zlib.h>
extern
const
uint8_t
png_sig
[];
//#define DEBUG
#define PNG_COLOR_MASK_PALETTE 1
#define PNG_COLOR_MASK_COLOR 2
#define PNG_COLOR_MASK_ALPHA 4
#define PNG_COLOR_TYPE_GRAY 0
#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
#define PNG_FILTER_VALUE_NONE 0
#define PNG_FILTER_VALUE_SUB 1
#define PNG_FILTER_VALUE_UP 2
#define PNG_FILTER_VALUE_AVG 3
#define PNG_FILTER_VALUE_PAETH 4
#define PNG_IHDR 0x0001
#define PNG_IDAT 0x0002
#define PNG_ALLIMAGE 0x0004
#define IOBUF_SIZE 4096
typedef
struct
PNGDecodeState
{
int
state
;
int
width
,
height
;
int
bit_depth
;
int
color_type
;
int
compression_type
;
int
interlace_type
;
int
filter_type
;
int
channels
;
int
bits_per_pixel
;
int
bpp
;
uint8_t
*
image_buf
;
int
image_linesize
;
uint8_t
*
crow_buf
;
uint8_t
*
empty_row
;
int
crow_size
;
/* compressed row size (include filter type) */
int
row_size
;
/* decompressed row size */
int
y
;
z_stream
zstream
;
}
PNGDecodeState
;
const
uint8_t
pngsig
[
8
]
=
{
137
,
80
,
78
,
71
,
13
,
10
,
26
,
10
};
static
int
png_probe
(
AVProbeData
*
pd
)
static
int
png_probe
(
AVProbeData
*
pd
)
{
{
if
(
pd
->
buf_size
>=
8
&&
if
(
pd
->
buf_size
>=
8
&&
memcmp
(
pd
->
buf
,
png
_
sig
,
8
)
==
0
)
memcmp
(
pd
->
buf
,
pngsig
,
8
)
==
0
)
return
AVPROBE_SCORE_MAX
;
return
AVPROBE_SCORE_MAX
;
else
else
return
0
;
return
0
;
}
}
png_voidp
PNGAPI
void
*
png_zalloc
(
void
*
opaque
,
unsigned
int
items
,
unsigned
int
size
)
png_memset_check
(
png_structp
png_ptr
,
png_voidp
s1
,
int
value
,
png_uint_32
length
)
{
{
png_size_t
size
;
return
av_malloc
(
items
*
size
);
size
=
(
png_size_t
)
length
;
if
((
png_uint_32
)
size
!=
length
)
png_error
(
png_ptr
,
"Overflow in png_memset_check."
);
return
(
png_memset
(
s1
,
value
,
size
));
}
}
png_voidp
PNGAPI
void
png_zfree
(
void
*
opaque
,
void
*
ptr
)
png_memcpy_check
(
png_structp
png_ptr
,
png_voidp
s1
,
png_voidp
s2
,
png_uint_32
length
)
{
{
png_size_t
size
;
av_free
(
ptr
);
size
=
(
png_size_t
)
length
;
if
((
png_uint_32
)
size
!=
length
)
png_error
(
png_ptr
,
"Overflow in png_memcpy_check."
);
return
(
png_memcpy
(
s1
,
s2
,
size
));
}
}
void
png_error
(
png_struct
*
png_ptr
,
const
char
*
message
)
/* XXX: optimize */
static
void
png_filter_row
(
uint8_t
*
dst
,
int
filter_type
,
uint8_t
*
src
,
uint8_t
*
last
,
int
size
,
int
bpp
)
{
{
longjmp
(
png_ptr
->
jmpbuf
,
0
);
int
i
,
p
;
}
void
png_warning
(
png_struct
*
png_ptr
,
const
char
*
message
)
switch
(
filter_type
)
{
{
case
PNG_FILTER_VALUE_NONE
:
}
memcpy
(
dst
,
src
,
size
);
break
;
case
PNG_FILTER_VALUE_SUB
:
for
(
i
=
0
;
i
<
bpp
;
i
++
)
{
dst
[
i
]
=
src
[
i
];
}
for
(
i
=
bpp
;
i
<
size
;
i
++
)
{
p
=
dst
[
i
-
bpp
];
dst
[
i
]
=
p
+
src
[
i
];
}
break
;
case
PNG_FILTER_VALUE_UP
:
for
(
i
=
0
;
i
<
size
;
i
++
)
{
p
=
last
[
i
];
dst
[
i
]
=
p
+
src
[
i
];
}
break
;
case
PNG_FILTER_VALUE_AVG
:
for
(
i
=
0
;
i
<
bpp
;
i
++
)
{
p
=
(
last
[
i
]
>>
1
);
dst
[
i
]
=
p
+
src
[
i
];
}
for
(
i
=
bpp
;
i
<
size
;
i
++
)
{
p
=
((
dst
[
i
-
bpp
]
+
last
[
i
])
>>
1
);
dst
[
i
]
=
p
+
src
[
i
];
}
break
;
case
PNG_FILTER_VALUE_PAETH
:
for
(
i
=
0
;
i
<
bpp
;
i
++
)
{
p
=
last
[
i
];
dst
[
i
]
=
p
+
src
[
i
];
}
for
(
i
=
bpp
;
i
<
size
;
i
++
)
{
int
a
,
b
,
c
,
pa
,
pb
,
pc
;
void
PNGAPI
a
=
dst
[
i
-
bpp
];
png_chunk_error
(
png_structp
png_ptr
,
png_const_charp
error_message
)
b
=
last
[
i
];
{
c
=
last
[
i
-
bpp
];
char
msg
[
18
+
64
];
// png_format_buffer(png_ptr, msg, error_message);
png_error
(
png_ptr
,
msg
);
}
void
PNGAPI
p
=
b
-
c
;
png_chunk_warning
(
png_structp
png_ptr
,
png_const_charp
warning_message
)
pc
=
a
-
c
;
{
char
msg
[
18
+
64
];
// png_format_buffer(png_ptr, msg, warning_message);
png_warning
(
png_ptr
,
msg
);
}
void
png_read_data
(
png_struct
*
png_ptr
,
png_byte
*
data
,
png_uint_32
length
)
pa
=
abs
(
p
);
{
pb
=
abs
(
pc
);
int
ret
;
pc
=
abs
(
p
+
pc
)
;
ret
=
get_buffer
(
png_ptr
->
io_ptr
,
data
,
length
);
if
(
pa
<=
pb
&&
pa
<=
pc
)
if
(
ret
!=
length
)
p
=
a
;
png_error
(
png_ptr
,
"Read Error"
);
else
if
(
pb
<=
pc
)
p
=
b
;
else
p
=
c
;
dst
[
i
]
=
p
+
src
[
i
];
}
break
;
}
}
}
void
*
png_malloc
(
png_struct
*
png_ptr
,
png_uint_32
size
)
static
void
png_handle_row
(
PNGDecodeState
*
s
)
{
{
return
av_malloc
(
size
);
uint8_t
*
ptr
,
*
last_row
;
ptr
=
s
->
image_buf
+
s
->
image_linesize
*
s
->
y
;
if
(
s
->
y
==
0
)
last_row
=
s
->
empty_row
;
else
last_row
=
ptr
-
s
->
image_linesize
;
png_filter_row
(
ptr
,
s
->
crow_buf
[
0
],
s
->
crow_buf
+
1
,
last_row
,
s
->
row_size
,
s
->
bpp
);
}
}
void
png_free
(
png_struct
*
png_ptr
,
void
*
ptr
)
static
int
png_decode_idat
(
PNGDecodeState
*
s
,
ByteIOContext
*
f
,
int
length
)
{
{
return
av_free
(
ptr
);
uint8_t
buf
[
IOBUF_SIZE
];
int
buf_size
;
int
ret
;
while
(
length
>
0
)
{
/* read the buffer */
buf_size
=
IOBUF_SIZE
;
if
(
buf_size
>
length
)
buf_size
=
length
;
ret
=
get_buffer
(
f
,
buf
,
buf_size
);
if
(
ret
!=
buf_size
)
return
-
1
;
s
->
zstream
.
avail_in
=
buf_size
;
s
->
zstream
.
next_in
=
buf
;
/* decode one line if possible */
while
(
s
->
zstream
.
avail_in
>
0
)
{
ret
=
inflate
(
&
s
->
zstream
,
Z_PARTIAL_FLUSH
);
if
(
ret
!=
Z_OK
&&
ret
!=
Z_STREAM_END
)
{
return
-
1
;
}
if
(
s
->
zstream
.
avail_out
==
0
)
{
if
(
s
->
y
<
s
->
height
)
{
png_handle_row
(
s
);
s
->
y
++
;
if
(
s
->
y
==
s
->
height
)
s
->
state
|=
PNG_ALLIMAGE
;
}
s
->
zstream
.
avail_out
=
s
->
crow_size
;
s
->
zstream
.
next_out
=
s
->
crow_buf
;
}
}
length
-=
buf_size
;
}
return
0
;
}
}
static
int
png_read
(
ByteIOContext
*
f
,
static
int
png_read
(
ByteIOContext
*
f
,
int
(
*
alloc_cb
)(
void
*
opaque
,
AVImageInfo
*
info
),
void
*
opaque
)
int
(
*
alloc_cb
)(
void
*
opaque
,
AVImageInfo
*
info
),
void
*
opaque
)
{
{
png_struct
png_struct1
,
*
png_ptr
;
png_info
png_info1
,
png_info2
,
*
info_ptr
,
*
end_info
;
AVImageInfo
info1
,
*
info
=
&
info1
;
AVImageInfo
info1
,
*
info
=
&
info1
;
int
y
,
height
,
ret
,
row_size
;
PNGDecodeState
s1
,
*
s
=
&
s1
;
uint8_t
*
ptr
;
uint32_t
tag
,
length
;
int
ret
,
crc
;
png_ptr
=
&
png_struct1
;
uint8_t
buf
[
8
];
png_read_init
(
png_ptr
);
/* check signature */
info_ptr
=
&
png_info1
;
ret
=
get_buffer
(
f
,
buf
,
8
);
end_info
=
&
png_info2
;
if
(
ret
!=
8
)
png_info_init
(
info_ptr
);
png_info_init
(
end_info
);
png_ptr
->
io_ptr
=
f
;
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)))
{
png_read_destroy
(
png_ptr
,
info_ptr
,
NULL
);
return
-
1
;
return
-
1
;
}
if
(
memcmp
(
buf
,
pngsig
,
8
)
!=
0
)
return
-
1
;
png_read_info
(
png_ptr
,
info_ptr
);
memset
(
s
,
0
,
sizeof
(
PNGDecodeState
));
/* init the zlib */
s
->
zstream
.
zalloc
=
png_zalloc
;
s
->
zstream
.
zfree
=
png_zfree
;
s
->
zstream
.
opaque
=
NULL
;
ret
=
inflateInit
(
&
s
->
zstream
);
if
(
ret
!=
Z_OK
)
return
-
1
;
for
(;;)
{
if
(
url_feof
(
f
))
goto
fail
;
length
=
get_be32
(
f
);
if
(
length
>
0x7fffffff
)
goto
fail
;
tag
=
get_le32
(
f
);
#ifdef DEBUG
printf
(
"png: tag=%c%c%c%c length=%u
\n
"
,
(
tag
&
0xff
),
((
tag
>>
8
)
&
0xff
),
((
tag
>>
16
)
&
0xff
),
((
tag
>>
24
)
&
0xff
),
length
);
#endif
switch
(
tag
)
{
case
MKTAG
(
'I'
,
'H'
,
'D'
,
'R'
):
if
(
length
!=
13
)
goto
fail
;
s
->
width
=
get_be32
(
f
);
s
->
height
=
get_be32
(
f
);
s
->
bit_depth
=
get_byte
(
f
);
s
->
color_type
=
get_byte
(
f
);
s
->
compression_type
=
get_byte
(
f
);
s
->
filter_type
=
get_byte
(
f
);
s
->
interlace_type
=
get_byte
(
f
);
crc
=
get_be32
(
f
);
s
->
state
|=
PNG_IHDR
;
#ifdef DEBUG
printf
(
"width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d
\n
"
,
s
->
width
,
s
->
height
,
s
->
bit_depth
,
s
->
color_type
,
s
->
compression_type
,
s
->
filter_type
,
s
->
interlace_type
);
#endif
break
;
case
MKTAG
(
'I'
,
'D'
,
'A'
,
'T'
):
if
(
!
(
s
->
state
&
PNG_IHDR
))
goto
fail
;
if
(
!
(
s
->
state
&
PNG_IDAT
))
{
/* init image info */
/* init image info */
info
->
width
=
info_ptr
->
width
;
info
->
width
=
s
->
width
;
info
->
height
=
info_ptr
->
height
;
info
->
height
=
s
->
height
;
if
(
info_ptr
->
bit_depth
==
8
&&
s
->
channels
=
1
;
info_ptr
->
color_type
==
PNG_COLOR_TYPE_RGB
)
{
if
((
s
->
color_type
&
(
PNG_COLOR_MASK_COLOR
|
PNG_COLOR_MASK_PALETTE
))
==
PNG_COLOR_MASK_COLOR
)
s
->
channels
=
3
;
if
(
s
->
color_type
&
PNG_COLOR_MASK_ALPHA
)
s
->
channels
++
;
s
->
bits_per_pixel
=
s
->
bit_depth
*
s
->
channels
;
s
->
bpp
=
(
s
->
bits_per_pixel
+
7
)
>>
3
;
if
(
s
->
bit_depth
==
8
&&
s
->
color_type
==
PNG_COLOR_TYPE_RGB
)
{
info
->
pix_fmt
=
PIX_FMT_RGB24
;
info
->
pix_fmt
=
PIX_FMT_RGB24
;
row_size
=
info_ptr
->
width
*
3
;
s
->
row_size
=
s
->
width
*
3
;
}
else
if
(
info_ptr
->
bit_depth
==
8
&&
}
else
if
(
s
->
bit_depth
==
8
&&
info_ptr
->
color_type
==
PNG_COLOR_TYPE_GRAY
)
{
s
->
color_type
==
PNG_COLOR_TYPE_GRAY
)
{
info
->
pix_fmt
=
PIX_FMT_GRAY8
;
info
->
pix_fmt
=
PIX_FMT_GRAY8
;
row_size
=
info_ptr
->
width
;
s
->
row_size
=
s
->
width
;
}
else
if
(
info_ptr
->
bit_depth
==
1
&&
}
else
if
(
s
->
bit_depth
==
1
&&
info_ptr
->
color_type
==
PNG_COLOR_TYPE_GRAY
)
{
s
->
color_type
==
PNG_COLOR_TYPE_GRAY
)
{
info
->
pix_fmt
=
PIX_FMT_MONOBLACK
;
info
->
pix_fmt
=
PIX_FMT_MONOBLACK
;
row_size
=
(
info_ptr
->
width
+
7
)
>>
3
;
s
->
row_size
=
(
s
->
width
+
7
)
>>
3
;
}
else
{
}
else
{
png_read_destroy
(
png_ptr
,
info_ptr
,
NULL
);
goto
fail
;
return
-
1
;
}
/* compute the compressed row size */
if
(
!
s
->
interlace_type
)
{
s
->
crow_size
=
s
->
row_size
+
1
;
}
else
{
/* XXX: handle interlacing */
goto
fail
;
}
}
ret
=
alloc_cb
(
opaque
,
info
);
ret
=
alloc_cb
(
opaque
,
info
);
if
(
ret
)
{
if
(
ret
)
png_read_destroy
(
png_ptr
,
info_ptr
,
NULL
);
goto
the_end
;
return
ret
;
#ifdef DEBUG
printf
(
"row_size=%d crow_size =%d
\n
"
,
s
->
row_size
,
s
->
crow_size
);
#endif
s
->
image_buf
=
info
->
pict
.
data
[
0
];
s
->
image_linesize
=
info
->
pict
.
linesize
[
0
];
/* empty row is used if differencing to the first row */
s
->
empty_row
=
av_mallocz
(
s
->
row_size
);
if
(
!
s
->
empty_row
)
goto
fail
;
/* compressed row */
s
->
crow_buf
=
av_malloc
(
s
->
crow_size
);
if
(
!
s
->
crow_buf
)
goto
fail
;
s
->
zstream
.
avail_out
=
s
->
crow_size
;
s
->
zstream
.
next_out
=
s
->
crow_buf
;
}
s
->
state
|=
PNG_IDAT
;
if
(
png_decode_idat
(
s
,
f
,
length
)
<
0
)
goto
fail
;
/* skip crc */
crc
=
get_be32
(
f
);
break
;
case
MKTAG
(
'I'
,
'E'
,
'N'
,
'D'
):
if
(
!
(
s
->
state
&
PNG_ALLIMAGE
))
goto
fail
;
crc
=
get_be32
(
f
);
goto
exit_loop
;
default:
/* skip tag */
url_fskip
(
f
,
length
+
4
);
break
;
}
}
/* now read the whole image */
png_start_read_image
(
png_ptr
);
height
=
info
->
height
;
ptr
=
info
->
pict
.
data
[
0
];
for
(
y
=
0
;
y
<
height
;
y
++
)
{
png_read_row
(
png_ptr
,
NULL
,
NULL
);
memcpy
(
ptr
,
png_ptr
->
row_buf
+
1
,
row_size
);
ptr
+=
info
->
pict
.
linesize
[
0
];
}
}
exit_loop:
ret
=
0
;
the_end:
inflateEnd
(
&
s
->
zstream
);
av_free
(
s
->
crow_buf
);
return
ret
;
fail:
ret
=
-
1
;
goto
the_end
;
}
png_read_destroy
(
png_ptr
,
info_ptr
,
NULL
);
static
void
png_write_chunk
(
ByteIOContext
*
f
,
uint32_t
tag
,
return
0
;
const
uint8_t
*
buf
,
int
length
)
{
uint32_t
crc
;
uint8_t
tagbuf
[
4
];
put_be32
(
f
,
length
);
crc
=
crc32
(
0
,
Z_NULL
,
0
);
tagbuf
[
0
]
=
tag
;
tagbuf
[
1
]
=
tag
>>
8
;
tagbuf
[
2
]
=
tag
>>
16
;
tagbuf
[
3
]
=
tag
>>
24
;
crc
=
crc32
(
crc
,
tagbuf
,
4
);
put_le32
(
f
,
tag
);
if
(
length
>
0
)
{
crc
=
crc32
(
crc
,
buf
,
length
);
put_buffer
(
f
,
buf
,
length
);
}
put_be32
(
f
,
crc
);
}
}
void
/* XXX: use avcodec generic function ? */
png_write_data
(
png_structp
png_ptr
,
png_bytep
data
,
png_size_t
length
)
static
void
to_be32
(
uint8_t
*
p
,
uint32_t
v
)
{
{
put_buffer
(
png_ptr
->
io_ptr
,
data
,
length
);
p
[
0
]
=
v
>>
24
;
p
[
1
]
=
v
>>
16
;
p
[
2
]
=
v
>>
8
;
p
[
3
]
=
v
;
}
}
static
int
png_write
(
ByteIOContext
*
pb
,
AVImageInfo
*
info
)
static
int
png_write
(
ByteIOContext
*
f
,
AVImageInfo
*
info
)
{
{
png_struct
png_struct1
,
*
png_ptr
;
int
bit_depth
,
color_type
,
y
,
len
,
row_size
,
ret
;
png_info
png_info1
,
*
info_ptr
;
int
w
,
h
,
y
;
uint8_t
*
ptr
;
uint8_t
*
ptr
;
uint8_t
buf
[
IOBUF_SIZE
];
uint8_t
*
crow_buf
=
NULL
;
z_stream
zstream
;
png_ptr
=
&
png_struct1
;
info_ptr
=
&
png_info1
;
png_write_init
(
png_ptr
);
png_info_init
(
info_ptr
);
png_ptr
->
io_ptr
=
pb
;
if
(
setjmp
(
png_ptr
->
jmpbuf
))
{
png_write_destroy
(
png_ptr
);
return
-
1
;
}
w
=
info
->
width
;
h
=
info
->
height
;
info_ptr
->
width
=
w
;
info_ptr
->
height
=
h
;
switch
(
info
->
pix_fmt
)
{
switch
(
info
->
pix_fmt
)
{
case
PIX_FMT_RGB24
:
case
PIX_FMT_RGB24
:
info_ptr
->
bit_depth
=
8
;
bit_depth
=
8
;
info_ptr
->
color_type
=
PNG_COLOR_TYPE_RGB
;
color_type
=
PNG_COLOR_TYPE_RGB
;
row_size
=
info
->
width
*
3
;
break
;
break
;
case
PIX_FMT_GRAY8
:
case
PIX_FMT_GRAY8
:
info_ptr
->
bit_depth
=
8
;
bit_depth
=
8
;
info_ptr
->
color_type
=
PNG_COLOR_TYPE_GRAY
;
color_type
=
PNG_COLOR_TYPE_GRAY
;
row_size
=
info
->
width
;
break
;
break
;
case
PIX_FMT_MONOBLACK
:
case
PIX_FMT_MONOBLACK
:
info_ptr
->
bit_depth
=
1
;
bit_depth
=
1
;
info_ptr
->
color_type
=
PNG_COLOR_TYPE_GRAY
;
color_type
=
PNG_COLOR_TYPE_GRAY
;
row_size
=
(
info
->
width
+
7
)
>>
3
;
break
;
break
;
default:
default:
return
-
1
;
return
-
1
;
}
}
png_write_info
(
png_ptr
,
info_ptr
);
zstream
.
zalloc
=
png_zalloc
;
zstream
.
zfree
=
png_zfree
;
ptr
=
info
->
pict
.
data
[
0
];
zstream
.
opaque
=
NULL
;
for
(
y
=
0
;
y
<
h
;
y
++
)
{
ret
=
deflateInit2
(
&
zstream
,
Z_DEFAULT_COMPRESSION
,
png_write_row
(
png_ptr
,
ptr
);
Z_DEFLATED
,
15
,
8
,
Z_DEFAULT_STRATEGY
);
ptr
+=
info
->
pict
.
linesize
[
0
];
if
(
ret
!=
Z_OK
)
return
-
1
;
crow_buf
=
av_malloc
(
row_size
+
1
);
if
(
!
crow_buf
)
goto
fail
;
/* write png header */
put_buffer
(
f
,
pngsig
,
8
);
to_be32
(
buf
,
info
->
width
);
to_be32
(
buf
+
4
,
info
->
height
);
buf
[
8
]
=
bit_depth
;
buf
[
9
]
=
color_type
;
buf
[
10
]
=
0
;
/* compression type */
buf
[
11
]
=
0
;
/* filter type */
buf
[
12
]
=
0
;
/* interlace type */
png_write_chunk
(
f
,
MKTAG
(
'I'
,
'H'
,
'D'
,
'R'
),
buf
,
13
);
/* now put each row */
zstream
.
avail_out
=
IOBUF_SIZE
;
zstream
.
next_out
=
buf
;
for
(
y
=
0
;
y
<
info
->
height
;
y
++
)
{
/* XXX: do filtering */
ptr
=
info
->
pict
.
data
[
0
]
+
y
*
info
->
pict
.
linesize
[
0
];
memcpy
(
crow_buf
+
1
,
ptr
,
row_size
);
crow_buf
[
0
]
=
PNG_FILTER_VALUE_NONE
;
zstream
.
avail_in
=
row_size
+
1
;
zstream
.
next_in
=
crow_buf
;
while
(
zstream
.
avail_in
>
0
)
{
ret
=
deflate
(
&
zstream
,
Z_NO_FLUSH
);
if
(
ret
!=
Z_OK
)
goto
fail
;
if
(
zstream
.
avail_out
==
0
)
{
png_write_chunk
(
f
,
MKTAG
(
'I'
,
'D'
,
'A'
,
'T'
),
buf
,
IOBUF_SIZE
);
zstream
.
avail_out
=
IOBUF_SIZE
;
zstream
.
next_out
=
buf
;
}
}
png_write_end
(
png_ptr
,
info_ptr
);
}
png_write_destroy
(
png_ptr
);
}
put_flush_packet
(
pb
);
/* compress last bytes */
return
0
;
for
(;;)
{
ret
=
deflate
(
&
zstream
,
Z_FINISH
);
if
(
ret
==
Z_OK
||
ret
==
Z_STREAM_END
)
{
len
=
IOBUF_SIZE
-
zstream
.
avail_out
;
if
(
len
>
0
)
{
png_write_chunk
(
f
,
MKTAG
(
'I'
,
'D'
,
'A'
,
'T'
),
buf
,
len
);
}
zstream
.
avail_out
=
IOBUF_SIZE
;
zstream
.
next_out
=
buf
;
if
(
ret
==
Z_STREAM_END
)
break
;
}
else
{
goto
fail
;
}
}
png_write_chunk
(
f
,
MKTAG
(
'I'
,
'E'
,
'N'
,
'D'
),
NULL
,
0
);
put_flush_packet
(
f
);
ret
=
0
;
the_end:
av_free
(
crow_buf
);
deflateEnd
(
&
zstream
);
return
ret
;
fail:
ret
=
-
1
;
goto
the_end
;
}
}
AVImageFormat
png_image_format
=
{
AVImageFormat
png_image_format
=
{
...
...
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