Class: Rixmap::Format::PCX::RLE

Inherits:
Object
  • Object
show all
Defined in:
lib/rixmap/format/pcx.rb

Overview

RLEエンコーダ

Instance Method Summary collapse

Instance Method Details

#decode(bytes, total) ⇒ Array

バイト列をRLEとして復元します.

Examples:

例えばこんな感じになります (データは適当)

bytes = [0, 0, 0, 0, 0, ...]
data, offset = rle.decode(bytes, 5)
p data    #=> [0, 0, 0, 0, 0]
p offset  #=> 3

Parameters:

  • bytes (Array<Integer>)

    バイト列データ

  • total (Integer)

    最大復元バイト長

Returns:

  • (Array)

    復元されたバイト列データ (整数配列) と、入力バイト列のどこまでを解析したかのオフセット



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/rixmap/format/pcx.rb', line 161

def decode(bytes, total)
  data   = []
  offset = 0
  length = bytes.length
  count  = 0

  while offset < length && count < total
    byte0 = bytes[offset]
    offset += 1
    if byte0 >= 0xC0    # RLEパケット
      cnt = byte0 & 0x3F
      byte1 = bytes[offset]
      offset += 1
      data.concat([byte1] * cnt)
      count += cnt
    else                # 生データ
      data.push(byte0); count += 1
    end
  end

  return [data, offset]
end

#encode(bytes) ⇒ Array<Integer>

バイト列をRLEによって圧縮します.

Parameters:

  • bytes (Array<Integer>)

    バイト列

Returns:

  • (Array<Integer>)

    圧縮されたバイト列



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/rixmap/format/pcx.rb', line 130

def encode(bytes)
  return [] if bytes.empty?
  data = []
  byte0 = bytes[0]
  count = 1
  (1...bytes.size).each do |i|
    byte = bytes[i]
    if byte0 == byte
      count += 1
    else
      data.concat(self.pack(byte0, count))
      byte0 = byte
      count = 1
    end
  end
  if count > 0
    data.concat(self.pack(byte0, count))
  end
  return data
end

#pack(byte, count) ⇒ Array<Integer>

パケットを構築します.

Parameters:

  • byte (Integer)

    バイトデータ

  • count (Integer)

    バイトデータの数

Returns:

  • (Array<Integer>)

    パケットデータ



112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/rixmap/format/pcx.rb', line 112

def pack(byte, count)
  cnt = count / 0x3F
  rem = count % 0x3F
  packed = [0xFF, byte] * cnt
  if rem > 0
    if byte < 0xC0 && rem == 1
      packed.concat([byte])
    else
      packed.concat([0xC0 | rem, byte])
    end
  end
  return packed
end