2 * This file is part of MPlayer.
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.
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.
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.
27 #include "img_format.h"
32 #include "libswscale/swscale.h"
34 //===========================================================================//
36 // commented out 16 and 15 bit output support, because the conversion
37 // routines are incorrrect. they assume the palette to be of the same
38 // depth as the output, which is incorrect. --Joey
40 static const unsigned int bgr_list
[]={
47 static const unsigned int rgb_list
[]={
56 * Palette is assumed to contain BGR16, see rgb32to16 to convert the palette.
58 static void palette8torgb16(const uint8_t *src
, uint8_t *dst
, long num_pixels
, const uint8_t *palette
)
61 for (i
=0; i
<num_pixels
; i
++)
62 ((uint16_t *)dst
)[i
] = ((const uint16_t *)palette
)[src
[i
]];
65 static void palette8tobgr16(const uint8_t *src
, uint8_t *dst
, long num_pixels
, const uint8_t *palette
)
68 for (i
=0; i
<num_pixels
; i
++)
69 ((uint16_t *)dst
)[i
] = bswap_16(((const uint16_t *)palette
)[src
[i
]]);
72 static unsigned int gray_pal
[256];
74 static unsigned int find_best(struct vf_instance
*vf
, unsigned int fmt
){
77 const unsigned int* p
;
78 if(fmt
==IMGFMT_BGR8
) p
=bgr_list
;
79 else if(fmt
==IMGFMT_RGB8
) p
=rgb_list
;
82 ret
=vf
->next
->query_format(vf
->next
,*p
);
83 mp_msg(MSGT_VFILTER
,MSGL_DBG2
,"[%s] query(%s) -> %d\n",vf
->info
->name
,vo_format_name(*p
),ret
&3);
84 if(ret
&VFCAP_CSP_SUPPORTED_BY_HW
){ best
=*p
; break;} // no conversion -> bingo!
85 if(ret
&VFCAP_CSP_SUPPORTED
&& !best
) best
=*p
; // best with conversion
91 //===========================================================================//
98 static int config(struct vf_instance
*vf
,
99 int width
, int height
, int d_width
, int d_height
,
100 unsigned int flags
, unsigned int outfmt
){
102 vf
->priv
->fmt
=find_best(vf
,outfmt
);
104 // no matching fmt, so force one...
105 if(outfmt
==IMGFMT_RGB8
) vf
->priv
->fmt
=IMGFMT_RGB32
;
106 else if(outfmt
==IMGFMT_BGR8
) vf
->priv
->fmt
=IMGFMT_BGR32
;
109 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,vf
->priv
->fmt
);
112 static int put_image(struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
){
114 uint8_t *old_palette
= mpi
->planes
[1];
116 // hope we'll get DR buffer:
117 dmpi
=vf_get_image(vf
->next
,vf
->priv
->fmt
,
118 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
123 if(!vf
->priv
->pal_msg
){
124 mp_msg(MSGT_VFILTER
,MSGL_V
,"[%s] no palette given, assuming builtin grayscale one\n",vf
->info
->name
);
127 mpi
->planes
[1] = (unsigned char*)gray_pal
;
130 if(mpi
->w
==mpi
->stride
[0] && dmpi
->w
*(dmpi
->bpp
>>3)==dmpi
->stride
[0]){
131 // no stride conversion needed
132 switch(IMGFMT_RGB_DEPTH(dmpi
->imgfmt
)){
135 if (IMGFMT_IS_BGR(dmpi
->imgfmt
))
136 palette8tobgr16(mpi
->planes
[0],dmpi
->planes
[0],mpi
->h
*mpi
->w
,mpi
->planes
[1]);
138 palette8torgb16(mpi
->planes
[0],dmpi
->planes
[0],mpi
->h
*mpi
->w
,mpi
->planes
[1]);
141 if (IMGFMT_IS_BGR(dmpi
->imgfmt
))
142 sws_convertPalette8ToPacked24(mpi
->planes
[0],dmpi
->planes
[0],mpi
->h
*mpi
->w
,mpi
->planes
[1]);
144 sws_convertPalette8ToPacked24(mpi
->planes
[0],dmpi
->planes
[0],mpi
->h
*mpi
->w
,mpi
->planes
[1]);
147 if (IMGFMT_IS_BGR(dmpi
->imgfmt
))
148 sws_convertPalette8ToPacked32(mpi
->planes
[0],dmpi
->planes
[0],mpi
->h
*mpi
->w
,mpi
->planes
[1]);
150 sws_convertPalette8ToPacked32(mpi
->planes
[0],dmpi
->planes
[0],mpi
->h
*mpi
->w
,mpi
->planes
[1]);
155 for(y
=0;y
<mpi
->h
;y
++){
156 unsigned char* src
=mpi
->planes
[0]+y
*mpi
->stride
[0];
157 unsigned char* dst
=dmpi
->planes
[0]+y
*dmpi
->stride
[0];
158 switch(IMGFMT_RGB_DEPTH(dmpi
->imgfmt
)){
161 if (IMGFMT_IS_BGR(dmpi
->imgfmt
))
162 palette8tobgr16(src
,dst
,mpi
->w
,mpi
->planes
[1]);
164 palette8torgb16(src
,dst
,mpi
->w
,mpi
->planes
[1]);
167 if (IMGFMT_IS_BGR(dmpi
->imgfmt
))
168 sws_convertPalette8ToPacked24(src
,dst
,mpi
->w
,mpi
->planes
[1]);
170 sws_convertPalette8ToPacked24(src
,dst
,mpi
->w
,mpi
->planes
[1]);
173 if (IMGFMT_IS_BGR(dmpi
->imgfmt
))
174 sws_convertPalette8ToPacked32(src
,dst
,mpi
->w
,mpi
->planes
[1]);
176 sws_convertPalette8ToPacked32(src
,dst
,mpi
->w
,mpi
->planes
[1]);
181 mpi
->planes
[1] = old_palette
;
183 return vf_next_put_image(vf
,dmpi
, pts
);
186 //===========================================================================//
188 static int query_format(struct vf_instance
*vf
, unsigned int fmt
){
189 int best
=find_best(vf
,fmt
);
190 if(!best
) return 0; // no match
191 return vf
->next
->query_format(vf
->next
,best
);
194 static void uninit(vf_instance_t
*vf
) {
198 static int vf_open(vf_instance_t
*vf
, char *args
){
202 vf
->put_image
=put_image
;
203 vf
->query_format
=query_format
;
204 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
205 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
206 for(i
=0;i
<256;i
++) gray_pal
[i
]=0x01010101*i
;
209 if (!strcasecmp(args
,"rgb15")) vf
->priv
->fmt
=IMGFMT_RGB15
; else
210 if (!strcasecmp(args
,"rgb16")) vf
->priv
->fmt
=IMGFMT_RGB16
; else
211 if (!strcasecmp(args
,"rgb24")) vf
->priv
->fmt
=IMGFMT_RGB24
; else
212 if (!strcasecmp(args
,"rgb32")) vf
->priv
->fmt
=IMGFMT_RGB32
; else
213 if (!strcasecmp(args
,"bgr15")) vf
->priv
->fmt
=IMGFMT_BGR15
; else
214 if (!strcasecmp(args
,"bgr16")) vf
->priv
->fmt
=IMGFMT_BGR16
; else
215 if (!strcasecmp(args
,"bgr24")) vf
->priv
->fmt
=IMGFMT_BGR24
; else
216 if (!strcasecmp(args
,"bgr32")) vf
->priv
->fmt
=IMGFMT_BGR32
; else
218 mp_tmsg(MSGT_VFILTER
, MSGL_WARN
, "[VF_FORMAT] Unknown format name: '%s'.\n", args
);
225 const vf_info_t vf_info_palette
= {
226 "8bpp indexed (using palette) -> BGR 15/16/24/32 conversion",
234 //===========================================================================//