2 * vo_png.c, Portable Network Graphics Renderer for MPlayer
4 * Copyright 2001 by Felix Buenemann <atmosfear@users.sourceforge.net>
6 * Uses libpng (which uses zlib), so see according licenses.
21 #include "video_out.h"
22 #include "video_out_internal.h"
23 #include "subopt-helper.h"
25 static const vo_info_t info
=
29 "Felix Buenemann <atmosfear@users.sourceforge.net>",
33 const LIBVO_EXTERN (png
)
35 static int z_compression
= Z_NO_COMPRESSION
;
36 static int framenum
= 0;
43 enum {OK
,ERROR
} status
;
47 config(uint32_t width
, uint32_t height
, uint32_t d_width
, uint32_t d_height
, uint32_t flags
, char *title
, uint32_t format
)
50 if(z_compression
== 0) {
51 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_PNG_Warning1
);
52 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_PNG_Warning2
);
53 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_PNG_Warning3
);
56 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Compression level %i\n", z_compression
);
62 static struct pngdata
create_png (char * fname
, int image_width
, int image_height
, int swapped
)
66 /*png_structp png_ptr = png_create_write_struct
67 (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
68 user_error_fn, user_warning_fn);*/
69 //png_byte *row_pointers[image_height];
70 png
.png_ptr
= png_create_write_struct
71 (PNG_LIBPNG_VER_STRING
, NULL
,
73 png
.info_ptr
= png_create_info_struct(png
.png_ptr
);
76 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Failed to init png pointer\n");
82 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Failed to init png infopointer\n");
83 png_destroy_write_struct(&png
.png_ptr
,
89 if (setjmp(png
.png_ptr
->jmpbuf
)) {
90 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Internal error!\n");
91 png_destroy_write_struct(&png
.png_ptr
, &png
.info_ptr
);
97 png
.fp
= fopen (fname
, "wb");
99 mp_msg(MSGT_VO
,MSGL_WARN
, MSGTR_LIBVO_PNG_ErrorOpeningForWriting
, strerror(errno
));
104 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Init IO\n");
105 png_init_io(png
.png_ptr
, png
.fp
);
107 /* set the zlib compression level */
108 png_set_compression_level(png
.png_ptr
, z_compression
);
111 /*png_set_IHDR(png_ptr, info_ptr, width, height,
112 bit_depth, color_type, interlace_type,
113 compression_type, filter_type)*/
114 png_set_IHDR(png
.png_ptr
, png
.info_ptr
, image_width
, image_height
,
115 8, use_alpha
? PNG_COLOR_TYPE_RGBA
: PNG_COLOR_TYPE_RGB
, PNG_INTERLACE_NONE
,
116 PNG_COMPRESSION_TYPE_DEFAULT
, PNG_FILTER_TYPE_DEFAULT
);
118 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Write Info\n");
119 png_write_info(png
.png_ptr
, png
.info_ptr
);
122 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Set BGR Conversion\n");
123 png_set_bgr(png
.png_ptr
);
130 static uint8_t destroy_png(struct pngdata png
) {
132 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Write End\n");
133 png_write_end(png
.png_ptr
, png
.info_ptr
);
135 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Destroy Write Struct\n");
136 png_destroy_write_struct(&png
.png_ptr
, &png
.info_ptr
);
143 static uint32_t draw_image(mp_image_t
* mpi
){
147 png_byte
*row_pointers
[mpi
->h
];
149 // if -dr or -slices then do nothing:
150 if(mpi
->flags
&(MP_IMGFLAG_DIRECT
|MP_IMGFLAG_DRAW_CALLBACK
)) return VO_TRUE
;
152 snprintf (buf
, 100, "%08d.png", ++framenum
);
154 png
= create_png(buf
, mpi
->w
, mpi
->h
, IMGFMT_IS_BGR(mpi
->imgfmt
));
157 mp_msg(MSGT_VO
,MSGL_WARN
, MSGTR_LIBVO_PNG_ErrorInCreatePng
);
161 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Creating Row Pointers\n");
162 for ( k
= 0; k
< mpi
->h
; k
++ )
163 row_pointers
[k
] = mpi
->planes
[0]+mpi
->stride
[0]*k
;
165 //png_write_flush(png.png_ptr);
166 //png_set_flush(png.png_ptr, nrows);
168 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
169 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Writing Image Data\n"); }
170 png_write_image(png
.png_ptr
, row_pointers
);
177 static void draw_osd(void){}
179 static void flip_page (void){}
181 static int draw_frame(uint8_t * src
[])
186 static int draw_slice( uint8_t *src
[],int stride
[],int w
,int h
,int x
,int y
)
192 query_format(uint32_t format
)
194 const int supported_flags
= VFCAP_CSP_SUPPORTED
|VFCAP_CSP_SUPPORTED_BY_HW
|VFCAP_ACCEPT_STRIDE
;
198 return use_alpha
? 0 : supported_flags
;
201 return use_alpha
? supported_flags
: 0;
206 static void uninit(void){}
208 static void check_events(void){}
210 static int int_zero_to_nine(int *sh
)
212 if ( (*sh
< 0) || (*sh
> 9) )
217 static opt_t subopts
[] = {
218 {"alpha", OPT_ARG_BOOL
, &use_alpha
, NULL
, 0},
219 {"z", OPT_ARG_INT
, &z_compression
, (opt_test_f
)int_zero_to_nine
},
223 static int preinit(const char *arg
)
227 if (subopt_parse(arg
, subopts
) != 0) {
233 static int control(uint32_t request
, void *data
)
236 case VOCTRL_DRAW_IMAGE
:
237 return draw_image(data
);
238 case VOCTRL_QUERY_FORMAT
:
239 return query_format(*((uint32_t*)data
));