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?