Class: Omnizip::Filters::Delta

Inherits:
Omnizip::Filter show all
Defined in:
lib/omnizip/filters/delta.rb

Overview

Delta filter for multimedia and database preprocessing.

This filter computes byte-wise differences between adjacent bytes at a specified distance. It is particularly effective for multimedia files (WAV, BMP) and database dumps where adjacent bytes often have small differences.

The filter uses wrap-around arithmetic (modulo 256) and is fully reversible.

Filter IDs by format:

  • XZ: 0x03
  • 7-Zip: 0x03

Constant Summary collapse

DEFAULT_DISTANCE =

Default distance for delta calculation (audio/single channel)

1
MAX_DISTANCE =

Maximum allowed distance value

256
BYTE_MODULO =

Byte modulo for wrap-around arithmetic

256
XZ_FILTER_ID =

Filter ID for XZ format

0x03
SEVEN_ZIP_FILTER_ID =

Filter ID for 7-Zip format

0x03

Instance Attribute Summary collapse

Attributes inherited from Omnizip::Filter

#architecture, #name

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(distance_arg = DEFAULT_DISTANCE, distance: DEFAULT_DISTANCE) ⇒ Delta

Initialize Delta filter with specified distance.

Supports both positional and keyword argument styles:

Delta.new(3)           # positional
Delta.new(distance: 3) # keyword

Parameters:

  • distance (Integer) (defaults to: DEFAULT_DISTANCE)

    Byte distance for delta calculation

    • 1: Audio/single channel data
    • 2: Stereo 16-bit audio
    • 3: RGB image data (24-bit)
    • 4: RGBA image data (32-bit) or 32-bit integers

Raises:

  • (ArgumentError)

    If distance is invalid



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/omnizip/filters/delta.rb', line 64

def initialize(distance_arg = DEFAULT_DISTANCE,
distance: DEFAULT_DISTANCE)
  # Support both positional and keyword argument styles
  # If called with Delta.new(3), distance_arg=3, distance=DEFAULT (keyword not used)
  # If called with Delta.new(distance: 3), distance_arg=DEFAULT, distance=3
  dist = if distance == DEFAULT_DISTANCE
           distance_arg
         else
           distance
         end

  validate_distance(dist)
  @distance = dist
  super(architecture: :delta, name: "Delta")
end

Instance Attribute Details

#distanceObject (readonly)

Returns the value of attribute distance.



50
51
52
# File 'lib/omnizip/filters/delta.rb', line 50

def distance
  @distance
end

Class Method Details

.metadataHash

Get metadata about this filter.

Returns:

  • (Hash)

    Filter metadata



161
162
163
164
165
166
167
168
# File 'lib/omnizip/filters/delta.rb', line 161

def 
  {
    name: "Delta",
    description: "Byte-wise difference filter for multimedia " \
                 "and database preprocessing",
    typical_usage: "WAV audio, BMP images, database dumps",
  }
end

Instance Method Details

#decode(data, _position = 0) ⇒ String

Decode (postprocess) data by restoring from differences.

For each byte at position i >= distance:

old[i] = (new[i] + old[i - distance]) mod 256

Bytes before the distance remain unchanged (already original).

Parameters:

  • data (String)

    Binary data to decode

  • position (Integer)

    Current stream position (unused for Delta)

Returns:

  • (String)

    Decoded binary data



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/omnizip/filters/delta.rb', line 138

def decode(data, _position = 0)
  return data.dup if data.empty?

  source = data.b
  result = data.b
  size = data.bytesize

  # Process bytes starting from distance
  distance.upto(size - 1) do |i|
    diff = source.getbyte(i)
    previous = result.getbyte(i - distance)
    # Restore original value with wrap-around
    original = (diff + previous) & 0xFF
    result.setbyte(i, original)
  end

  result
end

#encode(data, _position = 0) ⇒ String

Encode (preprocess) data by computing forward differences.

For each byte at position i >= distance:

new[i] = (old[i] - old[i - distance]) mod 256

Bytes before the distance remain unchanged (no previous value).

Parameters:

  • data (String)

    Binary data to encode

  • position (Integer)

    Current stream position (unused for Delta)

Returns:

  • (String)

    Encoded binary data



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/omnizip/filters/delta.rb', line 108

def encode(data, _position = 0)
  return data.dup if data.empty?

  source = data.b
  result = data.b
  size = data.bytesize

  # Process bytes starting from distance
  distance.upto(size - 1) do |i|
    current = source.getbyte(i)
    previous = source.getbyte(i - distance)
    # Compute difference with wrap-around
    diff = (current - previous) & 0xFF
    result.setbyte(i, diff)
  end

  result
end

#id_for_format(format) ⇒ Integer

Get filter ID for specific format

Parameters:

  • format (Symbol)

    Format identifier (:seven_zip, :xz)

Returns:

  • (Integer)

    Format-specific filter ID

Raises:

  • (ArgumentError)

    If format is not supported



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/omnizip/filters/delta.rb', line 85

def id_for_format(format)
  case format
  when :seven_zip
    SEVEN_ZIP_FILTER_ID
  when :xz
    XZ_FILTER_ID
  else
    raise ArgumentError,
          "Unknown format: #{format}. Supported: :seven_zip, :xz"
  end
end