corrade-vassal – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | /* |
2 | * CVS identifier: |
||
3 | * |
||
4 | * $Id: Subband.java,v 1.47 2001/10/18 14:27:14 grosbois Exp $ |
||
5 | * |
||
6 | * Class: Subband |
||
7 | * |
||
8 | * Description: Asbtract element for a tree strcuture for |
||
9 | * a description of subbands. |
||
10 | * |
||
11 | * |
||
12 | * |
||
13 | * COPYRIGHT: |
||
14 | * |
||
15 | * This software module was originally developed by Raphaël Grosbois and |
||
16 | * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel |
||
17 | * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David |
||
18 | * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research |
||
19 | * Centre France S.A) in the course of development of the JPEG2000 |
||
20 | * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This |
||
21 | * software module is an implementation of a part of the JPEG 2000 |
||
22 | * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio |
||
23 | * Systems AB and Canon Research Centre France S.A (collectively JJ2000 |
||
24 | * Partners) agree not to assert against ISO/IEC and users of the JPEG |
||
25 | * 2000 Standard (Users) any of their rights under the copyright, not |
||
26 | * including other intellectual property rights, for this software module |
||
27 | * with respect to the usage by ISO/IEC and Users of this software module |
||
28 | * or modifications thereof for use in hardware or software products |
||
29 | * claiming conformance to the JPEG 2000 Standard. Those intending to use |
||
30 | * this software module in hardware or software products are advised that |
||
31 | * their use may infringe existing patents. The original developers of |
||
32 | * this software module, JJ2000 Partners and ISO/IEC assume no liability |
||
33 | * for use of this software module or modifications thereof. No license |
||
34 | * or right to this software module is granted for non JPEG 2000 Standard |
||
35 | * conforming products. JJ2000 Partners have full right to use this |
||
36 | * software module for his/her own purpose, assign or donate this |
||
37 | * software module to any third party and to inhibit third parties from |
||
38 | * using this software module for non JPEG 2000 Standard conforming |
||
39 | * products. This copyright notice must be included in all copies or |
||
40 | * derivative works of this software module. |
||
41 | * |
||
42 | * Copyright (c) 1999/2000 JJ2000 Partners. |
||
43 | * */ |
||
44 | using System; |
||
45 | using CSJ2K.j2k.image; |
||
46 | namespace CSJ2K.j2k.wavelet |
||
47 | { |
||
48 | |||
49 | /// <summary> This abstract class represents a subband in a bidirectional tree structure |
||
50 | /// that describes the subband decomposition for a wavelet transform. This |
||
51 | /// class is implemented by the SubbandAn and SubbandSyn classes, which are for |
||
52 | /// the analysis and synthesis sides respectively. |
||
53 | /// |
||
54 | /// <p>The element can be either a node or a leaf of the tree. If it is a node, |
||
55 | /// it has 4 descendants (LL, HL, LH and HH). If it is a leaf, it has no |
||
56 | /// descendant.</p> |
||
57 | /// |
||
58 | /// <p>The tree is bidirectional. Each element in the tree structure has a |
||
59 | /// "parent", which is the subband from which the element was obtained by |
||
60 | /// decomposition. The only exception is the root element which, for obvious |
||
61 | /// reasons, has no parent (i.e. it is null).</p> |
||
62 | /// |
||
63 | /// </summary> |
||
64 | /// <seealso cref="jj2000.j2k.wavelet.analysis.SubbandAn"> |
||
65 | /// </seealso> |
||
66 | /// <seealso cref="jj2000.j2k.wavelet.synthesis.SubbandSyn"> |
||
67 | /// |
||
68 | /// </seealso> |
||
69 | public abstract class Subband |
||
70 | { |
||
71 | /// <summary> Returns the parent of this subband. The parent of a subband is the |
||
72 | /// subband from which this one was obtained by decomposition. The root |
||
73 | /// element has no parent subband (null). |
||
74 | /// |
||
75 | /// </summary> |
||
76 | /// <returns> The parent subband, or null for the root one. |
||
77 | /// |
||
78 | /// </returns> |
||
79 | public abstract Subband Parent{get;} |
||
80 | /// <summary> Returns the LL child subband of this subband. |
||
81 | /// |
||
82 | /// </summary> |
||
83 | /// <returns> The LL child subband, or null if there are no childs. |
||
84 | /// |
||
85 | /// </returns> |
||
86 | public abstract Subband LL{get;} |
||
87 | /// <summary> Returns the HL (horizontal high-pass) child subband of this subband. |
||
88 | /// |
||
89 | /// </summary> |
||
90 | /// <returns> The HL child subband, or null if there are no childs. |
||
91 | /// |
||
92 | /// </returns> |
||
93 | public abstract Subband HL{get;} |
||
94 | /// <summary> Returns the LH (vertical high-pass) child subband of this subband. |
||
95 | /// |
||
96 | /// </summary> |
||
97 | /// <returns> The LH child subband, or null if there are no childs. |
||
98 | /// |
||
99 | /// </returns> |
||
100 | public abstract Subband LH{get;} |
||
101 | /// <summary> Returns the HH child subband of this subband. |
||
102 | /// |
||
103 | /// </summary> |
||
104 | /// <returns> The HH child subband, or null if there are no childs. |
||
105 | /// |
||
106 | /// </returns> |
||
107 | public abstract Subband HH{get;} |
||
108 | /// <summary> Returns the first leaf subband element in the next higher resolution |
||
109 | /// level. |
||
110 | /// |
||
111 | /// </summary> |
||
112 | /// <returns> The first leaf element in the next higher resolution level, or |
||
113 | /// null if there is no higher resolution level. |
||
114 | /// |
||
115 | /// </returns> |
||
116 | virtual public Subband NextResLevel |
||
117 | { |
||
118 | get |
||
119 | { |
||
120 | Subband sb; |
||
121 | |||
122 | if (level == 0) |
||
123 | { |
||
124 | // No higher res. level |
||
125 | return null; |
||
126 | } |
||
127 | // Go up until we get to a different resolution level |
||
128 | sb = this; |
||
129 | do |
||
130 | { |
||
131 | sb = sb.Parent; |
||
132 | if (sb == null) |
||
133 | { |
||
134 | // No higher resolution level |
||
135 | return null; |
||
136 | } |
||
137 | } |
||
138 | while (sb.resLvl == resLvl); |
||
139 | // Now go down to HL, which is in next higher resolution level |
||
140 | sb = sb.HL; |
||
141 | // Now go down LL until get to a leaf |
||
142 | while (sb.isNode) |
||
143 | { |
||
144 | sb = sb.LL; |
||
145 | } |
||
146 | return sb; |
||
147 | } |
||
148 | |||
149 | } |
||
150 | /// <summary> This function returns the horizontal wavelet filter relevant to this |
||
151 | /// subband |
||
152 | /// |
||
153 | /// </summary> |
||
154 | /// <returns> The horizontal wavelet filter |
||
155 | /// |
||
156 | /// </returns> |
||
157 | public abstract WaveletFilter HorWFilter{get;} |
||
158 | /// <summary> This function returns the vertical wavelet filter relevant to this |
||
159 | /// subband |
||
160 | /// |
||
161 | /// </summary> |
||
162 | /// <returns> The vertical wavelet filter |
||
163 | /// |
||
164 | /// </returns> |
||
165 | public abstract WaveletFilter VerWFilter{get;} |
||
166 | |||
167 | /// <summary>The ID for the LL orientation </summary> |
||
168 | public const int WT_ORIENT_LL = 0; |
||
169 | |||
170 | /// <summary>The ID for the HL (horizontal high-pass) orientation </summary> |
||
171 | public const int WT_ORIENT_HL = 1; |
||
172 | |||
173 | /// <summary>The ID for the LH (vertical high-pass) orientation </summary> |
||
174 | public const int WT_ORIENT_LH = 2; |
||
175 | |||
176 | /// <summary>The ID for the HH orientation </summary> |
||
177 | public const int WT_ORIENT_HH = 3; |
||
178 | |||
179 | /// <summary>True if it is a node in the tree, false if it is a leaf. </summary> |
||
180 | public bool isNode; |
||
181 | |||
182 | /// <summary>The orientation of this subband (WT_ORIENT_LL, WT_ORIENT_HL, |
||
183 | /// WT_ORIENT_LH, WT_ORIENT_HH). |
||
184 | /// </summary> |
||
185 | public int orientation; |
||
186 | |||
187 | /// <summary>The level in the tree to which this subband belongs, which is the |
||
188 | /// number of performed wavelet decompositions to get this subband. It is 0 |
||
189 | /// for the top-level (i.e. root) node. |
||
190 | /// </summary> |
||
191 | public int level; |
||
192 | |||
193 | /// <summary>The resolution level to which this subband contributes. 0 is the |
||
194 | /// smallest resolution level (the one with the lowest frequency LL |
||
195 | /// subband). |
||
196 | /// </summary> |
||
197 | public int resLvl; |
||
198 | |||
199 | /// <summary>The number of code-blocks (in both directions) contained in this |
||
200 | /// subband. |
||
201 | /// </summary> |
||
202 | public Coord numCb = null; |
||
203 | |||
204 | /// <summary> The base 2 exponent of the analysis gain of the subband. The analysis |
||
205 | /// gain of a subband is defined as the gain of the previous subband |
||
206 | /// (i.e. the one from which this one was obtained) multiplied by the line |
||
207 | /// gain and by the column gain. The line (column) gain is the gain of the |
||
208 | /// line (column) filter that was used to obtain it, which is the DC gain |
||
209 | /// for a low-pass filter and the Nyquist gain for a high-pass filter. It |
||
210 | /// is 0 by default. |
||
211 | /// |
||
212 | /// <p>Using the base 2 exponent of the value contrains the possible gains |
||
213 | /// to powers of 2. However this is perfectly compatible to the filter |
||
214 | /// normalization policy assumed here. See the split() method for more |
||
215 | /// details.</p> |
||
216 | /// |
||
217 | /// </summary> |
||
218 | /// <seealso cref="split"> |
||
219 | /// |
||
220 | /// </seealso> |
||
221 | public int anGainExp; |
||
222 | |||
223 | /// <summary> The subband index within its resolution level. This value uniquely |
||
224 | /// identifies a subband within a resolution level and a decomposition |
||
225 | /// level within it. Note that only leaf elements represent "real" |
||
226 | /// subbands, while node elements represent only intermediate stages. |
||
227 | /// |
||
228 | /// <p>It is defined recursively. The root node gets a value of 0. For a |
||
229 | /// given node, with a subband index 'b', its LL descendant gets 4*b, its |
||
230 | /// HL descendant 4*b+1, its LH descendant 4*b+2, and its HH descendant |
||
231 | /// 4*b+3, for their subband indexes.</p> |
||
232 | /// |
||
233 | /// </summary> |
||
234 | public int sbandIdx = 0; |
||
235 | |||
236 | /// <summary> The horizontal coordinate of the upper-left corner of the subband, with |
||
237 | /// respect to the canvas origin, in the component's grid and subband's |
||
238 | /// decomposition level. This is the real horizontal index of the first |
||
239 | /// column of this subband. If even the horizontal decomposition of this |
||
240 | /// subband should be done with the low-pass-first convention. If odd it |
||
241 | /// should be done with the high-pass-first convention. |
||
242 | /// |
||
243 | /// </summary> |
||
244 | public int ulcx; |
||
245 | |||
246 | /// <summary> The vertical coordinate of the upper-left corner of the subband, with |
||
247 | /// respect to the canvas origin, in the component's grid and subband's |
||
248 | /// decomposition level. This is the real vertical index of the first |
||
249 | /// column of this subband. If even the vertical decomposition of this |
||
250 | /// subband should be done with the low-pass-first convention. If odd it |
||
251 | /// should be done with the high-pass-first convention. |
||
252 | /// |
||
253 | /// </summary> |
||
254 | public int ulcy; |
||
255 | |||
256 | /// <summary>The horizontal coordinate of the upper-left corner of the subband </summary> |
||
257 | public int ulx; |
||
258 | |||
259 | /// <summary>The vertical coordinate of the upper-left corner of the subband </summary> |
||
260 | public int uly; |
||
261 | |||
262 | /// <summary>The width of the subband </summary> |
||
263 | public int w; |
||
264 | |||
265 | /// <summary>The height of the subband </summary> |
||
266 | public int h; |
||
267 | |||
268 | /// <summary>The nominal code-block width </summary> |
||
269 | public int nomCBlkW; |
||
270 | |||
271 | /// <summary>The nominal code-block height </summary> |
||
272 | public int nomCBlkH; |
||
273 | |||
274 | /// <summary> Splits the current subband in its four subbands. This creates the four |
||
275 | /// childs (LL, HL, LH and HH) and converts the leaf in a node. |
||
276 | /// |
||
277 | /// </summary> |
||
278 | /// <param name="hfilter">The horizontal wavelet filter used to decompose this |
||
279 | /// subband. |
||
280 | /// |
||
281 | /// </param> |
||
282 | /// <param name="vfilter">The vertical wavelet filter used to decompose this |
||
283 | /// subband. |
||
284 | /// |
||
285 | /// </param> |
||
286 | /// <returns> A reference to the LL leaf (getLL()). |
||
287 | /// |
||
288 | /// </returns> |
||
289 | protected internal abstract Subband split(WaveletFilter hfilter, WaveletFilter vfilter); |
||
290 | |||
291 | /// <summary> Initializes the childs of this node with the correct values. The sizes |
||
292 | /// of the child subbands are calculated by taking into account the |
||
293 | /// position of the subband in the canvas. |
||
294 | /// |
||
295 | /// <p>For the analysis subband gain calculation it is assumed that |
||
296 | /// analysis filters are normalized with a DC gain of 1 and a Nyquist gain |
||
297 | /// of 2.</p> |
||
298 | /// |
||
299 | /// </summary> |
||
300 | protected internal virtual void initChilds() |
||
301 | { |
||
302 | Subband subb_LL = LL; |
||
303 | Subband subb_HL = HL; |
||
304 | Subband subb_LH = LH; |
||
305 | Subband subb_HH = HH; |
||
306 | |||
307 | // LL subband |
||
308 | subb_LL.level = level + 1; |
||
309 | subb_LL.ulcx = (ulcx + 1) >> 1; |
||
310 | subb_LL.ulcy = (ulcy + 1) >> 1; |
||
311 | subb_LL.ulx = ulx; |
||
312 | subb_LL.uly = uly; |
||
313 | subb_LL.w = ((ulcx + w + 1) >> 1) - subb_LL.ulcx; |
||
314 | subb_LL.h = ((ulcy + h + 1) >> 1) - subb_LL.ulcy; |
||
315 | // If this subband in in the all LL path (i.e. it's global orientation |
||
316 | // is LL) then child LL band contributes to a lower resolution level. |
||
317 | subb_LL.resLvl = (orientation == WT_ORIENT_LL)?resLvl - 1:resLvl; |
||
318 | subb_LL.anGainExp = anGainExp; |
||
319 | subb_LL.sbandIdx = (sbandIdx << 2); |
||
320 | // HL subband |
||
321 | subb_HL.orientation = WT_ORIENT_HL; |
||
322 | subb_HL.level = subb_LL.level; |
||
323 | subb_HL.ulcx = ulcx >> 1; |
||
324 | subb_HL.ulcy = subb_LL.ulcy; |
||
325 | subb_HL.ulx = ulx + subb_LL.w; |
||
326 | subb_HL.uly = uly; |
||
327 | subb_HL.w = ((ulcx + w) >> 1) - subb_HL.ulcx; |
||
328 | subb_HL.h = subb_LL.h; |
||
329 | subb_HL.resLvl = resLvl; |
||
330 | subb_HL.anGainExp = anGainExp + 1; |
||
331 | subb_HL.sbandIdx = (sbandIdx << 2) + 1; |
||
332 | // LH subband |
||
333 | subb_LH.orientation = WT_ORIENT_LH; |
||
334 | subb_LH.level = subb_LL.level; |
||
335 | subb_LH.ulcx = subb_LL.ulcx; |
||
336 | subb_LH.ulcy = ulcy >> 1; |
||
337 | subb_LH.ulx = ulx; |
||
338 | subb_LH.uly = uly + subb_LL.h; |
||
339 | subb_LH.w = subb_LL.w; |
||
340 | subb_LH.h = ((ulcy + h) >> 1) - subb_LH.ulcy; |
||
341 | subb_LH.resLvl = resLvl; |
||
342 | subb_LH.anGainExp = anGainExp + 1; |
||
343 | subb_LH.sbandIdx = (sbandIdx << 2) + 2; |
||
344 | // HH subband |
||
345 | subb_HH.orientation = WT_ORIENT_HH; |
||
346 | subb_HH.level = subb_LL.level; |
||
347 | subb_HH.ulcx = subb_HL.ulcx; |
||
348 | subb_HH.ulcy = subb_LH.ulcy; |
||
349 | subb_HH.ulx = subb_HL.ulx; |
||
350 | subb_HH.uly = subb_LH.uly; |
||
351 | subb_HH.w = subb_HL.w; |
||
352 | subb_HH.h = subb_LH.h; |
||
353 | subb_HH.resLvl = resLvl; |
||
354 | subb_HH.anGainExp = anGainExp + 2; |
||
355 | subb_HH.sbandIdx = (sbandIdx << 2) + 3; |
||
356 | } |
||
357 | |||
358 | /// <summary> Creates a Subband element with all the default values. The dimensions |
||
359 | /// are (0,0), the upper left corner is (0,0) and the upper-left corner |
||
360 | /// with respect to the canvas is (0,0) too. |
||
361 | /// |
||
362 | /// </summary> |
||
363 | public Subband() |
||
364 | { |
||
365 | } |
||
366 | |||
367 | /// <summary> Creates the top-level node and the entire subband tree, with the |
||
368 | /// top-level dimensions, the number of decompositions, and the |
||
369 | /// decomposition tree as specified. |
||
370 | /// |
||
371 | /// <p>For the analysis subband gain calculation it is assumed that |
||
372 | /// analysis filters are normalized with a DC gain of 1 and a Nyquist gain |
||
373 | /// of 2.</p> |
||
374 | /// |
||
375 | /// <p>This constructor does not initialize the value of the magBits member |
||
376 | /// variable. This variable is normally initialized by the quantizer, on |
||
377 | /// the encoder side, or the bit stream reader, on the decoder side.</p> |
||
378 | /// |
||
379 | /// </summary> |
||
380 | /// <param name="w">The top-level width |
||
381 | /// |
||
382 | /// </param> |
||
383 | /// <param name="h">The top-level height |
||
384 | /// |
||
385 | /// </param> |
||
386 | /// <param name="ulcx">The horizontal coordinate of the upper-left corner with |
||
387 | /// respect to the canvas origin, in the component grid. |
||
388 | /// |
||
389 | /// </param> |
||
390 | /// <param name="ulcy">The vertical coordinate of the upper-left corner with |
||
391 | /// respect to the canvas origin, in the component grid. |
||
392 | /// |
||
393 | /// </param> |
||
394 | /// <param name="lvls">The number of levels (or LL decompositions) in the tree. |
||
395 | /// |
||
396 | /// </param> |
||
397 | /// <param name="hfilters">The horizontal wavelet filters (analysis or synthesis) |
||
398 | /// for each resolution level, starting at resolution level 0. If there are |
||
399 | /// less elements in the array than there are resolution levels, the last |
||
400 | /// element is used for the remaining resolution levels. |
||
401 | /// |
||
402 | /// </param> |
||
403 | /// <param name="vfilters">The vertical wavelet filters (analysis or synthesis) |
||
404 | /// for each resolution level, starting at resolution level 0. If there are |
||
405 | /// less elements in the array than there are resolution levels, the last |
||
406 | /// element is used for the remaining resolution levels. |
||
407 | /// |
||
408 | /// </param> |
||
409 | /// <seealso cref="WaveletTransform"> |
||
410 | /// |
||
411 | /// </seealso> |
||
412 | public Subband(int w, int h, int ulcx, int ulcy, int lvls, WaveletFilter[] hfilters, WaveletFilter[] vfilters) |
||
413 | { |
||
414 | int i, hi, vi; |
||
415 | Subband cur; // The current subband |
||
416 | |||
417 | // Initialize top-level node |
||
418 | this.w = w; |
||
419 | this.h = h; |
||
420 | this.ulcx = ulcx; |
||
421 | this.ulcy = ulcy; |
||
422 | this.resLvl = lvls; |
||
423 | // First create dyadic decomposition. |
||
424 | cur = this; |
||
425 | for (i = 0; i < lvls; i++) |
||
426 | { |
||
427 | hi = (cur.resLvl <= hfilters.Length)?cur.resLvl - 1:hfilters.Length - 1; |
||
428 | vi = (cur.resLvl <= vfilters.Length)?cur.resLvl - 1:vfilters.Length - 1; |
||
429 | cur = cur.split(hfilters[hi], vfilters[vi]); |
||
430 | } |
||
431 | } |
||
432 | |||
433 | /// <summary> Returns the next subband in the same resolution level, following the |
||
434 | /// subband index order. If already at the last subband then null is |
||
435 | /// returned. If this subband is not a leaf an IllegalArgumentException is |
||
436 | /// thrown. |
||
437 | /// |
||
438 | /// </summary> |
||
439 | /// <returns> The next subband in the same resolution level, following the |
||
440 | /// subband index order, or null if already at last subband. |
||
441 | /// |
||
442 | /// </returns> |
||
443 | public virtual Subband nextSubband() |
||
444 | { |
||
445 | Subband sb; |
||
446 | |||
447 | if (isNode) |
||
448 | { |
||
449 | throw new System.ArgumentException(); |
||
450 | } |
||
451 | |||
452 | switch (orientation) |
||
453 | { |
||
454 | |||
455 | case WT_ORIENT_LL: |
||
456 | sb = Parent; |
||
457 | if (sb == null || sb.resLvl != resLvl) |
||
458 | { |
||
459 | // Already at top-level or last subband in res. level |
||
460 | return null; |
||
461 | } |
||
462 | else |
||
463 | { |
||
464 | return sb.HL; |
||
465 | } |
||
466 | //goto case WT_ORIENT_HL; |
||
467 | |||
468 | case WT_ORIENT_HL: |
||
469 | return Parent.LH; |
||
470 | |||
471 | case WT_ORIENT_LH: |
||
472 | return Parent.HH; |
||
473 | |||
474 | case WT_ORIENT_HH: |
||
475 | // This is the complicated one |
||
476 | sb = this; |
||
477 | while (sb.orientation == WT_ORIENT_HH) |
||
478 | { |
||
479 | sb = sb.Parent; |
||
480 | } |
||
481 | switch (sb.orientation) |
||
482 | { |
||
483 | |||
484 | case WT_ORIENT_LL: |
||
485 | sb = sb.Parent; |
||
486 | if (sb == null || sb.resLvl != resLvl) |
||
487 | { |
||
488 | // Already at top-level or last subband in res. level |
||
489 | return null; |
||
490 | } |
||
491 | else |
||
492 | { |
||
493 | sb = sb.HL; |
||
494 | } |
||
495 | break; |
||
496 | |||
497 | case WT_ORIENT_HL: |
||
498 | sb = sb.Parent.LH; |
||
499 | break; |
||
500 | |||
501 | case WT_ORIENT_LH: |
||
502 | sb = sb.Parent.HH; |
||
503 | break; |
||
504 | |||
505 | default: |
||
506 | throw new System.ApplicationException("You have found a bug in JJ2000"); |
||
507 | |||
508 | } |
||
509 | while (sb.isNode) |
||
510 | { |
||
511 | sb = sb.LL; |
||
512 | } |
||
513 | return sb; |
||
514 | |||
515 | default: |
||
516 | throw new System.ApplicationException("You have found a bug in JJ2000"); |
||
517 | |||
518 | } |
||
519 | } |
||
520 | |||
521 | /// <summary> Returns a subband element in the tree, given its resolution level and |
||
522 | /// subband index. This method searches through the tree. |
||
523 | /// |
||
524 | /// </summary> |
||
525 | /// <param name="rl">The resolution level. |
||
526 | /// |
||
527 | /// </param> |
||
528 | /// <param name="sbi">The subband index, within the resolution level. |
||
529 | /// |
||
530 | /// </param> |
||
531 | public virtual Subband getSubbandByIdx(int rl, int sbi) |
||
532 | { |
||
533 | Subband sb = this; |
||
534 | |||
535 | // Find the root subband for the resolution level |
||
536 | if (rl > sb.resLvl || rl < 0) |
||
537 | { |
||
538 | throw new System.ArgumentException("Resolution level index " + "out of range"); |
||
539 | } |
||
540 | |||
541 | // Returns directly if it is itself |
||
542 | if (rl == sb.resLvl && sbi == sb.sbandIdx) |
||
543 | return sb; |
||
544 | |||
545 | if (sb.sbandIdx != 0) |
||
546 | sb = sb.Parent; |
||
547 | |||
548 | while (sb.resLvl > rl) |
||
549 | sb = sb.LL; |
||
550 | while (sb.resLvl < rl) |
||
551 | sb = sb.Parent; |
||
552 | |||
553 | switch (sbi) |
||
554 | { |
||
555 | |||
556 | case 0: |
||
557 | default: |
||
558 | return sb; |
||
559 | |||
560 | case 1: |
||
561 | return sb.HL; |
||
562 | |||
563 | case 2: |
||
564 | return sb.LH; |
||
565 | |||
566 | case 3: |
||
567 | return sb.HH; |
||
568 | } |
||
569 | } |
||
570 | |||
571 | /// <summary> Returns a reference to the Subband element to which the specified point |
||
572 | /// belongs. The specified point must be inside this (i.e. the one defined |
||
573 | /// by this object) subband. This method searches through the tree. |
||
574 | /// |
||
575 | /// </summary> |
||
576 | /// <param name="x">horizontal coordinate of the specified point. |
||
577 | /// |
||
578 | /// </param> |
||
579 | /// <param name="y">horizontal coordinate of the specified point. |
||
580 | /// |
||
581 | /// </param> |
||
582 | public virtual Subband getSubband(int x, int y) |
||
583 | { |
||
584 | Subband cur, hhs; |
||
585 | |||
586 | // Check that we are inside this subband |
||
587 | if (x < ulx || y < uly || x >= ulx + w || y >= uly + h) |
||
588 | { |
||
589 | throw new System.ArgumentException(); |
||
590 | } |
||
591 | |||
592 | cur = this; |
||
593 | while (cur.isNode) |
||
594 | { |
||
595 | hhs = cur.HH; |
||
596 | // While we are still at a node -> continue |
||
597 | if (x < hhs.ulx) |
||
598 | { |
||
599 | // Is the result of horizontal low-pass |
||
600 | if (y < hhs.uly) |
||
601 | { |
||
602 | // Vertical low-pass |
||
603 | cur = cur.LL; |
||
604 | } |
||
605 | else |
||
606 | { |
||
607 | // Vertical high-pass |
||
608 | cur = cur.LH; |
||
609 | } |
||
610 | } |
||
611 | else |
||
612 | { |
||
613 | // Is the result of horizontal high-pass |
||
614 | if (y < hhs.uly) |
||
615 | { |
||
616 | // Vertical low-pass |
||
617 | cur = cur.HL; |
||
618 | } |
||
619 | else |
||
620 | { |
||
621 | // Vertical high-pass |
||
622 | cur = cur.HH; |
||
623 | } |
||
624 | } |
||
625 | } |
||
626 | |||
627 | return cur; |
||
628 | } |
||
629 | |||
630 | /// <summary> Returns subband informations in a string. |
||
631 | /// |
||
632 | /// </summary> |
||
633 | /// <returns> Subband informations |
||
634 | /// |
||
635 | /// </returns> |
||
636 | public override System.String ToString() |
||
637 | { |
||
638 | System.String string_Renamed = "w=" + w + ",h=" + h + ",ulx=" + ulx + ",uly=" + uly + ",ulcx=" + ulcx + ",ulcy=" + ulcy + ",idx=" + sbandIdx + ",orient=" + orientation + ",node=" + isNode + ",level=" + level + ",resLvl=" + resLvl + ",nomCBlkW=" + nomCBlkW + ",nomCBlkH=" + nomCBlkH + ",numCb=" + numCb; |
||
639 | |||
640 | return string_Renamed; |
||
641 | } |
||
642 | } |
||
643 | } |