Class: Rixmap::Format::XPM::XPM2ImageIO

Inherits:
ImageIO::BaseImageIO show all
Defined in:
lib/rixmap/format/xpm.rb

Overview

XPM2形式用入出力実装クラス.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ImageIO::BaseImageIO

#initialize, #open, #read, #readable?, #save, #writable?, #write

Constructor Details

This class inherits a constructor from Rixmap::ImageIO::BaseImageIO

Class Method Details

.readable?(magic) ⇒ Boolean

XPM2形式で読み込めるかどうかを調べます.

Parameters:

  • magic (String)

    先頭バイトデータ

Returns:

  • (Boolean)

    XPM2形式で読み込める場合はtrue



227
228
229
230
231
232
233
# File 'lib/rixmap/format/xpm.rb', line 227

def self.readable?(magic)
  if MAGIC_XPM2_PATTERN.match(magic)
    return true
  else
    return false
  end
end

.writable?(image) ⇒ Boolean

XPM2形式で書き込めるかどうかを調べます.

Parameters:

Returns:

  • (Boolean)

    XPM2形式で書き込める場合はtrue



239
240
241
242
243
244
245
# File 'lib/rixmap/format/xpm.rb', line 239

def self.writable?(image)
  if image.indexed?
    return true
  else
    return false
  end
end

Instance Method Details

#decode(data, options = {}) ⇒ Rixmap::Image

バイト列データからXPM2形式として画像を復元します.

Parameters:

  • data (String)

    XPM2形式画像データ

  • options (Hash) (defaults to: {})

    オプションパラメータ (未使用)

Returns:



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/rixmap/format/xpm.rb', line 281

def decode(data, options={})
  magic, imdata = data.split($/, 2)
  unless MAGIC_XPM2_PATTERN.match(magic)
    raise ArgumentError.new("input image is not XPM image")
  end

  # 行分割
  #xpmlines = Enumerator.new(imdata.split($/))
  xpmlines = imdata.split($/).to_enum

  begin
    # 画像情報
    xpminfo = %r{\s*([[:digit:]]+)\s+([[:digit:]]+)\s+([[:digit:]]+)\s+([[:digit:]]+)\s*}.match(xpmlines.next)
    unless xpminfo
      raise ArgumentError.new("input image data is broken as XPM")
    end
    width   = xpminfo[1].to_i
    height  = xpminfo[2].to_i
    ncolors = xpminfo[3].to_i
    nchars  = xpminfo[4].to_i

    # 画像オブジェクト
    palette = Rixmap::Palette.new(ncolors)
    image   = Rixmap::Image.new(Rixmap::INDEXED, width, height, :palette => palette)

    # カラーテーブル
    ctbl = {}
    cptn = %r{\s*(.{#{nchars}})\s+(c)\s+#([0-9A-Fa-f]{6})\s*.*}
    ncolors.times do |i|
      cmatch = cptn.match(xpmlines.next)
      if cmatch
        ckey   = cmatch[1]
        cvalue = cmatch[3]
        ctbl[ckey] = i
        palette[i] = Rixmap::Color.new(*(cvalue.unpack('a2a2a2').collect {|e| e.to_i(16) }))
      end
    end

    # ピクセルデータ
    pixptn  = %r{\s*(.{#{nchars * width}})\s*}
    packfmt = "a#{nchars}" * width
    height.times do |h|
      pixmatch = pixptn.match(xpmlines.next)
      if pixmatch
        pixmatch[1].unpack(packfmt).each_with_index do |e, w|
          image[w, h] = ctbl[e]
        end
      end
    end

    return image
  rescue StopIteration
    raise RuntimeError.new("illegal content")
  end
end

#encode(image, options = {}) ⇒ String

画像をXPM2形式でバイト列にエンコードします.

Parameters:

  • image (Rixmap::Image)

    対象画像

  • options (Hash) (defaults to: {})

    オプションパラメータ (未使用)

Returns:

  • (String)

    バイト列

Raises:

  • (ArgumentError)


252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/rixmap/format/xpm.rb', line 252

def encode(image, options={})
  raise ArgumentError.new("input image is not supported") unless image.indexed?

  # 書き込みバッファ
  tokens = []
  tokens << MAGIC_XPM2

  # パレット
  ctbl = XPMColorTable.new(image.palette)
  tokens << "#{image.width} #{image.height} #{image.palette.size} #{ctbl.code_size}"
  ctbl.each do |item|
    tokens << "#{item[0]}\tc\t#{item[1]}"
  end

  # ピクセルデータ
  image.height.times do |h|
    line = image[h].collect {|pixel| ctbl.codes[pixel] }.join("")
    tokens << line
  end

  # 連結
  return tokens.join("\n")
end