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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
26458
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
1 /*
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
2 * This file is part of MPlayer.
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
3 *
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
4 * MPlayer is free software; you can redistribute it and/or modify
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
5 * it under the terms of the GNU General Public License as published by
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
6 * the Free Software Foundation; either version 2 of the License, or
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
7 * (at your option) any later version.
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
8 *
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
9 * MPlayer is distributed in the hope that it will be useful,
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
12 * GNU General Public License for more details.
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
13 *
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
14 * You should have received a copy of the GNU General Public License along
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
17 */
b0a7b35b78d2 Add standard GPL header to individual files.
diego
parents: 26069
diff changeset
18
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
19 #include <stdio.h>
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
20 #include <stdlib.h>
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
21 #include <string.h>
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
22
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
23 #include "mp_msg.h"
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
24 #include "help_mp.h"
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
37
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
38 FILE *fp=fopen( fname,"rb" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
39 if ( !fp )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
40 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
41 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] file read error ( %s )\n",fname );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
42 return 1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
43 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
cdf3ba9e5b97 Fix compilation after FFmpeg r9283.
cehoyos
parents: 23226
diff changeset
54 avcodec_register_all();
cdf3ba9e5b97 Fix compilation after FFmpeg r9283.
cehoyos
parents: 23226
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
76
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
77 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] filename: %s.\n",fname );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
78 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] size: %dx%d bits: %d\n",bf->Width,bf->Height,bf->BPP );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
81 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
84 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
85 unsigned char * tmpImage;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
86 int i,c;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
87
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
88 if ( bf->BPP == 24 )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
89 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
90 tmpImage=bf->Image;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
91 bf->ImageSize=bf->Width * bf->Height * 4;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
92 bf->BPP=32;
23200
44cf48083874 Use calloc instead of malloc+memset
reimar
parents: 23199
diff changeset
93 if ( ( bf->Image=calloc( 1, bf->ImageSize ) ) == NULL )
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
94 {
23199
e1d0d26f5e3c Missing free on error in conv24to32
reimar
parents: 23198
diff changeset
95 free( tmpImage );
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
96 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] not enough memory for image\n" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
97 return 1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
102 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
103 free( tmpImage );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
104 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
105 return 0;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
106 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
109 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
110 int i;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
111 #ifndef WORDS_BIGENDIAN
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
112 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i+3]=0;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
113 #else
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
114 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i]=0;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
115 #endif
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
116 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
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
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
121 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
122 FILE * fl;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
123 unsigned char ext[][6] = { ".png\0",".PNG\0" };
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
124 int i;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
125
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
126 fl=fopen( fname,"rb" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
127 if ( fl != NULL )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
128 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
129 fclose( fl );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
130 return fname;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
131 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
132 for ( i=0;i<2;i++ )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
133 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
134 snprintf( tmp,511,"%s%s",fname,ext[i] );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
135 fl=fopen( tmp,"rb" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
136 if ( fl != NULL )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
137 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
138 fclose( fl );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
139 return tmp;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
140 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
141 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
142 return NULL;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
143 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
144
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
145 int bpRead( char * fname, txSample * bf )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
146 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
147 fname=fExist( fname );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
148 if ( fname == NULL ) return -2;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
149 if ( pngRead( fname,bf ) )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
150 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
151 mp_dbg( MSGT_GPLAYER,MSGL_FATAL,"[bitmap] unknown file type ( %s )\n",fname );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
152 return -5;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
153 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
154 if ( bf->BPP < 24 )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
155 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
156 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
157 return -1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
158 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
159 if ( conv24to32( bf ) ) return -8;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
160 Normalize( bf );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
161 return 0;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
162 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
163
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
164 void Convert32to1( txSample * in,txSample * out,int adaptivlimit )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
165 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
166 out->Width=in->Width;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
167 out->Height=in->Height;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
168 out->BPP=1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
169 out->ImageSize=(out->Width * out->Height + 7) / 8;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
170 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c32to1] imagesize: %d\n",out->ImageSize );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
171 out->Image=calloc( 1,out->ImageSize );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
172 if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_NotEnoughMemoryC32To1 );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
173 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
174 int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; int nothaveshape = 1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
175 buf=(unsigned int *)in->Image;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
176 for ( b=0,i=0;i < (int)(out->Width * out->Height);i++ )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
177 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
178 if ( (int)buf[i] != adaptivlimit ) tmp=( tmp >> 1 )|128;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
179 else { tmp=tmp >> 1; buf[i]=nothaveshape=0; }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
180 if ( b++ == 7 ) { out->Image[c++]=tmp; tmp=b=0; }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
181 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
182 if ( b ) out->Image[c]=tmp;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
183 if ( nothaveshape ) { free( out->Image ); out->Image=NULL; }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
184 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
185 }