.pbm file image render - [vhold] scanline-wiggles? - ghostscript

I'm trying to hack-up a program to read a pbm, pgm, or ppm file and render the image to the postscript output device using the image operator. Just testing the P4 input (binary portable (1-bit) bitmap) path, but my output is all screwy.
%!
% cf. http://en.wikipedia.org/wiki/Netpbm_format
% cf. http://en.wikipedia.org/wiki/Computer_Graphics (origin of image)
% $ wget http://upload.wikimedia.org/wikipedia/commons/thumb/2/23/Spacewar%21-PDP-1-20070512.jpg/320px-Spacewar%21-PDP-1-20070512.jpg
% $ convert 320px-Spacewar%21-PDP-1-20070512.jpg spacewar.pbm
% $ convert 320px-Spacewar%21-PDP-1-20070512.jpg spacewar.pgm
% $ convert 320px-Spacewar%21-PDP-1-20070512.jpg spacewar.ppm
/filename (spacewar.pbm) def
%/filename (spacewar.pgm) def
%/filename (spacewar.ppm) def
/infile filename (r) file def
/readscale false def
% Read magic number
infile token pop <<
/P1 { /depth 1 def
/readscale false def
/filetype /ascii def }
/P2 { /depth 8 def
/readscale true def
/filetype /ascii def }
/P3 { /depth 24 def
/readscale true def
/filetype /ascii def }
/P4 { /depth 1 def
/readscale false def
/filetype /binary def }
/P5 { /depth 8 def
/readscale true def
/filetype /binary def }
/P6 { /depth 24 def
/readscale true def
/filetype /binary def }
>> exch 2 copy known not{pop/default}if get exec
% Read header
/buf 256 string def
infile buf readline pop % line
(1:)print dup ==
(#) { % line (#)
(2a:)print 1 index =
search { % post (#) pre
pop pop pop %
infile buf readline pop % (#) next-line
(#) % next-line (#)
(2b pstack\n)print pstack()=
}{ % line
(2c:)print dup ==
exit
} ifelse
} loop % line
pstack()=
token pop /height exch def
token pop /width exch def
readscale {
token pop /scale exch def
}{
pop
}ifelse
/buf width
depth mul
8 div ceiling cvi
string def
(bufsize: )print buf length =
/pad
buf length 8 mul
width sub def
(pad: )print pad =
/readdata <<
/ascii { % file buf
0 1 width 1 sub { % file buf i
2 index token pop % file buf i
} for
}
/binary { % file buf
readstring pop
%dup length 0 ne { 0 1 index length pad sub getinterval } if
dup == flush
%(bin)= flush
}
>> filetype get def
%errordict/rangecheck{pstack dup length = quit}put
width
height
depth
[ 1 0 0 -1 0 height ]
{
infile buf readdata
} image
showpage
I'm pretty sure the problem is my calculation of the byte-width of a row and the expected padding:
/buf width
depth mul
8 div ceiling cvi
string def
(bufsize: )print buf length =
/pad
buf length 8 mul
width sub def
(pad: )print pad =
But that seems, right, when I step through it. For this 215-bit-wide bitmap, I get 27-bytes per row.
Edit: Removing the "pad"-chop helps. Perhaps I need to add extra padding?
The problem is demonstrated in the output:
Where the similar, but simpler program from the end of this answer renders ok.

Oh, dearie me, that was stupid.
I had these 2 lines flopped:
55 token pop /width exch def
56 token pop /height exch def
It all came to me during that last edit where I typed:
For this 215-bit-wide bitmap, I get 27-bytes per row.
And then I looked again at the identify output. Sure enough, 215 is the height, not the width.

Related

Memory efficient 2D bit storage in Ruby (100M items)

I want to use a large data structure to represent a bit (0 or 1) or boolean (true/false) in Ruby.
In below example code, I am using a 2D array of size 10^4 * 10^4, to store a boolean data.
require 'get_process_mem'
num = 10000
twod = Array.new(num) { Array.new(num, false)}
for i in 0..num-1 do
for j in 0..num-1 do
twod[i][j] = i>j
end
end
mem = GetProcessMem.new
puts mem.inspect
The output shows that it uses ~778 MB.
#<GetProcessMem:0x00000078 #mb=777.93359375 #gb=0.7597007751464844 #kb=796604.0 #bytes=0.815722496e9>
I just tried changing the data type to integer in the code, and memory usage reports the same value.
Updated code:
require 'get_process_mem'
num = 10000
twod = Array.new(num) { Array.new(num, 500)}
for i in 0..num-1 do
for j in 0..num-1 do
twod[i][j] = 1000+i+j
end
end
mem = GetProcessMem.new
puts mem.inspect
Output:
#<GetProcessMem:0x00000078 #mb=777.6015625 #gb=0.7593765258789062 #kb=796264.0 #bytes=0.815374336e9>
I was expecting that boolean array would use less memory than integer array, which does not seem to be the case!
Is there any other optimized way to store bit or boolean values?
You can build a byte array in a FFI:Buffer to get good size/performance
https://rubydoc.info/github/ffi/ffi/FFI/Buffer
and do bit operations on each byte:
#!/usr/bin/env ruby
require 'get_process_mem'
require 'ffi'
BIT_OP = {
get: 1,
set: 2,
clear: 3,
}
class BitStore
attr_accessor :buf, :size
def initialize(shape) # ex [10000,10000] [10,20,30], etc
#shp = shape
#size = 1;
shape.each do | sz |
#size *= sz
end
#size = max(next8(#size)/8, 8) + 1 # min size needed
clear = true
#buf = FFI::Buffer.new(#size,1,clear)
end
def max(x,y)
x > y ? x : y
end
def next8(val)
val % 8 == 0 ? val+8 : ((val / 8).to_i + 1)*8
end
def write_buf_to_file(fname)
fout = File.open(fname, "wb")
fout.write(#buf.get_bytes(0,#size))
fout.close
end
def check_position(coord_arr)
if coord_arr.size != #shp.size
raise "coord_arr size != shape size"
end
coord_arr.each_with_index do | coord, i |
if coord_arr[i] > #shp[i]-1
raise "coord index out of bounds "
end
end
end
def get_position(coord_arr)
position = coord_arr[0]
(1..coord_arr.size-1).each do | i |
position += coord_arr[i] * #shp.reverse[i]
end
return position
end
def bit_op(coord_arr, op)
check_position(coord_arr)
position = get_position(coord_arr)
offset = (position / 8).to_i
bit_pos = (position % 8)
bit_val = 1 << bit_pos
val = #buf.get_string(offset, 1)
numeric_value = val == "" ? 0 : val.unpack("C")[0]
case op
when BIT_OP[:get]
numeric_value = numeric_value & bit_val
return numeric_value > 0 ? "set" : "clear"
when BIT_OP[:set]
numeric_value = numeric_value | bit_val
when BIT_OP[:clear]
numeric_value = numeric_value & (bit_val ^ 0xff)
end
#buf.put_string(offset,[numeric_value].pack("C"))
return ""
end
end
def main
begin
rows = 10000
cols = 10000
b = BitStore.new([rows,cols])
puts "setting [3,0]"
b.bit_op([3,0],BIT_OP[:set])
is_set = b.bit_op([3,0],BIT_OP[:get])
puts is_set
puts "setting [8000,8000]"
b.bit_op([8000,8000],BIT_OP[:set])
is_set = b.bit_op([8000,8000],BIT_OP[:get])
puts is_set
puts "clearing [8000,8000]"
b.bit_op([8000,8000],BIT_OP[:clear])
is_set = b.bit_op([8000,8000],BIT_OP[:get])
puts is_set
mem = GetProcessMem.new
puts mem.inspect
rescue NoMemoryError => e
puts "NoMemoryError"
p e
p e.backtrace.inspect
end
end
main
Memory use is 26MB:
user1#debian10 /home/user1/rubynew > ./pack_testb.rb
setting [3,0]
set
setting [8000,8000]
set
clearing [8000,8000]
clear
#<GetProcessMem:0x000000a0 #mb=26.6953125 #gb=0.02606964111328125 #kb=27336.0 #bytes=0.27992064e8>
The file structure on disk:
b = BitStore.new([7,6])
puts "setting [3,0]"
b.bit_op([3,0],BIT_OP[:set])
is_set = b.bit_op([3,0],BIT_OP[:get])
puts is_set
b.write_buf_to_file("/tmp/the_buf.bin")
system("xxd /tmp/the_buf.bin")
puts "setting [6,5]"
b.bit_op([6,5],BIT_OP[:set])
is_set = b.bit_op([6,5],BIT_OP[:get])
puts is_set
b.write_buf_to_file("/tmp/the_buf.bin")
system("xxd /tmp/the_buf.bin")
setting [3,0]
00000000: 0800 0000 0000 0000 00
setting [6,5]
00000000: 0000 0000 0002 0000 00

Ruby: Iterate the result from method using block

Now I have a ruby like this:
def fizzbuzz(numSize)
result = []
1.upto(numSize) do |num|
if num % 15 == 0
result << "FizzBuzz"
elsif num % 3 == 0
result << "Fizz"
elsif num % 5 == 0
result << "Buzz"
else
result << num.to_s
end
end
result
end
print fizzbuzz(10) {|item| "-#{i1tem}-"}
If I want to print the result like this:
["-1-", "-2-", "-Fizz-", "-4-", "-Buzz-", "-Fizz-", "-7-", "-8-", "-Fizz-", "-Buzz-"]
What can I modify my code in method fizzbuzz if I can not change the code:
print fizzbuzz(10) {|item| "-#{i1tem}-"}
Thanks
That block is being given to your method, but you're not making use of it. That's an easy fix:
def fizzbuzz(numSize, &block)
# ... (existing code) ...
result.map(&block)
end
Where that transforms the result value using map.
Note this requires fixing the typo in your print block which is i1tem not item.
It's also worth noting you should avoid this pattern:
x = [ ]
y.each do |v|
x << f(v)
end
x
That's just a long-winded version of this:
y.map do |v|
f(v)
end
Where when you're transforming on a 1:1 basis from the source just use map.
In your case that reduces the code to this more minimal form that has a lot less repetition:
def fizzbuzz(numSize, &block)
1.upto(numSize).map do |num|
if num % 15 == 0
"FizzBuzz"
elsif num % 3 == 0
"Fizz"
elsif num % 5 == 0
"Buzz"
else
num.to_s
end
end.map(&block)
end

How to create a Minimax algorithm comparing arrays

I'm trying to code a "minimax" algorithm for Tic Tac Toe.
Each node of the tree is of the form [nil/Int, String] where the last element is a nine character string describing the board, and the first is an Integer ranking the node, or nil by default.
If the value is nil, it tries to inherit the appropriate value from child nodes.
This is where I get an error, when comparing an array with an array failed.
class Scene_TicTacToe #Script 2/2
def initialize
#Boardstate as a str from top left corner to bottom right corner.
#boardstate = "---------"
#1 = player, -1 = comp
#active_player = 1
end
def wincheck(boardstate=#boardstate)
#should return -1 for loss, 0 for draw, 1 for win
["OOO","XXX"].each do |f|
for i in 0..2
if (boardstate[i]+boardstate[i+3]+boardstate[i+6]).chr == f || boardstate[(3*i)..(3*i)+2] == f
return f == "OOO" ? 1 : -1
end
end
if (boardstate[0]+boardstate[4]+boardstate[8]).chr == f || (boardstate[2]+boardstate[4]+boardstate[6]).chr == f
return f == "OOO" ? 1 : -1
end
end
return 0
end
def computer_play
#Sets depth,and alpha/beta for pruning, so far so good
depth = 3
alpha = -100
beta = 100
##boardstate starts as "---------"
##active_player: 1=player, -1=computer
play(minimax(#boardstate, depth, alpha, beta, #active_player))
end
def play(array)
#Check actual boardside with parameter boardside to see what move has been
#selected and plays that move
for i in 0...array[1].length
if #boardstate[i] != array[1][i]
#color = array[1][i].chr == "X" ? #ai : #player
##cursor.y = (i / 3) * #side
##cursor.x = (i % 3) * #side
##board.bitmap.fill_rect(#cursor.x,#cursor.y,#side,#side,color)
#boardstate = array[1].dup
end
end
end
def minimax(boardstate, depth, alpha, beta, active_player)
#If bottom node reached, returns [boardstate_score, boardstate]
#wincheck returns 1 if player wins, -1 if computer wins, and 0 otherwise
if depth == 0 or wincheck(boardstate) != 0 or (/-/ =~ boardstate) == nil
return [wincheck(boardstate),boardstate]
end
if active_player == 1 #if player's turn
#Gets an array of all the next possible boardstates and return the one with
#the best eval.
child = generate_child(boardstate, active_player)
child.each do |f| #f = [Int/nil, String]
if f[0] == nil
#This should turn all the nil wincheck values to the best value of children nodes
f[0] = minimax(f[1], depth-1, alpha, beta, -active_player).last[0]
end
alpha = [f[0], alpha].max
if beta <= alpha
break
end
end
return child.sort_by{|c| c[0]}
end
if active_player == -1 #if computer's turn
#Same as above but with worst eval.
child = generate_child(boardstate, active_player)
child.each do |f|
if f[0] == nil
f[0] = minimax(f[1], depth-1, alpha, beta, -active_player).first[0]
end
beta = [f[0], beta].min
if beta <= alpha
break
end
end
#Following line raises "comparison of array with array failed" error :
return child.sort_by{|c| c[0]}
end
end
def generate_child(boardstate, active_player)
#returns boardstate string with one X or O more than current boardstate
#and sets nil as a default wincheck value
c = active_player == 1 ? "O" : "X"
a = []
for i in 0...boardstate.length
if boardstate[i].chr == "-"
s = boardstate.dup
s[i]= c
a << [nil, s]
end
end
return a
end
end
Error: comparison of array with array failed

Ruby find max number w/o running method twice

I want to find the max number without running the function twice
def foo(num)
num * 10
end
def bar
x = 0
for i in 0..5
if foo(i) > x
x = foo(i) # I don't want to run foo a second time
end
end
end
How about
def bar
(1..5).map{|i| foo(i)}.max
end
This will traverse 1 to 5, and max a new enumerable with foo(i) instead of i, then return the max.
If you want the value of x:
define_method(:foo) { |x| x * 10 }
(1..5).max_by { |x| foo(x) }
#=> 5
If you want the value of f(x):
(1..5).map { |x| foo(x) }.max
#=> 50
You can save the result of the function as a variable, so you can use it later without calling the function again.
Applied to your code example, it would look like this:
#...
fooOfI = foo(i)
if fooOfI > x
x = fooOfI
end
#...
Store the result of the method in a local variable.
def bar
x = 0
for i in 0..5
foo_result = foo i
if foo_result > x
x = foo_result
end
end
end
I would do some change in your code :
def foo(num)
num * 10
end
def bar
x = 0
for i in 0..5
_,x = [foo(i),x].sort #or you can write as x = [foo(i),x].max
end
x
end
p bar
# >> 50
Elegant and simple
foo = -> x { x * 10 }
(1..5).map(&foo).max
# => 50
In one iteration (no so elegant but performs better)
def foo(num); num * 10; end;
(1..5).reduce(-1.0/0) { |a, e| f = foo(e); f > a ? f : a }
# => 50

Parser in Ruby: #slice! inside #each_with_index = missing element

Let's say, I want to separate certain combinations of elements from an array. For example
data = %w{ start before rgb 255 255 255 between hex FFFFFF after end }
rgb, hex = [], []
data.each_with_index do |v,i|
p [i,v]
case v.downcase
when 'rgb' then rgb = data.slice! i,4
when 'hex' then hex = data.slice! i,2
end
end
pp [rgb, hex, data]
# >> [0, "start"]
# >> [1, "before"]
# >> [2, "rgb"]
# >> [3, "hex"]
# >> [4, "end"]
# >> [["rgb", "255", "255", "255"],
# >> ["hex", "FFFFFF"],
# >> ["start", "before", "between", "after", "end"]]
The code have done the correct extraction, but it missed the elements just after the extracted sets. So if my data array is
data = %w{ start before rgb 255 255 255 hex FFFFFF after end }
then
pp [rgb, hex, data]
# >> [["rgb", "255", "255", "255"],
# >> [],
# >> ["start", "before", "hex", "FFFFFF", "after", "end"]]
Why does it happen? How to get those missed elements inside #each_with_index? Or may be there is a better solution for this problem assuming that there are much more sets to extract?
The problem is that you are mutating the collection while you are iterating over it. This cannot possibly work. (And in my opinion, it shouldn't. Ruby should raise an exception in this case, instead of silently allowing incorrect behavior. That's what pretty much all other imperative languages do.)
This here is the best I could come up with while still keeping your original style:
require 'pp'
data = %w[start before rgb 255 255 255 hex FFFFFF after end]
rgb_count = hex_count = 0
rgb, hex, rest = data.reduce([[], [], []]) do |acc, el|
acc.tap do |rgb, hex, rest|
next (rgb_count = 3 ; rgb << el) if /rgb/i =~ el
next (rgb_count -= 1 ; rgb << el) if rgb_count > 0
next (hex_count = 1 ; hex << el) if /hex/i =~ el
next (hex_count -= 1 ; hex << el) if hex_count > 0
rest << el
end
end
data.replace(rest)
pp rgb, hex, data
# ["rgb", "255", "255", "255"]
# ["hex", "FFFFFF"]
# ["start", "before", "after", "end"]
However, what you have is a parsing problem and that should really be solved by a parser. A simple hand-rolled parser/state machine will probably be a little bit more code than the above, but it will be so much more readable.
Here's a simple recursive-descent parser that solves your problem:
class ColorParser
def initialize(input)
#input = input.dup
#rgb, #hex, #data = [], [], []
end
def parse
parse_element until #input.empty?
return #rgb, #hex, #data
end
private
def parse_element
parse_color or parse_stop_word
end
def parse_color
parse_rgb or parse_hex
end
def parse_rgb
return unless /rgb/i =~ peek
#rgb << consume
parse_rgb_values
end
I really like recursive-descent parsers because their structure almost perfectly matches the grammar: just keep parsing elements until the input is empty. What is an element? Well, it's a color specification or a stop word. What is a color specification? Well, it's either an RGB color specification or a hex color specification. What is an RGB color specification? Well, it's something that matches the Regexp /rgb/i followed by RGB values. What are RGB values? Well, it's just three numbers …
def parse_rgb_values
3.times do #rgb << consume.to_i end
end
def parse_hex
return unless /hex/i =~ peek
#hex << consume
parse_hex_value
end
def parse_hex_value
#hex << consume.to_i(16)
end
def parse_stop_word
#data << consume unless /rgb|hex/i =~ peek
end
def consume
#input.slice!(0)
end
def peek
#input.first
end
end
Use it like so:
data = %w[start before rgb 255 255 255 hex FFFFFF after end]
rgb, hex, rest = ColorParser.new(data).parse
require 'pp'
pp rgb, hex, rest
# ["rgb", 255, 255, 255]
# ["hex", 16777215]
# ["start", "before", "after", "end"]
For comparison, here's the grammar:
S → element*
element → color | word
color → rgb | hex
rgb → rgb rgbvalues
rgbvalues → token token token
hex → hex hexvalue
hexvalue → token
word → token
Because you are manipulating data in place.
When you hit rgb the next element in the loop would be 255, but you are deleting those elements so now between is in the place that rgb was, so the next element is hex
Something like this may work better for you:
when 'rgb' then rgb = data.slice! i+1,3
when 'hex' then hex = data.slice! i+1,1
Here is a bit nicer solution
data = %w{ start before rgb 255 255 255 hex FFFFFF hex EEEEEE after end }
rest, rgb, hex = [], [], []
until data.empty?
case (key = data.shift).downcase
when 'rgb' then rgb += [key] + data.shift(3)
when 'hex' then hex += [key] + data.shift(1)
else rest << key
end
end
p rgb, hex, rest
# >> ["rgb", "255", "255", "255"]
# >> ["hex", "FFFFFF", "hex", "EEEEEE"]
# >> ["start", "before", "after", "end"]

Resources