4 * Copyright 2001 TAKESHIMA Hidenori <hidenori@a2.ctktv.ne.jp>
20 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(msrle32);
26 typedef struct CodecImpl
33 /***********************************************************************/
35 static LONG MSRLE32_DecompressRLE4(
36 BYTE* pDst, LONG pitch,
38 LONG width, LONG height )
40 FIXME( "RLE4 - not implemented yet\n" );
41 return ICERR_UNSUPPORTED;
44 static LONG MSRLE32_DecompressRLE8(
45 BYTE* pDst, LONG pitch,
47 LONG width, LONG height )
56 len = *pSrc++; data = *pSrc++;
59 /* run length encoding */
60 while ( len-- > 0 && x < width )
61 pDst[x++] = (BYTE)data;
68 x = 0; y++; pDst += pitch;
73 x += (LONG)*pSrc++; y += (LONG)*pSrc++;
77 if ( (len+x) > width )
79 memcpy( &pDst[x], pSrc, len );
81 pSrc += (data+1)&(~1);
90 /***********************************************************************/
92 static BOOL MSRLE32_IsValidInfoHeader( const BITMAPINFO* pbiIn )
94 if ( pbiIn->bmiHeader.biSize < sizeof(BITMAPINFOHEADER) ||
95 pbiIn->bmiHeader.biWidth <= 0 ||
96 pbiIn->bmiHeader.biHeight == 0 ||
97 pbiIn->bmiHeader.biPlanes != 1 )
103 static DWORD MSRLE32_GetClrUsed( const BITMAPINFO* pbiIn )
105 if ( pbiIn->bmiHeader.biBitCount > 8 )
107 return (pbiIn->bmiHeader.biClrUsed == 0) ? (1<<pbiIn->bmiHeader.biBitCount) : pbiIn->bmiHeader.biClrUsed;
110 static DWORD MSRLE32_GetUncompressedPitch( const BITMAPINFOHEADER* pbiIn )
112 return ((((pbiIn->biWidth*pbiIn->biBitCount)+7)>>3)+3)&(~3);
115 static DWORD MSRLE32_GetUncompressedSize( const BITMAPINFOHEADER* pbiIn )
117 return MSRLE32_GetUncompressedPitch( pbiIn ) * abs(pbiIn->biHeight);
121 static BOOL MSRLE32_IsValidRGB( const BITMAPINFO* pbiIn )
123 if ( !MSRLE32_IsValidInfoHeader( pbiIn ) )
126 if ( pbiIn->bmiHeader.biSizeImage != 0 &&
127 pbiIn->bmiHeader.biSizeImage < MSRLE32_GetUncompressedSize( &pbiIn->bmiHeader ) )
131 switch ( pbiIn->bmiHeader.biCompression )
134 case mmioFOURCC('R','G','B',' '):
135 if ( pbiIn->bmiHeader.biBitCount == 1 ||
136 pbiIn->bmiHeader.biBitCount == 4 ||
137 pbiIn->bmiHeader.biBitCount == 8 ||
138 pbiIn->bmiHeader.biBitCount == 16 ||
139 pbiIn->bmiHeader.biBitCount == 24 ||
140 pbiIn->bmiHeader.biBitCount == 32 )
150 static BOOL MSRLE32_IsValidRLE( const BITMAPINFO* pbiIn )
152 if ( !MSRLE32_IsValidInfoHeader( pbiIn ) )
155 switch ( pbiIn->bmiHeader.biCompression )
159 case mmioFOURCC('R','L','E',' '):
160 case mmioFOURCC('R','L','E','8'):
161 case mmioFOURCC('R','L','E','4'):
162 case mmioFOURCC('M','R','L','E'):
163 if ( pbiIn->bmiHeader.biBitCount == 8 ||
164 pbiIn->bmiHeader.biBitCount == 4 )
174 static BOOL MSRLE32_CompareInfoHeader( const BITMAPINFO* pbiIn, const BITMAPINFO* pbiOut )
176 if ( !MSRLE32_IsValidInfoHeader( pbiIn ) ||
177 !MSRLE32_IsValidInfoHeader( pbiOut ) )
180 if ( pbiIn->bmiHeader.biWidth != pbiOut->bmiHeader.biWidth ||
181 pbiIn->bmiHeader.biHeight != pbiOut->bmiHeader.biHeight ||
182 pbiIn->bmiHeader.biPlanes != pbiOut->bmiHeader.biPlanes ||
183 pbiIn->bmiHeader.biBitCount != pbiOut->bmiHeader.biBitCount )
190 /***********************************************************************/
192 static LONG Codec_DrvQueryConfigure( CodecImpl* This )
194 return ICERR_UNSUPPORTED;
197 static LONG Codec_DrvConfigure( CodecImpl* This, HWND hwnd, DRVCONFIGINFO* pinfo )
199 return ICERR_UNSUPPORTED;
202 static LONG Codec_QueryAbout( void )
204 return ICERR_UNSUPPORTED;
207 static LONG Codec_About( HWND hwnd )
209 return ICERR_UNSUPPORTED;
212 static LONG Codec_CompressQuery( CodecImpl* This, BITMAPINFO* pbiIn, BITMAPINFO* pbiOut )
214 FIXME( "compression is not implemented!\n" );
215 return ICERR_UNSUPPORTED;
218 static LONG Codec_CompressBegin( CodecImpl* This, BITMAPINFO* pbiIn, BITMAPINFO* pbiOut )
220 return ICERR_UNSUPPORTED;
223 static LONG Codec_Compress( CodecImpl* This, ICCOMPRESS* picc, DWORD dwSize )
225 FIXME( "compression is not implemented!\n" );
226 return ICERR_UNSUPPORTED;
229 static LONG Codec_CompressEnd( CodecImpl* This )
231 This->bInCompress = FALSE;
232 return ICERR_UNSUPPORTED;
235 static LONG Codec_CompressFramesInfo( CodecImpl* This, ICCOMPRESSFRAMES* piccf, DWORD dwSize )
237 return ICERR_UNSUPPORTED;
240 static LONG Codec_CompressGetFormat( CodecImpl* This, BITMAPINFO* pbiIn, BITMAPINFO* pbiOut )
242 return ICERR_UNSUPPORTED;
245 static LONG Codec_CompressGetSize( CodecImpl* This, BITMAPINFO* pbiIn, BITMAPINFO* pbiOut )
247 return ICERR_UNSUPPORTED;
250 static LONG Codec_ICQueryConfigure( CodecImpl* This )
254 static LONG Codec_ICConfigure( CodecImpl* This, HWND hwnd )
256 MessageBoxA( hwnd, "Wine RLE Driver", "MSRLE32", MB_OK );
260 static LONG Codec_DecompressQuery( CodecImpl* This, BITMAPINFO* pbiIn, BITMAPINFO* pbiOut )
263 return ICERR_BADPARAM;
264 if ( !MSRLE32_IsValidRLE( pbiIn ) )
265 return ICERR_UNSUPPORTED;
267 if ( pbiOut != NULL )
269 if ( !MSRLE32_IsValidRGB( pbiOut ) )
270 return ICERR_UNSUPPORTED;
271 if ( !MSRLE32_CompareInfoHeader( pbiIn, pbiOut ) )
272 return ICERR_UNSUPPORTED;
278 static LONG Codec_DecompressBegin( CodecImpl* This, BITMAPINFO* pbiIn, BITMAPINFO* pbiOut )
282 if ( pbiIn == NULL || pbiOut == NULL )
283 return ICERR_BADPARAM;
284 lr = Codec_DecompressQuery( This, pbiIn, pbiOut );
285 if ( lr != ICERR_OK )
288 This->bInDecompress = TRUE;
293 static LONG Codec_Decompress( CodecImpl* This, ICDECOMPRESS* picd, DWORD dwSize )
297 if ( !This->bInDecompress )
298 return ICERR_BADHANDLE; /* FIXME? */
300 if ( ( picd->dwFlags & ICDECOMPRESS_NOTKEYFRAME ) &&
301 ( picd->dwFlags & ICDECOMPRESS_UPDATE ) )
302 return ICERR_CANTUPDATE; /* FIXME? */
304 if ( picd->lpbiInput == NULL ||
305 picd->lpInput == NULL ||
306 picd->lpbiOutput == NULL ||
307 picd->lpOutput == NULL )
308 return ICERR_BADPARAM;
310 switch ( picd->lpbiInput->biBitCount )
313 lr = MSRLE32_DecompressRLE4(
314 (BYTE*)picd->lpOutput,
315 MSRLE32_GetUncompressedPitch( picd->lpbiInput ),
316 (const BYTE*)picd->lpInput,
317 picd->lpbiInput->biWidth,
318 picd->lpbiInput->biHeight );
321 lr = MSRLE32_DecompressRLE8(
322 (BYTE*)picd->lpOutput,
323 MSRLE32_GetUncompressedPitch( picd->lpbiInput ),
324 (const BYTE*)picd->lpInput,
325 picd->lpbiInput->biWidth,
326 picd->lpbiInput->biHeight );
329 lr = ICERR_BADBITDEPTH;
336 static LONG Codec_DecompressEnd( CodecImpl* This )
338 This->bInDecompress = FALSE;
342 static LONG Codec_DecompressGetFormat( CodecImpl* This, BITMAPINFO* pbiIn, BITMAPINFO* pbiOut )
348 return ICERR_BADPARAM;
350 lr = Codec_DecompressQuery( This, pbiIn, NULL );
351 if ( lr != ICERR_OK )
352 return ( pbiOut == NULL ) ? 0 : lr;
354 biClrUsed = MSRLE32_GetClrUsed(pbiIn);
355 if ( pbiOut == NULL )
356 return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * biClrUsed;
358 ZeroMemory( pbiOut, sizeof(BITMAPINFOHEADER) );
359 memcpy( &pbiOut->bmiHeader, &pbiIn->bmiHeader, sizeof(BITMAPINFOHEADER) );
360 memcpy( &pbiOut->bmiColors, &pbiIn->bmiColors, sizeof(RGBQUAD) * biClrUsed );
361 pbiOut->bmiHeader.biCompression = 0;
362 pbiOut->bmiHeader.biSizeImage = MSRLE32_GetUncompressedSize( &pbiOut->bmiHeader );
367 static LONG Codec_DecompressGetPalette( CodecImpl* This, BITMAPINFO* pbiIn, BITMAPINFO* pbiOut )
370 return ICERR_BADPARAM;
372 return (pbiOut == NULL) ? 0 : ICERR_UNSUPPORTED;
375 static LONG Codec_DecompressSetPalette( CodecImpl* This, BITMAPINFO* pbiIn )
377 return ICERR_UNSUPPORTED;
380 static LONG Codec_DecompressExQuery( CodecImpl* This, ICDECOMPRESSEX* picdex, DWORD dwSize )
382 FIXME( "DecompressEx is not implemented!\n" );
383 return ICERR_UNSUPPORTED;
386 static LONG Codec_DecompressExBegin( CodecImpl* This, ICDECOMPRESSEX* picdex, DWORD dwSize )
388 FIXME( "DecompressEx is not implemented!\n" );
389 return ICERR_UNSUPPORTED;
392 static LONG Codec_DecompressEx( CodecImpl* This, ICDECOMPRESSEX* picdex, DWORD dwSize )
394 return ICERR_UNSUPPORTED;
397 static LONG Codec_DecompressExEnd( CodecImpl* This )
399 This->bInDecompressEx = FALSE;
400 return ICERR_UNSUPPORTED;
403 static LONG Codec_GetInfo( CodecImpl* This, ICINFO* pici, DWORD dwSize )
405 return ICERR_UNSUPPORTED;
408 static LONG Codec_GetQuality( CodecImpl* This, DWORD* pdwQuality )
410 return ICERR_UNSUPPORTED;
413 static LONG Codec_GetState( CodecImpl* This, LPVOID pvState, DWORD dwSize )
415 if ( pvState == NULL )
418 /* no driver-specific state */
423 static LONG Codec_SetQuality( CodecImpl* This, DWORD* pdwQuality )
425 return ICERR_UNSUPPORTED;
428 static LONG Codec_SetStatusProc(CodecImpl* This, ICSETSTATUSPROC* picssp, DWORD dwSize )
430 if ( picssp == NULL )
433 /* no driver-specific state */
438 static LONG Codec_SetState( CodecImpl* This, LPVOID pvState, DWORD dwSize )
440 return ICERR_UNSUPPORTED;
443 static CodecImpl* Codec_AllocDriver( void )
447 This = HeapAlloc( GetProcessHeap(), 0, sizeof(CodecImpl) );
450 ZeroMemory( This, sizeof(CodecImpl) );
451 This->bInCompress = FALSE;
452 This->bInDecompress = FALSE;
453 This->bInDecompressEx = FALSE;
458 static void Codec_Close( CodecImpl* This )
460 if ( This->bInCompress )
461 Codec_CompressEnd(This);
462 if ( This->bInDecompress )
463 Codec_DecompressEnd(This);
464 if ( This->bInDecompressEx )
465 Codec_DecompressExEnd(This);
467 HeapFree( GetProcessHeap(), 0, This );
475 LONG WINAPI MSRLE32_DriverProc(
476 DWORD dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1, LONG lParam2 )
478 TRACE( "DriverProc(%08lx,%08x,%08x,%08lx,%08lx)\n",
479 dwDriverId, hdrvr, msg, lParam1, lParam2 );
491 return (LONG)Codec_AllocDriver();
493 TRACE("DRV_CLOSE\n");
494 Codec_Close( (CodecImpl*)dwDriverId );
497 TRACE("DRV_ENABLE\n");
500 TRACE("DRV_DISABLE\n");
502 case DRV_QUERYCONFIGURE:
503 TRACE("DRV_QUERYCONFIGURE\n");
504 return Codec_DrvQueryConfigure( (CodecImpl*)dwDriverId );
506 TRACE("DRV_CONFIGURE\n");
507 return Codec_DrvConfigure( (CodecImpl*)dwDriverId,
508 (HWND)lParam1, (DRVCONFIGINFO*)lParam2 );
510 TRACE("DRV_INSTALL\n");
513 TRACE("DRV_REMOVE\n");
516 TRACE("DRV_POWER\n");
520 TRACE("ICM_ABOUT\n");
521 return (lParam1 == -1) ? Codec_QueryAbout() : Codec_About( (HWND)lParam1 );
523 TRACE("ICM_COMPRESS\n");
524 return Codec_Compress((CodecImpl*)dwDriverId,(ICCOMPRESS*)lParam1,(DWORD)lParam2);
525 case ICM_COMPRESS_BEGIN:
526 TRACE("ICM_COMPRESS_BEGIN\n");
527 return Codec_CompressBegin((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1,(BITMAPINFO*)lParam2);
528 case ICM_COMPRESS_END:
529 TRACE("ICM_COMPRESS_END\n");
530 return Codec_CompressEnd((CodecImpl*)dwDriverId);
531 case ICM_COMPRESS_FRAMES_INFO:
532 TRACE("ICM_COMPRESS_FRAMES_INFO\n");
533 return Codec_CompressFramesInfo((CodecImpl*)dwDriverId,(ICCOMPRESSFRAMES*)lParam1,(DWORD)lParam2);
534 case ICM_COMPRESS_GET_FORMAT:
535 TRACE("ICM_COMPRESS_GET_FORMAT\n");
536 return Codec_CompressGetFormat((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1,(BITMAPINFO*)lParam2);
537 case ICM_COMPRESS_GET_SIZE:
538 TRACE("ICM_COMPRESS_GET_SIZE\n");
539 return Codec_CompressGetSize((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1,(BITMAPINFO*)lParam2);
540 case ICM_COMPRESS_QUERY:
541 TRACE("ICM_COMPRESS_GET_SIZE\n");
542 return Codec_CompressQuery((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1,(BITMAPINFO*)lParam2);
545 TRACE("ICM_CONFIGURE\n");
546 return ( lParam1 == -1 ) ? Codec_ICQueryConfigure( (CodecImpl*)dwDriverId ) : Codec_ICConfigure( (CodecImpl*)dwDriverId, (HWND)lParam1 );
549 TRACE( "ICM_DECOMPRESS\n" );
550 return Codec_Decompress((CodecImpl*)dwDriverId,(ICDECOMPRESS*)lParam1,(DWORD)lParam2);
551 case ICM_DECOMPRESS_BEGIN:
552 TRACE( "ICM_DECOMPRESS_BEGIN\n" );
553 return Codec_DecompressBegin((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1,(BITMAPINFO*)lParam2);
554 case ICM_DECOMPRESS_END:
555 TRACE( "ICM_DECOMPRESS_END\n" );
556 return Codec_DecompressEnd((CodecImpl*)dwDriverId);
557 case ICM_DECOMPRESS_GET_FORMAT:
558 TRACE( "ICM_DECOMPRESS_GET_FORMAT\n" );
559 return Codec_DecompressGetFormat((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1,(BITMAPINFO*)lParam2);
560 case ICM_DECOMPRESS_GET_PALETTE:
561 TRACE( "ICM_DECOMPRESS_GET_PALETTE\n" );
562 return Codec_DecompressGetPalette((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1,(BITMAPINFO*)lParam2);
563 case ICM_DECOMPRESS_QUERY:
564 TRACE( "ICM_DECOMPRESS_QUERY\n" );
565 return Codec_DecompressQuery((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1,(BITMAPINFO*)lParam2);
566 case ICM_DECOMPRESS_SET_PALETTE:
567 TRACE( "ICM_DECOMPRESS_SET_PALETTE\n" );
568 return Codec_DecompressSetPalette((CodecImpl*)dwDriverId,(BITMAPINFO*)lParam1);
570 case ICM_DECOMPRESSEX_BEGIN:
571 TRACE( "ICM_DECOMPRESSEX_BEGIN\n" );
572 return Codec_DecompressExBegin((CodecImpl*)dwDriverId,(ICDECOMPRESSEX*)lParam1,(DWORD)lParam2);
573 case ICM_DECOMPRESSEX:
574 TRACE( "ICM_DECOMPRESSEX\n" );
575 return Codec_DecompressEx((CodecImpl*)dwDriverId,(ICDECOMPRESSEX*)lParam1,(DWORD)lParam2);
576 case ICM_DECOMPRESSEX_END:
577 TRACE( "ICM_DECOMPRESSEX_END\n" );
578 return Codec_DecompressExEnd((CodecImpl*)dwDriverId);
579 case ICM_DECOMPRESSEX_QUERY:
580 TRACE( "ICM_DECOMPRESSEX_QUERY\n" );
581 return Codec_DecompressExQuery((CodecImpl*)dwDriverId,(ICDECOMPRESSEX*)lParam1,(DWORD)lParam2);
584 TRACE( "ICM_GETINFO\n" );
585 return Codec_GetInfo((CodecImpl*)dwDriverId,(ICINFO*)lParam1,(DWORD)lParam2);
587 TRACE( "ICM_SETQUALITY\n");
588 return Codec_GetQuality((CodecImpl*)dwDriverId,(DWORD*)lParam1);
590 TRACE( "ICM_GETSTATE\n" );
591 return Codec_GetState((CodecImpl*)dwDriverId,(LPVOID)lParam1,(DWORD)lParam2);
593 TRACE( "ICM_SETQUALITY\n");
594 return Codec_SetQuality((CodecImpl*)dwDriverId,(DWORD*)lParam1);
595 case ICM_SET_STATUS_PROC:
596 TRACE( "ICM_SET_STATUS_PROC\n" );
597 return Codec_SetStatusProc((CodecImpl*)dwDriverId,(ICSETSTATUSPROC*)lParam1,(DWORD)lParam2);
599 TRACE( "ICM_SETSTATE\n" );
600 return Codec_SetState((CodecImpl*)dwDriverId,(LPVOID)lParam1,(DWORD)lParam2);
604 return DefDriverProc( dwDriverId, hdrvr, msg, lParam1, lParam2 );
607 BOOL WINAPI MSRLE32_DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved )
609 TRACE( "(%08x,%08lx,%p)\n",hInst,dwReason,lpvReserved );