vo_tag: fix RGB with alpha output on little-endian
[mplayer/glamo.git] / libmpcodecs / vf_1bpp.c
blob8d1373594275016a8f1eea08e1edee2c52552c15
1 /*
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.
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <inttypes.h>
24 #include "config.h"
25 #include "mp_msg.h"
27 #include "img_format.h"
28 #include "mp_image.h"
29 #include "vf.h"
31 //===========================================================================//
33 static const unsigned int bgr_list[]={
34 IMGFMT_Y800,
35 IMGFMT_Y8,
36 IMGFMT_BGR8,
37 IMGFMT_RGB8,
39 IMGFMT_YVU9,
40 IMGFMT_411P,
41 IMGFMT_YV12,
42 IMGFMT_I420,
43 IMGFMT_IYUV,
44 IMGFMT_422P,
45 IMGFMT_444P,
47 IMGFMT_YUY2,
48 IMGFMT_BGR12,
49 IMGFMT_RGB12,
50 IMGFMT_BGR15,
51 IMGFMT_RGB15,
52 IMGFMT_BGR16,
53 IMGFMT_RGB16,
55 IMGFMT_BGR32,
56 IMGFMT_RGB32,
58 // IMGFMT_BGR24,
59 // IMGFMT_RGB24,
63 static unsigned int find_best(struct vf_instance *vf){
64 unsigned int best=0;
65 int ret;
66 const unsigned int* p=bgr_list;
67 while(*p){
68 ret=vf->next->query_format(vf->next,*p);
69 mp_msg(MSGT_VFILTER,MSGL_V,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3);
70 if(ret&VFCAP_CSP_SUPPORTED_BY_HW){ best=*p; break;} // no conversion -> bingo!
71 if(ret&VFCAP_CSP_SUPPORTED && !best) best=*p; // best with conversion
72 ++p;
74 return best;
77 //===========================================================================//
79 struct vf_priv_s {
80 unsigned int fmt;
83 static int config(struct vf_instance *vf,
84 int width, int height, int d_width, int d_height,
85 unsigned int flags, unsigned int outfmt){
86 if (!vf->priv->fmt)
87 vf->priv->fmt=find_best(vf);
88 if(!vf->priv->fmt){
89 // no matching fmt, so force one...
90 if(outfmt==IMGFMT_RGB8) vf->priv->fmt=IMGFMT_RGB32;
91 else if(outfmt==IMGFMT_BGR8) vf->priv->fmt=IMGFMT_BGR32;
92 else return 0;
94 return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt);
97 static const int bittab[8]={128,64,32,16,8,4,2,1};
99 static void convert(mp_image_t *mpi, mp_image_t *dmpi, int value0, int value1,int bpp){
100 int y;
101 for(y=0;y<mpi->h;y++){
102 unsigned char* src=mpi->planes[0]+mpi->stride[0]*y;
103 switch(bpp){
104 case 1: {
105 unsigned char* dst=dmpi->planes[0]+dmpi->stride[0]*y;
106 int x;
107 for(x=0;x<mpi->w;x++)
108 dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
109 break; }
110 case 2: {
111 uint16_t* dst=(uint16_t*)(dmpi->planes[0]+dmpi->stride[0]*y);
112 int x;
113 for(x=0;x<mpi->w;x++)
114 dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
115 break; }
116 case 4: {
117 uint32_t* dst=(uint32_t*)(dmpi->planes[0]+dmpi->stride[0]*y);
118 int x;
119 for(x=0;x<mpi->w;x++)
120 dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
121 break; }
126 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
127 mp_image_t *dmpi;
129 // hope we'll get DR buffer:
130 dmpi=vf_get_image(vf->next,vf->priv->fmt,
131 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
132 mpi->w, mpi->h);
134 switch(dmpi->imgfmt){
135 case IMGFMT_Y800:
136 case IMGFMT_Y8:
137 case IMGFMT_BGR8:
138 case IMGFMT_RGB8:
139 convert(mpi,dmpi,0,255,1);
140 break;
141 case IMGFMT_YVU9:
142 case IMGFMT_411P:
143 case IMGFMT_YV12:
144 case IMGFMT_I420:
145 case IMGFMT_IYUV:
146 case IMGFMT_422P:
147 case IMGFMT_444P:
148 convert(mpi,dmpi,0,255,1);
149 memset(dmpi->planes[1],128,dmpi->stride[1]*dmpi->chroma_height);
150 memset(dmpi->planes[2],128,dmpi->stride[2]*dmpi->chroma_height);
151 break;
152 case IMGFMT_YUY2:
153 convert(mpi,dmpi,0x8000,0x80ff,2);
154 break;
155 case IMGFMT_BGR12:
156 case IMGFMT_RGB12:
157 convert(mpi,dmpi,0,0x0fff,2);
158 break;
159 case IMGFMT_BGR15:
160 case IMGFMT_RGB15:
161 convert(mpi,dmpi,0,0x7fff,2);
162 break;
163 case IMGFMT_BGR16:
164 case IMGFMT_RGB16:
165 convert(mpi,dmpi,0,0xffff,2);
166 break;
167 case IMGFMT_BGR32:
168 case IMGFMT_RGB32:
169 convert(mpi,dmpi,0,0x00ffffff,4);
170 break;
171 default:
172 mp_msg(MSGT_VFILTER,MSGL_ERR,"Unhandled format: 0x%X\n",dmpi->imgfmt);
173 return 0;
176 return vf_next_put_image(vf,dmpi, pts);
179 //===========================================================================//
181 static int query_format(struct vf_instance *vf, unsigned int fmt){
182 int best;
183 if(fmt!=IMGFMT_RGB1 && fmt!=IMGFMT_BGR1) return 0;
184 best=find_best(vf);
185 if(!best) return 0; // no match
186 return vf->next->query_format(vf->next,best);
189 static int vf_open(vf_instance_t *vf, char *args){
190 vf->config=config;
191 vf->put_image=put_image;
192 vf->query_format=query_format;
193 vf->priv=malloc(sizeof(struct vf_priv_s));
194 memset(vf->priv, 0, sizeof(struct vf_priv_s));
195 return 1;
198 const vf_info_t vf_info_1bpp = {
199 "1bpp bitmap -> YUV/BGR 8/15/16/32 conversion",
200 "1bpp",
201 "A'rpi",
203 vf_open,
204 NULL
207 //===========================================================================//