4656
|
1
|
|
2 #include <stdlib.h>
|
|
3
|
|
4 #include "config.h"
|
|
5 #include "bswap.h"
|
|
6 #include "postproc/rgb2rgb.h"
|
|
7 #include "mp_msg.h"
|
|
8 #include "png.h"
|
|
9
|
|
10 int pngPointer;
|
|
11
|
|
12 void pngReadFN( png_structp pngstr,png_bytep buffer,png_size_t size )
|
|
13 {
|
|
14 char * p = pngstr->io_ptr;
|
|
15 memcpy( buffer,(char *)&p[pngPointer],size );
|
|
16 pngPointer+=size;
|
|
17 }
|
|
18
|
|
19 void decode_mpng(
|
|
20 unsigned char *encoded,
|
|
21 int encoded_size,
|
|
22 unsigned char *decoded,
|
|
23 int width,
|
|
24 int height,
|
|
25 int bytes_per_pixel)
|
|
26 {
|
|
27 png_structp png;
|
|
28 png_infop info;
|
|
29 png_infop endinfo;
|
|
30 png_bytep data;
|
|
31 png_bytep * row_p;
|
|
32 png_uint_32 png_width,png_height;
|
|
33 char * palette = NULL;
|
|
34 int depth,color;
|
|
35 png_uint_32 i;
|
|
36 png=png_create_read_struct( PNG_LIBPNG_VER_STRING,NULL,NULL,NULL );
|
|
37 info=png_create_info_struct( png );
|
|
38 endinfo=png_create_info_struct( png );
|
|
39
|
|
40 pngPointer=8;
|
|
41 png_set_read_fn( png,encoded,pngReadFN );
|
|
42 png_set_sig_bytes( png,8 );
|
|
43 png_read_info( png,info );
|
|
44 png_get_IHDR( png,info,&png_width,&png_height,&depth,&color,NULL,NULL,NULL );
|
|
45
|
|
46 png_set_bgr( png );
|
|
47
|
|
48 #if 0
|
|
49 switch( info->color_type )
|
|
50 {
|
|
51 case PNG_COLOR_TYPE_GRAY_ALPHA: printf( "[png] used GrayA -> stripping alpha channel\n" ); break;
|
|
52 case PNG_COLOR_TYPE_GRAY: printf( "[png] used Gray -> rgb\n" ); break;
|
|
53 case PNG_COLOR_TYPE_PALETTE: printf( "[png] used palette -> rgb\n" ); break;
|
|
54 case PNG_COLOR_TYPE_RGB_ALPHA: printf( "[png] used RGBA -> stripping alpha channel\n" ); break;
|
|
55 case PNG_COLOR_TYPE_RGB: printf( "[png] read rgb datas.\n" ); break;
|
|
56 }
|
|
57 #endif
|
|
58
|
|
59 if ( info->color_type == PNG_COLOR_TYPE_RGB ) data=decoded;
|
|
60 else data=(png_bytep)malloc( png_get_rowbytes( png,info ) * height );
|
|
61
|
|
62 row_p=(png_bytep*)malloc( sizeof( png_bytep ) * png_height );
|
|
63 for ( i=0; i < png_height; i++ ) row_p[i]=&data[png_get_rowbytes( png,info ) * i];
|
|
64 png_read_image( png,row_p );
|
|
65 free( row_p );
|
|
66
|
|
67 switch( info->color_type )
|
|
68 {
|
|
69 case PNG_COLOR_TYPE_GRAY_ALPHA:
|
|
70 mp_msg( MSGT_DECVIDEO,MSGL_INFO,"Sorry gray scaled png with alpha channel not supported at moment.\n" );
|
|
71 free( data );
|
|
72 break;
|
|
73 case PNG_COLOR_TYPE_GRAY:
|
|
74 palette=malloc( 1024 );
|
|
75 for ( i=0;i < 256;i++ ) palette[(i*4)]=palette[(i*4)+1]=palette[(i*4)+2]=(char)i;
|
|
76 palette8torgb24( data,decoded,png_width * png_height,palette );
|
|
77 free( data );
|
|
78 break;
|
|
79 case PNG_COLOR_TYPE_PALETTE:
|
|
80 {
|
|
81 int cols;
|
|
82 unsigned char * pal;
|
|
83 png_get_PLTE( png,info,(png_colorp*)&pal,&cols );
|
|
84 palette=calloc( 1,1024 );
|
|
85 for ( i=0;i < cols;i++ )
|
|
86 {
|
|
87 palette[(i*4) ]=pal[(i*3)+2];
|
|
88 palette[(i*4)+1]=pal[(i*3)+1];
|
|
89 palette[(i*4)+2]=pal[(i*3) ];
|
|
90 }
|
|
91 }
|
|
92 palette8torgb24( data,decoded,png_width * png_height,palette );
|
|
93 free( data );
|
|
94 break;
|
|
95 case PNG_COLOR_TYPE_RGB_ALPHA:
|
|
96 rgb32to24( data,decoded,png_width * png_height * 4 );
|
|
97 free( data );
|
|
98 break;
|
|
99 }
|
|
100
|
|
101 if ( palette ) free( palette );
|
|
102
|
|
103 png_read_end( png,endinfo );
|
|
104 png_destroy_read_struct( &png,&info,&endinfo );
|
|
105 }
|
|
106
|