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;
42 enum {OK
,ERROR
} status
;
46 config(uint32_t width
, uint32_t height
, uint32_t d_width
, uint32_t d_height
, uint32_t flags
, char *title
, uint32_t format
)
49 if(z_compression
== 0) {
50 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_PNG_Warning1
);
51 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_PNG_Warning2
);
52 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_PNG_Warning3
);
55 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Compression level %i\n", z_compression
);
61 static struct pngdata
create_png (char * fname
, int image_width
, int image_height
, int swapped
)
65 /*png_structp png_ptr = png_create_write_struct
66 (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
67 user_error_fn, user_warning_fn);*/
68 //png_byte *row_pointers[image_height];
69 png
.png_ptr
= png_create_write_struct
70 (PNG_LIBPNG_VER_STRING
, NULL
,
72 png
.info_ptr
= png_create_info_struct(png
.png_ptr
);
75 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Failed to init png pointer\n");
81 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Failed to init png infopointer\n");
82 png_destroy_write_struct(&png
.png_ptr
,
88 if (setjmp(png
.png_ptr
->jmpbuf
)) {
89 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Internal error!\n");
90 png_destroy_write_struct(&png
.png_ptr
, &png
.info_ptr
);
96 png
.fp
= fopen (fname
, "wb");
98 mp_msg(MSGT_VO
,MSGL_WARN
, MSGTR_LIBVO_PNG_ErrorOpeningForWriting
, strerror(errno
));
103 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Init IO\n");
104 png_init_io(png
.png_ptr
, png
.fp
);
106 /* set the zlib compression level */
107 png_set_compression_level(png
.png_ptr
, z_compression
);
110 /*png_set_IHDR(png_ptr, info_ptr, width, height,
111 bit_depth, color_type, interlace_type,
112 compression_type, filter_type)*/
113 png_set_IHDR(png
.png_ptr
, png
.info_ptr
, image_width
, image_height
,
114 8, PNG_COLOR_TYPE_RGB
, PNG_INTERLACE_NONE
,
115 PNG_COMPRESSION_TYPE_DEFAULT
, PNG_FILTER_TYPE_DEFAULT
);
117 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Write Info\n");
118 png_write_info(png
.png_ptr
, png
.info_ptr
);
121 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Set BGR Conversion\n");
122 png_set_bgr(png
.png_ptr
);
129 static uint8_t destroy_png(struct pngdata png
) {
131 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Write End\n");
132 png_write_end(png
.png_ptr
, png
.info_ptr
);
134 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Destroy Write Struct\n");
135 png_destroy_write_struct(&png
.png_ptr
, &png
.info_ptr
);
142 static uint32_t draw_image(mp_image_t
* mpi
){
146 png_byte
*row_pointers
[mpi
->h
];
148 // if -dr or -slices then do nothing:
149 if(mpi
->flags
&(MP_IMGFLAG_DIRECT
|MP_IMGFLAG_DRAW_CALLBACK
)) return VO_TRUE
;
151 snprintf (buf
, 100, "%08d.png", ++framenum
);
153 png
= create_png(buf
, mpi
->w
, mpi
->h
, IMGFMT_IS_BGR(mpi
->imgfmt
));
156 mp_msg(MSGT_VO
,MSGL_WARN
, MSGTR_LIBVO_PNG_ErrorInCreatePng
);
160 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Creating Row Pointers\n");
161 for ( k
= 0; k
< mpi
->h
; k
++ )
162 row_pointers
[k
] = mpi
->planes
[0]+mpi
->stride
[0]*k
;
164 //png_write_flush(png.png_ptr);
165 //png_set_flush(png.png_ptr, nrows);
167 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
168 mp_msg(MSGT_VO
,MSGL_DBG2
, "PNG Writing Image Data\n"); }
169 png_write_image(png
.png_ptr
, row_pointers
);
176 static void draw_osd(void){}
178 static void flip_page (void){}
180 static int draw_frame(uint8_t * src
[])
185 static int draw_slice( uint8_t *src
[],int stride
[],int w
,int h
,int x
,int y
)
191 query_format(uint32_t format
)
196 return VFCAP_CSP_SUPPORTED
|VFCAP_CSP_SUPPORTED_BY_HW
|VFCAP_ACCEPT_STRIDE
;
201 static void uninit(void){}
203 static void check_events(void){}
205 static int int_zero_to_nine(int *sh
)
207 if ( (*sh
< 0) || (*sh
> 9) )
212 static opt_t subopts
[] = {
213 {"z", OPT_ARG_INT
, &z_compression
, (opt_test_f
)int_zero_to_nine
},
217 static int preinit(const char *arg
)
220 if (subopt_parse(arg
, subopts
) != 0) {
226 static int control(uint32_t request
, void *data
, ...)
229 case VOCTRL_DRAW_IMAGE
:
230 return draw_image(data
);
231 case VOCTRL_QUERY_FORMAT
:
232 return query_format(*((uint32_t*)data
));