Module: Gsplat::Compression::PngCodec

Defined in:
lib/gsplat/compression/png_codec.rb

Overview

Dependency-free PNG codec for 8-bit parameter grids.

Constant Summary collapse

SIGNATURE =
"\x89PNG\r\n\x1A\n".b
COLOR_TYPES =
{ 1 => 0, 2 => 4, 3 => 2, 4 => 6 }.freeze
CHANNELS =
COLOR_TYPES.invert.freeze

Class Method Summary collapse

Class Method Details

.read(path) ⇒ Object

Raises:



27
28
29
30
31
32
33
34
# File 'lib/gsplat/compression/png_codec.rb', line 27

def read(path)
  data = File.binread(path)
  raise Gsplat::Error, "invalid PNG signature" unless data.start_with?(SIGNATURE)

  width, height, channels, compressed = parse_chunks(data.byteslice(SIGNATURE.bytesize..))
  bytes = unfilter(Zlib::Inflate.inflate(compressed), width, height, channels)
  Numo::UInt8.from_binary(bytes).reshape(height, width, channels)
end

.write(path, pixels) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/gsplat/compression/png_codec.rb', line 15

def write(path, pixels)
  validate_pixels!(pixels)
  height, width, channels = pixels.shape
  rows = pixels.to_a.map { |row| "\0".b + row.flatten.pack("C*") }.join
  header = [width, height, 8, COLOR_TYPES.fetch(channels), 0, 0, 0].pack("NNC5")
  File.binwrite(
    path,
    SIGNATURE + chunk("IHDR", header) + chunk("IDAT", Zlib::Deflate.deflate(rows)) + chunk("IEND", "")
  )
  path
end