Ctrl K
ComunidadGuías…

vlib/image/decoders/common/common.v

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**********************************************************************
*
* Shared decoder types: decoded image, animation frame, bit reader
*
* Copyright (c) 2026 Dario Deledda. All rights reserved.
* Use of this source code is governed by an MIT license
* that can be found in the LICENSE file.
*
**********************************************************************/

module common

// Image is a decoded, top-down RGBA image (straight, non-premultiplied alpha).
pub struct Image {
pub:
	width  int
	height int
	rgba   []u8 // len == width * height * 4
}

// Frame is one coalesced animation frame.
pub struct Frame {
pub:
	image    Image
	delay_ms int
	disposal int
}

// Animation is a sequence of frames with a loop count.
pub struct Animation {
pub:
	frames     []Frame
	loop_count int // 0 = forever, >= 1 finite
}

// BitReader reads bits from a byte buffer in either LSB-first (GIF/WebP)
// or MSB-first (JPEG) order. Format-specific byte stuffing (e.g. JPEG
// FF00) is handled by the caller.
pub struct BitReader {
mut:
	data     []u8
	byte_pos int
	bit_pos  int // bits already consumed in the current byte (0..8)
	msb      bool
}

// new_bitreader_lsb creates an LSB-first reader.
pub fn new_bitreader_lsb(data []u8) BitReader {
	return BitReader{
		data: data
		msb:  false
	}
}

// new_bitreader_msb creates an MSB-first reader.
pub fn new_bitreader_msb(data []u8) BitReader {
	return BitReader{
		data: data
		msb:  true
	}
}

// read_bits reads up to 32 bits and returns them as a u32.
// Bits are assembled in the order they are read.
pub fn (mut r BitReader) read_bits(n int) !u32 {
	mut val := u32(0)
	if r.msb {
		for _ in 0 .. n {
			if r.bit_pos == 8 {
				r.bit_pos = 0
				r.byte_pos++
			}
			if r.byte_pos >= r.data.len {
				return error('BitReader: unexpected EOF (msb)')
			}
			bit := (r.data[r.byte_pos] >> (7 - r.bit_pos)) & 1
			val = (val << 1) | u32(bit)
			r.bit_pos++
		}
	} else {
		for i in 0 .. n {
			if r.bit_pos == 8 {
				r.bit_pos = 0
				r.byte_pos++
			}
			if r.byte_pos >= r.data.len {
				return error('BitReader: unexpected EOF (lsb)')
			}
			bit := (r.data[r.byte_pos] >> r.bit_pos) & 1
			val |= u32(bit) << i
			r.bit_pos++
		}
	}
	return val
}

// align_bytes skips to the next byte boundary (no-op if already aligned).
pub fn (mut r BitReader) align_bytes() {
	if r.bit_pos != 0 {
		r.bit_pos = 0
		r.byte_pos++
	}
}

// remaining returns the number of whole bytes left (approximate).
pub fn (r BitReader) remaining() int {
	return r.data.len - r.byte_pos
}