pixelflut 0.0.13 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46bc6d8430a0a37a766f925558d1279fbf69457f859f9f6286c2fb4a3f3a9e81
4
- data.tar.gz: f634ffe53ec48385c8c9b42f032f3fa0e56d91155cf075a05b2b9c15794d8dbb
3
+ metadata.gz: b29b8ce88df1c1d08de27f9c87fae728d58d25759cbfc88c2f0c62865492f054
4
+ data.tar.gz: 55311c23772975543c15e74741a5bbb452e4a48eb0e4af4d351d28e9ed5cbfa3
5
5
  SHA512:
6
- metadata.gz: 53bb74856603e0d46563b707726cdb8d5d96f5192ebd641c00ebba463e45ba5165536f4b95ea60d28e0468f8735acb32d3439802541791faf9a2dcbe13b94dab
7
- data.tar.gz: 2f26150a3d40045e6030018cbcbf807dcbb1f415f193f156d1c45d8c4eea5e5c6d56e5205d764b701b6d644346d0892042f5fb1cdd9ce0d9cd6ee5ba4fbad099
6
+ metadata.gz: c078c2eb4b3dfe4c4faf5d0c3b9bc652c90d3b602c0166b89bcc5f6ccfe8c01e02e9ade0098d5b951f82beab9ef165a8e0bb9363542ebf93264f73d45985ef7e
7
+ data.tar.gz: 244d2e819a90182daf2883c49a73454e0367dc098a3ed3f50748846efec8605e14f34dff346f347f7df453d977de9e5b1bc1b9bf2eefbaf4bd36a24aea52d094
data/README.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # Pixelflut
2
2
 
3
- A Pixelflut server & client tool collection written in Ruby.
3
+ A Pixelflut client written in Ruby.
4
4
 
5
5
  ## Description
6
6
 
7
- Based on the idea of a simple server protocol to collaborate on a shared canvas named [Pixel Flut](https://cccgoe.de/wiki/Pixelflut) this gem implements a Ruby version.
7
+ Based on the idea of a simple server protocol to collaborate on a shared canvas named [Pixel Flut](https://cccgoe.de/wiki/Pixelflut) this gem implements a Ruby version of a client.
8
8
 
9
- This gem is an open experiment to write a fast server and canvas in Ruby. You are welcome to fork or create pull requests to find the fastest solution!
10
-
11
- The gem includes some tools to develop Pixelflut clients and pre-processors.
9
+ This gem is an open experiment. You are welcome to fork or create pull requests to find the fastest solution!
12
10
 
13
11
  ### Installation
14
12
 
@@ -26,76 +24,16 @@ You'll find some help on the command line:
26
24
 
27
25
  ```bash
28
26
  $ pxf
29
- usage: pxf command [options]
30
-
31
- valid commands:
32
- convert Convert given IMAGE file to Pixelflut ASCII format.
33
- generate Execute given generator FILEs.
34
- help Print help for given COMMAND.
35
- send Send given Pixelflut ASCII file to a server.
36
- server Start Pixelflut server.
37
- version Print version information.
38
- ```
27
+ Usage: pxf [options] IMAGE
39
28
 
40
- ### Start a Sserver
29
+ Options:
30
+ --host ADDRESS target host address
31
+ -p, --port NUMBER target port (default 1234)
32
+ -c, --connections COUNT count of connections (default 4)
33
+ -x, --transpose-x X transpose image X pixels
34
+ -y, --transpose-y Y transpose image Y pixels
35
+ -s, --scale FACTOR scale image by FACTOR
41
36
 
42
- Starting the server on default port `1234` and open a drawing screen is quite simple:
43
-
44
- ```bash
45
- $ pxf server
46
- ```
47
-
48
- With these options you can configure the server:
49
-
50
- ```
51
- -b, --bind ADDR bind to given address
52
- -p, --port PORT select port(default: 1234)
53
- -k, --keep-alive set maximum keep-alive time
54
- -r, --read_buffer SIZE set read buffer size (default: 1024)
55
- -w, --width WIDTH set canvas width (default: 800)
56
- -h, --height HEIGHT set canvas height (default: 600)
57
- -f, --[no-]fullscreen run in fullscreen mode
37
+ -h, --help print this help
38
+ -v, --version print version information
58
39
  ```
59
-
60
- ### Convert an Image
61
-
62
- There is a conversion command which can be used to convert a given image to the Pixelflut ASCII text format:
63
-
64
- ```bash
65
- $ pxf convert image.png
66
- ```
67
-
68
- The result can send directly to a server (sample assumes the server runs on localhost port 1234):
69
-
70
- ```bash
71
- $ pxf convert image.png | pxf send
72
- ```
73
-
74
- The converter can help you to resize and positioning the image at the servers canvas. These options are avail:
75
-
76
- ```
77
- -x, --transpose-x X transpose image X pixels
78
- -y, --transpose-y Y transpose image Y pixels
79
- -w, --width WIDTH resize the image to given WIDTH
80
- -h, --height HEIGHT resize the image to given HEIGHT
81
- ```
82
-
83
- It maybe faster to pre-process your images and send them later:
84
-
85
- ```bash
86
- $ pxf convert -x 50 -y 100 --width 100 image1.png > image1.px
87
- $ pxf convert -x 150 --width 2100 image2.png > image2.px
88
- $ pxf send -h pixel_host image1.px image2.px
89
- ```
90
-
91
- ### Send Pixelflut ASCII Text
92
-
93
- The `pxf send` command can be used to send given Pixelflut ASCII text files to a server. It uses several connections at the same time to fasten the transmission.
94
-
95
- Next sample will send the Pixelflut ASCII text file named `pixels.px` to the server on port 1234 at address `pixelhost` using 12 connections:
96
-
97
- ```bash
98
- $ pxf send -h pixelhost -p 1234 -c 12 pixels.px
99
- ```
100
-
101
- If no file is given the STDIN will be read and send afterwards to the server.
data/bin/pxf CHANGED
@@ -1,33 +1,84 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- def bin_root
5
- File.realdirpath('../', __FILE__).freeze
6
- end
4
+ Process.setproctitle($name = 'pxf')
5
+ $stderr.sync = $stdout.sync = true
6
+
7
+ require 'optparse'
8
+ require_relative '../lib/pixelflut'
7
9
 
8
- def find_commands
9
- Hash[Dir.glob(File.join(bin_root, 'pxf-*')).map!{ |cmd| [File.basename(cmd)[4..-1], cmd] }]
10
+ def err(msg, code = 1)
11
+ $stderr.puts("#{$name}: #{msg}")
12
+ exit(code)
10
13
  end
11
14
 
12
- def err(msg)
13
- $stderr.puts("pxf: #{msg}")
14
- exit 1
15
+ OPTS = Struct
16
+ .new(:host, :port, :count, :x, :y, :scale, :image)
17
+ .new('127.0.0.1', 1234, 4, 0, 0)
18
+
19
+ def parse(args)
20
+ OptionParser.new do |parser|
21
+ parser.summary_indent = ' '
22
+ parser.banner = 'Usage: pxf [options] IMAGE'
23
+ parser.separator(nil)
24
+ parser.separator('Options:')
25
+ parser.on(
26
+ '--host ADDRESS', 'target host address'
27
+ ){ |v| OPTS.host = v }
28
+ parser.on(
29
+ '-p', '--port NUMBER', Integer, 'target port (default 1234)'
30
+ ){ |v| OPTS.port = v }
31
+ parser.on(
32
+ '-c', '--connections COUNT', Integer, 'count of connections (default 4)'
33
+ ){ |v| OPTS.count = v }
34
+ parser.on(
35
+ '-x', '--transpose-x X', Integer, 'transpose image X pixels'
36
+ ){ |v| OPTS.x = v }
37
+ parser.on(
38
+ '-y', '--transpose-y Y', Integer, 'transpose image Y pixels'
39
+ ){ |v| OPTS.y = v }
40
+ parser.on(
41
+ '-s', '--scale FACTOR', OptionParser::DecimalNumeric, 'scale image by FACTOR'
42
+ ){ |v| OPTS.scale = v }
43
+ parser.separator(nil)
44
+ parser.on('-h', '--help', 'print this help') do
45
+ exit(!puts(parser))
46
+ end
47
+ parser.on('-v', '--version', 'print version information') do
48
+ require_relative '../lib/pixelflut/version'
49
+ exit(!puts("pxf-#{Pixelflut::VERSION}"))
50
+ end
51
+ end.parse!(args)
52
+ OPTS.image = args.first or err('image name expected')
53
+ OPTS
54
+ rescue OptionParser::ParseError => e
55
+ err(e)
15
56
  end
16
57
 
17
- def general_help
18
- puts('usage: pxf command [options]', nil, 'valid commands:')
19
- map = find_commands.transform_values!{ |cmd| %x(#{cmd} --short-help) }
20
- cmds = map.keys.sort!
21
- len = cmds.max_by(&:size).size + 3
22
- cmds.each do |cmd|
23
- print cmd.ljust(len)
24
- puts(map[cmd])
58
+ begin
59
+ parse(ARGV)
60
+ addr = Pixelflut::Sender.address(OPTS.host, OPTS.port)
61
+ slices = Pixelflut.as_slices(
62
+ source: OPTS.image,
63
+ count: OPTS.count,
64
+ x: OPTS.x,
65
+ y: OPTS.y,
66
+ scale: OPTS.scale
67
+ )
68
+ slices.size.times do |i|
69
+ next unless fork
70
+ Process.setproctitle($name = format('pxf-%02d', i + 1))
71
+ sender = Pixelflut::Sender.new(addr, slices[i].join)
72
+ slices.clear
73
+ puts "#{$name}: run"
74
+ sender.run
25
75
  end
26
- exit
76
+ rescue SocketError => e
77
+ err(e, 3)
78
+ rescue LoadError => e
79
+ err(e, 4)
80
+ rescue Errno::EPIPE
81
+ err('connection lost', 2)
82
+ rescue Interrupt
83
+ err('interrupted', 130)
27
84
  end
28
-
29
- general_help if ARGV.empty? || ARGV[0] == '--help' || ARGV[0] == '-h'
30
- cmd = ARGV.shift
31
- fname = File.join(bin_root, 'pxf-' + cmd)
32
- err("no such command - #{cmd}") unless File.executable?(fname)
33
- exec(fname, *ARGV)
@@ -1,8 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'pixelflut/image'
4
+ require_relative 'pixelflut/convert'
5
+ require_relative 'pixelflut/sender'
6
+
1
7
  module Pixelflut
2
- LIB_DIR = File.realdirpath('../pixelflut', __FILE__).freeze
3
- autoload :App, File.join(LIB_DIR, 'app.rb')
4
- autoload :Server, File.join(LIB_DIR, 'server.rb')
5
- autoload :Canvas, File.join(LIB_DIR, 'canvas.rb')
6
- autoload :Converter, File.join(LIB_DIR, 'converter.rb')
7
- autoload :VERSION, File.join(LIB_DIR, 'version.rb')
8
+ def self.converted(source, x = 0, y = 0, scale = nil)
9
+ image = Image.new(source)
10
+ image.scale(scale) if scale
11
+ Convert.each_line(image, x, y)
12
+ end
13
+
14
+ def self.as_slices(source:, count: 4, x: 0, y: 0, scale: nil)
15
+ image = Image.new(source)
16
+ image.scale(scale) if scale
17
+ Convert.as_slices(image, x, y, count)
18
+ end
8
19
  end
@@ -0,0 +1,28 @@
1
+ module Pixelflut
2
+ module Convert
3
+ def self.each_line0(image)
4
+ return to_enum(__method__, image) unless block_given?
5
+ image.each_pixel do |x, y, px|
6
+ px = px.to_color(Magick::AllCompliance, true, 8, true)[
7
+ 1, 255 == px.alpha ? 6 : 8
8
+ ]
9
+ yield("PX #{x} #{y} #{px}\n")
10
+ end
11
+ end
12
+
13
+ def self.each_line(image, dx, dy)
14
+ return to_enum(__method__, image, dx, dy) unless block_given?
15
+ image.each_pixel do |x, y, px|
16
+ px = px.to_color(Magick::AllCompliance, true, 8, true)[
17
+ 1, 255 == px.alpha ? 6 : 8
18
+ ]
19
+ yield("PX #{x + dx} #{y + dy} #{px}\n")
20
+ end
21
+ end
22
+
23
+ def self.as_slices(image, dx, dy, count)
24
+ ret = each_line(image, dx, dy).to_a.shuffle!
25
+ ret.each_slice(ret.size / count).to_a
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ require 'rmagick'
2
+
3
+ module Pixelflut
4
+ class Image
5
+ def initialize(file_name)
6
+ @image = Magick::ImageList.new(file_name)[0]
7
+ rescue Magick::ImageMagickError => e
8
+ raise(LoadError, e.message, cause: e)
9
+ end
10
+
11
+ def width
12
+ @image.columns
13
+ end
14
+
15
+ def height
16
+ @image.rows
17
+ end
18
+
19
+ def resize_to(width, height = nil)
20
+ @image.resize_to_fit!(width, height)
21
+ end
22
+
23
+ def scale(factor)
24
+ @image.scale!(factor)
25
+ end
26
+
27
+ def each_pixel
28
+ return to_enum(__method__) unless block_given?
29
+ @image.each_pixel{ |px, x, y| 0 != px.alpha and yield(x, y, px) }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,53 @@
1
+ require 'socket'
2
+
3
+ module Pixelflut
4
+ class Sender
5
+ def self.address(host, port)
6
+ Addrinfo.tcp(host, port)
7
+ end
8
+
9
+ def initialize(address, data)
10
+ @data = data.freeze
11
+ @addr = Socket.pack_sockaddr_in(address.ip_port, address.ip_address)
12
+ @socket = configure(Socket.new(address.ipv6? ? :INET6 : :INET, :STREAM))
13
+ end
14
+
15
+ def run
16
+ connect
17
+ send(@socket, @data)
18
+ @socket.close
19
+ end
20
+
21
+ private
22
+
23
+ def send(socket, data)
24
+ curr = String.new(data)
25
+ loop do
26
+ written = socket.write(curr)
27
+ curr =
28
+ if (size = curr.bytesize - written) > 0
29
+ curr.byteslice(written, size)
30
+ else
31
+ String.new(data)
32
+ end
33
+ end
34
+ end
35
+
36
+ def connect
37
+ loop do
38
+ (
39
+ :wait_writable == @socket.connect_nonblock(@addr, exception: false)
40
+ ) and break
41
+ end
42
+ loop{ @socket.wait_writable(10) and break }
43
+ end
44
+
45
+ def configure(socket)
46
+ socket.sync = true
47
+ socket.setsockopt(:TCP, :NODELAY, 1)
48
+ socket.setsockopt(:SOCKET, :KEEPALIVE, 0)
49
+ socket.do_not_reverse_lookup = true
50
+ socket
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  module Pixelflut
2
- VERSION = '0.0.13'.freeze
2
+ VERSION = '0.1.2'.freeze
3
3
  end
@@ -5,22 +5,23 @@ require_relative 'lib/pixelflut/version'
5
5
  GemSpec = Gem::Specification.new do |spec|
6
6
  spec.name = 'pixelflut'
7
7
  spec.version = Pixelflut::VERSION
8
- spec.summary = 'A Pixelflut server & client tool collection written in Ruby.'
8
+ spec.summary = 'A fast Pixelflut client written in Ruby.'
9
9
  spec.description = <<~DESCRIPTION
10
10
  Based on the idea of a simple server protocol to collaborate on a shared canvas named
11
- [Pixel Flut](https://cccgoe.de/wiki/Pixelflut) this gem implements a Ruby version.
11
+ [Pixel Flut](https://cccgoe.de/wiki/Pixelflut) this gem implements a fast Ruby client version.
12
12
  DESCRIPTION
13
13
  spec.author = 'Mike Blumtritt'
14
- spec.email = 'mike.blumtritt@invision.de'
14
+ spec.email = 'mike.blumtritt@pm.me'
15
15
  spec.homepage = 'https://github.com/mblumtritt/pixelflut'
16
16
  spec.metadata = {
17
- 'issue_tracker' => 'https://github.com/mblumtritt/pixelflut/issues'
17
+ 'source_code_uri' => 'https://github.com/mblumtritt/pixelflut',
18
+ 'bug_tracker_uri' => 'https://github.com/mblumtritt/pixelflut/issues'
18
19
  }
19
20
  spec.rubyforge_project = spec.name
20
21
 
21
- spec.add_runtime_dependency 'gosu', '>= 0.13.2'
22
- spec.add_development_dependency 'bundler', '>= 1.16.0'
23
- spec.add_development_dependency 'rake', '>= 12.3.0'
22
+ spec.add_runtime_dependency 'rmagick'
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'rake'
24
25
 
25
26
  spec.platform = Gem::Platform::RUBY
26
27
  spec.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
metadata CHANGED
@@ -1,106 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pixelflut
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-26 00:00:00.000000000 Z
11
+ date: 2019-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: gosu
14
+ name: rmagick
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.13.2
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.13.2
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.16.0
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 1.16.0
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 12.3.0
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 12.3.0
54
+ version: '0'
55
55
  description: |
56
56
  Based on the idea of a simple server protocol to collaborate on a shared canvas named
57
- [Pixel Flut](https://cccgoe.de/wiki/Pixelflut) this gem implements a Ruby version.
58
- email: mike.blumtritt@invision.de
57
+ [Pixel Flut](https://cccgoe.de/wiki/Pixelflut) this gem implements a fast Ruby client version.
58
+ email: mike.blumtritt@pm.me
59
59
  executables:
60
60
  - pxf
61
- - pxf-generate
62
- - pxf-server
63
- - pxf-convert
64
- - pxf-help
65
- - pxf-send
66
- - pxf-version
67
- - pxf-info
68
61
  extensions: []
69
62
  extra_rdoc_files:
70
63
  - README.md
71
64
  files:
72
65
  - ".gitignore"
73
66
  - README.md
74
- - TODO.md
75
67
  - bin/pxf
76
- - bin/pxf-convert
77
- - bin/pxf-generate
78
- - bin/pxf-help
79
- - bin/pxf-info
80
- - bin/pxf-send
81
- - bin/pxf-server
82
- - bin/pxf-version
83
68
  - gems.rb
84
69
  - lib/pixelflut.rb
85
- - lib/pixelflut/app.rb
86
- - lib/pixelflut/canvas.rb
87
- - lib/pixelflut/canvas/base.rb
88
- - lib/pixelflut/canvas/buffered.rb
89
- - lib/pixelflut/canvas/streamed.rb
90
- - lib/pixelflut/client.rb
91
- - lib/pixelflut/client/socket.rb
92
- - lib/pixelflut/converter.rb
93
- - lib/pixelflut/server.rb
94
- - lib/pixelflut/server/configuration.rb
95
- - lib/pixelflut/server/connection.rb
96
- - lib/pixelflut/text_image.rb
70
+ - lib/pixelflut/convert.rb
71
+ - lib/pixelflut/image.rb
72
+ - lib/pixelflut/sender.rb
97
73
  - lib/pixelflut/version.rb
98
74
  - pixelflut.gemspec
99
75
  - rakefile.rb
100
76
  homepage: https://github.com/mblumtritt/pixelflut
101
77
  licenses: []
102
78
  metadata:
103
- issue_tracker: https://github.com/mblumtritt/pixelflut/issues
79
+ source_code_uri: https://github.com/mblumtritt/pixelflut
80
+ bug_tracker_uri: https://github.com/mblumtritt/pixelflut/issues
104
81
  post_install_message:
105
82
  rdoc_options: []
106
83
  require_paths:
@@ -116,8 +93,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
93
  - !ruby/object:Gem::Version
117
94
  version: 1.3.6
118
95
  requirements: []
119
- rubygems_version: 3.0.1
96
+ rubygems_version: 3.0.6
120
97
  signing_key:
121
98
  specification_version: 4
122
- summary: A Pixelflut server & client tool collection written in Ruby.
99
+ summary: A fast Pixelflut client written in Ruby.
123
100
  test_files: []