pixelflut 0.0.13 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/README.md +15 -77
- data/bin/pxf +58 -22
- data/bin/pxf-info +26 -49
- data/gems.rb +1 -1
- data/lib/pixelflut.rb +55 -6
- data/lib/pixelflut/image.rb +32 -0
- data/lib/pixelflut/sender.rb +29 -0
- data/lib/pixelflut/version.rb +3 -1
- data/pixelflut.gemspec +18 -25
- data/rakefile.rb +5 -3
- metadata +38 -45
- data/TODO.md +0 -11
- data/bin/pxf-convert +0 -55
- data/bin/pxf-generate +0 -35
- data/bin/pxf-help +0 -23
- data/bin/pxf-send +0 -44
- data/bin/pxf-server +0 -64
- data/bin/pxf-version +0 -17
- data/lib/pixelflut/app.rb +0 -81
- data/lib/pixelflut/canvas.rb +0 -4
- data/lib/pixelflut/canvas/base.rb +0 -99
- data/lib/pixelflut/canvas/buffered.rb +0 -27
- data/lib/pixelflut/canvas/streamed.rb +0 -20
- data/lib/pixelflut/client.rb +0 -35
- data/lib/pixelflut/client/socket.rb +0 -93
- data/lib/pixelflut/converter.rb +0 -53
- data/lib/pixelflut/server.rb +0 -58
- data/lib/pixelflut/server/configuration.rb +0 -26
- data/lib/pixelflut/server/connection.rb +0 -98
- data/lib/pixelflut/text_image.rb +0 -89
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: a4b1d4d4f5be08766e694539cf82507427f901f71ae1ec4c5568cec7344d1345
         | 
| 4 | 
            +
              data.tar.gz: 65d9ebde1aa48a5989c28340d3da137b8d99d3952a85fbfb904ad7af64420df8
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 377feb36cdde2221e3d6c7739acc9773d771d15cf319e93e379c6f86248189c286af91a25e13acda88fc40e030b956761ffa205215e4bb37ddd9ee64e805e748
         | 
| 7 | 
            +
              data.tar.gz: 910cd772cedf70ddd4cb01445821ccf360f54d96a3c4076b9845886a0e5e1a232a0b153e640b574e6540c490c77691bd515a6b42bb74ade60f0970e2e201c9f9
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,14 +1,12 @@ | |
| 1 1 | 
             
            # Pixelflut
         | 
| 2 2 |  | 
| 3 | 
            -
            A Pixelflut  | 
| 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 [ | 
| 7 | 
            +
            Based on the idea of a simple server protocol to collaborate on a shared canvas named [Pixelflut](https://cccgoe.de/wiki/Pixelflut) this gem implements a Ruby version of a client.
         | 
| 8 8 |  | 
| 9 | 
            -
            This gem is an open experiment | 
| 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 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 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
         | 
| 27 | 
            +
            Usage: pxf [OPTIONS] IMAGE
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            Options:
         | 
| 30 | 
            +
                --host ADDRESS        target host address
         | 
| 31 | 
            +
            -p, --port PORT           target port (default 1234)
         | 
| 32 | 
            +
            -c, --connections CONN    count of connections (default 4)
         | 
| 33 | 
            +
            -b, --bytes BYTES         send junks of BYTES size
         | 
| 34 | 
            +
            -x, --transpose-x X       transpose image X pixels
         | 
| 35 | 
            +
            -y, --transpose-y Y       transpose image Y pixels
         | 
| 36 | 
            +
            -s, --scale SCALE         scale image by SCALE factor
         | 
| 37 | 
            +
            -m, --pixel MODE          select pixel coding (RGBX | RGBA | RGB)
         | 
| 38 | 
            +
            -h, --help                print this help
         | 
| 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,69 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 3 |  | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 4 | 
            +
            help <<~end, 'IMAGE'
         | 
| 5 | 
            +
                  --host ADDRESS        target host address
         | 
| 6 | 
            +
              -p, --port PORT           target port (default 1234)
         | 
| 7 | 
            +
              -c, --connections CONN    count of connections (default 4)
         | 
| 8 | 
            +
              -b, --bytes BYTES         send junks of BYTES size
         | 
| 9 | 
            +
              -x, --transpose-x X       transpose image X pixels
         | 
| 10 | 
            +
              -y, --transpose-y Y       transpose image Y pixels
         | 
| 11 | 
            +
              -s, --scale SCALE         scale image by SCALE factor
         | 
| 12 | 
            +
              -m, --pixel MODE          select pixel coding (RGBX | RGBA | RGB)
         | 
| 13 | 
            +
              -h, --help                print this help
         | 
| 6 14 | 
             
            end
         | 
| 7 15 |  | 
| 8 | 
            -
             | 
| 9 | 
            -
               | 
| 16 | 
            +
            main do |opts|
         | 
| 17 | 
            +
              data = create_junks(opts)
         | 
| 18 | 
            +
              print("spawn #{data.size}")
         | 
| 19 | 
            +
              data.size.times do |i|
         | 
| 20 | 
            +
                next unless fork
         | 
| 21 | 
            +
                Process.setproctitle(name(format("#{name}-%02d", i + 1)))
         | 
| 22 | 
            +
                data = data[i].join
         | 
| 23 | 
            +
                GC.start
         | 
| 24 | 
            +
                GC.disable
         | 
| 25 | 
            +
                Pixelflut::Sender.send(opts.address, data) { print('.') }
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            rescue SocketError => e
         | 
| 28 | 
            +
              error(3, e)
         | 
| 29 | 
            +
            rescue LoadError => e
         | 
| 30 | 
            +
              error(4, e)
         | 
| 31 | 
            +
            rescue Errno::ECONNREFUSED
         | 
| 32 | 
            +
              error(2, 'unable to connect')
         | 
| 33 | 
            +
            rescue Errno::EPIPE
         | 
| 34 | 
            +
              error(2, 'connection lost')
         | 
| 10 35 | 
             
            end
         | 
| 11 36 |  | 
| 12 | 
            -
            def  | 
| 13 | 
            -
               | 
| 14 | 
            -
               | 
| 37 | 
            +
            def create_junks(opts)
         | 
| 38 | 
            +
              lines = Pixelflut.convert(**opts.to_h)
         | 
| 39 | 
            +
              return Pixelflut.slices(lines, count: opts.count) if opts.bytes.zero?
         | 
| 40 | 
            +
              Pixelflut.junks(lines, bytes: opts.bytes)
         | 
| 15 41 | 
             
            end
         | 
| 16 42 |  | 
| 17 | 
            -
             | 
| 18 | 
            -
               | 
| 19 | 
            -
               | 
| 20 | 
            -
               | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 43 | 
            +
            before do
         | 
| 44 | 
            +
              $stderr.sync = $stdout.sync = true
         | 
| 45 | 
            +
              Process.setproctitle(name)
         | 
| 46 | 
            +
              require_relative('../lib/pixelflut')
         | 
| 47 | 
            +
            end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            parse_argv do |args|
         | 
| 50 | 
            +
              Struct.new(:address, :count, :bytes, :x, :y, :mode, :scale, :source) do
         | 
| 51 | 
            +
                def to_h
         | 
| 52 | 
            +
                  { source: source, x: x, y: y, scale: scale, mode: mode }
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end.new(
         | 
| 55 | 
            +
                Pixelflut::Sender.address(
         | 
| 56 | 
            +
                  args['ADDRESS'] || '127.0.0.1',
         | 
| 57 | 
            +
                  (args['PORT'] || 1234).to_i
         | 
| 58 | 
            +
                ),
         | 
| 59 | 
            +
                (args['CONN'] || 4).to_i,
         | 
| 60 | 
            +
                args['BYTES'].to_i,
         | 
| 61 | 
            +
                args['X'].to_i,
         | 
| 62 | 
            +
                args['Y'].to_i,
         | 
| 63 | 
            +
                { 'RGBA' => :rgba, 'RGB' => :rgb }[args['MODE']] || :rgbx,
         | 
| 64 | 
            +
                args.key?('SCALE') ? args['SCALE'].to_f : nil,
         | 
| 65 | 
            +
                args['IMAGE']
         | 
| 66 | 
            +
              )
         | 
| 27 67 | 
             
            end
         | 
| 28 68 |  | 
| 29 | 
            -
             | 
| 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)
         | 
| 69 | 
            +
            BEGIN { require('mini-cli') and include(MiniCli) }
         | 
    
        data/bin/pxf-info
    CHANGED
    
    | @@ -1,55 +1,32 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            # frozen_string_literal: true
         | 
| 1 | 
            +
            #! /bin/sh
         | 
| 3 2 |  | 
| 4 | 
            -
             | 
| 5 | 
            -
              require 'optparse'
         | 
| 6 | 
            -
              OptionParser.new do |opts|
         | 
| 7 | 
            -
                opts.summary_indent = '  '
         | 
| 8 | 
            -
                opts.banner = 'usage: pxf info [options]'
         | 
| 9 | 
            -
                opts.separator(nil)
         | 
| 10 | 
            -
                opts.separator('valid options:')
         | 
| 11 | 
            -
                opts.on('-h', '--host HOST', String, 'target host name (default localhost)'){ |v| cfg[:host] = v }
         | 
| 12 | 
            -
                opts.on('-p', '--port PORT', Integer, 'target port (default 1234)'){ |v| cfg[:port] = v }
         | 
| 13 | 
            -
              end
         | 
| 14 | 
            -
            end
         | 
| 3 | 
            +
            set -e
         | 
| 15 4 |  | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
               | 
| 19 | 
            -
              exit
         | 
| 20 | 
            -
            end
         | 
| 5 | 
            +
            if [ "$1" = '--help' ]
         | 
| 6 | 
            +
            then
         | 
| 7 | 
            +
              echo "Usage: ${0##*/} [-p|--port PORT] ADDRESS
         | 
| 21 8 |  | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
              exit | 
| 25 | 
            -
             | 
| 9 | 
            +
            Requests screen size of Pixelflut server at ADDRESS.
         | 
| 10 | 
            +
            "
         | 
| 11 | 
            +
              exit 0
         | 
| 12 | 
            +
            fi
         | 
| 26 13 |  | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
            rescue OptionParser::ParseError => e
         | 
| 30 | 
            -
              err(e)
         | 
| 31 | 
            -
            end
         | 
| 14 | 
            +
            PORT="1234"
         | 
| 15 | 
            +
            ADDRESS=""
         | 
| 32 16 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 17 | 
            +
            while [ $# -gt 0 ]
         | 
| 18 | 
            +
            do
         | 
| 19 | 
            +
              key="$1"
         | 
| 20 | 
            +
              case $key in
         | 
| 21 | 
            +
              -p|--port)
         | 
| 22 | 
            +
                PORT="$2"
         | 
| 23 | 
            +
                shift; shift
         | 
| 24 | 
            +
                ;;
         | 
| 25 | 
            +
              *)
         | 
| 26 | 
            +
                ADDRESS="$key"
         | 
| 27 | 
            +
                shift
         | 
| 28 | 
            +
                ;;
         | 
| 29 | 
            +
              esac
         | 
| 30 | 
            +
            done
         | 
| 39 31 |  | 
| 40 | 
            -
             | 
| 41 | 
            -
              err("unable to connect - #{options[:host]}:options[:port])", 2) unless socket.connect? || socket.wait_writable(5)
         | 
| 42 | 
            -
              err("server busy - #{options[:host]}:options[:port])", 3) unless socket.write_with_timout("SIZE\n", 5)
         | 
| 43 | 
            -
              line = socket.readline_with_timeout(5)
         | 
| 44 | 
            -
              socket.close
         | 
| 45 | 
            -
              err("server does not respond - #{options[:host]}:options[:port])", 4) unless line
         | 
| 46 | 
            -
              mark, width, height = line.split(' ', 3)
         | 
| 47 | 
            -
              width = width.to_i
         | 
| 48 | 
            -
              height = height.to_i
         | 
| 49 | 
            -
              err("no Pixelflut server - #{options[:host]}:options[:port])", 5) if mark != 'SIZE' || width <= 0 || height <= 0
         | 
| 50 | 
            -
              puts "canvas size: #{width}x#{height}"
         | 
| 51 | 
            -
            rescue SocketError, SystemCallError => e
         | 
| 52 | 
            -
              err(e.message, 2)
         | 
| 53 | 
            -
            rescue Interrupt
         | 
| 54 | 
            -
              exit
         | 
| 55 | 
            -
            end
         | 
| 32 | 
            +
            echo "SIZE\nQUIT\n" | nc "$ADDRESS" "$PORT"
         | 
    
        data/gems.rb
    CHANGED
    
    
    
        data/lib/pixelflut.rb
    CHANGED
    
    | @@ -1,8 +1,57 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative 'pixelflut/image'
         | 
| 4 | 
            +
            require_relative 'pixelflut/sender'
         | 
| 5 | 
            +
             | 
| 1 6 | 
             
            module Pixelflut
         | 
| 2 | 
            -
               | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 7 | 
            +
              class << self
         | 
| 8 | 
            +
                def convert(source:, x: 0, y: 0, scale: nil, mode: :rgbx)
         | 
| 9 | 
            +
                  _convert(as_image(source, scale), x, y, &as_cvt(mode))
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def slices(lines, count: 4)
         | 
| 13 | 
            +
                  Array.new(count) { [] }.tap do |ret|
         | 
| 14 | 
            +
                    lines.each_with_index { |line, idx| ret[idx % count] << line }
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def junks(lines, bytes:)
         | 
| 19 | 
            +
                  size, ret = 0, [current = []]
         | 
| 20 | 
            +
                  lines.each do |line|
         | 
| 21 | 
            +
                    next current << line if (size += line.bytesize) < bytes
         | 
| 22 | 
            +
                    ret << (current = [line])
         | 
| 23 | 
            +
                    size = line.bytesize
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                  ret
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                alias packages junks # backward compatibility
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                private
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def _convert(image, dx, dy)
         | 
| 32 | 
            +
                  image.each_pixel.to_a.map! do |x, y, px|
         | 
| 33 | 
            +
                    "PX #{x + dx} #{y + dy} #{yield(px)}\n"
         | 
| 34 | 
            +
                  end.shuffle!
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def as_image(source, scale)
         | 
| 38 | 
            +
                  Image.new(source).tap { |image| image.scale(scale) if scale }
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def as_cvt(mode)
         | 
| 42 | 
            +
                  case mode
         | 
| 43 | 
            +
                  when :rgb
         | 
| 44 | 
            +
                    lambda { |px| px.to_color(Magick::AllCompliance, false, 8, true)[1, 6] }
         | 
| 45 | 
            +
                  when :rgba
         | 
| 46 | 
            +
                    lambda { |px| px.to_color(Magick::AllCompliance, true, 8, true)[1, 8] }
         | 
| 47 | 
            +
                  else
         | 
| 48 | 
            +
                    lambda do |px|
         | 
| 49 | 
            +
                      px.to_color(Magick::AllCompliance, false, 8, true)[
         | 
| 50 | 
            +
                        1,
         | 
| 51 | 
            +
                        px.alpha >= 65_535 ? 6 : 8
         | 
| 52 | 
            +
                      ]
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 8 57 | 
             
            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,29 @@ | |
| 1 | 
            +
            require 'socket'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Pixelflut
         | 
| 4 | 
            +
              module Sender
         | 
| 5 | 
            +
                def self.address(host, port)
         | 
| 6 | 
            +
                  Addrinfo.tcp(host, port)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def self.send(address, data)
         | 
| 10 | 
            +
                  socket = create_socket(address)
         | 
| 11 | 
            +
                  yield(socket) if block_given?
         | 
| 12 | 
            +
                  loop { socket.write(data) }
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def self.create_socket(address)
         | 
| 16 | 
            +
                  Socket
         | 
| 17 | 
            +
                    .new(address.ipv6? ? :INET6 : :INET, :STREAM)
         | 
| 18 | 
            +
                    .tap do |socket|
         | 
| 19 | 
            +
                      socket.sync = false
         | 
| 20 | 
            +
                      socket.setsockopt(:TCP, :NODELAY, 0)
         | 
| 21 | 
            +
                      socket.setsockopt(:SOCKET, :KEEPALIVE, 0)
         | 
| 22 | 
            +
                      socket.do_not_reverse_lookup = true
         | 
| 23 | 
            +
                      socket.connect(
         | 
| 24 | 
            +
                        Socket.pack_sockaddr_in(address.ip_port, address.ip_address)
         | 
| 25 | 
            +
                      )
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
    
        data/lib/pixelflut/version.rb
    CHANGED
    
    
    
        data/pixelflut.gemspec
    CHANGED
    
    | @@ -2,40 +2,33 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            require_relative 'lib/pixelflut/version'
         | 
| 4 4 |  | 
| 5 | 
            -
             | 
| 5 | 
            +
            Gem::Specification.new do |spec|
         | 
| 6 6 | 
             
              spec.name = 'pixelflut'
         | 
| 7 7 | 
             
              spec.version = Pixelflut::VERSION
         | 
| 8 | 
            -
              spec. | 
| 8 | 
            +
              spec.author = 'Mike Blumtritt'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              spec.required_ruby_version = '>= 2.7.2'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              spec.summary = 'A fast Pixelflut client written in Ruby.'
         | 
| 9 13 | 
             
              spec.description = <<~DESCRIPTION
         | 
| 10 | 
            -
                Based on the idea of a simple server protocol to collaborate on a shared | 
| 11 | 
            -
                [ | 
| 14 | 
            +
                Based on the idea of a simple server protocol to collaborate on a shared
         | 
| 15 | 
            +
                canvas named [Pixelflut](https://cccgoe.de/wiki/Pixelflut) this gem
         | 
| 16 | 
            +
                implements a fast Ruby client version.
         | 
| 12 17 | 
             
              DESCRIPTION
         | 
| 13 | 
            -
              spec.author = 'Mike Blumtritt'
         | 
| 14 | 
            -
              spec.email = 'mike.blumtritt@invision.de'
         | 
| 15 18 | 
             
              spec.homepage = 'https://github.com/mblumtritt/pixelflut'
         | 
| 16 | 
            -
              spec.metadata = {
         | 
| 17 | 
            -
                'issue_tracker' => 'https://github.com/mblumtritt/pixelflut/issues'
         | 
| 18 | 
            -
              }
         | 
| 19 | 
            -
              spec.rubyforge_project = spec.name
         | 
| 20 19 |  | 
| 21 | 
            -
              spec. | 
| 22 | 
            -
              spec. | 
| 23 | 
            -
             | 
| 20 | 
            +
              spec.metadata['source_code_uri'] = 'https://github.com/mblumtritt/pixelflut'
         | 
| 21 | 
            +
              spec.metadata['bug_tracker_uri'] =
         | 
| 22 | 
            +
                'https://github.com/mblumtritt/pixelflut/issues'
         | 
| 24 23 |  | 
| 25 | 
            -
              spec. | 
| 26 | 
            -
              spec. | 
| 27 | 
            -
              spec. | 
| 24 | 
            +
              spec.add_runtime_dependency 'rmagick'
         | 
| 25 | 
            +
              spec.add_runtime_dependency 'mini-cli', '>= 0.4.0'
         | 
| 26 | 
            +
              spec.add_development_dependency 'bundler'
         | 
| 27 | 
            +
              spec.add_development_dependency 'rake'
         | 
| 28 28 |  | 
| 29 | 
            -
              spec.require_paths = %w[lib]
         | 
| 30 29 | 
             
              spec.bindir = 'bin'
         | 
| 31 | 
            -
              spec.executables =
         | 
| 32 | 
            -
                Dir
         | 
| 33 | 
            -
                .glob(File.expand_path('../bin/*', __FILE__))
         | 
| 34 | 
            -
                .map!{ |fn| File.basename(fn) }
         | 
| 35 | 
            -
             | 
| 36 | 
            -
              all_files = %x(git ls-files -z).split(0.chr)
         | 
| 37 | 
            -
              spec.test_files = all_files.grep(%r{^(spec|test)/})
         | 
| 38 | 
            -
              spec.files = all_files - spec.test_files
         | 
| 30 | 
            +
              spec.executables = %w[pxf pxf-info]
         | 
| 39 31 |  | 
| 32 | 
            +
              spec.files = Dir.chdir(__dir__) { `git ls-files -z`.split(0.chr) }
         | 
| 40 33 | 
             
              spec.extra_rdoc_files = %w[README.md]
         | 
| 41 34 | 
             
            end
         |