Mercurial > mplayer.hg
annotate Gui/bitmap.c @ 15205:19243f85e164
nico partially fixed the bug i reported; here's the rest of the fix.
basically demux_audio was mixing data in its header buffer in a bogus
manner, whereby it could sometimes "make up" valid mpeg headers where
no such header actually occurred in the file. it should be correct now.
btw these changes also fix the bug where mplayer reports huge initial
cpu usage for sound when playing mp3 files.
author | rfelker |
---|---|
date | Sun, 17 Apr 2005 17:17:52 +0000 |
parents | c30e193ac112 |
children | 0e1471d9da74 |
rev | line source |
---|---|
2080 | 1 #include <stdio.h> |
1693 | 2 #include <stdlib.h> |
2080 | 3 #include <string.h> |
1693 | 4 |
8046 | 5 #include <png.h> |
6 | |
14156 | 7 #include "../mp_msg.h" |
8 #include "../help_mp.h" | |
1693 | 9 #include "bitmap.h" |
10 | |
8046 | 11 int pngRead( unsigned char * fname,txSample * bf ) |
12 { | |
13 unsigned char header[8]; | |
14 png_structp png; | |
15 png_infop info; | |
16 png_infop endinfo; | |
17 png_bytep * row_p; | |
18 png_bytep palette = NULL; | |
19 int color; | |
20 png_uint_32 i; | |
21 | |
22 FILE *fp=fopen( fname,"rb" ); | |
23 if ( !fp ) | |
24 { | |
14156 | 25 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] file read error ( %s )\n",fname ); |
8046 | 26 return 1; |
27 } | |
28 | |
29 fread( header,1,8,fp ); | |
30 if ( !png_check_sig( header,8 ) ) return 1; | |
31 | |
32 png=png_create_read_struct( PNG_LIBPNG_VER_STRING,NULL,NULL,NULL ); | |
33 info=png_create_info_struct( png ); | |
34 endinfo=png_create_info_struct( png ); | |
35 | |
36 png_init_io( png,fp ); | |
37 png_set_sig_bytes( png,8 ); | |
38 png_read_info( png,info ); | |
39 png_get_IHDR( png,info,&bf->Width,&bf->Height,&bf->BPP,&color,NULL,NULL,NULL ); | |
40 | |
41 row_p=(png_bytep *)malloc( sizeof( png_bytep ) * bf->Height ); | |
42 if ( !row_p ) | |
43 { | |
14156 | 44 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] not enough memory for row buffer\n" ); |
8046 | 45 return 2; |
46 } | |
47 bf->Image=(png_bytep)malloc( png_get_rowbytes( png,info ) * bf->Height ); | |
48 if ( !bf->Image ) | |
49 { | |
14156 | 50 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] not enough memory for image buffer\n" ); |
8046 | 51 return 2; |
52 } | |
53 for ( i=0; i < bf->Height; i++ ) row_p[i]=&bf->Image[png_get_rowbytes( png,info ) * i]; | |
54 | |
55 png_read_image( png,row_p ); | |
56 free( row_p ); | |
57 | |
58 #if 0 | |
59 if ( color == PNG_COLOR_TYPE_PALETTE ) | |
60 { | |
61 int cols; | |
62 png_get_PLTE( png,info,(png_colorp *)&palette,&cols ); | |
63 } | |
64 #endif | |
65 | |
66 if ( color&PNG_COLOR_MASK_ALPHA ) | |
67 { | |
68 if ( color&PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY_ALPHA ) bf->BPP*=2; | |
69 else bf->BPP*=4; | |
70 } | |
71 else | |
72 { | |
73 if ( color&PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY ) bf->BPP*=1; | |
74 else bf->BPP*=3; | |
75 } | |
76 | |
77 png_read_end( png,endinfo ); | |
78 png_destroy_read_struct( &png,&info,&endinfo ); | |
79 | |
80 if ( fclose( fp ) != 0 ) | |
81 { | |
82 free( bf->Image ); | |
83 free( palette ); | |
84 return 1; | |
85 } | |
86 bf->ImageSize=bf->Width * bf->Height * ( bf->BPP / 8 ); | |
87 | |
88 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] filename: %s.\n",fname ); | |
89 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] size: %dx%d bits: %d\n",bf->Width,bf->Height,bf->BPP ); | |
90 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] imagesize: %lu\n",bf->ImageSize ); | |
91 return 0; | |
92 } | |
93 | |
1693 | 94 int conv24to32( txSample * bf ) |
95 { | |
96 unsigned char * tmpImage; | |
97 int i,c; | |
98 | |
99 if ( bf->BPP == 24 ) | |
100 { | |
101 tmpImage=bf->Image; | |
102 bf->ImageSize=bf->Width * bf->Height * 4; | |
103 bf->BPP=32; | |
104 if ( ( bf->Image=malloc( bf->ImageSize ) ) == NULL ) | |
105 { | |
14156 | 106 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] not enough memory for image\n" ); |
1693 | 107 return 1; |
108 } | |
109 memset( bf->Image,0,bf->ImageSize ); | |
4818
3473ca9ef158
new gui interface, and gtk moved into mplayer process. fork ... bleh :)
pontscho
parents:
2717
diff
changeset
|
110 for ( c=0,i=0;i < (int)(bf->Width * bf->Height * 3); ) |
1693 | 111 { |
6054 | 112 bf->Image[c++]=tmpImage[i++]; //red |
113 bf->Image[c++]=tmpImage[i++]; //green | |
114 bf->Image[c++]=tmpImage[i++]; c++; //blue | |
1693 | 115 } |
116 free( tmpImage ); | |
117 } | |
118 return 0; | |
119 } | |
120 | |
121 void bgr2rgb( txSample * bf ) | |
122 { | |
123 unsigned char c; | |
124 int i; | |
125 | |
4818
3473ca9ef158
new gui interface, and gtk moved into mplayer process. fork ... bleh :)
pontscho
parents:
2717
diff
changeset
|
126 for ( i=0;i < (int)bf->ImageSize;i+=4 ) |
1693 | 127 { |
128 c=bf->Image[i]; | |
129 bf->Image[i]=bf->Image[i+2]; | |
130 bf->Image[i+2]=c; | |
131 } | |
132 } | |
133 | |
134 void Normalize( txSample * bf ) | |
135 { | |
136 int i; | |
6054 | 137 #ifndef WORDS_BIGENDIAN |
4818
3473ca9ef158
new gui interface, and gtk moved into mplayer process. fork ... bleh :)
pontscho
parents:
2717
diff
changeset
|
138 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i+3]=0; |
6054 | 139 #else |
140 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i]=0; | |
141 #endif | |
1693 | 142 } |
143 | |
144 unsigned char tmp[512]; | |
145 | |
146 unsigned char * fExist( unsigned char * fname ) | |
147 { | |
148 FILE * fl; | |
7265 | 149 unsigned char ext[][6] = { ".png\0",".PNG\0" }; |
1693 | 150 int i; |
151 | |
152 fl=fopen( fname,"rb" ); | |
153 if ( fl != NULL ) | |
154 { | |
155 fclose( fl ); | |
156 return fname; | |
157 } | |
7265 | 158 for ( i=0;i<2;i++ ) |
1693 | 159 { |
10168 | 160 snprintf( tmp,511,"%s%s",fname,ext[i] ); |
1693 | 161 fl=fopen( tmp,"rb" ); |
162 if ( fl != NULL ) | |
163 { | |
164 fclose( fl ); | |
165 return tmp; | |
166 } | |
167 } | |
168 return NULL; | |
169 } | |
170 | |
171 int bpRead( char * fname, txSample * bf ) | |
172 { | |
173 fname=fExist( fname ); | |
174 if ( fname == NULL ) return -2; | |
7265 | 175 if ( pngRead( fname,bf ) ) |
1693 | 176 { |
14156 | 177 mp_dbg( MSGT_GPLAYER,MSGL_FATAL,"[bitmap] unknown file type ( %s )\n",fname ); |
7265 | 178 return -5; |
1693 | 179 } |
180 if ( bf->BPP < 24 ) | |
181 { | |
10168 | 182 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" ); |
1693 | 183 return -1; |
184 } | |
10169
46badb3d0b1c
simplyfied it and fixed some 10ls (but sadly xshape still don't works)
alex
parents:
10168
diff
changeset
|
185 if ( conv24to32( bf ) ) return -8; |
10168 | 186 #ifdef WORDS_BIGENDIAN |
10169
46badb3d0b1c
simplyfied it and fixed some 10ls (but sadly xshape still don't works)
alex
parents:
10168
diff
changeset
|
187 swab(bf->Image, bf->Image, bf->ImageSize); |
10168 | 188 #endif |
7265 | 189 bgr2rgb( bf ); |
1693 | 190 Normalize( bf ); |
191 return 0; | |
192 } | |
2717 | 193 |
194 void Convert32to1( txSample * in,txSample * out,int adaptivlimit ) | |
195 { | |
196 out->Width=in->Width; | |
197 out->Height=in->Height; | |
198 out->BPP=1; | |
7352
757e876d36fe
Off-by-one error allocating bitmap, when (width*height) % 8 != 0
jkeil
parents:
7265
diff
changeset
|
199 out->ImageSize=(out->Width * out->Height + 7) / 8; |
10169
46badb3d0b1c
simplyfied it and fixed some 10ls (but sadly xshape still don't works)
alex
parents:
10168
diff
changeset
|
200 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c32to1] imagesize: %d\n",out->ImageSize ); |
2717 | 201 out->Image=(char *)calloc( 1,out->ImageSize ); |
14156 | 202 if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_NotEnoughMemoryC32To1 ); |
2717 | 203 { |
6145
26cb8736927b
Gui and 64-bit issues patch from Gui and 64-bit issues
pontscho
parents:
6054
diff
changeset
|
204 int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; int nothaveshape = 1; |
26cb8736927b
Gui and 64-bit issues patch from Gui and 64-bit issues
pontscho
parents:
6054
diff
changeset
|
205 buf=(unsigned int *)in->Image; |
4818
3473ca9ef158
new gui interface, and gtk moved into mplayer process. fork ... bleh :)
pontscho
parents:
2717
diff
changeset
|
206 for ( b=0,i=0;i < (int)(out->Width * out->Height);i++ ) |
2717 | 207 { |
4818
3473ca9ef158
new gui interface, and gtk moved into mplayer process. fork ... bleh :)
pontscho
parents:
2717
diff
changeset
|
208 if ( (int)buf[i] != adaptivlimit ) tmp=( tmp >> 1 )|128; |
2717 | 209 else { tmp=tmp >> 1; buf[i]=nothaveshape=0; } |
210 if ( b++ == 7 ) { out->Image[c++]=tmp; tmp=b=0; } | |
211 } | |
212 if ( b ) out->Image[c]=tmp; | |
213 if ( nothaveshape ) { free( out->Image ); out->Image=NULL; } | |
214 } | |
215 } | |
216 | |
217 void Convert1to32( txSample * in,txSample * out ) | |
218 { | |
219 if ( in->Image == NULL ) return; | |
220 out->Width=in->Width; | |
221 out->Height=in->Height; | |
222 out->BPP=32; | |
223 out->ImageSize=out->Width * out->Height * 4; | |
224 out->Image=(char *)calloc( 1,out->ImageSize ); | |
10169
46badb3d0b1c
simplyfied it and fixed some 10ls (but sadly xshape still don't works)
alex
parents:
10168
diff
changeset
|
225 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c1to32] imagesize: %d\n",out->ImageSize ); |
14156 | 226 if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_NotEnoughMemoryC1To32 ); |
2717 | 227 { |
6145
26cb8736927b
Gui and 64-bit issues patch from Gui and 64-bit issues
pontscho
parents:
6054
diff
changeset
|
228 int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; |
26cb8736927b
Gui and 64-bit issues patch from Gui and 64-bit issues
pontscho
parents:
6054
diff
changeset
|
229 buf=(unsigned int *)out->Image; |
4818
3473ca9ef158
new gui interface, and gtk moved into mplayer process. fork ... bleh :)
pontscho
parents:
2717
diff
changeset
|
230 for ( c=0,i=0;i < (int)(in->Width * in->Height / 8);i++ ) |
2717 | 231 { |
232 tmp=in->Image[i]; | |
233 for ( b=0;b<8;b++ ) | |
234 { | |
235 buf[c]=0; | |
236 if ( tmp&0x1 ) buf[c]=0xffffffff; | |
237 c++; tmp=tmp>>1; | |
238 } | |
239 } | |
240 } | |
241 } |