extract-curves 0.1.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.
Files changed (172) hide show
  1. data/Changelog +21 -0
  2. data/bin/ec_rect2polar +22 -0
  3. data/bin/ec_rect2polar.rb +22 -0
  4. data/bin/ec_rev_lines +5 -0
  5. data/bin/ec_rev_lines.rb +5 -0
  6. data/bin/ec_sph_area +30 -0
  7. data/bin/ec_sph_area.rb +30 -0
  8. data/bin/extract_curves +1670 -0
  9. data/bin/extract_curves.rb +1670 -0
  10. data/ruby_ext/pav/cstr.c +82 -0
  11. data/ruby_ext/pav/cstr.h +17 -0
  12. data/ruby_ext/pav/extconf.rb +22 -0
  13. data/ruby_ext/pav/pav.c +162 -0
  14. data/ruby_ext/pav/pgtk.c +40 -0
  15. data/ruby_ext/pav/pgtk.h +14 -0
  16. data/ruby_ext/pav/pix.c +806 -0
  17. data/ruby_ext/pav/pix.h +236 -0
  18. data/ruby_ext/pav/t.rb +35 -0
  19. data/ruby_ext/pav/t1.rb +35 -0
  20. data/ruby_libs/pav/attr_cache.rb +211 -0
  21. data/ruby_libs/pav/attr_cache.t1.rb +32 -0
  22. data/ruby_libs/pav/cache.rb +31 -0
  23. data/ruby_libs/pav/collection/std.rb +58 -0
  24. data/ruby_libs/pav/dbg_log.rb +458 -0
  25. data/ruby_libs/pav/floatsio.rb +53 -0
  26. data/ruby_libs/pav/generator_cache.rb +165 -0
  27. data/ruby_libs/pav/graph/node.rb +602 -0
  28. data/ruby_libs/pav/graph/node_grp.rb +865 -0
  29. data/ruby_libs/pav/gtk.rb +6 -0
  30. data/ruby_libs/pav/gtk/button.rb +118 -0
  31. data/ruby_libs/pav/gtk/dialog.rb +29 -0
  32. data/ruby_libs/pav/gtk/guiobj.rb +772 -0
  33. data/ruby_libs/pav/gtk/icons.rb +124 -0
  34. data/ruby_libs/pav/gtk/rulers.rb +264 -0
  35. data/ruby_libs/pav/gtk/toolbar.rb +189 -0
  36. data/ruby_libs/pav/guiobj.rb +2 -0
  37. data/ruby_libs/pav/guiobj/info_asm.rb +41 -0
  38. data/ruby_libs/pav/guiobj/method.rb +211 -0
  39. data/ruby_libs/pav/guiobj/obj.rb +134 -0
  40. data/ruby_libs/pav/guiobj/signals.rb +9 -0
  41. data/ruby_libs/pav/heap.rb +54 -0
  42. data/ruby_libs/pav/icons/alt_handle.xcf +0 -0
  43. data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
  44. data/ruby_libs/pav/icons/alt_handle_hover.xcf +0 -0
  45. data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
  46. data/ruby_libs/pav/icons/alt_handle_pressed.xcf +0 -0
  47. data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
  48. data/ruby_libs/pav/icons/blob.gif +0 -0
  49. data/ruby_libs/pav/icons/clover_base.xcf +0 -0
  50. data/ruby_libs/pav/icons/contour.gif +0 -0
  51. data/ruby_libs/pav/icons/contour.xcf +0 -0
  52. data/ruby_libs/pav/icons/contour_carpet.gif +0 -0
  53. data/ruby_libs/pav/icons/contour_carpet.xcf +0 -0
  54. data/ruby_libs/pav/icons/curve.gif +0 -0
  55. data/ruby_libs/pav/icons/curve.xcf +0 -0
  56. data/ruby_libs/pav/icons/curve_carpet.gif +0 -0
  57. data/ruby_libs/pav/icons/curve_carpet.xcf +0 -0
  58. data/ruby_libs/pav/icons/expand_base.xcf +0 -0
  59. data/ruby_libs/pav/icons/expand_closed.xpm +1791 -0
  60. data/ruby_libs/pav/icons/expand_closed_hover.xpm +1775 -0
  61. data/ruby_libs/pav/icons/expand_open.xpm +1788 -0
  62. data/ruby_libs/pav/icons/expand_open_hover.xpm +1752 -0
  63. data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  64. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  65. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.xcf +0 -0
  66. data/ruby_libs/pav/icons/extract_curves/trace_mark.xcf +0 -0
  67. data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
  68. data/ruby_libs/pav/icons/handle.xcf +0 -0
  69. data/ruby_libs/pav/icons/handle.xpm +213 -0
  70. data/ruby_libs/pav/icons/loop.gif +0 -0
  71. data/ruby_libs/pav/icons/loop.xcf +0 -0
  72. data/ruby_libs/pav/icons/loop_carpet.gif +0 -0
  73. data/ruby_libs/pav/icons/loop_carpet.xcf +0 -0
  74. data/ruby_libs/pav/icons/next.xpm +29 -0
  75. data/ruby_libs/pav/icons/next_hover.xpm +315 -0
  76. data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
  77. data/ruby_libs/pav/icons/prev.xpm +29 -0
  78. data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
  79. data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
  80. data/ruby_libs/pav/icons/shaved-core.gif +0 -0
  81. data/ruby_libs/pav/icons/vnext.xpm +29 -0
  82. data/ruby_libs/pav/icons/vprev.xpm +29 -0
  83. data/ruby_libs/pav/numeric/ext.rb +21 -0
  84. data/ruby_libs/pav/patterns/hsep.gif +0 -0
  85. data/ruby_libs/pav/patterns/tnode.gif +0 -0
  86. data/ruby_libs/pav/patterns/tnode_w_link.gif +0 -0
  87. data/ruby_libs/pav/patterns/vlink.gif +0 -0
  88. data/ruby_libs/pav/patterns/vsep.gif +0 -0
  89. data/ruby_libs/pav/patterns/yg_hrope.xpm +492 -0
  90. data/ruby_libs/pav/patterns/yg_hrope_thick.xpm +1904 -0
  91. data/ruby_libs/pav/patterns/yg_hrope_thin.xpm +130 -0
  92. data/ruby_libs/pav/patterns/yg_tnode.xpm +180 -0
  93. data/ruby_libs/pav/patterns/yg_tnode_thick.xpm +615 -0
  94. data/ruby_libs/pav/patterns/yg_tnode_thin.xpm +55 -0
  95. data/ruby_libs/pav/patterns/yg_tnode_w_link.xpm +190 -0
  96. data/ruby_libs/pav/patterns/yg_tnode_w_link_thick.xpm +676 -0
  97. data/ruby_libs/pav/patterns/yg_tnode_w_link_thin.xpm +62 -0
  98. data/ruby_libs/pav/patterns/yg_vrope.xpm +563 -0
  99. data/ruby_libs/pav/patterns/yg_vrope_thick.xpm +2047 -0
  100. data/ruby_libs/pav/patterns/yg_vrope_thin.xpm +166 -0
  101. data/ruby_libs/pav/pav_find.rb +90 -0
  102. data/ruby_libs/pav/pix.rb +402 -0
  103. data/ruby_libs/pav/pix/aapix.rb +378 -0
  104. data/ruby_libs/pav/pix/blob.rb +678 -0
  105. data/ruby_libs/pav/pix/circle.rb +73 -0
  106. data/ruby_libs/pav/pix/contour.rb +676 -0
  107. data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
  108. data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
  109. data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
  110. data/ruby_libs/pav/pix/contour/situations.rb +21 -0
  111. data/ruby_libs/pav/pix/curve.rb +1544 -0
  112. data/ruby_libs/pav/pix/img_obj.rb +865 -0
  113. data/ruby_libs/pav/pix/node.rb +159 -0
  114. data/ruby_libs/pav/pix/shaved_core.rb +697 -0
  115. data/ruby_libs/pav/pix/subpix.rb +212 -0
  116. data/ruby_libs/pav/rand_accessible.rb +16 -0
  117. data/ruby_libs/pav/rangeset.rb +63 -0
  118. data/ruby_libs/pav/search.rb +210 -0
  119. data/ruby_libs/pav/set.rb +130 -0
  120. data/ruby_libs/pav/string/bits.rb +523 -0
  121. data/ruby_libs/pav/string/ext.rb +58 -0
  122. data/ruby_libs/pav/string/observable.rb +155 -0
  123. data/ruby_libs/pav/string/text.rb +79 -0
  124. data/ruby_libs/pav/string/words.rb +42 -0
  125. data/ruby_libs/pav/sub_arr.rb +56 -0
  126. data/ruby_libs/pav/traced_obj.rb +79 -0
  127. data/web/index.html +280 -0
  128. data/web/media/icons/alt_handle.xcf +0 -0
  129. data/web/media/icons/alt_handle.xpm +3832 -0
  130. data/web/media/icons/alt_handle_hover.xcf +0 -0
  131. data/web/media/icons/alt_handle_hover.xpm +3368 -0
  132. data/web/media/icons/alt_handle_pressed.xcf +0 -0
  133. data/web/media/icons/alt_handle_pressed.xpm +3828 -0
  134. data/web/media/icons/blob.gif +0 -0
  135. data/web/media/icons/clover_base.xcf +0 -0
  136. data/web/media/icons/contour.gif +0 -0
  137. data/web/media/icons/contour.xcf +0 -0
  138. data/web/media/icons/contour_carpet.gif +0 -0
  139. data/web/media/icons/contour_carpet.xcf +0 -0
  140. data/web/media/icons/curve.gif +0 -0
  141. data/web/media/icons/curve.xcf +0 -0
  142. data/web/media/icons/curve_carpet.gif +0 -0
  143. data/web/media/icons/curve_carpet.xcf +0 -0
  144. data/web/media/icons/expand_base.xcf +0 -0
  145. data/web/media/icons/expand_closed.xpm +1791 -0
  146. data/web/media/icons/expand_closed_hover.xpm +1775 -0
  147. data/web/media/icons/expand_open.xpm +1788 -0
  148. data/web/media/icons/expand_open_hover.xpm +1752 -0
  149. data/web/media/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  150. data/web/media/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  151. data/web/media/icons/extract_curves/extract_curves-logo-rgb.xcf +0 -0
  152. data/web/media/icons/extract_curves/trace_mark.xcf +0 -0
  153. data/web/media/icons/extract_curves/trace_mark.xpm +38 -0
  154. data/web/media/icons/handle.xcf +0 -0
  155. data/web/media/icons/handle.xpm +213 -0
  156. data/web/media/icons/loop.gif +0 -0
  157. data/web/media/icons/loop.xcf +0 -0
  158. data/web/media/icons/loop_carpet.gif +0 -0
  159. data/web/media/icons/loop_carpet.xcf +0 -0
  160. data/web/media/icons/next.xpm +29 -0
  161. data/web/media/icons/next_hover.xpm +315 -0
  162. data/web/media/icons/next_pressed.xpm +144 -0
  163. data/web/media/icons/prev.xpm +29 -0
  164. data/web/media/icons/prev_hover.xpm +315 -0
  165. data/web/media/icons/prev_pressed.xpm +144 -0
  166. data/web/media/icons/shaved-core.gif +0 -0
  167. data/web/media/icons/vnext.xpm +29 -0
  168. data/web/media/icons/vprev.xpm +29 -0
  169. data/web/media/title.jpeg +0 -0
  170. data/web/media/title.xcf +0 -0
  171. data/web/stylesheets/default.css +20 -0
  172. metadata +229 -0
@@ -0,0 +1,130 @@
1
+ require 'set'
2
+ require 'pav/search'
3
+
4
+ class SortedArrSet
5
+ attr_reader :arr, :comparator
6
+
7
+ def initialize(arr, &comparator)
8
+ @arr = arr
9
+ @comparator = comparator
10
+ end
11
+
12
+ def include?(m)
13
+ PSearch.bsearch(@arr, m, &@comparator) >= 0
14
+ end
15
+
16
+ alias_method :member?, :include?
17
+
18
+ def method_missing(id, *args, &block)
19
+ @arr.send(id, *args, &block)
20
+ end
21
+ end
22
+
23
+ class ObjIdSet < Hash
24
+ def initialize
25
+ super(0)
26
+ end
27
+
28
+ def add(obj)
29
+ self[obj.object_id] += 1
30
+ self
31
+ end
32
+
33
+ alias_method :<<, :add
34
+
35
+ def push(obj)
36
+ self[obj.object_id] += 1
37
+ obj
38
+ end
39
+
40
+ def pop_obj(obj)
41
+ if (left = (self[obj.object_id] -= 1)) < 1
42
+ warn("#{self.class.name}.pop_obj: Obj. not in set: #{
43
+ obj}!") if left < 0
44
+ self.delete(obj)
45
+ end
46
+ end
47
+
48
+ def delete(obj)
49
+ super(obj.object_id)
50
+ end
51
+
52
+ def member?(obj)
53
+ super(obj.object_id)
54
+ end
55
+
56
+ alias_method :include?, :member?
57
+
58
+ def each
59
+ self.each_key { |oid| yield(ObjectSpace._id2ref(oid)) }
60
+ end
61
+
62
+ alias_method :each_value, :each
63
+
64
+ def to_a
65
+ res = []
66
+ self.each { |obj| res << obj }
67
+ res
68
+ end
69
+
70
+ def first
71
+ self.each { |res| return res }
72
+ nil
73
+ end
74
+ end
75
+
76
+ class ObjIdSetWithArr < Array
77
+ attr_reader :set
78
+
79
+ def initialize
80
+ @set = Hash.new(0)
81
+ super()
82
+ end
83
+
84
+ def <<(obj)
85
+ @set[obj.object_id] += 1
86
+ super(obj)
87
+ self
88
+ end
89
+
90
+ alias_method :add, :<<
91
+
92
+ def push(obj)
93
+ @set[obj.object_id] += 1
94
+ super(obj)
95
+ end
96
+
97
+ def pop
98
+ if self.empty?
99
+ return nil
100
+ else
101
+ @set[(res=super).object_id] -= 1
102
+ res
103
+ end
104
+ end
105
+
106
+ def member?(obj)
107
+ @set.member?(obj.object_id)
108
+ end
109
+
110
+ alias_method :include?, :member?
111
+
112
+ def pop_obj(obj)
113
+ if (left = (@set[obj.object_id] -= 1)) < 1
114
+ @set.delete(obj.object_id)
115
+ if left < 0
116
+ warn("#{self.class.name}.pop_obj: Obj. not in set: #{
117
+ obj}!")
118
+ return
119
+ end
120
+ end
121
+ i = 0
122
+ while i < self.length
123
+ if obj.equal?(self.at(i))
124
+ self.delete_at(i)
125
+ return
126
+ end
127
+ i += 1
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,523 @@
1
+ require 'sync'
2
+ require 'pav/string/observable'
3
+
4
+ class BitArr
5
+ attr_reader :str, :length
6
+
7
+ include Sync_m
8
+ include Enumerable
9
+ include Comparable
10
+
11
+ alias_method :__ba_sync_init__, :initialize
12
+ protected :__ba_sync_init__
13
+
14
+ def initialize(bits="", length=nil)
15
+ if bits.kind_of? String
16
+ @length = length
17
+ if !length
18
+ @str = bits
19
+ @length = @str.length * 8
20
+ else
21
+ str_len = @length/8 + (@length%8 == 0 ? 0 : 1)
22
+ @str = bits[0, str_len]
23
+ @str << "\0" * (str_len - @str.length) if
24
+ str_len > @str.length
25
+ @str[str_len-1] &= (0xff >> 8 - length % 8) if
26
+ length % 8 != 0
27
+ end
28
+ self.__ba_sync_init__()
29
+ elsif bits.kind_of? Array
30
+ @str = "\0" * ((bits.length/8)+(bits.length%8==0 ? 0:1))
31
+ (@length = bits.length).times { |i|
32
+ if bits[i] != 0
33
+ @str[i/8] = @str[i/8] | (1 << i%8)
34
+ end
35
+ }
36
+ self.__ba_sync_init__()
37
+ elsif bits.kind_of? BitArr
38
+ initialize(bits.str, length)
39
+ elsif bits.kind_of? Integer
40
+ @str = ""
41
+ while bits > 0xff
42
+ @str << bits & 0xff
43
+ bits >>= 8
44
+ end
45
+ @length = @str.length * 8
46
+ if bits > 0
47
+ @str << bits
48
+ while bits > 0
49
+ @length += 1
50
+ bits >>= 1
51
+ end
52
+ end
53
+ self.__ba_sync_init__()
54
+ else
55
+ raise ArgumentError,
56
+ "Invalid bits argument: #{bits.inspect}"
57
+ end
58
+ end
59
+
60
+ def push(bit)
61
+ self.synchronize {
62
+ bit = bit & 1
63
+ if (ofs = @length % 8) == 0
64
+ @str << bit
65
+ else
66
+ @str[-1] = @str[-1] | (bit << ofs)
67
+ end
68
+ @length = @length + 1
69
+ self
70
+ }
71
+ end
72
+
73
+ alias_method :<<, :push
74
+
75
+ def delete_at(idx)
76
+ self.synchronize {
77
+ idx = -idx-1 if idx < 0
78
+ return nil if idx >= @length
79
+ byte_i, ofs = idx / 8, idx % 8
80
+ res = @str[byte_i][ofs]
81
+ @str[byte_i] = ( (@str[byte_i] & (0xff >> 8-ofs)) << 1 ) |
82
+ (@str[byte_i] & ((0xff << ofs+1) & 0xff))
83
+ for i in byte_i...@str.length-1
84
+ @str[i] = @str[i] >> 1 | ((@str[i+1] & 1) << 7)
85
+ end
86
+ if (@length = @length - 1) % 8 == 0
87
+ @str[-1] = ""
88
+ else
89
+ @str[-1] = @str[-1] >> 1
90
+ end
91
+ res
92
+ }
93
+ end
94
+
95
+ def slice!(i, len=nil)
96
+ self.synchronize {
97
+ if i.kind_of? Range
98
+ i, len = [i.first, i.last].min, (i.last - i.first).abs
99
+ len = len + 1 if !i.exclude_end?
100
+ elsif len == nil
101
+ return delete_at(i)
102
+ end
103
+ i = @length+i if i < 0
104
+ return nil if i >= @length || i < 0 || len < 1
105
+ res = self[i, len]
106
+ len = @length - i if i + len > @length
107
+ byte_i, ofs = i / 8, i % 8
108
+ if len <= 8 - ofs
109
+ @str[byte_i] = ((@str[byte_i] & (0xff >> 8-ofs))<<len) |
110
+ (@str[byte_i] & ((0xff << ofs+len) & 0xff))
111
+ ofs = 8 - len
112
+ else
113
+ del_algn_bits_cnt = len - 8 + ofs
114
+ @str.slice!(byte_i+1, del_algn_bits_cnt / 8)
115
+ if del_algn_bits_cnt % 8 > 0
116
+ del_algn_bits_cnt = del_algn_bits_cnt % 8
117
+ dst_mask = (0xff >> 8-ofs)
118
+ push_bits = @str[byte_i+1] >> del_algn_bits_cnt
119
+ @str[byte_i] = (@str[byte_i] & dst_mask) |
120
+ ((push_bits << ofs) & 0xff)
121
+ if ofs > del_algn_bits_cnt
122
+ byte_i = byte_i + 1
123
+ @str[byte_i] = push_bits >> 8-ofs
124
+ else
125
+ @str[byte_i+1] = ""
126
+ end
127
+ ofs = (ofs + 8-del_algn_bits_cnt) % 8
128
+ @str[byte_i] = @str[byte_i] << 8-ofs
129
+ end
130
+ end
131
+ for i in byte_i...@str.length-1
132
+ @str[i] = (@str[i] >> 8-ofs) |
133
+ ((@str[i+1] << ofs) & 0xff)
134
+ end
135
+ if @length % 8 <= 8-ofs
136
+ @str[-1] = ""
137
+ else
138
+ @str[-1] = @str[-1] >> 8-ofs
139
+ end
140
+ @length = @length - len
141
+ res
142
+ }
143
+ end
144
+
145
+ def at(i)
146
+ i = @length+i if i < 0
147
+ return 0 if i >= @length || i < 0
148
+ @str[i/8][i%8]
149
+ end
150
+
151
+ def [](i, len=nil)
152
+ self.synchronize {
153
+ if !len
154
+ if i.kind_of?(Range)
155
+ if i.last >= i.first
156
+ return self[i.first, i.last - i.first +
157
+ (i.exclude_end? ? 0 : 1)]
158
+ else
159
+ is = i
160
+ end
161
+ elsif i.kind_of?(Array)
162
+ is = i
163
+ elsif i.kind_of?(Integer)
164
+ i = @length+i if i < 0
165
+ return 0 if i >= @length || i < 0
166
+ return @str[i / 8][i % 8]
167
+ else
168
+ raise ArgumentError, "Wrong single argument"
169
+ end
170
+ else
171
+ i = @length+i if i < 0
172
+ return nil if len < 0 || i >= @length || i < 0
173
+ return BitArr.new if len == 0
174
+ len = @length - i if i + len > @length
175
+ byte_i, ofs = i / 8, i % 8
176
+ if ofs == 0
177
+ res = @str[byte_i, len/8]
178
+ if len % 8 > 0
179
+ res << @str[byte_i + len/8]
180
+ res[-1] = res[-1] & (0xff >> (8-len%8))
181
+ end
182
+ return BitArr.new(res, len)
183
+ end
184
+ mask,res = 0xff>>8-ofs, "\0"*(len/8 + (len%8==0 ? 0:1))
185
+ i = -1
186
+ (len/8).times { |i|
187
+ res[i] = (@str[byte_i] >> ofs) |
188
+ ((@str[byte_i+1] & mask) << (8 - ofs))
189
+ byte_i = byte_i + 1
190
+ }
191
+ if len % 8 != 0
192
+ res[i+1] = (@str[byte_i] >> ofs)
193
+ if ofs + len % 8 > 8
194
+ res[i+1] = res[i+1] |
195
+ ((@str[byte_i+1] & mask) << (8 - ofs))
196
+ end
197
+ res[i+1] = res[i+1] & (0xff >> 8 - len % 8)
198
+ end
199
+ return BitArr.new(res, len)
200
+ end
201
+ res = BitArr.new
202
+ is.each { |i|
203
+ i = @length+i if i < 0
204
+ if i >= @length || i < 0
205
+ res.push(0)
206
+ else
207
+ res.push(@str[i / 8][i % 8])
208
+ end
209
+ }
210
+ res
211
+ }
212
+ end
213
+
214
+ def []=(i, rval, len=nil)
215
+ self.synchronize {
216
+ rval, len = len, rval if len
217
+ rval = BitArr.new(rval) if rval.kind_of?(Array) ||
218
+ rval.kind_of?(String)
219
+ if !len
220
+ if i.kind_of? Range
221
+ return self[[i.first,i.last].min,
222
+ (i.last - i.first).abs +
223
+ (i.exclude_end? ? 0 : 1)] = rval
224
+ elsif i.kind_of? Array
225
+ is = i
226
+ elsif i.kind_of? Integer
227
+ if rval.kind_of?(BitArr)
228
+ return self.delete_at(i) if rval.empty?
229
+ return self[i,1] = rval
230
+ end
231
+ if rval == nil
232
+ return self.delete_at(i)
233
+ else
234
+ @str << "\0"*(i/8-@str.length+1) if
235
+ i/8 >= @str.length
236
+ @length = i + 1 if i+1 > @length
237
+ if rval == 0
238
+ return @str[i/8] = @str[i/8] &
239
+ ( (1 << (i%8)) ^ 0xff )
240
+ else
241
+ return @str[i/8] = @str[i/8] |
242
+ (1 << (i%8))
243
+ end
244
+ end
245
+ else
246
+ raise ArgumentError, "Invalid single argument"
247
+ end
248
+ else
249
+ len = 0 if len < 0
250
+ return self.slice!(i, len) if rval == nil
251
+ rval = BitArr.new(rval) if rval.kind_of? Integer
252
+ if len > rval.length
253
+ self.slice!(i + rval.length, len - rval.length)
254
+ len = rval.length
255
+ elsif len < rval.length
256
+ j = i + len
257
+ ins_len, byte_i, ofs = rval.length-len, j/8, j%8
258
+ if ofs + ins_len <= 8
259
+ shl_cnt = ins_len
260
+ else
261
+ shl_cnt = (ins_len - 8 + ofs) % 8
262
+ end
263
+ @str << "\0" if @length % 8 + shl_cnt > 8
264
+ (@str.length - 1).downto(byte_i + 1) { |k|
265
+ @str[k] = ((@str[k]<<shl_cnt) & 0xff) |
266
+ (@str[k-1] >> 8-shl_cnt)
267
+ }
268
+ if ofs + ins_len <= 8
269
+ @str[byte_i] = (@str[byte_i] &
270
+ (0xff >> 8-ofs)) |
271
+ (((@str[byte_i] &
272
+ ((0xff << ofs) & 0xff)) << ins_len) &
273
+ 0xff)
274
+ else
275
+ @str[byte_i] = @str[byte_i] &
276
+ (0xff >> 8-ofs)
277
+ @str[byte_i, 0] = "\0" *
278
+ ((ins_len - 8 + ofs) / 8)
279
+ end
280
+ @length = @length + ins_len
281
+ end
282
+ byte_i, ofs = (i+len-1) / 8, (i+len-1) % 8
283
+ if i + len > @length
284
+ @str << "\0" * (byte_i + 1 - @str.length)
285
+ @length = i + len
286
+ end
287
+ if byte_i == i / 8
288
+ @str[byte_i] = (@str[byte_i] &
289
+ ((0xff << ofs) & 0xff)) |
290
+ (@str[byte_i] & (0xff >> 8 - i % 8)) |
291
+ (rval.to_i << i % 8)
292
+ else
293
+ @str[byte_i] = (@str[byte_i] &
294
+ ((0xff << ofs) & 0xff)) |
295
+ rval[-8+ofs-1, ofs].str[0]
296
+ byte_i, ofs = i / 8, i % 8
297
+ @str[byte_i] = (@str[byte_i] & (0xff>>8-ofs)) |
298
+ (rval[0..8-ofs].to_i << ofs)
299
+ ofs = 8 - ofs
300
+ bytes_cnt = (i + rval.length) / 8 - byte_i - 1
301
+ @str[i, bytes_cnt] = rval[ofs, 8 * bytes_cnt].
302
+ str if bytes_cnt > 0
303
+ end
304
+ return
305
+ end
306
+ [is.length, rval.length].min.times { |i|
307
+ self[is[i]] = rval[rval_i]
308
+ }
309
+ if is.length > rval.length
310
+ del_is = (is[rval.length...is.length]).sort!
311
+ prev_i, c = del_is.last, 1
312
+ del_is.reverse_each { |i|
313
+ next if i == prev_i
314
+ if i = prev_i-1
315
+ c = c + 1
316
+ else
317
+ self.slice!(prev_i,c)
318
+ c = 1
319
+ end
320
+ prev_i = i
321
+ }
322
+ self.slice!(prev_i, c)
323
+ end
324
+ }
325
+ end
326
+
327
+ def each
328
+ self.synchronize {
329
+ @str.each_byte { |b|
330
+ 8.times { |i| yield b[i] }
331
+ }
332
+ }
333
+ end
334
+
335
+ def empty?
336
+ @length == 0
337
+ end
338
+
339
+ def to_s
340
+ self.synchronize {
341
+ @str.unpack("b#{@length}")[0]
342
+ }
343
+ end
344
+
345
+ def to_i
346
+ self.synchronize {
347
+ res = 0
348
+ shl_cnt = 0
349
+ @str.each_byte { |b|
350
+ res = res | (b << shl_cnt)
351
+ shl_cnt = shl_cnt + 8
352
+ }
353
+ res
354
+ }
355
+ end
356
+
357
+ def <=>(other)
358
+ if other.kind_of?(BitArr)
359
+ return @length <=> other.length if @length!=other.length
360
+ 0.upto((@length-1)/8) { |i|
361
+ return leg if (leg=(@str[i]<=>other.str[i]))!=0
362
+ }
363
+ return 0
364
+ elsif other.kind_of?(String)
365
+ return (@length/8) <=> other.length if
366
+ @length/8 != other.length
367
+ for i in 0.upto((@length-1)/8)
368
+ return leg if (leg = (@str[i] <=> other[i]))!=0
369
+ end
370
+ return 0
371
+ elsif other.kind_of?(Array)
372
+ return @length <=> other.length if @length!=other.length
373
+ for i in 0..@length
374
+ return leg if (leg = (self[i]<=>other[i])) != 0
375
+ end
376
+ return 0
377
+ elsif other.kind_of?(Integer)
378
+ return self.to_i <=> other
379
+ end
380
+ end
381
+ end
382
+
383
+ class IntBitPlaneArr
384
+ attr_reader :length, :bit_planes_cnt, :bit_arr
385
+
386
+ def initialize(bits="", length=nil, bit_planes_cnt=nil)
387
+ @bit_arr = BitArr.new(bits, length)
388
+ if bit_planes_cnt
389
+ @bit_planes_cnt = bit_planes_cnt
390
+ @length = @bit_arr.length * @bit_planes_cnt
391
+ else
392
+ if (@length = @bit_arr.length) == 0
393
+ @bit_planes_cnt = 0
394
+ else
395
+ @bit_planes_cnt = 1
396
+ end
397
+ end
398
+ end
399
+
400
+ def at(i)
401
+ i = @length+i if i < 0
402
+ return nil if i >= @length || i < 0
403
+ lm = 0
404
+ bp_start = 0
405
+ for p in 0...@bit_planes_cnt
406
+ lm |= (@bit_arr.at(bp_start + i) << p)
407
+ bp_start += @length
408
+ end
409
+ lm
410
+ end
411
+
412
+ def at?(i, val)
413
+ i = @length+i if i < 0
414
+ return val == nil if i >= @length || i < 0
415
+ bp_start = 0
416
+ for p in 0...@bit_planes_cnt
417
+ return false if (val & 1) != @bit_arr[bp_start + i]
418
+ bp_start += @length
419
+ val >>= 1
420
+ end
421
+ return val == 0
422
+ end
423
+
424
+ def bit_planes_cnt=(val)
425
+ @bit_planes_cnt = val
426
+ if val < @bit_planes_cnt
427
+ @bit_arr[@length*@bit_planes_cnt...@bit_arr.length]=nil
428
+ end
429
+ end
430
+
431
+ def [](i, len=nil)
432
+ if len
433
+ is = i...(i+len)
434
+ else
435
+ if i.kind_of?(Range) || i.kind_of?(Array)
436
+ is = i
437
+ elsif i.kind_of?(Integer)
438
+ return self.at(i)
439
+ else
440
+ raise ArgumentError,
441
+ "Invalid index: #{i.inspect}"
442
+ end
443
+ end
444
+ is.collect { |i| self.at(i) }
445
+ end
446
+
447
+ def []=(i, *args)
448
+ if args.length == 1
449
+ rval = args[0]
450
+ raise NotImplementError, "rval=nil" if !rval
451
+ raise NotImplementError, "i>length" if i>@length
452
+ rval = [rval] if rval.kind_of?(Integer)
453
+ if i.kind_of?(Range) || i.kind_of?(Array)
454
+ is = i
455
+ elsif i.kind_of?(Integer)
456
+ i = @length+i if i < 0
457
+ bp_start = 0
458
+ for p in 0...@bit_planes_cnt
459
+ bits = []
460
+ rval.each_with_index { |v, idx|
461
+ bits << (v&1)
462
+ rval[idx] >>= 1
463
+ }
464
+ @bit_arr[bp_start+i] = bits
465
+ bp_start += @length
466
+ end
467
+ not_all_0 = false
468
+ for v in rval
469
+ if v != 0
470
+ not_all_0 = true
471
+ break
472
+ end
473
+ end
474
+ while not_all_0
475
+ not_all_0 = false
476
+ bits = []
477
+ rval.each_with_index { |v, idx|
478
+ bits << (v&1)
479
+ rval[idx] >>= 1
480
+ not_all_0=true if rval[idx]!= 0
481
+ }
482
+ @bit_arr[bp_start+i] = bits
483
+ bp_start += @length
484
+ @bit_planes_cnt += 1
485
+ end
486
+ return
487
+ else
488
+ raise ArgumentError,
489
+ "Invalid index: #{i.inspect}"
490
+ end
491
+ elsif args.length == 2
492
+ len, rval = *args
493
+ is = i...(i+len)
494
+ else
495
+ raise ArgumentError,
496
+ "Invalid number of arguments: #{args.inspect}"
497
+ end
498
+ is.each_with_index { |i, idx|
499
+ self[i] = rval[idx]
500
+ }
501
+ end
502
+ end
503
+
504
+ class StringBitsObserver
505
+ def self.update(str, meth, args, block)
506
+ str.kill_bits
507
+ end
508
+ end
509
+
510
+ class String
511
+ def bits
512
+ self.add_observer(StringBitsObserver)
513
+ def bits
514
+ @bits = BitArr.new(self) unless @bits
515
+ @bits
516
+ end
517
+ self.bits
518
+ end
519
+
520
+ def kill_bits
521
+ @bits = nil
522
+ end
523
+ end