Module: JXL

Defined in:
lib/jxl.rb,
lib/jxl/dct.rb,
lib/jxl/num.rb,
lib/jxl/image.rb,
lib/jxl/plane.rb,
lib/jxl/trace.rb,
lib/jxl/errors.rb,
lib/jxl/io/npy.rb,
lib/jxl/io/pam.rb,
lib/jxl/io/pfm.rb,
lib/jxl/io/pgx.rb,
lib/jxl/io/png.rb,
lib/jxl/io/ppm.rb,
lib/jxl/decoder.rb,
lib/jxl/encoder.rb,
lib/jxl/version.rb,
lib/jxl/bit/field.rb,
lib/jxl/frame/toc.rb,
lib/jxl/basic_info.rb,
lib/jxl/bit/reader.rb,
lib/jxl/bit/writer.rb,
lib/jxl/filter/epf.rb,
lib/jxl/color/gamut.rb,
lib/jxl/color/opsin.rb,
lib/jxl/color/ycbcr.rb,
lib/jxl/container/box.rb,
lib/jxl/color/transfer.rb,
lib/jxl/features/noise.rb,
lib/jxl/modular/stream.rb,
lib/jxl/render/blender.rb,
lib/jxl/vardct/decoder.rb,
lib/jxl/vardct/dequant.rb,
lib/jxl/entropy/decoder.rb,
lib/jxl/entropy/encoder.rb,
lib/jxl/filter/gaborish.rb,
lib/jxl/modular/decoder.rb,
lib/jxl/modular/ma_tree.rb,
lib/jxl/vardct/lf_group.rb,
lib/jxl/container/parser.rb,
lib/jxl/features/patches.rb,
lib/jxl/features/splines.rb,
lib/jxl/modular/weighted.rb,
lib/jxl/vardct/hf_global.rb,
lib/jxl/vardct/lf_global.rb,
lib/jxl/vardct/quantizer.rb,
lib/jxl/codestream/reader.rb,
lib/jxl/color/icc_profile.rb,
lib/jxl/headers/bit_depth.rb,
lib/jxl/modular/predictor.rb,
lib/jxl/modular/transform.rb,
lib/jxl/vardct/pass_group.rb,
lib/jxl/entropy/icc_stream.rb,
lib/jxl/render/orientation.rb,
lib/jxl/vardct/ac_strategy.rb,
lib/jxl/vardct/coeff_order.rb,
lib/jxl/container/signature.rb,
lib/jxl/entropy/hybrid_uint.rb,
lib/jxl/entropy/permutation.rb,
lib/jxl/entropy/prefix_code.rb,
lib/jxl/features/upsampling.rb,
lib/jxl/headers/size_header.rb,
lib/jxl/features/spot_colour.rb,
lib/jxl/headers/frame_header.rb,
lib/jxl/modular/group_header.rb,
lib/jxl/vardct/reconstructor.rb,
lib/jxl/headers/image_metadata.rb,
lib/jxl/headers/colour_encoding.rb,
lib/jxl/vardct/chroma_from_luma.rb,
lib/jxl/entropy/ans_distribution.rb,
lib/jxl/headers/custom_transform.rb,
lib/jxl/vardct/block_context_map.rb

Defined Under Namespace

Modules: Bit, Codestream, Color, Container, DCT, Entropy, Features, Filter, Headers, IO, Modular, Num, Render, Trace, VarDCT Classes: BasicInfo, CorruptError, Decoder, Encoder, Error, Event, FormatError, Frame, Image, InternalError, Plane, ResourceLimitError, SignatureError, TruncatedError, UnsupportedFeatureError

Constant Summary collapse

VERSION =
"1.0.0"

Class Method Summary collapse

Class Method Details

.decode(data, pixel_format: :native, color_space: :original, desired_scale: 1, max_pixels: 100_000_000, max_memory: 2 << 30, strict: true, apply_orientation: true, render_spot_colors: true) ⇒ Object

Decodes a JPEG XL codestream or container into an Image.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/jxl.rb', line 84

def decode(data, pixel_format: :native, color_space: :original, desired_scale: 1,
           max_pixels: 100_000_000, max_memory: 2 << 30, strict: true,
           apply_orientation: true, render_spot_colors: true) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/ParameterLists
  validate_options!(pixel_format, color_space, desired_scale)
  frames = Codestream::Reader.new(data, max_pixels:).read_all_headers
  enforce_memory_limit!(frames.first.basic_info, max_memory)
  references = Array.new(4)
  dc_frames = Array.new(4)
  output = nil
  displayed = []
  frames.each do |parsed|
    frame = parsed.frame_header
    raw = if frame.encoding == :vardct
            VarDCT::Decoder.decode(parsed, references:, dc_frames:)
          else
            Modular::Decoder.decode_parsed(parsed, render: true, references:)
          end
    if frame.type == 1
      dc_frames[frame.dc_level - 1] = raw
      next
    end
    image = frame.encoding == :modular ? convert_modular_colour(raw, parsed) : raw
    if frame.type == 2
      references[frame.save_as_reference] = frame.save_before_colour_transform ? raw : image
    else
      composed = Render::Blender.compose(image, frame, references, parsed.basic_info.width, parsed.basic_info.height)
      if !frame.last && (frame.duration.zero? || !frame.save_as_reference.zero?)
        references[frame.save_as_reference] = frame.save_before_colour_transform ? raw : composed
      end
      rendered = render_spot_colors ? Features::SpotColour.apply(composed) : composed
      output = apply_orientation ? Render::Orientation.apply(rendered) : rendered
      if !frame.duration.zero? || frame.last
        displayed << Frame.new(planes: output.channels, duration: frame.duration, timecode: frame.timecode,
                               name: frame.name, blend_info: frame.blend)
      end
    end
  end
  output ||= raise(CorruptError, "codestream has no display frame")
  encoding = frames.first.basic_info..colour_encoding
  profile = if encoding.want_icc && frames.first.frame_header.colour_transform == :xyb
              Color::ICCProfile.create(encoding.with(want_icc: false, transfer_function: 8))
            else
              frames.first.icc_profile || Color::ICCProfile.create(encoding)
            end
  output = output.with(frames: displayed.freeze, icc_profile: profile)
  output = convert_output_colour(output, color_space)
  output = downsample(output, desired_scale) unless desired_scale == 1
  validate_samples!(output, strict)
end

.encode(image) ⇒ Object

Encodes an image as a lossless Modular JPEG XL codestream.



78
# File 'lib/jxl.rb', line 78

def encode(image, **) = Encoder.new(image, **).encode

.info(data) ⇒ Object

Reads basic image metadata without decoding pixels.



81
# File 'lib/jxl.rb', line 81

def info(data, **) = BasicInfo.read(data, **)