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.
26 #include "libavcodec/avcodec.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libvo/fastmemcpy.h"
30 static int pngRead( unsigned char * fname
,txSample
* bf
)
35 AVCodecContext
*avctx
;
38 FILE *fp
=fopen( fname
,"rb" );
41 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"[png] file read error ( %s )\n",fname
);
45 fseek(fp
, 0, SEEK_END
);
47 if (len
> 50 * 1024 * 1024) return 2;
48 data
= av_malloc(len
+ FF_INPUT_BUFFER_PADDING_SIZE
);
49 fseek(fp
, 0, SEEK_SET
);
50 fread(data
, len
, 1, fp
);
52 avctx
= avcodec_alloc_context();
53 frame
= avcodec_alloc_frame();
54 avcodec_register_all();
55 avcodec_open(avctx
, avcodec_find_decoder(CODEC_ID_PNG
));
56 avcodec_decode_video(avctx
, frame
, &decode_ok
, data
, len
);
57 memset(bf
, 0, sizeof(*bf
));
58 switch (avctx
->pix_fmt
) {
59 case PIX_FMT_GRAY8
: bf
->BPP
= 8; break;
60 case PIX_FMT_GRAY16BE
: bf
->BPP
= 16; break;
61 case PIX_FMT_RGB24
: bf
->BPP
= 24; break;
63 case PIX_FMT_ARGB
: bf
->BPP
= 32; break;
64 default: bf
->BPP
= 0; break;
66 if (decode_ok
&& bf
->BPP
) {
68 bf
->Width
= avctx
->width
; bf
->Height
= avctx
->height
;
69 bpl
= bf
->Width
* (bf
->BPP
/ 8);
70 bf
->ImageSize
= bpl
* bf
->Height
;
71 bf
->Image
= malloc(bf
->ImageSize
);
72 memcpy_pic(bf
->Image
, frame
->data
[0], bpl
, bf
->Height
, bpl
, frame
->linesize
[0]);
79 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"[png] filename: %s.\n",fname
);
80 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"[png] size: %dx%d bits: %d\n",bf
->Width
,bf
->Height
,bf
->BPP
);
81 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"[png] imagesize: %lu\n",bf
->ImageSize
);
82 return !(decode_ok
&& bf
->BPP
);
85 static int conv24to32( txSample
* bf
)
87 unsigned char * tmpImage
;
93 bf
->ImageSize
=bf
->Width
* bf
->Height
* 4;
95 if ( ( bf
->Image
=calloc( 1, bf
->ImageSize
) ) == NULL
)
98 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"[bitmap] not enough memory for image\n" );
101 for ( c
=0,i
=0; c
< bf
->ImageSize
; c
+= 4, i
+= 3)
103 *(uint32_t *)&bf
->Image
[c
] = AV_RB24(&tmpImage
[i
]);
110 static void Normalize( txSample
* bf
)
114 for ( i
=0;i
< (int)bf
->ImageSize
;i
+=4 ) bf
->Image
[i
+3]=0;
116 for ( i
=0;i
< (int)bf
->ImageSize
;i
+=4 ) bf
->Image
[i
]=0;
120 static unsigned char tmp
[512];
122 static unsigned char * fExist( unsigned char * fname
)
125 unsigned char ext
[][6] = { ".png\0",".PNG\0" };
128 fl
=fopen( fname
,"rb" );
136 snprintf( tmp
,511,"%s%s",fname
,ext
[i
] );
137 fl
=fopen( tmp
,"rb" );
147 int bpRead( char * fname
, txSample
* bf
)
149 fname
=fExist( fname
);
150 if ( fname
== NULL
) return -2;
151 if ( pngRead( fname
,bf
) )
153 mp_dbg( MSGT_GPLAYER
,MSGL_FATAL
,"[bitmap] unknown file type ( %s )\n",fname
);
158 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" );
161 if ( conv24to32( bf
) ) return -8;
166 void Convert32to1( txSample
* in
,txSample
* out
,int adaptivlimit
)
168 out
->Width
=in
->Width
;
169 out
->Height
=in
->Height
;
171 out
->ImageSize
=(out
->Width
* out
->Height
+ 7) / 8;
172 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"[c32to1] imagesize: %d\n",out
->ImageSize
);
173 out
->Image
=calloc( 1,out
->ImageSize
);
174 if ( out
->Image
== NULL
) mp_msg( MSGT_GPLAYER
,MSGL_WARN
,MSGTR_NotEnoughMemoryC32To1
);
176 int i
,b
,c
=0; unsigned int * buf
= NULL
; unsigned char tmp
= 0; int nothaveshape
= 1;
177 buf
=(unsigned int *)in
->Image
;
178 for ( b
=0,i
=0;i
< (int)(out
->Width
* out
->Height
);i
++ )
180 if ( (int)buf
[i
] != adaptivlimit
) tmp
=( tmp
>> 1 )|128;
181 else { tmp
=tmp
>> 1; buf
[i
]=nothaveshape
=0; }
182 if ( b
++ == 7 ) { out
->Image
[c
++]=tmp
; tmp
=b
=0; }
184 if ( b
) out
->Image
[c
]=tmp
;
185 if ( nothaveshape
) { free( out
->Image
); out
->Image
=NULL
; }