subs: Add support for DVB and XSUB subtitles, not yet working properly
[mplayer/glamo.git] / libmpcodecs / vd_mpng.c
blob13dcfdbf78c16b319ddb254c42cab5696a1344bb
1 /*
2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <stdio.h>
20 #include <stdlib.h>
22 #include "config.h"
23 #include "mp_msg.h"
25 #include <png.h>
27 #include "libavutil/common.h"
28 #include "mpbswap.h"
29 #include "libvo/fastmemcpy.h"
31 #include "vd_internal.h"
33 static const vd_info_t info = {
34 "PNG Images decoder",
35 "mpng",
36 "A'rpi",
37 ".so, based on mpng.c",
38 "uses libpng, 8bpp modes not supported yet"
41 LIBVD_EXTERN(mpng)
43 static unsigned int out_fmt=0;
45 static int last_w=-1;
46 static int last_h=-1;
47 static int last_c=-1;
49 // to set/get/query special features/parameters
50 static int control(sh_video_t *sh,int cmd,void* arg,...){
51 switch (cmd)
53 case VDCTRL_QUERY_FORMAT:
54 if (*((int *) arg) == out_fmt) return CONTROL_TRUE;
55 return CONTROL_FALSE;
57 return CONTROL_UNKNOWN;
60 // init driver
61 static int init(sh_video_t *sh){
62 last_w=-1;
63 return 1;
66 // uninit driver
67 static void uninit(sh_video_t *sh){
70 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
72 static int pngPointer;
73 static int pngLength;
75 static void pngReadFN( png_structp pngstr,png_bytep buffer,png_size_t size )
77 char * p = pngstr->io_ptr;
78 if(size>pngLength-pngPointer && pngLength>=pngPointer) size=pngLength-pngPointer;
79 fast_memcpy( buffer,(char *)&p[pngPointer],size );
80 pngPointer+=size;
83 // decode a frame
84 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
85 png_structp png;
86 png_infop info;
87 png_infop endinfo;
88 // png_bytep data;
89 png_bytep * row_p;
90 png_uint_32 png_width=0,png_height=0;
91 int depth,color;
92 png_uint_32 i;
93 mp_image_t* mpi;
95 int cols;
96 png_colorp pal;
97 unsigned char *p;
99 if(len<=0) return NULL; // skipped frame
101 png=png_create_read_struct( PNG_LIBPNG_VER_STRING,NULL,NULL,NULL );
102 info=png_create_info_struct( png );
103 endinfo=png_create_info_struct( png );
105 pngPointer=8;
106 pngLength=len;
107 png_set_read_fn( png,data,pngReadFN );
108 png_set_strip_16( png );
109 png_set_sig_bytes( png,8 );
110 png_read_info( png,info );
111 png_get_IHDR( png,info,&png_width,&png_height,&depth,&color,NULL,NULL,NULL );
112 png_set_bgr( png );
114 switch( info->color_type ) {
115 case PNG_COLOR_TYPE_GRAY_ALPHA:
116 mp_msg( MSGT_DECVIDEO,MSGL_INFO,"Sorry gray scaled png with alpha channel not supported at moment.\n" );
117 break;
118 case PNG_COLOR_TYPE_GRAY:
119 out_fmt=IMGFMT_Y800;
120 break;
121 case PNG_COLOR_TYPE_PALETTE:
122 out_fmt=IMGFMT_BGR8;
123 break;
124 case PNG_COLOR_TYPE_RGB_ALPHA:
125 out_fmt=IMGFMT_BGR32;
126 break;
127 case PNG_COLOR_TYPE_RGB:
128 out_fmt=IMGFMT_BGR24;
129 break;
130 default:
131 mp_msg( MSGT_DECVIDEO,MSGL_INFO,"Sorry, unsupported PNG colorspace: %d.\n" ,info->color_type);
134 // (re)init libvo if image parameters changed (width/height/colorspace)
135 if(last_w!=png_width || last_h!=png_height || last_c!=out_fmt){
136 last_w=png_width; last_h=png_height; last_c=out_fmt;
137 if(!out_fmt) return NULL;
138 if(!mpcodecs_config_vo(sh,png_width,png_height,out_fmt)) return NULL;
141 #if 0
142 switch( info->color_type )
144 case PNG_COLOR_TYPE_GRAY_ALPHA: printf( "[png] used GrayA -> stripping alpha channel\n" ); break;
145 case PNG_COLOR_TYPE_GRAY: printf( "[png] used Gray -> rgb\n" ); break;
146 case PNG_COLOR_TYPE_PALETTE: printf( "[png] used palette -> rgb\n" ); break;
147 case PNG_COLOR_TYPE_RGB_ALPHA: printf( "[png] used RGBA -> stripping alpha channel\n" ); break;
148 case PNG_COLOR_TYPE_RGB: printf( "[png] read rgb datas.\n" ); break;
150 #endif
152 mpi=mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
153 png_width,png_height);
154 if(!mpi) return NULL;
156 // Let's DECODE!
157 row_p=malloc( sizeof( png_bytep ) * png_height );
158 //png_get_rowbytes( png,info )
159 for ( i=0; i < png_height; i++ ) row_p[i]=mpi->planes[0] + mpi->stride[0]*i;
160 png_read_image( png,row_p );
161 free( row_p );
163 if (out_fmt==IMGFMT_BGR8) {
164 png_get_PLTE( png,info,&pal,&cols );
165 mpi->planes[1] = realloc(mpi->planes[1], 4*cols);
166 p = mpi->planes[1];
167 for (i = 0; i < cols; i++) {
168 *p++ = pal[i].blue;
169 *p++ = pal[i].green;
170 *p++ = pal[i].red;
171 *p++ = 0;
175 png_read_end( png,endinfo );
176 png_destroy_read_struct( &png,&info,&endinfo );
178 return mpi;