Class: PureJPEG::JFIFWriter

Inherits:
Object
  • Object
show all
Defined in:
lib/pure_jpeg/jfif_writer.rb

Instance Method Summary collapse

Constructor Details

#initialize(io, scramble_quantization: false) ⇒ JFIFWriter

Returns a new instance of JFIFWriter.



5
6
7
8
# File 'lib/pure_jpeg/jfif_writer.rb', line 5

def initialize(io, scramble_quantization: false)
  @io = io
  @scramble_quantization = scramble_quantization
end

Instance Method Details

#write_app0Object



18
19
20
21
22
23
24
25
26
# File 'lib/pure_jpeg/jfif_writer.rb', line 18

def write_app0
  write_marker(0xE0)
  data = "JFIF\0".b
  data << [1, 1].pack("CC")        # version 1.1
  data << [0].pack("C")            # density units: no units
  data << [1, 1].pack("nn")        # X/Y density
  data << [0, 0].pack("CC")        # no thumbnail
  write_length_and_data(data)
end

#write_dht(table_class, table_id, bits, values) ⇒ Object

Write a Huffman table. ‘table_class` is 0 for DC, 1 for AC. `table_id` is 0 or 1.



57
58
59
60
61
62
63
# File 'lib/pure_jpeg/jfif_writer.rb', line 57

def write_dht(table_class, table_id, bits, values)
  write_marker(0xC4)
  data = [((table_class & 1) << 4) | (table_id & 0x0F)].pack("C")
  data << bits.pack("C16")
  data << values.pack("C*")
  write_length_and_data(data)
end

#write_dqt(table, table_id) ⇒ Object

Write a quantization table. ‘table_id` is 0 or 1. Table is in raster order internally; DQT spec requires zigzag order.



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/pure_jpeg/jfif_writer.rb', line 30

def write_dqt(table, table_id)
  write_marker(0xDB)
  data = [(table_id & 0x0F)].pack("C")  # 8-bit precision, table ID
  out_table = if @scramble_quantization
                table # write raster order as-is (non-compliant, creative effect)
              else
                Zigzag::ORDER.map { |i| table[i] }
              end
  data << out_table.pack("C64")
  write_length_and_data(data)
end

#write_eoiObject



14
15
16
# File 'lib/pure_jpeg/jfif_writer.rb', line 14

def write_eoi
  write_marker(0xD9)
end

#write_scan_data(data) ⇒ Object

Write raw scan data (already byte-stuffed).



78
79
80
# File 'lib/pure_jpeg/jfif_writer.rb', line 78

def write_scan_data(data)
  @io.write(data)
end

#write_sof0(width, height, components) ⇒ Object

Write Start of Frame (baseline DCT). ‘components` is an array of [id, h_sampling, v_sampling, quant_table_id].



44
45
46
47
48
49
50
51
52
53
# File 'lib/pure_jpeg/jfif_writer.rb', line 44

def write_sof0(width, height, components)
  write_marker(0xC0)
  data = [8].pack("C")                   # 8-bit precision
  data << [height, width].pack("nn")
  data << [components.length].pack("C")
  components.each do |id, h, v, qt|
    data << [id, (h << 4) | v, qt].pack("CCC")
  end
  write_length_and_data(data)
end

#write_soiObject



10
11
12
# File 'lib/pure_jpeg/jfif_writer.rb', line 10

def write_soi
  write_marker(0xD8)
end

#write_sos(components) ⇒ Object

Write Start of Scan. ‘components` is an array of [id, dc_table_id, ac_table_id].



67
68
69
70
71
72
73
74
75
# File 'lib/pure_jpeg/jfif_writer.rb', line 67

def write_sos(components)
  write_marker(0xDA)
  data = [components.length].pack("C")
  components.each do |id, dc_id, ac_id|
    data << [id, (dc_id << 4) | ac_id].pack("CC")
  end
  data << [0, 63, 0].pack("CCC")  # spectral selection start, end, approx
  write_length_and_data(data)
end