Module: JXL::IO::NPY
- Defined in:
- lib/jxl/io/npy.rb
Constant Summary collapse
- MAGIC =
"\x93NUMPY".b
- FORMATS =
{ "<f4" => "e*", "<f8" => "E*", "|u1" => "C*", "<u2" => "v*", "<i4" => "l<*" }.freeze
Class Method Summary collapse
- .dump(path, shape, values, descriptor: "<f4") ⇒ Object
- .dump_image(path, image) ⇒ Object
- .load(path) ⇒ Object
Class Method Details
.dump(path, shape, values, descriptor: "<f4") ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/jxl/io/npy.rb', line 41 def dump(path, shape, values, descriptor: "<f4") format = FORMATS[descriptor] || raise(UnsupportedFeatureError, "NPY dtype #{descriptor}") expected = shape.inject(1, :*) raise ArgumentError, "shape does not match values" unless expected == values.length shape_text = shape.length == 1 ? "#{shape.first}," : shape.join(", ") dictionary = "{'descr': '#{descriptor}', 'fortran_order': False, 'shape': (#{shape_text}), }" padding = 16 - ((MAGIC.bytesize + 4 + dictionary.bytesize + 1) % 16) header = "#{dictionary}#{' ' * padding}\n" File.binwrite(path, MAGIC + [1, 0, header.bytesize].pack("CCv") + header + values.pack(format)) end |
.dump_image(path, image) ⇒ Object
53 54 55 56 57 58 |
# File 'lib/jxl/io/npy.rb', line 53 def dump_image(path, image) frame_planes = image.frames.empty? ? [image.channels] : image.frames.map(&:planes) channels = image.num_color_channels + image..extra_channels.length values = frame_planes.flat_map { |planes| planes.first(channels).map(&:data).transpose.flatten } dump(path, [frame_planes.length, image.height, image.width, channels], values) end |
.load(path) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/jxl/io/npy.rb', line 17 def load(path) data = File.binread(path) raise FormatError, "invalid NPY signature" unless data.start_with?(MAGIC) major = data.getbyte(6) header_offset, header_length = header_location(data, major) header = data.byteslice(header_offset, header_length) descriptor = header[/['"]descr['"]\s*:\s*['"]([^'"]+)['"]/, 1] fortran = header[/['"]fortran_order['"]\s*:\s*(True|False)/, 1] raise FormatError, "invalid NPY header" unless descriptor && fortran raise UnsupportedFeatureError, "Fortran-order NPY array" if fortran == "True" shape = parse_shape(header) format = FORMATS[descriptor] || raise(UnsupportedFeatureError, "NPY dtype #{descriptor}") values = data.byteslice((header_offset + header_length)..).unpack(format) expected = shape.inject(1, :*) unless values.length == expected raise CorruptError, "NPY shape contains #{expected} values, got #{values.length}" end [shape, values] end |