annotate gui/bitmap.c @ 25661:293aeec83153

Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with an almost-trivial implementation. This allows making the builtin codec structs const, and it also makes clearer that this "selected" status is not used outside the init functions.
author reimar
date Sat, 12 Jan 2008 14:05:46 +0000
parents cdf3ba9e5b97
children 1318e956c092
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
1 #include <stdio.h>
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
2 #include <stdlib.h>
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
3 #include <string.h>
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
4
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
5 #include "mp_msg.h"
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
6 #include "help_mp.h"
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
7 #include "bitmap.h"
23193
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
8 #ifdef USE_LIBAVCODEC_SO
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
9 #include <ffmpeg/avcodec.h>
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
10 #else
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
11 #include "libavcodec/avcodec.h"
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
12 #endif
23225
794aba782ebd Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents: 23200
diff changeset
13 #include "libavutil/intreadwrite.h"
23193
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
14 #include "libvo/fastmemcpy.h"
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
15
23196
019bfce0c0dc Make functions and variables not used outside bitmap.c static
reimar
parents: 23195
diff changeset
16 static int pngRead( unsigned char * fname,txSample * bf )
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
17 {
23193
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
18 int decode_ok;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
19 void *data;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
20 int len;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
21 AVCodecContext *avctx;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
22 AVFrame *frame;
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
23
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
24 FILE *fp=fopen( fname,"rb" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
25 if ( !fp )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
26 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
27 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] file read error ( %s )\n",fname );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
28 return 1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
29 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
30
23193
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
31 fseek(fp, 0, SEEK_END);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
32 len = ftell(fp);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
33 if (len > 50 * 1024 * 1024) return 2;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
34 data = malloc(len + FF_INPUT_BUFFER_PADDING_SIZE);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
35 fseek(fp, 0, SEEK_SET);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
36 fread(data, len, 1, fp);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
37 fclose(fp);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
38 avctx = avcodec_alloc_context();
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
39 frame = avcodec_alloc_frame();
23526
cdf3ba9e5b97 Fix compilation after FFmpeg r9283.
cehoyos
parents: 23226
diff changeset
40 avcodec_register_all();
cdf3ba9e5b97 Fix compilation after FFmpeg r9283.
cehoyos
parents: 23226
diff changeset
41 avcodec_open(avctx, avcodec_find_decoder(CODEC_ID_PNG));
23193
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
42 avcodec_decode_video(avctx, frame, &decode_ok, data, len);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
43 memset(bf, 0, sizeof(*bf));
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
44 switch (avctx->pix_fmt) {
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
45 case PIX_FMT_GRAY8: bf->BPP = 8; break;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
46 case PIX_FMT_GRAY16BE: bf->BPP = 16; break;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
47 case PIX_FMT_RGB24: bf->BPP = 24; break;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
48 case PIX_FMT_RGB32: bf->BPP = 32; break;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
49 default: bf->BPP = 0; break;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
50 }
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
51 if (decode_ok && bf->BPP) {
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
52 int bpl;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
53 bf->Width = avctx->width; bf->Height = avctx->height;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
54 bpl = bf->Width * (bf->BPP / 8);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
55 bf->ImageSize = bpl * bf->Height;
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
56 bf->Image = malloc(bf->ImageSize);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
57 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
58 }
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
59 avcodec_close(avctx);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
60 av_freep(&frame);
7857af1ca50b Remove libpng dependency for Gui, use libavcodec instead
reimar
parents: 23077
diff changeset
61 av_freep(&avctx);
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
62
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
63 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] filename: %s.\n",fname );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
64 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
65 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
66 return !(decode_ok && bf->BPP);
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
67 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
68
23196
019bfce0c0dc Make functions and variables not used outside bitmap.c static
reimar
parents: 23195
diff changeset
69 static int conv24to32( txSample * bf )
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
70 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
71 unsigned char * tmpImage;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
72 int i,c;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
73
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
74 if ( bf->BPP == 24 )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
75 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
76 tmpImage=bf->Image;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
77 bf->ImageSize=bf->Width * bf->Height * 4;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
78 bf->BPP=32;
23200
44cf48083874 Use calloc instead of malloc+memset
reimar
parents: 23199
diff changeset
79 if ( ( bf->Image=calloc( 1, bf->ImageSize ) ) == NULL )
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
80 {
23199
e1d0d26f5e3c Missing free on error in conv24to32
reimar
parents: 23198
diff changeset
81 free( tmpImage );
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
82 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] not enough memory for image\n" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
83 return 1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
84 }
23225
794aba782ebd Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents: 23200
diff changeset
85 for ( c=0,i=0; c < bf->ImageSize; c += 4, i += 3)
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
86 {
23225
794aba782ebd Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents: 23200
diff changeset
87 *(uint32_t *)&bf->Image[c] = AV_RB24(&tmpImage[i]);
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
88 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
89 free( tmpImage );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
90 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
91 return 0;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
92 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
93
23196
019bfce0c0dc Make functions and variables not used outside bitmap.c static
reimar
parents: 23195
diff changeset
94 static void Normalize( txSample * bf )
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
95 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
96 int i;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
97 #ifndef WORDS_BIGENDIAN
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
98 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i+3]=0;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
99 #else
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
100 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i]=0;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
101 #endif
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
102 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
103
23196
019bfce0c0dc Make functions and variables not used outside bitmap.c static
reimar
parents: 23195
diff changeset
104 static unsigned char tmp[512];
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
105
23196
019bfce0c0dc Make functions and variables not used outside bitmap.c static
reimar
parents: 23195
diff changeset
106 static unsigned char * fExist( unsigned char * fname )
23077
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
107 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
108 FILE * fl;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
109 unsigned char ext[][6] = { ".png\0",".PNG\0" };
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
110 int i;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
111
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
112 fl=fopen( fname,"rb" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
113 if ( fl != NULL )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
114 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
115 fclose( fl );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
116 return fname;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
117 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
118 for ( i=0;i<2;i++ )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
119 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
120 snprintf( tmp,511,"%s%s",fname,ext[i] );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
121 fl=fopen( tmp,"rb" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
122 if ( fl != NULL )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
123 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
124 fclose( fl );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
125 return tmp;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
126 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
127 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
128 return NULL;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
129 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
130
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
131 int bpRead( char * fname, txSample * bf )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
132 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
133 fname=fExist( fname );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
134 if ( fname == NULL ) return -2;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
135 if ( pngRead( fname,bf ) )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
136 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
137 mp_dbg( MSGT_GPLAYER,MSGL_FATAL,"[bitmap] unknown file type ( %s )\n",fname );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
138 return -5;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
139 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
140 if ( bf->BPP < 24 )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
141 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
142 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
143 return -1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
144 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
145 if ( conv24to32( bf ) ) return -8;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
146 Normalize( bf );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
147 return 0;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
148 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
149
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
150 void Convert32to1( txSample * in,txSample * out,int adaptivlimit )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
151 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
152 out->Width=in->Width;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
153 out->Height=in->Height;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
154 out->BPP=1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
155 out->ImageSize=(out->Width * out->Height + 7) / 8;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
156 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c32to1] imagesize: %d\n",out->ImageSize );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
157 out->Image=calloc( 1,out->ImageSize );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
158 if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_NotEnoughMemoryC32To1 );
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
159 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
160 int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; int nothaveshape = 1;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
161 buf=(unsigned int *)in->Image;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
162 for ( b=0,i=0;i < (int)(out->Width * out->Height);i++ )
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
163 {
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
164 if ( (int)buf[i] != adaptivlimit ) tmp=( tmp >> 1 )|128;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
165 else { tmp=tmp >> 1; buf[i]=nothaveshape=0; }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
166 if ( b++ == 7 ) { out->Image[c++]=tmp; tmp=b=0; }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
167 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
168 if ( b ) out->Image[c]=tmp;
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
169 if ( nothaveshape ) { free( out->Image ); out->Image=NULL; }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
170 }
17bf4f4b0715 Gui --> gui
diego
parents:
diff changeset
171 }