I have a basic RIFF AVI made in the early 1990's and I'm tyring to make a basic video player in native VB/C# code. According to the header, it uses the old MS RLE codec. The bitmap header in the AVI indicates it is RLE8 compressed.
- the is the result of the raw 'xxdc' compressed data written to a bitmap pragmatically created from scratch and opened in Windows Photo Viewer
- the same frame extracted using VirtualDub
- the code below decompressing the RLE8 bitmap
The problem is both the code below AND Windows does the same thing, portions are missing which leads me to the following from an old VirtualDub blog post;
(GDI's RLE isn't the same as AVI's RLE)".
The problem is I cannot find the difference :(. I cannot find any sources on the internet or any material on MSDN.
I ported an RLE8 decompression sample from htttp://dirkbertels.net/computing/bitmap_decompression.php to VB (bitmap structures omitted for brevity). It works a treat. Problem is it doesn't work correctly for AVI frames that use RLE8.
Dim firstByte As Byte Dim secondByte As Byte Dim currX As UInteger = 0 Dim currY As UInteger = 0 Dim i As UInteger Do firstByte = br.ReadByte If 0 <> firstByte Then ' Encoded Mode secondByte = br.ReadByte For i = 0 To firstByte - 1 frame.SetPixel(currX, currY, _bitmap.biClut(secondByte)) currX += 1 Next i Else ' Absolute Mode firstByte = br.ReadByte ' store next byte Select Case firstByte Case 0 ' new line currX = 0 currY += 1 ' move cursor to beginning of next line Case 1 ' end of bitmap Exit Do Case 2 ' delta = goto X and Y currX += CInt(br.ReadByte) ' read byte and add value to x value currY += CInt(br.ReadByte) ' read byte and add value to y value Case Else For i = 0 To firstByte - 1 secondByte = br.ReadByte frame.SetPixel(currX, currY, _bitmap.biClut(secondByte)) currX += 1 Next i 'If 0 <> (firstByte And &H1) Then ' br.ReadByte() 'End If If firstByte And &H1 Then ' if the run doesn't end on a word boundary, br.ReadByte() End If End Select End If Loop
I'm at a loss now as to how VirtualDub, FFMPEG and others do it without using the old MSRLE.DLL codec... Does anybody have any ideas?