Major improvements to UnifiedPlayer: 1. GetFrameImage() now works when paused for responsive UI updates 2. Play() method properly starts FFmpeg process 3. Frame display loop runs continuously for smooth video display 4. Disabled audio temporarily to fix video playback fundamentals 5. Simplified FFmpeg command to focus on video stream only Player now: - Generates video frames correctly - Shows video when paused - Has responsive progress tracking - Starts playback properly Next steps: Re-enable audio playback once video is stable
147 lines
3.2 KiB
Go
147 lines
3.2 KiB
Go
// ◄◄◄ gobmp/rle.go ►►►
|
|
// Copyright © 2012 Jason Summers
|
|
// Use of this code is governed by an MIT-style license that can
|
|
// be found in the readme.md file.
|
|
//
|
|
// BMP RLE decoder
|
|
//
|
|
|
|
package gobmp
|
|
|
|
import "io"
|
|
import "bufio"
|
|
|
|
type rleState struct {
|
|
xpos, ypos int // Position in the target image
|
|
badColorFlag bool
|
|
}
|
|
|
|
func (d *decoder) rlePutPixel(rle *rleState, v byte) {
|
|
// Make sure the position is valid.
|
|
if rle.xpos < 0 || rle.xpos >= d.width ||
|
|
rle.ypos < 0 || rle.ypos >= d.height {
|
|
return
|
|
}
|
|
// Make sure the palette index is valid.
|
|
if int(v) >= d.dstPalNumEntries {
|
|
rle.badColorFlag = true
|
|
return
|
|
}
|
|
|
|
// Set the pixel, and advance the current position.
|
|
var dstRow int
|
|
|
|
if d.isTopDown {
|
|
// Top-down RLE-compressed images are not legal in any known BMP
|
|
// specification, but we'll tolerate them.
|
|
dstRow = rle.ypos
|
|
} else {
|
|
dstRow = d.height - rle.ypos - 1
|
|
}
|
|
|
|
d.img_Paletted.Pix[dstRow*d.img_Paletted.Stride+rle.xpos] = v
|
|
rle.xpos++
|
|
}
|
|
|
|
func (d *decoder) readBitsRLE() error {
|
|
var err error
|
|
var b1, b2 byte
|
|
var uncPixelsLeft int
|
|
var deltaFlag bool
|
|
var k int
|
|
|
|
bufferedR := bufio.NewReader(d.r)
|
|
rle := new(rleState)
|
|
rle.xpos = 0
|
|
rle.ypos = 0
|
|
|
|
for {
|
|
if rle.badColorFlag {
|
|
return FormatError("palette index out of range")
|
|
}
|
|
|
|
if rle.ypos >= d.height || (rle.ypos == (d.height-1) && rle.xpos >= d.width) {
|
|
break // Reached the end of the target image; may as well stop
|
|
}
|
|
|
|
// Read the next two bytes
|
|
b1, err = bufferedR.ReadByte()
|
|
if err == nil {
|
|
b2, err = bufferedR.ReadByte()
|
|
}
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
return err
|
|
}
|
|
|
|
if uncPixelsLeft > 0 {
|
|
if d.biCompression == bI_RLE4 {
|
|
// The two bytes we're processing store up to 4 uncompressed pixels.
|
|
d.rlePutPixel(rle, b1>>4)
|
|
uncPixelsLeft--
|
|
if uncPixelsLeft > 0 {
|
|
d.rlePutPixel(rle, b1&0x0f)
|
|
uncPixelsLeft--
|
|
}
|
|
if uncPixelsLeft > 0 {
|
|
d.rlePutPixel(rle, b2>>4)
|
|
uncPixelsLeft--
|
|
}
|
|
if uncPixelsLeft > 0 {
|
|
d.rlePutPixel(rle, b2&0x0f)
|
|
uncPixelsLeft--
|
|
}
|
|
} else { // RLE8
|
|
// The two bytes we're processing store up to 2 uncompressed pixels.
|
|
d.rlePutPixel(rle, b1)
|
|
uncPixelsLeft--
|
|
if uncPixelsLeft > 0 {
|
|
d.rlePutPixel(rle, b2)
|
|
uncPixelsLeft--
|
|
}
|
|
}
|
|
} else if deltaFlag {
|
|
rle.xpos += int(b1)
|
|
rle.ypos += int(b2)
|
|
deltaFlag = false
|
|
} else if b1 == 0 {
|
|
// An uncompressed run, or a special code.
|
|
//
|
|
// Any pixels skipped by special codes will be left at whatever
|
|
// image.NewPaletted() initialized them to, which we assume is 0,
|
|
// meaning palette entry 0.
|
|
if b2 == 0 { // End of row
|
|
rle.ypos++
|
|
rle.xpos = 0
|
|
} else if b2 == 1 { // End of bitmap
|
|
break
|
|
} else if b2 == 2 { // Delta
|
|
deltaFlag = true
|
|
} else {
|
|
// An upcoming uncompressed run of b2 pixels
|
|
uncPixelsLeft = int(b2)
|
|
}
|
|
} else { // A compressed run of pixels
|
|
if d.biCompression == bI_RLE4 {
|
|
// b1 pixels, alternating between two colors
|
|
for k = 0; k < int(b1); k++ {
|
|
if k%2 == 0 {
|
|
d.rlePutPixel(rle, b2>>4)
|
|
} else {
|
|
d.rlePutPixel(rle, b2&0x0f)
|
|
}
|
|
}
|
|
} else { // RLE8
|
|
// b1 pixels of color b2
|
|
for k = 0; k < int(b1); k++ {
|
|
d.rlePutPixel(rle, b2)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|