4 * Copyright 2001 TAKESHIMA Hidenori <hidenori@a2.ctktv.ne.jp>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msrle32
);
40 typedef struct CodecImpl
47 /***********************************************************************/
49 static LONG
MSRLE32_DecompressRLE4(
50 BYTE
* pDst
, LONG pitch
,
52 LONG width
, LONG height
)
54 FIXME( "RLE4 - not implemented yet\n" );
55 return ICERR_UNSUPPORTED
;
58 static LONG
MSRLE32_DecompressRLE8(
59 BYTE
* pDst
, LONG pitch
,
61 LONG width
, LONG height
)
71 len
= *pSrc
++; data
= *pSrc
++;
74 /* run length encoding */
75 while ( len
-- > 0 && x
< width
)
76 pDst
[x
++] = (BYTE
)data
;
83 x
= 0; y
++; pDst
+= pitch
;
88 delta_x
= (LONG
)*pSrc
++;
89 delta_y
= (LONG
)*pSrc
++;
92 pDst
+= delta_y
* pitch
;
96 if ( (len
+x
) > width
)
98 memcpy( &pDst
[x
], pSrc
, len
);
100 pSrc
+= (data
+1)&(~1);
109 /***********************************************************************/
111 static BOOL
MSRLE32_IsValidInfoHeader( const BITMAPINFO
* pbiIn
)
113 if ( pbiIn
->bmiHeader
.biSize
< sizeof(BITMAPINFOHEADER
) ||
114 pbiIn
->bmiHeader
.biWidth
<= 0 ||
115 pbiIn
->bmiHeader
.biHeight
== 0 ||
116 pbiIn
->bmiHeader
.biPlanes
!= 1 )
122 static DWORD
MSRLE32_GetClrUsed( const BITMAPINFO
* pbiIn
)
124 if ( pbiIn
->bmiHeader
.biBitCount
> 8 )
126 return (pbiIn
->bmiHeader
.biClrUsed
== 0) ? (1<<pbiIn
->bmiHeader
.biBitCount
) : pbiIn
->bmiHeader
.biClrUsed
;
129 static DWORD
MSRLE32_GetUncompressedPitch( const BITMAPINFOHEADER
* pbiIn
)
131 return ((((pbiIn
->biWidth
*pbiIn
->biBitCount
)+7)>>3)+3)&(~3);
134 static DWORD
MSRLE32_GetUncompressedSize( const BITMAPINFOHEADER
* pbiIn
)
136 return MSRLE32_GetUncompressedPitch( pbiIn
) * abs(pbiIn
->biHeight
);
140 static BOOL
MSRLE32_IsValidRGB( const BITMAPINFO
* pbiIn
)
142 if ( !MSRLE32_IsValidInfoHeader( pbiIn
) )
145 if ( pbiIn
->bmiHeader
.biSizeImage
!= 0 &&
146 pbiIn
->bmiHeader
.biSizeImage
< MSRLE32_GetUncompressedSize( &pbiIn
->bmiHeader
) )
150 switch ( pbiIn
->bmiHeader
.biCompression
)
153 case mmioFOURCC('R','G','B',' '):
154 if ( pbiIn
->bmiHeader
.biBitCount
== 1 ||
155 pbiIn
->bmiHeader
.biBitCount
== 4 ||
156 pbiIn
->bmiHeader
.biBitCount
== 8 ||
157 pbiIn
->bmiHeader
.biBitCount
== 16 ||
158 pbiIn
->bmiHeader
.biBitCount
== 24 ||
159 pbiIn
->bmiHeader
.biBitCount
== 32 )
169 static BOOL
MSRLE32_IsValidRLE( const BITMAPINFO
* pbiIn
)
171 if ( !MSRLE32_IsValidInfoHeader( pbiIn
) )
174 switch ( pbiIn
->bmiHeader
.biCompression
)
178 case mmioFOURCC('R','L','E',' '):
179 case mmioFOURCC('R','L','E','8'):
180 case mmioFOURCC('R','L','E','4'):
181 case mmioFOURCC('M','R','L','E'):
182 if ( pbiIn
->bmiHeader
.biBitCount
== 8 ||
183 pbiIn
->bmiHeader
.biBitCount
== 4 )
193 static BOOL
MSRLE32_CompareInfoHeader( const BITMAPINFO
* pbiIn
, const BITMAPINFO
* pbiOut
)
195 if ( !MSRLE32_IsValidInfoHeader( pbiIn
) ||
196 !MSRLE32_IsValidInfoHeader( pbiOut
) )
199 if ( pbiIn
->bmiHeader
.biWidth
!= pbiOut
->bmiHeader
.biWidth
||
200 pbiIn
->bmiHeader
.biHeight
!= pbiOut
->bmiHeader
.biHeight
||
201 pbiIn
->bmiHeader
.biPlanes
!= pbiOut
->bmiHeader
.biPlanes
||
202 pbiIn
->bmiHeader
.biBitCount
!= pbiOut
->bmiHeader
.biBitCount
)
209 /***********************************************************************/
211 static LONG
Codec_DrvQueryConfigure( CodecImpl
* This
)
213 return ICERR_UNSUPPORTED
;
216 static LONG
Codec_DrvConfigure( CodecImpl
* This
, HWND hwnd
, DRVCONFIGINFO
* pinfo
)
218 return ICERR_UNSUPPORTED
;
221 static LONG
Codec_QueryAbout( void )
223 return ICERR_UNSUPPORTED
;
226 static LONG
Codec_About( HWND hwnd
)
228 return ICERR_UNSUPPORTED
;
231 static LONG
Codec_CompressQuery( CodecImpl
* This
, BITMAPINFO
* pbiIn
, BITMAPINFO
* pbiOut
)
233 FIXME( "compression is not implemented!\n" );
234 return ICERR_UNSUPPORTED
;
237 static LONG
Codec_CompressBegin( CodecImpl
* This
, BITMAPINFO
* pbiIn
, BITMAPINFO
* pbiOut
)
239 return ICERR_UNSUPPORTED
;
242 static LONG
Codec_Compress( CodecImpl
* This
, ICCOMPRESS
* picc
, DWORD dwSize
)
244 FIXME( "compression is not implemented!\n" );
245 return ICERR_UNSUPPORTED
;
248 static LONG
Codec_CompressEnd( CodecImpl
* This
)
250 This
->bInCompress
= FALSE
;
251 return ICERR_UNSUPPORTED
;
254 static LONG
Codec_CompressFramesInfo( CodecImpl
* This
, ICCOMPRESSFRAMES
* piccf
, DWORD dwSize
)
256 return ICERR_UNSUPPORTED
;
259 static LONG
Codec_CompressGetFormat( CodecImpl
* This
, BITMAPINFO
* pbiIn
, BITMAPINFO
* pbiOut
)
261 return ICERR_UNSUPPORTED
;
264 static LONG
Codec_CompressGetSize( CodecImpl
* This
, BITMAPINFO
* pbiIn
, BITMAPINFO
* pbiOut
)
266 return ICERR_UNSUPPORTED
;
269 static LONG
Codec_ICQueryConfigure( CodecImpl
* This
)
273 static LONG
Codec_ICConfigure( CodecImpl
* This
, HWND hwnd
)
275 MessageBoxA( hwnd
, "Wine RLE Driver", "MSRLE32", MB_OK
);
279 static LONG
Codec_DecompressQuery( CodecImpl
* This
, BITMAPINFO
* pbiIn
, BITMAPINFO
* pbiOut
)
282 return ICERR_BADPARAM
;
283 if ( !MSRLE32_IsValidRLE( pbiIn
) )
284 return ICERR_UNSUPPORTED
;
286 if ( pbiOut
!= NULL
)
288 if ( !MSRLE32_IsValidRGB( pbiOut
) )
289 return ICERR_UNSUPPORTED
;
290 if ( !MSRLE32_CompareInfoHeader( pbiIn
, pbiOut
) )
291 return ICERR_UNSUPPORTED
;
297 static LONG
Codec_DecompressBegin( CodecImpl
* This
, BITMAPINFO
* pbiIn
, BITMAPINFO
* pbiOut
)
301 if ( pbiIn
== NULL
|| pbiOut
== NULL
)
302 return ICERR_BADPARAM
;
303 lr
= Codec_DecompressQuery( This
, pbiIn
, pbiOut
);
304 if ( lr
!= ICERR_OK
)
307 This
->bInDecompress
= TRUE
;
312 static LONG
Codec_Decompress( CodecImpl
* This
, ICDECOMPRESS
* picd
, DWORD dwSize
)
316 if ( !This
->bInDecompress
)
317 return ICERR_BADHANDLE
; /* FIXME? */
319 if ( ( picd
->dwFlags
& ICDECOMPRESS_NOTKEYFRAME
) &&
320 ( picd
->dwFlags
& ICDECOMPRESS_UPDATE
) )
321 return ICERR_CANTUPDATE
; /* FIXME? */
323 if ( picd
->lpbiInput
== NULL
||
324 picd
->lpInput
== NULL
||
325 picd
->lpbiOutput
== NULL
||
326 picd
->lpOutput
== NULL
)
327 return ICERR_BADPARAM
;
329 switch ( picd
->lpbiInput
->biBitCount
)
332 lr
= MSRLE32_DecompressRLE4(
333 (BYTE
*)picd
->lpOutput
,
334 MSRLE32_GetUncompressedPitch( picd
->lpbiInput
),
335 (const BYTE
*)picd
->lpInput
,
336 picd
->lpbiInput
->biWidth
,
337 picd
->lpbiInput
->biHeight
);
340 lr
= MSRLE32_DecompressRLE8(
341 (BYTE
*)picd
->lpOutput
,
342 MSRLE32_GetUncompressedPitch( picd
->lpbiInput
),
343 (const BYTE
*)picd
->lpInput
,
344 picd
->lpbiInput
->biWidth
,
345 picd
->lpbiInput
->biHeight
);
348 lr
= ICERR_BADBITDEPTH
;
355 static LONG
Codec_DecompressEnd( CodecImpl
* This
)
357 This
->bInDecompress
= FALSE
;
361 static LONG
Codec_DecompressGetFormat( CodecImpl
* This
, BITMAPINFO
* pbiIn
, BITMAPINFO
* pbiOut
)
367 return ICERR_BADPARAM
;
369 lr
= Codec_DecompressQuery( This
, pbiIn
, NULL
);
370 if ( lr
!= ICERR_OK
)
371 return ( pbiOut
== NULL
) ? 0 : lr
;
373 biClrUsed
= MSRLE32_GetClrUsed(pbiIn
);
374 if ( pbiOut
== NULL
)
375 return sizeof(BITMAPINFOHEADER
) + sizeof(RGBQUAD
) * biClrUsed
;
377 ZeroMemory( pbiOut
, sizeof(BITMAPINFOHEADER
) );
378 memcpy( &pbiOut
->bmiHeader
, &pbiIn
->bmiHeader
, sizeof(BITMAPINFOHEADER
) );
379 memcpy( &pbiOut
->bmiColors
, &pbiIn
->bmiColors
, sizeof(RGBQUAD
) * biClrUsed
);
380 pbiOut
->bmiHeader
.biCompression
= 0;
381 pbiOut
->bmiHeader
.biSizeImage
= MSRLE32_GetUncompressedSize( &pbiOut
->bmiHeader
);
386 static LONG
Codec_DecompressGetPalette( CodecImpl
* This
, BITMAPINFO
* pbiIn
, BITMAPINFO
* pbiOut
)
389 return ICERR_BADPARAM
;
391 return (pbiOut
== NULL
) ? 0 : ICERR_UNSUPPORTED
;
394 static LONG
Codec_DecompressSetPalette( CodecImpl
* This
, BITMAPINFO
* pbiIn
)
396 return ICERR_UNSUPPORTED
;
399 static LONG
Codec_DecompressExQuery( CodecImpl
* This
, ICDECOMPRESSEX
* picdex
, DWORD dwSize
)
401 FIXME( "DecompressEx is not implemented!\n" );
402 return ICERR_UNSUPPORTED
;
405 static LONG
Codec_DecompressExBegin( CodecImpl
* This
, ICDECOMPRESSEX
* picdex
, DWORD dwSize
)
407 FIXME( "DecompressEx is not implemented!\n" );
408 return ICERR_UNSUPPORTED
;
411 static LONG
Codec_DecompressEx( CodecImpl
* This
, ICDECOMPRESSEX
* picdex
, DWORD dwSize
)
413 return ICERR_UNSUPPORTED
;
416 static LONG
Codec_DecompressExEnd( CodecImpl
* This
)
418 This
->bInDecompressEx
= FALSE
;
419 return ICERR_UNSUPPORTED
;
422 static LONG
Codec_GetInfo( CodecImpl
* This
, ICINFO
* pici
, DWORD dwSize
)
424 return ICERR_UNSUPPORTED
;
427 static LONG
Codec_GetQuality( CodecImpl
* This
, DWORD
* pdwQuality
)
429 return ICERR_UNSUPPORTED
;
432 static LONG
Codec_GetState( CodecImpl
* This
, LPVOID pvState
, DWORD dwSize
)
434 if ( pvState
== NULL
)
437 /* no driver-specific state */
442 static LONG
Codec_SetQuality( CodecImpl
* This
, DWORD
* pdwQuality
)
444 return ICERR_UNSUPPORTED
;
447 static LONG
Codec_SetStatusProc(CodecImpl
* This
, ICSETSTATUSPROC
* picssp
, DWORD dwSize
)
449 if ( picssp
== NULL
)
452 /* no driver-specific state */
457 static LONG
Codec_SetState( CodecImpl
* This
, LPVOID pvState
, DWORD dwSize
)
459 return ICERR_UNSUPPORTED
;
462 static CodecImpl
* Codec_AllocDriver( void )
466 This
= HeapAlloc( GetProcessHeap(), 0, sizeof(CodecImpl
) );
469 ZeroMemory( This
, sizeof(CodecImpl
) );
470 This
->bInCompress
= FALSE
;
471 This
->bInDecompress
= FALSE
;
472 This
->bInDecompressEx
= FALSE
;
477 static void Codec_Close( CodecImpl
* This
)
479 if ( This
->bInCompress
)
480 Codec_CompressEnd(This
);
481 if ( This
->bInDecompress
)
482 Codec_DecompressEnd(This
);
483 if ( This
->bInDecompressEx
)
484 Codec_DecompressExEnd(This
);
486 HeapFree( GetProcessHeap(), 0, This
);
494 LONG WINAPI
MSRLE32_DriverProc(
495 DWORD dwDriverId
, HDRVR hdrvr
, UINT msg
, LONG lParam1
, LONG lParam2
)
497 TRACE( "DriverProc(%08lx,%08x,%08x,%08lx,%08lx)\n",
498 dwDriverId
, hdrvr
, msg
, lParam1
, lParam2
);
510 return (LONG
)Codec_AllocDriver();
512 TRACE("DRV_CLOSE\n");
513 Codec_Close( (CodecImpl
*)dwDriverId
);
516 TRACE("DRV_ENABLE\n");
519 TRACE("DRV_DISABLE\n");
521 case DRV_QUERYCONFIGURE
:
522 TRACE("DRV_QUERYCONFIGURE\n");
523 return Codec_DrvQueryConfigure( (CodecImpl
*)dwDriverId
);
525 TRACE("DRV_CONFIGURE\n");
526 return Codec_DrvConfigure( (CodecImpl
*)dwDriverId
,
527 (HWND
)lParam1
, (DRVCONFIGINFO
*)lParam2
);
529 TRACE("DRV_INSTALL\n");
532 TRACE("DRV_REMOVE\n");
535 TRACE("DRV_POWER\n");
539 TRACE("ICM_ABOUT\n");
540 return (lParam1
== -1) ? Codec_QueryAbout() : Codec_About( (HWND
)lParam1
);
542 TRACE("ICM_COMPRESS\n");
543 return Codec_Compress((CodecImpl
*)dwDriverId
,(ICCOMPRESS
*)lParam1
,(DWORD
)lParam2
);
544 case ICM_COMPRESS_BEGIN
:
545 TRACE("ICM_COMPRESS_BEGIN\n");
546 return Codec_CompressBegin((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
,(BITMAPINFO
*)lParam2
);
547 case ICM_COMPRESS_END
:
548 TRACE("ICM_COMPRESS_END\n");
549 return Codec_CompressEnd((CodecImpl
*)dwDriverId
);
550 case ICM_COMPRESS_FRAMES_INFO
:
551 TRACE("ICM_COMPRESS_FRAMES_INFO\n");
552 return Codec_CompressFramesInfo((CodecImpl
*)dwDriverId
,(ICCOMPRESSFRAMES
*)lParam1
,(DWORD
)lParam2
);
553 case ICM_COMPRESS_GET_FORMAT
:
554 TRACE("ICM_COMPRESS_GET_FORMAT\n");
555 return Codec_CompressGetFormat((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
,(BITMAPINFO
*)lParam2
);
556 case ICM_COMPRESS_GET_SIZE
:
557 TRACE("ICM_COMPRESS_GET_SIZE\n");
558 return Codec_CompressGetSize((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
,(BITMAPINFO
*)lParam2
);
559 case ICM_COMPRESS_QUERY
:
560 TRACE("ICM_COMPRESS_GET_SIZE\n");
561 return Codec_CompressQuery((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
,(BITMAPINFO
*)lParam2
);
564 TRACE("ICM_CONFIGURE\n");
565 return ( lParam1
== -1 ) ? Codec_ICQueryConfigure( (CodecImpl
*)dwDriverId
) : Codec_ICConfigure( (CodecImpl
*)dwDriverId
, (HWND
)lParam1
);
568 TRACE( "ICM_DECOMPRESS\n" );
569 return Codec_Decompress((CodecImpl
*)dwDriverId
,(ICDECOMPRESS
*)lParam1
,(DWORD
)lParam2
);
570 case ICM_DECOMPRESS_BEGIN
:
571 TRACE( "ICM_DECOMPRESS_BEGIN\n" );
572 return Codec_DecompressBegin((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
,(BITMAPINFO
*)lParam2
);
573 case ICM_DECOMPRESS_END
:
574 TRACE( "ICM_DECOMPRESS_END\n" );
575 return Codec_DecompressEnd((CodecImpl
*)dwDriverId
);
576 case ICM_DECOMPRESS_GET_FORMAT
:
577 TRACE( "ICM_DECOMPRESS_GET_FORMAT\n" );
578 return Codec_DecompressGetFormat((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
,(BITMAPINFO
*)lParam2
);
579 case ICM_DECOMPRESS_GET_PALETTE
:
580 TRACE( "ICM_DECOMPRESS_GET_PALETTE\n" );
581 return Codec_DecompressGetPalette((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
,(BITMAPINFO
*)lParam2
);
582 case ICM_DECOMPRESS_QUERY
:
583 TRACE( "ICM_DECOMPRESS_QUERY\n" );
584 return Codec_DecompressQuery((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
,(BITMAPINFO
*)lParam2
);
585 case ICM_DECOMPRESS_SET_PALETTE
:
586 TRACE( "ICM_DECOMPRESS_SET_PALETTE\n" );
587 return Codec_DecompressSetPalette((CodecImpl
*)dwDriverId
,(BITMAPINFO
*)lParam1
);
589 case ICM_DECOMPRESSEX_BEGIN
:
590 TRACE( "ICM_DECOMPRESSEX_BEGIN\n" );
591 return Codec_DecompressExBegin((CodecImpl
*)dwDriverId
,(ICDECOMPRESSEX
*)lParam1
,(DWORD
)lParam2
);
592 case ICM_DECOMPRESSEX
:
593 TRACE( "ICM_DECOMPRESSEX\n" );
594 return Codec_DecompressEx((CodecImpl
*)dwDriverId
,(ICDECOMPRESSEX
*)lParam1
,(DWORD
)lParam2
);
595 case ICM_DECOMPRESSEX_END
:
596 TRACE( "ICM_DECOMPRESSEX_END\n" );
597 return Codec_DecompressExEnd((CodecImpl
*)dwDriverId
);
598 case ICM_DECOMPRESSEX_QUERY
:
599 TRACE( "ICM_DECOMPRESSEX_QUERY\n" );
600 return Codec_DecompressExQuery((CodecImpl
*)dwDriverId
,(ICDECOMPRESSEX
*)lParam1
,(DWORD
)lParam2
);
603 TRACE( "ICM_GETINFO\n" );
604 return Codec_GetInfo((CodecImpl
*)dwDriverId
,(ICINFO
*)lParam1
,(DWORD
)lParam2
);
606 TRACE( "ICM_SETQUALITY\n");
607 return Codec_GetQuality((CodecImpl
*)dwDriverId
,(DWORD
*)lParam1
);
609 TRACE( "ICM_GETSTATE\n" );
610 return Codec_GetState((CodecImpl
*)dwDriverId
,(LPVOID
)lParam1
,(DWORD
)lParam2
);
612 TRACE( "ICM_SETQUALITY\n");
613 return Codec_SetQuality((CodecImpl
*)dwDriverId
,(DWORD
*)lParam1
);
614 case ICM_SET_STATUS_PROC
:
615 TRACE( "ICM_SET_STATUS_PROC\n" );
616 return Codec_SetStatusProc((CodecImpl
*)dwDriverId
,(ICSETSTATUSPROC
*)lParam1
,(DWORD
)lParam2
);
618 TRACE( "ICM_SETSTATE\n" );
619 return Codec_SetState((CodecImpl
*)dwDriverId
,(LPVOID
)lParam1
,(DWORD
)lParam2
);
623 return DefDriverProc( dwDriverId
, hdrvr
, msg
, lParam1
, lParam2
);
626 BOOL WINAPI
MSRLE32_DllMain( HINSTANCE hInst
, DWORD dwReason
, LPVOID lpvReserved
)
628 TRACE( "(%08x,%08lx,%p)\n",hInst
,dwReason
,lpvReserved
);