Mercurial > mplayer.hg
annotate gui/bitmap.c @ 32676:db882cd69776
Do not #define _WIN32 on the command line for Cygwin.
Newer Cygwin versions no longer do this and hopefully we should be able
to survive without this hack as well. This change necessitates adapting
two #ifdefs in the MPlayer codebase. It is committed untested as I do
not have access to a Cygwin system.
author | diego |
---|---|
date | Thu, 06 Jan 2011 12:42:59 +0000 |
parents | 6be4d46328dd |
children | 6ff3cc81d602 |
rev | line source |
---|---|
26458 | 1 /* |
2 * This file is part of MPlayer. | |
3 * | |
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. | |
8 * | |
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. | |
13 * | |
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. | |
17 */ | |
18 | |
23077 | 19 #include <stdio.h> |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 | |
23 #include "mp_msg.h" | |
24 #include "help_mp.h" | |
25 #include "bitmap.h" | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
26 #include "libavcodec/avcodec.h" |
23225
794aba782ebd
Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents:
23200
diff
changeset
|
27 #include "libavutil/intreadwrite.h" |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
28 #include "libvo/fastmemcpy.h" |
23077 | 29 |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
30 static int pngRead( unsigned char * fname,txSample * bf ) |
23077 | 31 { |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
32 int decode_ok; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
33 void *data; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
34 int len; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
35 AVCodecContext *avctx; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
36 AVFrame *frame; |
31730
6be4d46328dd
Switch to non-deprecated avcodec_decode_video2 API.
reimar
parents:
30388
diff
changeset
|
37 AVPacket pkt; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26458
diff
changeset
|
38 |
23077 | 39 FILE *fp=fopen( fname,"rb" ); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26458
diff
changeset
|
40 if ( !fp ) |
23077 | 41 { |
42 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] file read error ( %s )\n",fname ); | |
43 return 1; | |
44 } | |
45 | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
46 fseek(fp, 0, SEEK_END); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
47 len = ftell(fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
48 if (len > 50 * 1024 * 1024) return 2; |
30388
45dcf93d41fa
Use av_malloc to ensure sufficient alignment and also free at least some
reimar
parents:
30310
diff
changeset
|
49 data = av_malloc(len + FF_INPUT_BUFFER_PADDING_SIZE); |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
50 fseek(fp, 0, SEEK_SET); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
51 fread(data, len, 1, fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
52 fclose(fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
53 avctx = avcodec_alloc_context(); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
54 frame = avcodec_alloc_frame(); |
23526 | 55 avcodec_register_all(); |
56 avcodec_open(avctx, avcodec_find_decoder(CODEC_ID_PNG)); | |
31730
6be4d46328dd
Switch to non-deprecated avcodec_decode_video2 API.
reimar
parents:
30388
diff
changeset
|
57 av_init_packet(&pkt); |
6be4d46328dd
Switch to non-deprecated avcodec_decode_video2 API.
reimar
parents:
30388
diff
changeset
|
58 pkt.data = data; |
6be4d46328dd
Switch to non-deprecated avcodec_decode_video2 API.
reimar
parents:
30388
diff
changeset
|
59 pkt.size = len; |
6be4d46328dd
Switch to non-deprecated avcodec_decode_video2 API.
reimar
parents:
30388
diff
changeset
|
60 // HACK: make PNGs decode normally instead of as CorePNG delta frames |
6be4d46328dd
Switch to non-deprecated avcodec_decode_video2 API.
reimar
parents:
30388
diff
changeset
|
61 pkt.flags = PKT_FLAG_KEY; |
6be4d46328dd
Switch to non-deprecated avcodec_decode_video2 API.
reimar
parents:
30388
diff
changeset
|
62 avcodec_decode_video2(avctx, frame, &decode_ok, &pkt); |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
63 memset(bf, 0, sizeof(*bf)); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
64 switch (avctx->pix_fmt) { |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
65 case PIX_FMT_GRAY8: bf->BPP = 8; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
66 case PIX_FMT_GRAY16BE: bf->BPP = 16; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
67 case PIX_FMT_RGB24: bf->BPP = 24; break; |
30310
6693b4a6a284
Do not depend on PIX_FMT_RGB32 which is (currently?) not part of the public API.
reimar
parents:
29401
diff
changeset
|
68 case PIX_FMT_BGRA: |
6693b4a6a284
Do not depend on PIX_FMT_RGB32 which is (currently?) not part of the public API.
reimar
parents:
29401
diff
changeset
|
69 case PIX_FMT_ARGB: bf->BPP = 32; break; |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
70 default: bf->BPP = 0; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
71 } |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
72 if (decode_ok && bf->BPP) { |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
73 int bpl; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
74 bf->Width = avctx->width; bf->Height = avctx->height; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
75 bpl = bf->Width * (bf->BPP / 8); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
76 bf->ImageSize = bpl * bf->Height; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
77 bf->Image = malloc(bf->ImageSize); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
78 memcpy_pic(bf->Image, frame->data[0], bpl, bf->Height, bpl, frame->linesize[0]); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
79 } |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
80 avcodec_close(avctx); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
81 av_freep(&frame); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
82 av_freep(&avctx); |
30388
45dcf93d41fa
Use av_malloc to ensure sufficient alignment and also free at least some
reimar
parents:
30310
diff
changeset
|
83 av_freep(&data); |
23077 | 84 |
85 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] filename: %s.\n",fname ); | |
86 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] size: %dx%d bits: %d\n",bf->Width,bf->Height,bf->BPP ); | |
87 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] imagesize: %lu\n",bf->ImageSize ); | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
88 return !(decode_ok && bf->BPP); |
23077 | 89 } |
90 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
91 static int conv24to32( txSample * bf ) |
23077 | 92 { |
93 unsigned char * tmpImage; | |
94 int i,c; | |
95 | |
96 if ( bf->BPP == 24 ) | |
97 { | |
98 tmpImage=bf->Image; | |
99 bf->ImageSize=bf->Width * bf->Height * 4; | |
100 bf->BPP=32; | |
23200 | 101 if ( ( bf->Image=calloc( 1, bf->ImageSize ) ) == NULL ) |
23077 | 102 { |
23199 | 103 free( tmpImage ); |
23077 | 104 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] not enough memory for image\n" ); |
105 return 1; | |
106 } | |
23225
794aba782ebd
Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents:
23200
diff
changeset
|
107 for ( c=0,i=0; c < bf->ImageSize; c += 4, i += 3) |
23077 | 108 { |
23225
794aba782ebd
Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents:
23200
diff
changeset
|
109 *(uint32_t *)&bf->Image[c] = AV_RB24(&tmpImage[i]); |
23077 | 110 } |
111 free( tmpImage ); | |
112 } | |
113 return 0; | |
114 } | |
115 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
116 static void Normalize( txSample * bf ) |
23077 | 117 { |
118 int i; | |
29401
f01023c524c3
Replace WORDS_BIGENDIAN by HAVE_BIGENDIAN in all internal code.
diego
parents:
29263
diff
changeset
|
119 #if !HAVE_BIGENDIAN |
23077 | 120 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i+3]=0; |
121 #else | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26458
diff
changeset
|
122 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i]=0; |
23077 | 123 #endif |
124 } | |
125 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
126 static unsigned char tmp[512]; |
23077 | 127 |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
128 static unsigned char * fExist( unsigned char * fname ) |
23077 | 129 { |
130 FILE * fl; | |
131 unsigned char ext[][6] = { ".png\0",".PNG\0" }; | |
132 int i; | |
133 | |
134 fl=fopen( fname,"rb" ); | |
135 if ( fl != NULL ) | |
136 { | |
137 fclose( fl ); | |
138 return fname; | |
139 } | |
140 for ( i=0;i<2;i++ ) | |
141 { | |
142 snprintf( tmp,511,"%s%s",fname,ext[i] ); | |
143 fl=fopen( tmp,"rb" ); | |
144 if ( fl != NULL ) | |
145 { | |
146 fclose( fl ); | |
147 return tmp; | |
148 } | |
149 } | |
150 return NULL; | |
151 } | |
152 | |
153 int bpRead( char * fname, txSample * bf ) | |
154 { | |
155 fname=fExist( fname ); | |
156 if ( fname == NULL ) return -2; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26458
diff
changeset
|
157 if ( pngRead( fname,bf ) ) |
23077 | 158 { |
159 mp_dbg( MSGT_GPLAYER,MSGL_FATAL,"[bitmap] unknown file type ( %s )\n",fname ); | |
160 return -5; | |
161 } | |
162 if ( bf->BPP < 24 ) | |
163 { | |
164 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" ); | |
165 return -1; | |
166 } | |
167 if ( conv24to32( bf ) ) return -8; | |
168 Normalize( bf ); | |
169 return 0; | |
170 } | |
171 | |
172 void Convert32to1( txSample * in,txSample * out,int adaptivlimit ) | |
173 { | |
174 out->Width=in->Width; | |
175 out->Height=in->Height; | |
176 out->BPP=1; | |
177 out->ImageSize=(out->Width * out->Height + 7) / 8; | |
178 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c32to1] imagesize: %d\n",out->ImageSize ); | |
179 out->Image=calloc( 1,out->ImageSize ); | |
180 if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_NotEnoughMemoryC32To1 ); | |
181 { | |
182 int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; int nothaveshape = 1; | |
183 buf=(unsigned int *)in->Image; | |
184 for ( b=0,i=0;i < (int)(out->Width * out->Height);i++ ) | |
185 { | |
186 if ( (int)buf[i] != adaptivlimit ) tmp=( tmp >> 1 )|128; | |
187 else { tmp=tmp >> 1; buf[i]=nothaveshape=0; } | |
188 if ( b++ == 7 ) { out->Image[c++]=tmp; tmp=b=0; } | |
189 } | |
190 if ( b ) out->Image[c]=tmp; | |
191 if ( nothaveshape ) { free( out->Image ); out->Image=NULL; } | |
192 } | |
193 } |