Merge with MPC-HC 6d1472b2f18266d92e5bc068667de348c0cd3b3b.
[xy_vsfilter.git] / src / subtitles / xy_bitmap.cpp
blob341591bd539dc2d3e99fcdda770fa202fa02973f
1 #include "stdafx.h"
2 #include "xy_bitmap.h"
3 #include "xy_malloc.h"
4 #include "../SubPic/ISubPic.h"
5 #include "../subpic/color_conv_table.h"
7 XyBitmap::~XyBitmap()
9 xy_free(bits);
12 XyBitmap * XyBitmap::CreateBitmap( const CRect& target_rect, MemLayout layout )
14 XyBitmap *result = new XyBitmap();
15 if (result==NULL)
17 ASSERT(0);
18 return result;
20 result->type = layout;
21 result->x = target_rect.left;
22 result->y = target_rect.top;
23 result->w = target_rect.Width();
24 result->h = target_rect.Height();
25 int w16 = (result->w + 15) & ~15;
27 switch (result->type)
29 case PACK:
30 result->pitch = w16*4;
31 result->bits = xy_malloc(4*w16*result->h, (result->x*4)&15);
32 result->plans[0] = reinterpret_cast<BYTE*>(result->bits);
33 break;
34 case PLANNA:
35 result->bits = xy_malloc(4*w16*result->h, result->x&15);
36 result->pitch = w16;
37 result->plans[0] = reinterpret_cast<BYTE*>(result->bits);
38 result->plans[1] = result->plans[0] + result->pitch * result->h;
39 result->plans[2] = result->plans[1] + result->pitch * result->h;
40 result->plans[3] = result->plans[2] + result->pitch * result->h;
41 break;
42 default:
43 ASSERT(0);
44 result->bits = NULL;
45 break;
47 ClearBitmap(result);
48 return result;
51 void XyBitmap::ClearBitmap( XyBitmap *bitmap )
53 if (!bitmap)
54 return;
55 if (bitmap->type==XyBitmap::PLANNA)
57 memset(bitmap->plans[0], 0xFF, bitmap->h * bitmap->pitch);
58 memset(bitmap->plans[1], 0, bitmap->h * bitmap->pitch * 3);//assuming the other 2 plans lied right after plan 1
60 else
62 BYTE * p = bitmap->plans[0];
63 for (int i=0;i<bitmap->h;i++, p+=bitmap->pitch)
65 memsetd(p, 0xFF000000, bitmap->w*4);
70 void XyBitmap::AlphaBltPack( SubPicDesc& spd, POINT pos, SIZE size, LPCVOID pixels, int pitch )
72 ASSERT( spd.type!=MSP_AYUV_PLANAR );
73 CRect r(0, 0, spd.w, spd.h);
75 int x = pos.x;
76 int y = pos.y;
77 int w = size.cx;
78 int h = size.cy;
79 int x_src = 0, y_src = 0;
81 if(x < r.left) {x_src = r.left-x; w -= r.left-x; x = r.left;}
82 if(y < r.top) {y_src = r.top-y; h -= r.top-y; y = r.top;}
83 if(x+w > r.right) w = r.right-x;
84 if(y+h > r.bottom) h = r.bottom-y;
86 const BYTE* src = reinterpret_cast<const BYTE*>(pixels) + y_src*pitch + x_src*4;
88 BYTE* dst = reinterpret_cast<BYTE*>(spd.bits) + spd.pitch * y + ((x*spd.bpp)>>3);
90 for(int i=0;i<h;i++, src += pitch, dst += spd.pitch)
92 const BYTE* s2 = src;
93 const BYTE* s2end = s2 + w*4;
94 DWORD* d2 = (DWORD*)dst;
95 for(; s2 < s2end; s2 += 4, d2++)
97 int tmp = s2[3]+1;
98 *d2 = (((((*d2&0x00ff00ff)*tmp)>>8) + (*((DWORD*)s2)&0x00ff00ff))&0x00ff00ff)
99 | (((((*d2&0x0000ff00)*tmp)>>8) + (*((DWORD*)s2)&0x0000ff00))&0x0000ff00);
104 void XyBitmap::AlphaBltPlannar( SubPicDesc& spd, POINT pos, SIZE size, const XyPlannerFormatExtra& pixels, int pitch )
106 ASSERT( spd.type==MSP_AYUV_PLANAR );
108 CRect r(0, 0, spd.w, spd.h);
110 int x = pos.x;
111 int y = pos.y;
112 int w = size.cx;
113 int h = size.cy;
114 int x_src = 0, y_src = 0;
116 if(x < r.left) {x_src = r.left-x; w -= r.left-x; x = r.left;}
117 if(y < r.top) {y_src = r.top-y; h -= r.top-y; y = r.top;}
118 if(x+w > r.right) w = r.right-x;
119 if(y+h > r.bottom) h = r.bottom-y;
121 BYTE* dst = reinterpret_cast<BYTE*>(spd.bits) + spd.pitch * y + ((x*spd.bpp)>>3);
123 const BYTE* src_A = reinterpret_cast<const BYTE*>(pixels.plans[0]) + y_src*pitch + x_src;
124 const BYTE* src_Y = reinterpret_cast<const BYTE*>(pixels.plans[1]) + y_src*pitch + x_src;
125 const BYTE* src_U = reinterpret_cast<const BYTE*>(pixels.plans[2]) + y_src*pitch + x_src;
126 const BYTE* src_V = reinterpret_cast<const BYTE*>(pixels.plans[3]) + y_src*pitch + x_src;
128 BYTE* dst_A = dst;
129 BYTE* dst_Y = dst_A + spd.pitch*spd.h;
130 BYTE* dst_U = dst_Y + spd.pitch*spd.h;
131 BYTE* dst_V = dst_U + spd.pitch*spd.h;
133 const BYTE* src_A1 = src_A;
134 for (int i=0;i<h;i++, src_A += pitch, dst_A += spd.pitch)
136 for (int j=0;j<w;j++)
138 dst_A[j] = (dst_A[j]*(src_A[j]+1))>>8;
142 src_A = src_A1;
143 for (int i=0;i<h;i++, src_A += pitch, src_Y += pitch, dst_Y += spd.pitch)
145 for (int j=0;j<w;j++)
147 dst_Y[j] = ((dst_Y[j]*(src_A[j]+1))>>8) + src_Y[j];
150 src_A = src_A1;
151 for (int i=0;i<h;i++, src_A += pitch, src_U += pitch, dst_U += spd.pitch)
153 for (int j=0;j<w;j++)
155 dst_U[j] = ((dst_U[j]*(src_A[j]+1))>>8) + src_U[j];
158 src_A = src_A1;
159 for (int i=0;i<h;i++, src_A += pitch, src_V += pitch, dst_V += spd.pitch)
161 for (int j=0;j<w;j++)
163 dst_V[j] = ((dst_V[j]*(src_A[j]+1))>>8) + src_V[j];
168 //////////////////////////////////////////////////////////////////////////
170 // SubRenderFrame
173 XySubRenderFrame::XySubRenderFrame()
174 : CUnknown(NAME("XySubRenderFrameWrapper"), NULL)
179 XySubRenderFrame::~XySubRenderFrame()
183 STDMETHODIMP XySubRenderFrame::NonDelegatingQueryInterface( REFIID riid, void** ppv )
185 return
186 QI(IXySubRenderFrame)
187 __super::NonDelegatingQueryInterface(riid, ppv);
190 STDMETHODIMP XySubRenderFrame::GetOutputRect( RECT *outputRect )
192 if (!outputRect)
194 return E_POINTER;
196 *outputRect = m_output_rect;
197 return S_OK;
200 STDMETHODIMP XySubRenderFrame::GetClipRect( RECT *clipRect )
202 if (!clipRect)
204 return E_POINTER;
206 *clipRect = m_clip_rect;
207 return S_OK;
210 STDMETHODIMP XySubRenderFrame::GetXyColorSpace( int *xyColorSpace )
212 if (!xyColorSpace)
214 return E_POINTER;
216 *xyColorSpace = m_xy_color_space;
217 return S_OK;
220 STDMETHODIMP XySubRenderFrame::GetBitmapCount( int *count )
222 if (!count)
224 return E_POINTER;
226 *count = m_bitmaps.GetCount();
227 return S_OK;
230 STDMETHODIMP XySubRenderFrame::GetBitmap( int index, ULONGLONG *id, POINT *position, SIZE *size, LPCVOID *pixels, int *pitch )
232 if (index<0 || index>=(int)m_bitmaps.GetCount())
234 return E_INVALIDARG;
236 if (id)
238 *id = m_bitmap_ids.GetAt(index);
240 const XyBitmap& bitmap = *(m_bitmaps.GetAt(index));
241 if (position)
243 position->x = bitmap.x;
244 position->y = bitmap.y;
246 if (size)
248 size->cx = bitmap.w;
249 size->cy = bitmap.h;
251 if (pixels)
253 *pixels = bitmap.plans[0];
255 if (pitch)
257 *pitch = bitmap.pitch;
259 return S_OK;
262 STDMETHODIMP XySubRenderFrame::GetBitmapExtra( int index, LPVOID extra_info )
264 if (index<0 || index>=(int)m_bitmaps.GetCount())
266 return E_INVALIDARG;
268 if (extra_info && m_xy_color_space == XY_CS_AYUV_PLANAR)
270 const XyBitmap& bitmap = *(m_bitmaps.GetAt(index));
271 XyPlannerFormatExtra *output = reinterpret_cast<XyPlannerFormatExtra*>(extra_info);
273 output->plans[0] = bitmap.plans[0];
274 output->plans[1] = bitmap.plans[1];
275 output->plans[2] = bitmap.plans[2];
276 output->plans[3] = bitmap.plans[3];
278 return S_OK;
281 //////////////////////////////////////////////////////////////////////////
283 // XySubRenderFrameCreater
286 XySubRenderFrameCreater* XySubRenderFrameCreater::GetDefaultCreater()
288 static XySubRenderFrameCreater s_default_creater;
289 return &s_default_creater;
292 HRESULT XySubRenderFrameCreater::SetOutputRect( const RECT& output_rect )
294 m_output_rect = output_rect;
295 return S_OK;
298 HRESULT XySubRenderFrameCreater::SetClipRect( const RECT& clip_rect )
300 m_clip_rect = clip_rect;
301 return S_OK;
304 HRESULT XySubRenderFrameCreater::SetColorSpace( XyColorSpace color_space )
306 m_xy_color_space = color_space;
307 switch (m_xy_color_space)
309 case XY_CS_AYUV_PLANAR:
310 m_bitmap_layout = XyBitmap::PLANNA;
311 break;
312 default:
313 m_bitmap_layout = XyBitmap::PACK;
314 break;
316 return S_OK;
319 HRESULT XySubRenderFrameCreater::GetOutputRect( RECT *output_rect )
321 if (!output_rect)
323 return S_FALSE;
325 *output_rect = m_output_rect;
326 return S_OK;
329 HRESULT XySubRenderFrameCreater::GetClipRect( RECT *clip_rect )
331 if (!clip_rect)
333 return S_FALSE;
335 *clip_rect = m_clip_rect;
336 return S_OK;
339 HRESULT XySubRenderFrameCreater::GetColorSpace( XyColorSpace *color_space )
341 if (!color_space)
343 return S_FALSE;
345 *color_space = m_xy_color_space;
346 return S_OK;
349 XySubRenderFrame* XySubRenderFrameCreater::NewXySubRenderFrame( UINT bitmap_count )
351 XySubRenderFrame *result = new XySubRenderFrame();
352 ASSERT(result);
353 result->m_output_rect = m_output_rect;
354 result->m_clip_rect = m_clip_rect;
355 result->m_xy_color_space = m_xy_color_space;
356 result->m_bitmap_ids.SetCount(bitmap_count);
357 result->m_bitmaps.SetCount(bitmap_count);
358 return result;
361 XyBitmap* XySubRenderFrameCreater::CreateBitmap( const RECT& target_rect )
363 return XyBitmap::CreateBitmap(target_rect, m_bitmap_layout);
366 DWORD XySubRenderFrameCreater::TransColor( DWORD argb )
368 switch(m_xy_color_space)
370 case XY_CS_AYUV_PLANAR:
371 case XY_CS_AYUV:
372 return ColorConvTable::Argb2Ayuv(argb);
373 break;
374 case XY_CS_AUYV:
375 return ColorConvTable::Argb2Auyv(argb);
376 break;
377 case XY_CS_ARGB:
378 return argb;
379 break;
381 return argb;