Class: Omnizip::Algorithms::BZip2::Rle
- Inherits:
-
Object
- Object
- Omnizip::Algorithms::BZip2::Rle
- Defined in:
- lib/omnizip/algorithms/bzip2/rle.rb
Overview
Run-Length Encoding (RLE) for BZip2
This is a BZip2-specific RLE variant that encodes runs of identical bytes. After MTF, the data often contains long runs of zeros, which RLE compresses efficiently.
BZip2 RLE encoding scheme:
- Runs of 4-259 identical bytes are encoded as: [byte, byte, byte, byte, count-4]
- Where count is 0-255 representing 4-259 repetitions
- Runs < 4 are left unencoded
- This scheme avoids ambiguity in decoding
Constant Summary collapse
- MAX_RUN_LENGTH =
Maximum run length (4 + 255)
259- MIN_RUN_LENGTH =
Minimum run length for encoding
4
Instance Method Summary collapse
-
#decode(data) ⇒ String
Decode RLE-encoded data.
-
#encode(data) ⇒ String
Encode data using BZip2 RLE.
Instance Method Details
#decode(data) ⇒ String
Decode RLE-encoded data
79 80 81 82 83 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 |
# File 'lib/omnizip/algorithms/bzip2/rle.rb', line 79 def decode(data) return "".b if data.empty? result = [] i = 0 skip_count = 0 while i < data.length byte = data.getbyte(i) result << byte i += 1 # Decrement skip counter if active if skip_count.positive? skip_count -= 1 next end # Check for run encoding (4 consecutive identical bytes) next unless i >= 4 && consecutive_match?(result, byte, 4) # Read run count break if i >= data.length count = data.getbyte(i) i += 1 # Emit additional copies count.times { result << byte } # Skip checking for next 3 bytes (need 4 to form a run) skip_count = 3 end result.pack("C*") end |
#encode(data) ⇒ String
Encode data using BZip2 RLE
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/omnizip/algorithms/bzip2/rle.rb', line 49 def encode(data) return "".b if data.empty? result = [] i = 0 while i < data.length byte = data.getbyte(i) run_length = count_run(data, i) if run_length >= MIN_RUN_LENGTH # Encode run: emit 4 copies + extra count extra = [run_length - MIN_RUN_LENGTH, 255].min 4.times { result << byte } result << extra i += MIN_RUN_LENGTH + extra else # No run, emit single byte result << byte i += 1 end end result.pack("C*") end |