Mercurial > mplayer.hg
annotate gui/bitmap.c @ 27559:21590d0bb4e6
The yuv->rgb tables are too small for clipping to be avoidable,
thus revert the respective optimization. The table generator code
has to be rewritten anyway one day by some volunteer because it is
not LGPL, fixing the GPL table generator thus seems like wasted time.
author | michael |
---|---|
date | Fri, 12 Sep 2008 21:25:42 +0000 |
parents | b0a7b35b78d2 |
children | 0f1b5b68af32 |
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; |
23077 | 37 |
38 FILE *fp=fopen( fname,"rb" ); | |
39 if ( !fp ) | |
40 { | |
41 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] file read error ( %s )\n",fname ); | |
42 return 1; | |
43 } | |
44 | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
45 fseek(fp, 0, SEEK_END); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
46 len = ftell(fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
47 if (len > 50 * 1024 * 1024) return 2; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
48 data = malloc(len + FF_INPUT_BUFFER_PADDING_SIZE); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
49 fseek(fp, 0, SEEK_SET); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
50 fread(data, len, 1, fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
51 fclose(fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
52 avctx = avcodec_alloc_context(); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
53 frame = avcodec_alloc_frame(); |
23526 | 54 avcodec_register_all(); |
55 avcodec_open(avctx, avcodec_find_decoder(CODEC_ID_PNG)); | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
56 avcodec_decode_video(avctx, frame, &decode_ok, data, len); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
57 memset(bf, 0, sizeof(*bf)); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
58 switch (avctx->pix_fmt) { |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
59 case PIX_FMT_GRAY8: bf->BPP = 8; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
60 case PIX_FMT_GRAY16BE: bf->BPP = 16; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
61 case PIX_FMT_RGB24: bf->BPP = 24; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
62 case PIX_FMT_RGB32: bf->BPP = 32; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
63 default: bf->BPP = 0; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
64 } |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
65 if (decode_ok && bf->BPP) { |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
66 int bpl; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
67 bf->Width = avctx->width; bf->Height = avctx->height; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
68 bpl = bf->Width * (bf->BPP / 8); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
69 bf->ImageSize = bpl * bf->Height; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
70 bf->Image = malloc(bf->ImageSize); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
71 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
|
72 } |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
73 avcodec_close(avctx); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
74 av_freep(&frame); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
75 av_freep(&avctx); |
23077 | 76 |
77 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] filename: %s.\n",fname ); | |
78 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] size: %dx%d bits: %d\n",bf->Width,bf->Height,bf->BPP ); | |
79 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
|
80 return !(decode_ok && bf->BPP); |
23077 | 81 } |
82 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
83 static int conv24to32( txSample * bf ) |
23077 | 84 { |
85 unsigned char * tmpImage; | |
86 int i,c; | |
87 | |
88 if ( bf->BPP == 24 ) | |
89 { | |
90 tmpImage=bf->Image; | |
91 bf->ImageSize=bf->Width * bf->Height * 4; | |
92 bf->BPP=32; | |
23200 | 93 if ( ( bf->Image=calloc( 1, bf->ImageSize ) ) == NULL ) |
23077 | 94 { |
23199 | 95 free( tmpImage ); |
23077 | 96 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] not enough memory for image\n" ); |
97 return 1; | |
98 } | |
23225
794aba782ebd
Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents:
23200
diff
changeset
|
99 for ( c=0,i=0; c < bf->ImageSize; c += 4, i += 3) |
23077 | 100 { |
23225
794aba782ebd
Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents:
23200
diff
changeset
|
101 *(uint32_t *)&bf->Image[c] = AV_RB24(&tmpImage[i]); |
23077 | 102 } |
103 free( tmpImage ); | |
104 } | |
105 return 0; | |
106 } | |
107 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
108 static void Normalize( txSample * bf ) |
23077 | 109 { |
110 int i; | |
111 #ifndef WORDS_BIGENDIAN | |
112 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i+3]=0; | |
113 #else | |
114 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i]=0; | |
115 #endif | |
116 } | |
117 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
118 static unsigned char tmp[512]; |
23077 | 119 |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
120 static unsigned char * fExist( unsigned char * fname ) |
23077 | 121 { |
122 FILE * fl; | |
123 unsigned char ext[][6] = { ".png\0",".PNG\0" }; | |
124 int i; | |
125 | |
126 fl=fopen( fname,"rb" ); | |
127 if ( fl != NULL ) | |
128 { | |
129 fclose( fl ); | |
130 return fname; | |
131 } | |
132 for ( i=0;i<2;i++ ) | |
133 { | |
134 snprintf( tmp,511,"%s%s",fname,ext[i] ); | |
135 fl=fopen( tmp,"rb" ); | |
136 if ( fl != NULL ) | |
137 { | |
138 fclose( fl ); | |
139 return tmp; | |
140 } | |
141 } | |
142 return NULL; | |
143 } | |
144 | |
145 int bpRead( char * fname, txSample * bf ) | |
146 { | |
147 fname=fExist( fname ); | |
148 if ( fname == NULL ) return -2; | |
149 if ( pngRead( fname,bf ) ) | |
150 { | |
151 mp_dbg( MSGT_GPLAYER,MSGL_FATAL,"[bitmap] unknown file type ( %s )\n",fname ); | |
152 return -5; | |
153 } | |
154 if ( bf->BPP < 24 ) | |
155 { | |
156 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" ); | |
157 return -1; | |
158 } | |
159 if ( conv24to32( bf ) ) return -8; | |
160 Normalize( bf ); | |
161 return 0; | |
162 } | |
163 | |
164 void Convert32to1( txSample * in,txSample * out,int adaptivlimit ) | |
165 { | |
166 out->Width=in->Width; | |
167 out->Height=in->Height; | |
168 out->BPP=1; | |
169 out->ImageSize=(out->Width * out->Height + 7) / 8; | |
170 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c32to1] imagesize: %d\n",out->ImageSize ); | |
171 out->Image=calloc( 1,out->ImageSize ); | |
172 if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_NotEnoughMemoryC32To1 ); | |
173 { | |
174 int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; int nothaveshape = 1; | |
175 buf=(unsigned int *)in->Image; | |
176 for ( b=0,i=0;i < (int)(out->Width * out->Height);i++ ) | |
177 { | |
178 if ( (int)buf[i] != adaptivlimit ) tmp=( tmp >> 1 )|128; | |
179 else { tmp=tmp >> 1; buf[i]=nothaveshape=0; } | |
180 if ( b++ == 7 ) { out->Image[c++]=tmp; tmp=b=0; } | |
181 } | |
182 if ( b ) out->Image[c]=tmp; | |
183 if ( nothaveshape ) { free( out->Image ); out->Image=NULL; } | |
184 } | |
185 } |