Files should be opened in binary mode on OS/2.
[mplayer/glamo.git] / libmpcodecs / vf_1bpp.c
blob039fa8e895e3fd96bfa66a97d596108886cafce8
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <inttypes.h>
6 #include "config.h"
7 #include "mp_msg.h"
9 #include "img_format.h"
10 #include "mp_image.h"
11 #include "vf.h"
13 //===========================================================================//
15 static const unsigned int bgr_list[]={
16 IMGFMT_Y800,
17 IMGFMT_Y8,
18 IMGFMT_BGR8,
19 IMGFMT_RGB8,
21 IMGFMT_YVU9,
22 IMGFMT_411P,
23 IMGFMT_YV12,
24 IMGFMT_I420,
25 IMGFMT_IYUV,
26 IMGFMT_422P,
27 IMGFMT_444P,
29 IMGFMT_YUY2,
30 IMGFMT_BGR15,
31 IMGFMT_RGB15,
32 IMGFMT_BGR16,
33 IMGFMT_RGB16,
35 IMGFMT_BGR32,
36 IMGFMT_RGB32,
38 // IMGFMT_BGR24,
39 // IMGFMT_RGB24,
43 static unsigned int find_best(struct vf_instance_s* vf){
44 unsigned int best=0;
45 int ret;
46 const unsigned int* p=bgr_list;
47 while(*p){
48 ret=vf->next->query_format(vf->next,*p);
49 mp_msg(MSGT_VFILTER,MSGL_V,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3);
50 if(ret&VFCAP_CSP_SUPPORTED_BY_HW){ best=*p; break;} // no conversion -> bingo!
51 if(ret&VFCAP_CSP_SUPPORTED && !best) best=*p; // best with conversion
52 ++p;
54 return best;
57 //===========================================================================//
59 struct vf_priv_s {
60 unsigned int fmt;
63 static int config(struct vf_instance_s* vf,
64 int width, int height, int d_width, int d_height,
65 unsigned int flags, unsigned int outfmt){
66 if (!vf->priv->fmt)
67 vf->priv->fmt=find_best(vf);
68 if(!vf->priv->fmt){
69 // no matching fmt, so force one...
70 if(outfmt==IMGFMT_RGB8) vf->priv->fmt=IMGFMT_RGB32;
71 else if(outfmt==IMGFMT_BGR8) vf->priv->fmt=IMGFMT_BGR32;
72 else return 0;
74 return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt);
77 static const int bittab[8]={128,64,32,16,8,4,2,1};
79 static void convert(mp_image_t *mpi, mp_image_t *dmpi, int value0, int value1,int bpp){
80 int y;
81 for(y=0;y<mpi->h;y++){
82 unsigned char* src=mpi->planes[0]+mpi->stride[0]*y;
83 switch(bpp){
84 case 1: {
85 unsigned char* dst=dmpi->planes[0]+dmpi->stride[0]*y;
86 int x;
87 for(x=0;x<mpi->w;x++)
88 dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
89 break; }
90 case 2: {
91 uint16_t* dst=(uint16_t*)(dmpi->planes[0]+dmpi->stride[0]*y);
92 int x;
93 for(x=0;x<mpi->w;x++)
94 dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
95 break; }
96 case 4: {
97 uint32_t* dst=(uint32_t*)(dmpi->planes[0]+dmpi->stride[0]*y);
98 int x;
99 for(x=0;x<mpi->w;x++)
100 dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0;
101 break; }
106 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){
107 mp_image_t *dmpi;
109 // hope we'll get DR buffer:
110 dmpi=vf_get_image(vf->next,vf->priv->fmt,
111 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
112 mpi->w, mpi->h);
114 switch(dmpi->imgfmt){
115 case IMGFMT_Y800:
116 case IMGFMT_Y8:
117 case IMGFMT_BGR8:
118 case IMGFMT_RGB8:
119 convert(mpi,dmpi,0,255,1);
120 break;
121 case IMGFMT_YVU9:
122 case IMGFMT_411P:
123 case IMGFMT_YV12:
124 case IMGFMT_I420:
125 case IMGFMT_IYUV:
126 case IMGFMT_422P:
127 case IMGFMT_444P:
128 convert(mpi,dmpi,0,255,1);
129 memset(dmpi->planes[1],128,dmpi->stride[1]*dmpi->chroma_height);
130 memset(dmpi->planes[2],128,dmpi->stride[2]*dmpi->chroma_height);
131 break;
132 case IMGFMT_YUY2:
133 convert(mpi,dmpi,0x8000,0x80ff,2);
134 break;
135 case IMGFMT_BGR15:
136 case IMGFMT_RGB15:
137 convert(mpi,dmpi,0,0x7fff,2);
138 break;
139 case IMGFMT_BGR16:
140 case IMGFMT_RGB16:
141 convert(mpi,dmpi,0,0xffff,2);
142 break;
143 case IMGFMT_BGR32:
144 case IMGFMT_RGB32:
145 convert(mpi,dmpi,0,0x00ffffff,4);
146 break;
147 default:
148 mp_msg(MSGT_VFILTER,MSGL_ERR,"Unhandled format: 0x%X\n",dmpi->imgfmt);
149 return 0;
152 return vf_next_put_image(vf,dmpi, pts);
155 //===========================================================================//
157 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
158 int best;
159 if(fmt!=IMGFMT_RGB1 && fmt!=IMGFMT_BGR1) return 0;
160 best=find_best(vf);
161 if(!best) return 0; // no match
162 return vf->next->query_format(vf->next,best);
165 static int open(vf_instance_t *vf, char* args){
166 vf->config=config;
167 vf->put_image=put_image;
168 vf->query_format=query_format;
169 vf->priv=malloc(sizeof(struct vf_priv_s));
170 memset(vf->priv, 0, sizeof(struct vf_priv_s));
171 return 1;
174 const vf_info_t vf_info_1bpp = {
175 "1bpp bitmap -> YUV/BGR 8/15/16/32 conversion",
176 "1bpp",
177 "A'rpi",
179 open,
180 NULL
183 //===========================================================================//