qr_reader 0.0.1 → 0.0.2
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/CHANGELOG.md +18 -0
- data/README.md +23 -7
- data/exe/qr_reader +1 -1
- data/lib/qr_reader/formats/jpeg.rb +61 -2
- data/lib/qr_reader/formats/jpeg2000/codestream.rb +447 -0
- data/lib/qr_reader/formats/jpeg2000/container.rb +156 -0
- data/lib/qr_reader/formats/jpeg2000/dwt.rb +607 -0
- data/lib/qr_reader/formats/jpeg2000/tier1.rb +1084 -0
- data/lib/qr_reader/formats/jpeg2000/tile.rb +722 -0
- data/lib/qr_reader/formats/jpeg2000.rb +764 -0
- data/lib/qr_reader/formats/pdf/font_programs.rb +1205 -0
- data/lib/qr_reader/formats/pdf/font_tables.rb +224 -0
- data/lib/qr_reader/formats/pdf/fonts.rb +412 -0
- data/lib/qr_reader/formats/pdf/text.rb +151 -0
- data/lib/qr_reader/formats/pdf/vector.rb +799 -0
- data/lib/qr_reader/formats/pdf.rb +183 -44
- data/lib/qr_reader/formats.rb +13 -4
- data/lib/qr_reader/reader.rb +36 -10
- data/lib/qr_reader/version.rb +1 -1
- data/lib/qr_reader.rb +1 -1
- metadata +15 -4
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QrReader
|
|
4
|
+
module Formats
|
|
5
|
+
module JPEG2000
|
|
6
|
+
# Inverse discrete wavelet transform (ITU-T T.800 Annex F): one
|
|
7
|
+
# synthesis level at a time from the four subbands, by lifting with
|
|
8
|
+
# periodic symmetric extension. The parity of the resolution's first
|
|
9
|
+
# coordinate (+cas+) says whether its first sample is low-pass (0) or
|
|
10
|
+
# high-pass (1), as in the standard's 1D_SR procedure. Rows are
|
|
11
|
+
# transformed first, then columns (like OpenJPEG).
|
|
12
|
+
#
|
|
13
|
+
# Planes are Arrays of row Arrays. Columns are lifted as whole rows
|
|
14
|
+
# (no gathering), and the subbands' rows are reused for the output.
|
|
15
|
+
# The lifting steps are pipelined: step k runs a fixed lag behind
|
|
16
|
+
# step k-1, so one loop applies all of them (2 for 5/3, 4 for 9/7)
|
|
17
|
+
# while the operands are in local variables; only the first and last
|
|
18
|
+
# few samples, where the symmetric extension mirrors, take the
|
|
19
|
+
# generic path.
|
|
20
|
+
#
|
|
21
|
+
# The 9/7 synthesis omits the K / (2/K) scaling of the lifting
|
|
22
|
+
# scheme: the decoder folds those factors into the dequantization
|
|
23
|
+
# step sizes (see DWT.scale_factor), saving a multiplication per
|
|
24
|
+
# sample and level.
|
|
25
|
+
module DWT
|
|
26
|
+
f32 = ->(v) { [v].pack("e").unpack1("e") }
|
|
27
|
+
# 9/7 lifting constants (Table F.4) as the single-precision values
|
|
28
|
+
# OpenJPEG uses, whose output is the reference; OpenJPEG scales
|
|
29
|
+
# high-pass samples by 1.625732422 instead of 2/K and compensates in
|
|
30
|
+
# the step sizes.
|
|
31
|
+
ALPHA = f32.call(-1.586134342)
|
|
32
|
+
BETA = f32.call(-0.052980118)
|
|
33
|
+
GAMMA = f32.call(0.882911075)
|
|
34
|
+
DELTA = f32.call(0.443506852)
|
|
35
|
+
K = f32.call(1.230174105)
|
|
36
|
+
TWO_INV_K = f32.call(1.625732422)
|
|
37
|
+
|
|
38
|
+
# The four 9/7 synthesis steps: t += c * (s[i + o] + s[i + o + 1]).
|
|
39
|
+
COEFFS97 = [-DELTA, -GAMMA, -BETA, -ALPHA].freeze
|
|
40
|
+
|
|
41
|
+
module_function
|
|
42
|
+
|
|
43
|
+
# The factor by which the 9/7 synthesis would scale a subband in
|
|
44
|
+
# one direction: +high+ is whether the band is high-pass in this
|
|
45
|
+
# direction at its own level, +sizes+ the sizes (width or height) of
|
|
46
|
+
# the resolutions from the band's own level up to the decoded one.
|
|
47
|
+
# Levels of size 1 are not scaled (like OpenJPEG).
|
|
48
|
+
def scale_factor(high, sizes)
|
|
49
|
+
factor = 1.0
|
|
50
|
+
sizes.each_with_index do |n, i|
|
|
51
|
+
next if n <= 1
|
|
52
|
+
|
|
53
|
+
factor *= i.zero? && high ? TWO_INV_K : K
|
|
54
|
+
end
|
|
55
|
+
factor
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# One synthesis level: +ll+ (sn_y rows of sn_x), +hl+ (sn_y x
|
|
59
|
+
# dn_x), +lh+ (dn_y x sn_x) and +hh+ (dn_y x dn_x) become the next
|
|
60
|
+
# resolution's +rw+ x +rh+ rows. +cas_x+ / +cas_y+ are the parities
|
|
61
|
+
# of its x0 / y0. Subband rows may be nil: all zero (never written by
|
|
62
|
+
# tier-1). Rows with zero high-pass input take shortcuts (exact: the
|
|
63
|
+
# skipped terms are zero). Consumed subband rows are released.
|
|
64
|
+
def synthesize(ll, hl, lh, hh, rw, rh, sn_x, sn_y, cas_x, cas_y, reversible)
|
|
65
|
+
dn_x = rw - sn_x
|
|
66
|
+
dn_y = rh - sn_y
|
|
67
|
+
zero = reversible ? 0 : 0.0
|
|
68
|
+
perm = interleave_order(sn_x, dn_x, cas_x)
|
|
69
|
+
lows = Array.new(sn_y)
|
|
70
|
+
i = 0
|
|
71
|
+
while i < sn_y
|
|
72
|
+
high = hl[i]
|
|
73
|
+
lows[i] = horizontal(ll[i] || Array.new(sn_x, zero), high || Array.new(dn_x, zero), sn_x, dn_x, cas_x,
|
|
74
|
+
reversible, perm, !high.nil?)
|
|
75
|
+
ll[i] = hl[i] = nil
|
|
76
|
+
i += 1
|
|
77
|
+
end
|
|
78
|
+
highs = Array.new(dn_y)
|
|
79
|
+
zero_rows = Array.new(dn_y, false)
|
|
80
|
+
i = 0
|
|
81
|
+
while i < dn_y
|
|
82
|
+
low = lh[i]
|
|
83
|
+
high = hh[i]
|
|
84
|
+
if low.nil? && high.nil?
|
|
85
|
+
zero_rows[i] = true # stays nil: an all-zero row
|
|
86
|
+
else
|
|
87
|
+
highs[i] = horizontal(low || Array.new(sn_x, zero), high || Array.new(dn_x, zero), sn_x, dn_x, cas_x,
|
|
88
|
+
reversible, perm, !high.nil?)
|
|
89
|
+
lh[i] = hh[i] = nil
|
|
90
|
+
end
|
|
91
|
+
i += 1
|
|
92
|
+
end
|
|
93
|
+
vertical(lows, highs, sn_y, dn_y, rw, cas_y, reversible, zero_rows)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Indices into low + high that give the interleaved row.
|
|
97
|
+
def interleave_order(sn, dn, cas)
|
|
98
|
+
Array.new(sn + dn) do |k|
|
|
99
|
+
if (k + cas).even?
|
|
100
|
+
(k - cas) >> 1
|
|
101
|
+
else
|
|
102
|
+
sn + ((k - 1 + cas) >> 1)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Horizontal synthesis of one row: +low+ (sn samples) and +high+
|
|
108
|
+
# (dn samples) are lifted in place and returned interleaved.
|
|
109
|
+
# +high_nonzero+ false says that +high+ is all zero.
|
|
110
|
+
def horizontal(low, high, sn, dn, cas, reversible, perm, high_nonzero = true)
|
|
111
|
+
n = sn + dn
|
|
112
|
+
if n <= 1
|
|
113
|
+
if cas == 1 && dn == 1
|
|
114
|
+
v = high[0]
|
|
115
|
+
v = v.negative? ? -(-v / 2) : v / 2 if reversible
|
|
116
|
+
return [v]
|
|
117
|
+
end
|
|
118
|
+
return low
|
|
119
|
+
end
|
|
120
|
+
if reversible
|
|
121
|
+
high_nonzero ? lift53(low, high, sn, dn, cas) : predict53_only(low, high, sn, dn, cas)
|
|
122
|
+
else
|
|
123
|
+
lift97(low, high, sn, dn, cas, high_nonzero)
|
|
124
|
+
end
|
|
125
|
+
# Interleaved in place (the row keeps its storage; high is dropped).
|
|
126
|
+
low.replace(low.concat(high).values_at(*perm))
|
|
127
|
+
high.clear # frees its storage now (it would wait for a major GC)
|
|
128
|
+
low
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Lags of the pipelined steps behind step 1 (see the module notes).
|
|
132
|
+
def lags(cas, reversible)
|
|
133
|
+
if reversible
|
|
134
|
+
cas.zero? ? [0, 1] : [0, 0]
|
|
135
|
+
else
|
|
136
|
+
cas.zero? ? [0, 1, 1, 2] : [0, 0, 1, 1]
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# First wavefront after the pipelined interior.
|
|
141
|
+
def interior_end(sn, dn, cas)
|
|
142
|
+
cas.zero? ? [sn, dn].min : [sn, dn - 1].min
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# 9/7 lifting of one row (low and high samples separately). With
|
|
146
|
+
# all-zero high samples step 1 changes nothing and is skipped.
|
|
147
|
+
def lift97(l, h, sn, dn, cas, high_nonzero = true)
|
|
148
|
+
lag = lags(cas, false)
|
|
149
|
+
last = [sn - 1 + lag[2], dn - 1 + lag[3]].max
|
|
150
|
+
ge = interior_end(sn, dn, cas)
|
|
151
|
+
lo = cas.zero? ? -1 : 0
|
|
152
|
+
ho = cas.zero? ? 0 : -1
|
|
153
|
+
g = 0
|
|
154
|
+
while g <= last
|
|
155
|
+
if g >= 2 && g < ge
|
|
156
|
+
if high_nonzero
|
|
157
|
+
cas.zero? ? fused97_cas0(l, h, g, ge) : fused97_cas1(l, h, g, ge)
|
|
158
|
+
else
|
|
159
|
+
cas.zero? ? fused97z_cas0(l, h, g, ge) : fused97z_cas1(l, h, g, ge)
|
|
160
|
+
end
|
|
161
|
+
g = ge
|
|
162
|
+
next
|
|
163
|
+
end
|
|
164
|
+
k = high_nonzero ? 0 : 1
|
|
165
|
+
while k < 4
|
|
166
|
+
i = g - lag[k]
|
|
167
|
+
if k.even?
|
|
168
|
+
step_at(l, h, dn, i, lo, COEFFS97[k]) if i >= 0 && i < sn
|
|
169
|
+
elsif i >= 0 && i < dn
|
|
170
|
+
step_at(h, l, sn, i, ho, COEFFS97[k])
|
|
171
|
+
end
|
|
172
|
+
k += 1
|
|
173
|
+
end
|
|
174
|
+
g += 1
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# t[i] += c * (s[i + o] + s[i + o + 1]), indices mirrored into s.
|
|
179
|
+
def step_at(t, s, ns, i, o, c)
|
|
180
|
+
j = i + o
|
|
181
|
+
j1 = j + 1
|
|
182
|
+
last = ns - 1
|
|
183
|
+
j = 0 if j.negative?
|
|
184
|
+
j = last if j > last
|
|
185
|
+
j1 = last if j1 > last
|
|
186
|
+
t[i] += c * (s[j] + s[j1])
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Wavefronts g...ge of the 9/7 steps for cas 0, operands carried in
|
|
190
|
+
# locals (see the module notes).
|
|
191
|
+
def fused97_cas0(l, h, g, ge)
|
|
192
|
+
c1 = -DELTA
|
|
193
|
+
c2 = -GAMMA
|
|
194
|
+
c3 = -BETA
|
|
195
|
+
c4 = -ALPHA
|
|
196
|
+
hm1 = h[g - 1]
|
|
197
|
+
lm1 = l[g - 1]
|
|
198
|
+
hm2 = h[g - 2]
|
|
199
|
+
lm2 = l[g - 2]
|
|
200
|
+
while g < ge
|
|
201
|
+
hg = h[g]
|
|
202
|
+
a = l[g] + c1 * (hm1 + hg)
|
|
203
|
+
b = hm1 + c2 * (lm1 + a)
|
|
204
|
+
d = lm1 + c3 * (hm2 + b)
|
|
205
|
+
h[g - 2] = hm2 + c4 * (lm2 + d)
|
|
206
|
+
l[g - 1] = d
|
|
207
|
+
lm2 = d
|
|
208
|
+
hm2 = b
|
|
209
|
+
lm1 = a
|
|
210
|
+
hm1 = hg
|
|
211
|
+
g += 1
|
|
212
|
+
end
|
|
213
|
+
l[ge - 1] = lm1
|
|
214
|
+
h[ge - 2] = hm2
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def fused97_cas1(l, h, g, ge)
|
|
218
|
+
c1 = -DELTA
|
|
219
|
+
c2 = -GAMMA
|
|
220
|
+
c3 = -BETA
|
|
221
|
+
c4 = -ALPHA
|
|
222
|
+
hc = h[g]
|
|
223
|
+
lm1 = l[g - 1]
|
|
224
|
+
hm1 = h[g - 1]
|
|
225
|
+
lm2 = l[g - 2]
|
|
226
|
+
while g < ge
|
|
227
|
+
hn = h[g + 1]
|
|
228
|
+
a = l[g] + c1 * (hc + hn)
|
|
229
|
+
b = hc + c2 * (lm1 + a)
|
|
230
|
+
d = lm1 + c3 * (hm1 + b)
|
|
231
|
+
h[g - 1] = hm1 + c4 * (lm2 + d)
|
|
232
|
+
l[g - 1] = d
|
|
233
|
+
lm2 = d
|
|
234
|
+
hm1 = b
|
|
235
|
+
lm1 = a
|
|
236
|
+
hc = hn
|
|
237
|
+
g += 1
|
|
238
|
+
end
|
|
239
|
+
l[ge - 1] = lm1
|
|
240
|
+
h[ge - 1] = hm1
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# fused97_cas0 for all-zero high input (step 1 is the identity).
|
|
244
|
+
def fused97z_cas0(l, h, g, ge)
|
|
245
|
+
c2 = -GAMMA
|
|
246
|
+
c3 = -BETA
|
|
247
|
+
c4 = -ALPHA
|
|
248
|
+
lm1 = l[g - 1]
|
|
249
|
+
hm2 = h[g - 2]
|
|
250
|
+
lm2 = l[g - 2]
|
|
251
|
+
while g < ge
|
|
252
|
+
a = l[g]
|
|
253
|
+
b = c2 * (lm1 + a)
|
|
254
|
+
d = lm1 + c3 * (hm2 + b)
|
|
255
|
+
h[g - 2] = hm2 + c4 * (lm2 + d)
|
|
256
|
+
l[g - 1] = d
|
|
257
|
+
lm2 = d
|
|
258
|
+
hm2 = b
|
|
259
|
+
lm1 = a
|
|
260
|
+
g += 1
|
|
261
|
+
end
|
|
262
|
+
h[ge - 2] = hm2
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def fused97z_cas1(l, h, g, ge)
|
|
266
|
+
c2 = -GAMMA
|
|
267
|
+
c3 = -BETA
|
|
268
|
+
c4 = -ALPHA
|
|
269
|
+
lm1 = l[g - 1]
|
|
270
|
+
hm1 = h[g - 1]
|
|
271
|
+
lm2 = l[g - 2]
|
|
272
|
+
while g < ge
|
|
273
|
+
a = l[g]
|
|
274
|
+
b = c2 * (lm1 + a)
|
|
275
|
+
d = lm1 + c3 * (hm1 + b)
|
|
276
|
+
h[g - 1] = hm1 + c4 * (lm2 + d)
|
|
277
|
+
l[g - 1] = d
|
|
278
|
+
lm2 = d
|
|
279
|
+
hm1 = b
|
|
280
|
+
lm1 = a
|
|
281
|
+
g += 1
|
|
282
|
+
end
|
|
283
|
+
h[ge - 1] = hm1
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# 5/3 synthesis of a row whose high samples are all zero: the update
|
|
287
|
+
# step is the identity, the predict step reads low samples only.
|
|
288
|
+
def predict53_only(l, h, sn, dn, cas)
|
|
289
|
+
last = sn - 1
|
|
290
|
+
i = 0
|
|
291
|
+
if cas.zero?
|
|
292
|
+
while i < dn
|
|
293
|
+
j1 = i + 1
|
|
294
|
+
j1 = last if j1 > last
|
|
295
|
+
h[i] = (l[i] + l[j1]) >> 1
|
|
296
|
+
i += 1
|
|
297
|
+
end
|
|
298
|
+
else
|
|
299
|
+
while i < dn
|
|
300
|
+
j = i - 1
|
|
301
|
+
j = 0 if j.negative?
|
|
302
|
+
j1 = i
|
|
303
|
+
j1 = last if j1 > last
|
|
304
|
+
h[i] = (l[j] + l[j1]) >> 1
|
|
305
|
+
i += 1
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# 5/3 lifting of one row.
|
|
311
|
+
def lift53(l, h, sn, dn, cas)
|
|
312
|
+
lag = lags(cas, true)
|
|
313
|
+
last = [sn - 1, dn - 1 + lag[1]].max
|
|
314
|
+
ge = interior_end(sn, dn, cas)
|
|
315
|
+
lo = cas.zero? ? -1 : 0
|
|
316
|
+
ho = cas.zero? ? 0 : -1
|
|
317
|
+
g = 0
|
|
318
|
+
while g <= last
|
|
319
|
+
if g >= 1 && g < ge
|
|
320
|
+
cas.zero? ? fused53_cas0(l, h, g, ge) : fused53_cas1(l, h, g, ge)
|
|
321
|
+
g = ge
|
|
322
|
+
next
|
|
323
|
+
end
|
|
324
|
+
update53_at(l, h, dn, g, lo) if g < sn
|
|
325
|
+
i = g - lag[1]
|
|
326
|
+
predict53_at(h, l, sn, i, ho) if i >= 0 && i < dn
|
|
327
|
+
g += 1
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def update53_at(t, s, ns, i, o)
|
|
332
|
+
j = i + o
|
|
333
|
+
j1 = j + 1
|
|
334
|
+
last = ns - 1
|
|
335
|
+
j = 0 if j.negative?
|
|
336
|
+
j = last if j > last
|
|
337
|
+
j1 = last if j1 > last
|
|
338
|
+
t[i] -= (s[j] + s[j1] + 2) >> 2
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def predict53_at(t, s, ns, i, o)
|
|
342
|
+
j = i + o
|
|
343
|
+
j1 = j + 1
|
|
344
|
+
last = ns - 1
|
|
345
|
+
j = 0 if j.negative?
|
|
346
|
+
j = last if j > last
|
|
347
|
+
j1 = last if j1 > last
|
|
348
|
+
t[i] += (s[j] + s[j1]) >> 1
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def fused53_cas0(l, h, g, ge)
|
|
352
|
+
hm1 = h[g - 1]
|
|
353
|
+
lm1 = l[g - 1]
|
|
354
|
+
while g < ge
|
|
355
|
+
hg = h[g]
|
|
356
|
+
a = l[g] - ((hm1 + hg + 2) >> 2)
|
|
357
|
+
h[g - 1] = hm1 + ((lm1 + a) >> 1)
|
|
358
|
+
l[g] = a
|
|
359
|
+
lm1 = a
|
|
360
|
+
hm1 = hg
|
|
361
|
+
g += 1
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def fused53_cas1(l, h, g, ge)
|
|
366
|
+
hc = h[g]
|
|
367
|
+
lm1 = l[g - 1]
|
|
368
|
+
while g < ge
|
|
369
|
+
hn = h[g + 1]
|
|
370
|
+
a = l[g] - ((hc + hn + 2) >> 2)
|
|
371
|
+
h[g] = hc + ((lm1 + a) >> 1)
|
|
372
|
+
l[g] = a
|
|
373
|
+
lm1 = a
|
|
374
|
+
hc = hn
|
|
375
|
+
g += 1
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# Vertical synthesis of whole rows; returns the interleaved rows.
|
|
380
|
+
# +zero_rows+ flags high rows that are all zero (given as nil).
|
|
381
|
+
def vertical(lows, highs, sn, dn, width, cas, reversible, zero_rows = nil)
|
|
382
|
+
n = sn + dn
|
|
383
|
+
if zero_rows
|
|
384
|
+
zero = reversible ? 0 : 0.0
|
|
385
|
+
i = 0
|
|
386
|
+
while i < dn
|
|
387
|
+
highs[i] ||= Array.new(width, zero)
|
|
388
|
+
i += 1
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
if n <= 1
|
|
392
|
+
if cas == 1 && dn == 1
|
|
393
|
+
row = highs[0]
|
|
394
|
+
halve_row(row, width) if reversible
|
|
395
|
+
return [row]
|
|
396
|
+
end
|
|
397
|
+
return lows
|
|
398
|
+
end
|
|
399
|
+
if reversible
|
|
400
|
+
rows53(lows, highs, sn, dn, cas, width, zero_rows)
|
|
401
|
+
else
|
|
402
|
+
rows97(lows, highs, sn, dn, cas, width, zero_rows)
|
|
403
|
+
end
|
|
404
|
+
out = Array.new(n)
|
|
405
|
+
i = 0
|
|
406
|
+
while i < sn
|
|
407
|
+
out[2 * i + cas] = lows[i]
|
|
408
|
+
i += 1
|
|
409
|
+
end
|
|
410
|
+
i = 0
|
|
411
|
+
while i < dn
|
|
412
|
+
out[2 * i + 1 - cas] = highs[i]
|
|
413
|
+
i += 1
|
|
414
|
+
end
|
|
415
|
+
out
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
# The 9/7 steps on rows, pipelined like lift97.
|
|
419
|
+
def rows97(l, h, sn, dn, cas, width, zero_rows = nil)
|
|
420
|
+
lag = lags(cas, false)
|
|
421
|
+
last = [sn - 1 + lag[2], dn - 1 + lag[3]].max
|
|
422
|
+
ge = interior_end(sn, dn, cas)
|
|
423
|
+
lo = cas.zero? ? -1 : 0
|
|
424
|
+
ho = cas.zero? ? 0 : -1
|
|
425
|
+
g = 0
|
|
426
|
+
while g <= last
|
|
427
|
+
if g >= 2 && g < ge
|
|
428
|
+
if cas.zero?
|
|
429
|
+
if zero_rows && zero_rows[g - 1] && zero_rows[g]
|
|
430
|
+
row_fused97z(l[g], h[g - 1], l[g - 1], h[g - 2], l[g - 2], width)
|
|
431
|
+
else
|
|
432
|
+
row_fused97(l[g], h[g - 1], h[g], l[g - 1], h[g - 2], l[g - 2], width)
|
|
433
|
+
end
|
|
434
|
+
elsif zero_rows && zero_rows[g] && zero_rows[g + 1]
|
|
435
|
+
row_fused97z(l[g], h[g], l[g - 1], h[g - 1], l[g - 2], width)
|
|
436
|
+
else
|
|
437
|
+
row_fused97(l[g], h[g], h[g + 1], l[g - 1], h[g - 1], l[g - 2], width)
|
|
438
|
+
end
|
|
439
|
+
else
|
|
440
|
+
k = 0
|
|
441
|
+
while k < 4
|
|
442
|
+
i = g - lag[k]
|
|
443
|
+
if k.even?
|
|
444
|
+
row_step(l, h, dn, i, lo, COEFFS97[k], width) if i >= 0 && i < sn
|
|
445
|
+
elsif i >= 0 && i < dn
|
|
446
|
+
row_step(h, l, sn, i, ho, COEFFS97[k], width)
|
|
447
|
+
end
|
|
448
|
+
k += 1
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
g += 1
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def row_step(t, s, ns, i, o, c, width)
|
|
456
|
+
j = i + o
|
|
457
|
+
j1 = j + 1
|
|
458
|
+
last = ns - 1
|
|
459
|
+
j = 0 if j.negative?
|
|
460
|
+
j = last if j > last
|
|
461
|
+
j1 = last if j1 > last
|
|
462
|
+
row_axpy(t[i], s[j], s[j1], c, width)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
# All four 9/7 steps of one wavefront on rows: a += c1 (b + c);
|
|
466
|
+
# b += c2 (d + a); d += c3 (e + b); e += c4 (f + d).
|
|
467
|
+
def row_fused97(ra, rb, rc, rd, re, rf, width)
|
|
468
|
+
c1 = -DELTA
|
|
469
|
+
c2 = -GAMMA
|
|
470
|
+
c3 = -BETA
|
|
471
|
+
c4 = -ALPHA
|
|
472
|
+
x = 0
|
|
473
|
+
while x < width
|
|
474
|
+
b = rb[x]
|
|
475
|
+
a = ra[x] + c1 * (b + rc[x])
|
|
476
|
+
ra[x] = a
|
|
477
|
+
d = rd[x]
|
|
478
|
+
b += c2 * (d + a)
|
|
479
|
+
rb[x] = b
|
|
480
|
+
e = re[x]
|
|
481
|
+
d += c3 * (e + b)
|
|
482
|
+
rd[x] = d
|
|
483
|
+
re[x] = e + c4 * (rf[x] + d)
|
|
484
|
+
x += 1
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
# row_fused97 when rows b and c are all zero (a is unchanged).
|
|
489
|
+
def row_fused97z(ra, rb, rd, re, rf, width)
|
|
490
|
+
c2 = -GAMMA
|
|
491
|
+
c3 = -BETA
|
|
492
|
+
c4 = -ALPHA
|
|
493
|
+
x = 0
|
|
494
|
+
while x < width
|
|
495
|
+
d = rd[x]
|
|
496
|
+
b = c2 * (d + ra[x])
|
|
497
|
+
rb[x] = b
|
|
498
|
+
e = re[x]
|
|
499
|
+
d += c3 * (e + b)
|
|
500
|
+
rd[x] = d
|
|
501
|
+
re[x] = e + c4 * (rf[x] + d)
|
|
502
|
+
x += 1
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
def rows53(l, h, sn, dn, cas, width, zero_rows = nil)
|
|
507
|
+
lag = lags(cas, true)
|
|
508
|
+
last = [sn - 1, dn - 1 + lag[1]].max
|
|
509
|
+
ge = interior_end(sn, dn, cas)
|
|
510
|
+
lo = cas.zero? ? -1 : 0
|
|
511
|
+
ho = cas.zero? ? 0 : -1
|
|
512
|
+
g = 0
|
|
513
|
+
while g <= last
|
|
514
|
+
if g >= 1 && g < ge
|
|
515
|
+
if cas.zero?
|
|
516
|
+
if zero_rows && zero_rows[g - 1] && zero_rows[g]
|
|
517
|
+
row_average(h[g - 1], l[g - 1], l[g], width)
|
|
518
|
+
else
|
|
519
|
+
row_fused53(l[g], h[g - 1], h[g], l[g - 1], width)
|
|
520
|
+
end
|
|
521
|
+
elsif zero_rows && zero_rows[g] && zero_rows[g + 1]
|
|
522
|
+
row_average(h[g], l[g - 1], l[g], width)
|
|
523
|
+
else
|
|
524
|
+
row_fused53(l[g], h[g], h[g + 1], l[g - 1], width)
|
|
525
|
+
end
|
|
526
|
+
else
|
|
527
|
+
row_step53(l, h, dn, g, lo, width, true) if g < sn
|
|
528
|
+
i = g - lag[1]
|
|
529
|
+
row_step53(h, l, sn, i, ho, width, false) if i >= 0 && i < dn
|
|
530
|
+
end
|
|
531
|
+
g += 1
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
def row_step53(t, s, ns, i, o, width, update)
|
|
536
|
+
j = i + o
|
|
537
|
+
j1 = j + 1
|
|
538
|
+
last = ns - 1
|
|
539
|
+
j = 0 if j.negative?
|
|
540
|
+
j = last if j > last
|
|
541
|
+
j1 = last if j1 > last
|
|
542
|
+
if update
|
|
543
|
+
row_update53(t[i], s[j], s[j1], width)
|
|
544
|
+
else
|
|
545
|
+
row_predict53(t[i], s[j], s[j1], width)
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
# Both 5/3 steps of one wavefront: a -= (b + c + 2) >> 2;
|
|
550
|
+
# b += (d + a) >> 1.
|
|
551
|
+
def row_fused53(ra, rb, rc, rd, width)
|
|
552
|
+
x = 0
|
|
553
|
+
while x < width
|
|
554
|
+
b = rb[x]
|
|
555
|
+
a = ra[x] - ((b + rc[x] + 2) >> 2)
|
|
556
|
+
ra[x] = a
|
|
557
|
+
rb[x] = b + ((rd[x] + a) >> 1)
|
|
558
|
+
x += 1
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
# t = (a + b) >> 1: the 5/3 wavefront when t and its neighbour
|
|
563
|
+
# high row are zero (the update step is then the identity).
|
|
564
|
+
def row_average(t, a, b, width)
|
|
565
|
+
x = 0
|
|
566
|
+
while x < width
|
|
567
|
+
t[x] = (a[x] + b[x]) >> 1
|
|
568
|
+
x += 1
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
def row_axpy(t, a, b, c, width)
|
|
573
|
+
x = 0
|
|
574
|
+
while x < width
|
|
575
|
+
t[x] += c * (a[x] + b[x])
|
|
576
|
+
x += 1
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def row_update53(t, a, b, width)
|
|
581
|
+
x = 0
|
|
582
|
+
while x < width
|
|
583
|
+
t[x] -= (a[x] + b[x] + 2) >> 2
|
|
584
|
+
x += 1
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
def row_predict53(t, a, b, width)
|
|
589
|
+
x = 0
|
|
590
|
+
while x < width
|
|
591
|
+
t[x] += (a[x] + b[x]) >> 1
|
|
592
|
+
x += 1
|
|
593
|
+
end
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
def halve_row(row, width)
|
|
597
|
+
x = 0
|
|
598
|
+
while x < width
|
|
599
|
+
v = row[x]
|
|
600
|
+
row[x] = v.negative? ? -(-v / 2) : v / 2
|
|
601
|
+
x += 1
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
end
|
|
607
|
+
end
|