Update --help with Dirac support.
[frameshot.git] / output.c
blobc50aeb4dae3b818421791d7489426363e77ab380
1 /*****************************************************************************
2 * output.c: output drivers.
3 *****************************************************************************
4 * Copyright (C) 2009
6 * Authors: Nathan Caldwell <saintdev@gmail.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
21 *****************************************************************************/
23 #include <stdint.h>
24 #include <malloc.h>
25 #include <libavutil/avutil.h>
26 #include <libswscale/swscale.h>
27 #include <png.h>
29 #include "common.h"
30 #include "output.h"
32 typedef struct {
33 FILE *fh;
34 png_structp p_png;
35 png_infop p_info;
36 } png_output_t;
38 int open_file_png(char *psz_filename, hnd_t *p_handle, int i_compression )
40 png_output_t *h = NULL;
41 if( (h = calloc(1, sizeof(*h))) == NULL )
42 return -1;
44 if( !strcmp(psz_filename, "-") )
45 h->fh = stdout;
46 else if( (h->fh = fopen(psz_filename, "wb")) == NULL )
48 goto error;
51 if( (h->p_png = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL )) == NULL )
53 goto error;
56 if( (h->p_info = png_create_info_struct(h->p_png)) == NULL )
58 png_destroy_write_struct(&(h->p_png), (png_infopp)NULL);
59 goto error;
62 png_init_io( h->p_png, h->fh );
64 png_set_compression_level( h->p_png, i_compression );
66 *p_handle = h;
68 return 0;
70 error:
71 if( h->fh != NULL && h->fh != stdout )
72 fclose( h->fh );
73 free(h);
75 return -1;
78 int close_file_png( hnd_t handle )
80 int ret = 0;
81 png_output_t *h = handle;
83 png_destroy_write_struct( &(h->p_png), &(h->p_info) );
85 if ((h->fh == NULL) || (h->fh == stdout))
86 return ret;
88 ret = fclose(h->fh);
90 free(h);
92 return ret;
95 int write_image_png( hnd_t handle, picture_t *p_pic, config_t *p_config )
97 png_output_t *h = handle;
98 uint8_t *out_data = malloc(p_config->i_width * p_config->i_height * 4);
99 uint8_t **pp_rows = calloc(p_config->i_height, sizeof(*pp_rows));
100 picture_t pic_out;
101 struct SwsContext *p_sws;
102 int i;
104 pic_out.img.plane[0] = out_data;
105 pic_out.img.plane[1] = pic_out.img.plane[2] = pic_out.img.plane[3] = NULL;
106 pic_out.img.i_stride[0] = 3*p_config->i_width;
107 pic_out.img.i_stride[1] = pic_out.img.i_stride[2] = pic_out.img.i_stride[3] = 0;
109 p_sws = sws_getContext( p_config->i_width, p_config->i_height, PIX_FMT_YUV420P,
110 p_config->i_width, p_config->i_height, PIX_FMT_RGB24,
111 SWS_FAST_BILINEAR | SWS_ACCURATE_RND,
112 NULL, NULL, NULL );
114 sws_scale(p_sws, p_pic->img.plane, p_pic->img.i_stride, 0, p_config->i_height, pic_out.img.plane, pic_out.img.i_stride );
116 __asm__ volatile ("emms\n\t");
119 png_set_IHDR( h->p_png, h->p_info, p_config->i_width, p_config->i_height,
120 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
121 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );
123 for(i=0; i < p_config->i_height; i++)
124 pp_rows[i] = pic_out.img.plane[0] + i * pic_out.img.i_stride[0];
126 png_set_rows( h->p_png, h->p_info, pp_rows );
128 png_write_png( h->p_png, h->p_info, 0, NULL );
130 free(pp_rows);
131 free(out_data);
133 return 0;