2 * Implements Color Space Converter(CLSID_Colour).
4 * hidenori@a2.ctktv.ne.jp
22 #include "debugtools.h"
23 DEFAULT_DEBUG_CHANNEL(quartz);
25 #include "quartz_private.h"
29 static const WCHAR ColorConv_FilterName[] =
30 {'C','o','l','o','r',' ','S','p','a','c','e',' ','C','o','n','v','e','r','t','e','r',0};
34 const GUID* psubtypeIn;
35 const GUID* psubtypeOut;
39 static const struct BltHandler conv_handlers[] =
41 { &MEDIASUBTYPE_RGB24, &MEDIASUBTYPE_RGB32, VIDEOBLT_Blt_888_to_8888 },
42 { &MEDIASUBTYPE_RGB24, &MEDIASUBTYPE_RGB565, VIDEOBLT_Blt_888_to_565 },
43 { &MEDIASUBTYPE_RGB24, &MEDIASUBTYPE_RGB555, VIDEOBLT_Blt_888_to_555 },
44 { &MEDIASUBTYPE_RGB24, &MEDIASUBTYPE_RGB8, VIDEOBLT_Blt_888_to_332 },
48 typedef struct CColorConvImpl
51 AM_MEDIA_TYPE* m_pmtConv;
57 /***************************************************************************
59 * CColorConvImpl methods
63 static void ColorConv_FreeOutTypes(CColorConvImpl* This)
67 if ( This->m_pmtConv == NULL )
70 TRACE("cConv = %lu\n",This->m_cConv);
71 for ( i = 0; i < This->m_cConv; i++ )
73 QUARTZ_MediaType_Free(&This->m_pmtConv[i]);
75 QUARTZ_FreeMem(This->m_pmtConv);
76 This->m_pmtConv = NULL;
80 static HRESULT ColorConv_FillBitmapInfo( BITMAPINFO* pbiOut, LONG biWidth, LONG biHeight, const GUID* psubtype )
86 pbiOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
87 pbiOut->bmiHeader.biWidth = biWidth;
88 pbiOut->bmiHeader.biHeight = biHeight;
89 pbiOut->bmiHeader.biPlanes = 1;
91 if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB8 ) )
93 pbiOut->bmiHeader.biBitCount = 8;
94 for ( i = 0; i < 256; i++ )
96 pbiOut->bmiColors[i].rgbRed = ((i>>5)&7)*255/7;
97 pbiOut->bmiColors[i].rgbGreen = ((i>>2)&7)*255/7;
98 pbiOut->bmiColors[i].rgbBlue = (i&3)*255/3;
102 if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB555 ) )
104 pbiOut->bmiHeader.biBitCount = 16;
107 if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB565 ) )
109 pbiOut->bmiHeader.biBitCount = 16;
110 pbiOut->bmiHeader.biCompression = 3;
111 pdwBitf = (DWORD*)(&pbiOut->bmiColors[0]);
117 if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB24 ) )
119 pbiOut->bmiHeader.biBitCount = 24;
122 if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB32 ) )
124 pbiOut->bmiHeader.biBitCount = 32;
128 pbiOut->bmiHeader.biSizeImage = DIBSIZE(pbiOut->bmiHeader);
134 static HRESULT ColorConv_Init( CTransformBaseImpl* pImpl )
136 CColorConvImpl* This = pImpl->m_pUserData;
141 This = (CColorConvImpl*)QUARTZ_AllocMem( sizeof(CColorConvImpl) );
143 return E_OUTOFMEMORY;
144 ZeroMemory( This, sizeof(CColorConvImpl) );
145 pImpl->m_pUserData = This;
148 This->m_pmtConv = NULL;
154 static HRESULT ColorConv_Cleanup( CTransformBaseImpl* pImpl )
156 CColorConvImpl* This = pImpl->m_pUserData;
161 ColorConv_FreeOutTypes(This);
163 QUARTZ_FreeMem( This );
164 pImpl->m_pUserData = NULL;
169 static HRESULT ColorConv_CheckMediaType( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut )
171 CColorConvImpl* This = pImpl->m_pUserData;
172 BITMAPINFOHEADER* pbiIn = NULL;
173 BITMAPINFOHEADER* pbiOut = NULL;
176 const struct BltHandler* phandler;
178 TRACE("(%p)\n",This);
183 if ( !IsEqualGUID( &pmtIn->majortype, &MEDIATYPE_Video ) )
185 if ( !IsEqualGUID( &pmtIn->formattype, &FORMAT_VideoInfo ) )
187 pbiIn = (&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
188 if ( pbiIn->biCompression != 0 &&
189 pbiIn->biCompression != 3 )
192 hr = QUARTZ_MediaSubType_FromBitmap( &stIn, pbiIn );
193 if ( hr != S_OK || !IsEqualGUID( &pmtIn->subtype, &stIn ) )
196 if ( pmtOut != NULL )
198 if ( !IsEqualGUID( &pmtOut->majortype, &MEDIATYPE_Video ) )
200 if ( !IsEqualGUID( &pmtOut->formattype, &FORMAT_VideoInfo ) )
202 pbiOut = (&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
203 if ( pbiOut->biCompression != 0 &&
204 pbiOut->biCompression != 3 )
206 hr = QUARTZ_MediaSubType_FromBitmap( &stOut, pbiOut );
207 if ( hr != S_OK || !IsEqualGUID( &pmtOut->subtype, &stOut ) )
209 if ( pbiIn->biWidth != pbiOut->biWidth ||
210 pbiIn->biHeight != pbiOut->biHeight ||
211 pbiIn->biPlanes != 1 || pbiOut->biPlanes != 1 )
215 phandler = conv_handlers;
216 while ( phandler->psubtypeIn != NULL )
218 if ( IsEqualGUID( &pmtIn->subtype, phandler->psubtypeIn ) )
220 if ( pmtOut == NULL )
222 if ( IsEqualGUID( &pmtOut->subtype, phandler->psubtypeOut ) )
231 static HRESULT ColorConv_GetOutputTypes( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE** ppmtAcceptTypes, ULONG* pcAcceptTypes )
233 CColorConvImpl* This = pImpl->m_pUserData;
235 const struct BltHandler* phandler;
237 BITMAPINFOHEADER* pbiIn = NULL;
238 BITMAPINFOHEADER* pbiOut = NULL;
240 TRACE("(%p)\n",This);
245 hr = ColorConv_CheckMediaType( pImpl, pmtIn, NULL );
248 pbiIn = (&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
250 ColorConv_FreeOutTypes(This);
253 phandler = conv_handlers;
254 while ( phandler->psubtypeIn != NULL )
256 if ( IsEqualGUID( &pmtIn->subtype, phandler->psubtypeIn ) )
261 This->m_cConv = cConv;
262 This->m_pmtConv = (AM_MEDIA_TYPE*)QUARTZ_AllocMem(
263 sizeof(AM_MEDIA_TYPE) * cConv );
264 if ( This->m_pmtConv == NULL )
265 return E_OUTOFMEMORY;
266 ZeroMemory( This->m_pmtConv, sizeof(AM_MEDIA_TYPE) * cConv );
269 phandler = conv_handlers;
270 while ( phandler->psubtypeIn != NULL )
272 if ( IsEqualGUID( &pmtIn->subtype, phandler->psubtypeIn ) )
274 memcpy( &This->m_pmtConv[cConv].majortype, &MEDIATYPE_Video, sizeof(GUID) );
275 memcpy( &This->m_pmtConv[cConv].subtype, phandler->psubtypeOut, sizeof(GUID) );
276 This->m_pmtConv[cConv].bFixedSizeSamples = 1;
277 This->m_pmtConv[cConv].bTemporalCompression = 0;
278 This->m_pmtConv[cConv].lSampleSize = DIBSIZE(*pbiIn);
279 memcpy( &This->m_pmtConv[cConv].formattype, &FORMAT_VideoInfo, sizeof(GUID) );
280 This->m_pmtConv[cConv].cbFormat = sizeof(VIDEOINFO);
281 This->m_pmtConv[cConv].pbFormat = (BYTE*)CoTaskMemAlloc( This->m_pmtConv[cConv].cbFormat );
282 if ( This->m_pmtConv[cConv].pbFormat == NULL )
283 return E_OUTOFMEMORY;
284 ZeroMemory( This->m_pmtConv[cConv].pbFormat, This->m_pmtConv[cConv].cbFormat );
285 pbiOut = &(((VIDEOINFOHEADER*)(This->m_pmtConv[cConv].pbFormat))->bmiHeader);
286 hr = ColorConv_FillBitmapInfo( (BITMAPINFO*)pbiOut, pbiIn->biWidth, pbiIn->biHeight, phandler->psubtypeOut );
295 *ppmtAcceptTypes = This->m_pmtConv;
296 *pcAcceptTypes = This->m_cConv;
301 static HRESULT ColorConv_GetAllocProp( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, ALLOCATOR_PROPERTIES* pProp, BOOL* pbTransInPlace, BOOL* pbTryToReuseSample )
303 CColorConvImpl* This = pImpl->m_pUserData;
305 BITMAPINFOHEADER* pbiOut = NULL;
307 TRACE("(%p)\n",This);
312 hr = ColorConv_CheckMediaType( pImpl, pmtIn, pmtOut );
316 pbiOut = (&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
319 pProp->cbBuffer = DIBSIZE(*pbiOut);
320 TRACE("%ldx%ldx%u cbBuffer = %ld\n",pbiOut->biWidth,pbiOut->biHeight,(unsigned)pbiOut->biBitCount,pProp->cbBuffer);
325 static HRESULT ColorConv_BeginTransform( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, BOOL bReuseSample )
327 CColorConvImpl* This = pImpl->m_pUserData;
329 BITMAPINFOHEADER* pbiIn = NULL;
330 BITMAPINFOHEADER* pbiOut = NULL;
331 const struct BltHandler* phandler;
333 TRACE("(%p)\n",This);
338 hr = ColorConv_CheckMediaType( pImpl, pmtIn, pmtOut );
342 pbiIn = (&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
343 pbiOut = (&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
345 This->pitchIn = DIBWIDTHBYTES(*pbiIn);
346 This->pitchOut = DIBWIDTHBYTES(*pbiOut);
349 phandler = conv_handlers;
350 while ( phandler->psubtypeIn != NULL )
352 if ( IsEqualGUID( &pmtIn->subtype, phandler->psubtypeIn ) )
354 if ( IsEqualGUID( &pmtOut->subtype, phandler->psubtypeOut ) )
356 This->m_pBlt = phandler->pBlt;
366 static HRESULT ColorConv_Transform( CTransformBaseImpl* pImpl, IMediaSample* pSampIn, IMediaSample* pSampOut )
368 CColorConvImpl* This = pImpl->m_pUserData;
369 BYTE* pDataIn = NULL;
370 BYTE* pDataOut = NULL;
378 hr = IMediaSample_GetPointer( pSampIn, &pDataIn );
381 hr = IMediaSample_GetPointer( pSampOut, &pDataOut );
385 if ( This->m_pBlt != NULL )
387 pbiIn = (BITMAPINFO*)&(((VIDEOINFOHEADER*)pImpl->pInPin->pin.pmtConn->pbFormat)->bmiHeader);
388 pbiOut = (BITMAPINFO*)&(((VIDEOINFOHEADER*)pImpl->pOutPin->pin.pmtConn->pbFormat)->bmiHeader);
390 pDataOut, This->pitchOut,
391 pDataIn, This->pitchIn,
392 pbiIn->bmiHeader.biWidth,
393 abs(pbiIn->bmiHeader.biHeight),
394 &pbiIn->bmiColors[0], pbiIn->bmiHeader.biClrUsed );
395 hr = IMediaSample_SetActualDataLength(pSampOut,DIBSIZE(pbiOut->bmiHeader));
403 static HRESULT ColorConv_EndTransform( CTransformBaseImpl* pImpl )
405 CColorConvImpl* This = pImpl->m_pUserData;
416 static const TransformBaseHandlers transhandlers =
420 ColorConv_CheckMediaType,
421 ColorConv_GetOutputTypes,
422 ColorConv_GetAllocProp,
423 ColorConv_BeginTransform,
425 ColorConv_EndTransform,
428 HRESULT QUARTZ_CreateColour(IUnknown* punkOuter,void** ppobj)
430 return QUARTZ_CreateTransformBase(
433 ColorConv_FilterName,