Login
movetofront.cr at tip
Login

File src/remilib/compression/bzip/movetofront.cr from the latest check-in


     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
#### Bzip2 Implementation
#### Copyright (C) 2023-2024 Remilia Scarlet
#### Copyright (C) 2015 Jaime Olivares
#### Copyright (c) 2011 Matthew Francis
#### MIT License
####
#### Ported from the Java implementation by Matthew Francis:
#### https://github.com/MateuszBartosiewicz/bzip2.
####
#### Ported by Remilia Scarlet from the C# implementation by Jamie Olivares:
#### http://github.com/jaime-olivares/bzip2

module RemiLib::Compression::BZip2
  # A 256 entry Move-to-Front transformer.
  private class MoveToFront
    @mtf : Array(UInt8)

    # Creates a new `MoveToFront` instance.
    def initialize
      @mtf = Array(UInt8).new(256, &.to_u8!)
    end

    # Moves `value` to the head of the MTF list (forward Move To Front
    # transform).  Returns the position the value moved from.
    @[AlwaysInline]
    def valueToFront(value : UInt8) : Int32
      index : Int32 = 0
      tmp : UInt8 = @mtf.unsafe_fetch(0)
      tmp2 : UInt8 = 0

      unless value == tmp
        @mtf.unsafe_put(0, value)
        while value != tmp
          index += 1
          tmp2 = tmp
          tmp = @mtf.unsafe_fetch(index)
          @mtf.unsafe_put(index, tmp2)
        end
      end

      index
    end

    # Gets the value at `index` and moves it to the front of the MTF list
    # (inverse Move To Front transform).  This returns the value at the given
    # `index`.
    @[AlwaysInline]
    def indexToFront(index : Int32) : UInt8
      ret = @mtf[index]
      @mtf[1, index] = @mtf[0, index]
      @mtf.unsafe_put(0, ret)
      ret
    end
  end
end