4998
|
1 #include <stdio.h>
|
|
2 #include <stdlib.h>
|
|
3
|
|
4 #include "config.h"
|
|
5 #include "mp_msg.h"
|
|
6
|
|
7 #ifdef HAVE_PNG
|
|
8
|
|
9 #include <png.h>
|
|
10
|
|
11 #include "bswap.h"
|
|
12 #include "postproc/rgb2rgb.h"
|
|
13 #include "libvo/fastmemcpy.h"
|
|
14
|
|
15 #include "vd_internal.h"
|
|
16
|
|
17 static vd_info_t info = {
|
|
18 "PNG Images decoder",
|
|
19 "mpng",
|
|
20 "A'rpi",
|
|
21 ".so, based on mpng.c",
|
|
22 "uses libpng, 8bpp modes not supported yet"
|
|
23 };
|
|
24
|
|
25 LIBVD_EXTERN(mpng)
|
|
26
|
|
27 static unsigned int out_fmt=0;
|
|
28
|
|
29 static int last_w=-1;
|
|
30 static int last_h=-1;
|
|
31 static int last_c=-1;
|
|
32
|
|
33 // to set/get/query special features/parameters
|
|
34 static int control(sh_video_t *sh,int cmd,void* arg,...){
|
|
35 return CONTROL_UNKNOWN;
|
|
36 }
|
|
37
|
|
38 // init driver
|
|
39 static int init(sh_video_t *sh){
|
|
40 last_w=-1;
|
|
41 return 1;
|
|
42 }
|
|
43
|
|
44 // uninit driver
|
|
45 static void uninit(sh_video_t *sh){
|
|
46 }
|
|
47
|
|
48 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
|
|
49
|
|
50 static int pngPointer;
|
|
51 static int pngLength;
|
|
52
|
|
53 static void pngReadFN( png_structp pngstr,png_bytep buffer,png_size_t size )
|
|
54 {
|
|
55 char * p = pngstr->io_ptr;
|
|
56 if(size>pngLength-pngPointer && pngLength>=pngPointer) size=pngLength-pngPointer;
|
|
57 memcpy( buffer,(char *)&p[pngPointer],size );
|
|
58 pngPointer+=size;
|
|
59 }
|
|
60
|
|
61 // decode a frame
|
|
62 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
|
|
63 png_structp png;
|
|
64 png_infop info;
|
|
65 png_infop endinfo;
|
|
66 // png_bytep data;
|
|
67 png_bytep * row_p;
|
|
68 png_uint_32 png_width=0,png_height=0;
|
|
69 char * palette = NULL;
|
|
70 int depth,color;
|
|
71 png_uint_32 i;
|
|
72 mp_image_t* mpi;
|
|
73
|
|
74 if(len<=0) return NULL; // skipped frame
|
|
75
|
|
76 png=png_create_read_struct( PNG_LIBPNG_VER_STRING,NULL,NULL,NULL );
|
|
77 info=png_create_info_struct( png );
|
|
78 endinfo=png_create_info_struct( png );
|
|
79
|
|
80 pngPointer=8;
|
|
81 pngLength=len;
|
|
82 png_set_read_fn( png,data,pngReadFN );
|
|
83 png_set_sig_bytes( png,8 );
|
|
84 png_read_info( png,info );
|
|
85 png_get_IHDR( png,info,&png_width,&png_height,&depth,&color,NULL,NULL,NULL );
|
|
86
|
|
87 png_set_bgr( png );
|
|
88
|
|
89 switch( info->color_type ) {
|
|
90 case PNG_COLOR_TYPE_GRAY_ALPHA:
|
|
91 mp_msg( MSGT_DECVIDEO,MSGL_INFO,"Sorry gray scaled png with alpha channel not supported at moment.\n" );
|
|
92 break;
|
|
93 case PNG_COLOR_TYPE_GRAY:
|
|
94 case PNG_COLOR_TYPE_PALETTE:
|
|
95 out_fmt=IMGFMT_BGR8;
|
|
96 break;
|
|
97 case PNG_COLOR_TYPE_RGB_ALPHA:
|
|
98 out_fmt=IMGFMT_BGR32;
|
|
99 break;
|
|
100 case PNG_COLOR_TYPE_RGB:
|
|
101 out_fmt=IMGFMT_BGR24;
|
|
102 break;
|
|
103 default:
|
|
104 mp_msg( MSGT_DECVIDEO,MSGL_INFO,"Sorry, unsupported PNG colorspace: %d.\n" ,info->color_type);
|
|
105 }
|
|
106
|
|
107 // (re)init libvo if image parameters changed (width/height/colorspace)
|
|
108 if(last_w!=png_width || last_h!=png_height || last_c!=out_fmt){
|
|
109 last_w=png_width; last_h=png_height; last_c=out_fmt;
|
|
110 if(!out_fmt) return NULL;
|
5124
|
111 if(!mpcodecs_config_vo(sh,png_width,png_height,out_fmt)) return NULL;
|
4998
|
112 }
|
|
113
|
|
114 #if 0
|
|
115 switch( info->color_type )
|
|
116 {
|
|
117 case PNG_COLOR_TYPE_GRAY_ALPHA: printf( "[png] used GrayA -> stripping alpha channel\n" ); break;
|
|
118 case PNG_COLOR_TYPE_GRAY: printf( "[png] used Gray -> rgb\n" ); break;
|
|
119 case PNG_COLOR_TYPE_PALETTE: printf( "[png] used palette -> rgb\n" ); break;
|
|
120 case PNG_COLOR_TYPE_RGB_ALPHA: printf( "[png] used RGBA -> stripping alpha channel\n" ); break;
|
|
121 case PNG_COLOR_TYPE_RGB: printf( "[png] read rgb datas.\n" ); break;
|
|
122 }
|
|
123 #endif
|
|
124
|
|
125 mpi=mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
|
|
126 png_width,png_height);
|
|
127 if(!mpi) return NULL;
|
|
128
|
|
129 // Let's DECODE!
|
|
130 row_p=(png_bytep*)malloc( sizeof( png_bytep ) * png_height );
|
|
131 //png_get_rowbytes( png,info )
|
|
132 for ( i=0; i < png_height; i++ ) row_p[i]=mpi->planes[0] + mpi->stride[0]*i;
|
|
133 png_read_image( png,row_p );
|
|
134 free( row_p );
|
|
135
|
|
136 //png_get_PLTE( png,info,(png_colorp*)&pal,&cols );
|
|
137
|
|
138 png_read_end( png,endinfo );
|
|
139 png_destroy_read_struct( &png,&info,&endinfo );
|
|
140
|
|
141 return mpi;
|
|
142 }
|
|
143
|
|
144 #endif
|