corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * CVS identifier:
3 *
4 * $Id: PktEncoder.java,v 1.29 2001/11/08 18:32:09 grosbois Exp $
5 *
6 * Class: PktEncoder
7 *
8 * Description: Builds bit stream packets and keeps
9 * interpacket dependencies.
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.wavelet.analysis;
46 using CSJ2K.j2k.entropy.encoder;
47 using CSJ2K.j2k.codestream;
48 using CSJ2K.j2k.encoder;
49 using CSJ2K.j2k.wavelet;
50 using CSJ2K.j2k.image;
51 using CSJ2K.j2k.util;
52 using CSJ2K.j2k;
53 namespace CSJ2K.j2k.codestream.writer
54 {
55  
56 /// <summary> This class builds packets and keeps the state information of packet
57 /// interdependencies. It also supports saving the state and reverting
58 /// (restoring) to the last saved state, with the save() and restore() methods.
59 ///
60 /// <p>Each time the encodePacket() method is called a new packet is encoded,
61 /// the packet header is returned by the method, and the packet body can be
62 /// obtained with the getLastBodyBuf() and getLastBodyLen() methods.</p>
63 ///
64 /// </summary>
65 public class PktEncoder
66 {
67 /// <summary> Returns the buffer of the body of the last encoded packet. The length
68 /// of the body can be retrieved with the getLastBodyLen() method. The
69 /// length of the array returned by this method may be larger than the
70 /// actual body length.
71 ///
72 /// </summary>
73 /// <returns> The buffer of body of the last encoded packet.
74 ///
75 /// </returns>
76 /// <exception cref="IllegalArgumentException">If no packet has been coded since
77 /// last reset(), last restore(), or object creation.
78 ///
79 /// </exception>
80 /// <seealso cref="getLastBodyLen">
81 ///
82 /// </seealso>
83 virtual public byte[] LastBodyBuf
84 {
85 get
86 {
87 if (lbbuf == null)
88 {
89 throw new System.ArgumentException();
90 }
91 return lbbuf;
92 }
93  
94 }
95 /// <summary> Returns the length of the body of the last encoded packet, in
96 /// bytes. The body itself can be retrieved with the getLastBodyBuf()
97 /// method.
98 ///
99 /// </summary>
100 /// <returns> The length of the body of last encoded packet, in bytes.
101 ///
102 /// </returns>
103 /// <seealso cref="getLastBodyBuf">
104 ///
105 /// </seealso>
106 virtual public int LastBodyLen
107 {
108 get
109 {
110 return lblen;
111 }
112  
113 }
114 /// <summary> Returns true if the current packet is writable i.e. should be written.
115 /// Returns false otherwise.
116 ///
117 /// </summary>
118 virtual public bool PacketWritable
119 {
120 get
121 {
122 return packetWritable;
123 }
124  
125 }
126 /// <summary> Tells if there was ROI information in the last written packet
127 ///
128 /// </summary>
129 virtual public bool ROIinPkt
130 {
131 get
132 {
133 return roiInPkt;
134 }
135  
136 }
137 /// <summary>Gives the length to read in current packet body to get all ROI
138 /// information
139 /// </summary>
140 virtual public int ROILen
141 {
142 get
143 {
144 return roiLen;
145 }
146  
147 }
148 /// <summary> Returns the parameters that are used in this class and implementing
149 /// classes. It returns a 2D String array. Each of the 1D arrays is for a
150 /// different option, and they have 3 elements. The first element is the
151 /// option name, the second one is the synopsis, the third one is a long
152 /// description of what the parameter is and the fourth is its default
153 /// value. The synopsis or description may be 'null', in which case it is
154 /// assumed that there is no synopsis or description of the option,
155 /// respectively. Null may be returned if no options are supported.
156 ///
157 /// </summary>
158 /// <returns> the options name, their synopsis and their explanation,
159 /// or null if no options are supported.
160 ///
161 /// </returns>
162 public static System.String[][] ParameterInfo
163 {
164 get
165 {
166 return pinfo;
167 }
168  
169 }
170  
171 /// <summary>The prefix for packet encoding options: 'P' </summary>
172 public const char OPT_PREFIX = 'P';
173  
174 /// <summary>The list of parameters that is accepted for packet encoding.</summary>
175 //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
176 private static readonly System.String[][] pinfo = new System.String[][]{new System.String[]{"Psop", "[<tile idx>] on|off" + "[ [<tile idx>] on|off ...]", "Specifies whether start of packet (SOP) markers should be used. " + "'on' enables, 'off' disables it.", "off"}, new System.String[]{"Peph", "[<tile idx>] on|off" + "[ [<tile idx>] on|off ...]", "Specifies whether end of packet header (EPH) markers should be " + " used. 'on' enables, 'off' disables it.", "off"}};
177  
178 /// <summary>The initial value for the lblock </summary>
179 private const int INIT_LBLOCK = 3;
180  
181 /// <summary>The source object </summary>
182 private CodedCBlkDataSrcEnc infoSrc;
183  
184 /// <summary>The encoder specs </summary>
185 private EncoderSpecs encSpec;
186  
187 /// <summary> The tag tree for inclusion information. The indexes are outlined
188 /// below. Note that the layer indexes start at 1, therefore, the layer
189 /// index minus 1 is used. The subband indices are used as they are defined
190 /// in the Subband class. The tile indices start at 0 and follow a
191 /// lexicographical order.
192 ///
193 /// <ul>
194 /// <li>1st index: tile index, in lexicographical order</li>
195 /// <li>2nd index: component index </li>
196 /// <li>3rd index: resolution level </li>
197 /// <li>4th index: precinct index </li>
198 /// <li>5th index: subband index </li>
199 /// </ul>
200 ///
201 /// </summary>
202 private TagTreeEncoder[][][][][] ttIncl;
203  
204 /// <summary> The tag tree for the maximum significant bit-plane. The indexes are
205 /// outlined below. Note that the layer indexes start at 1, therefore, the
206 /// layer index minus 1 is used. The subband indices are used as they are
207 /// defined in the Subband class. The tile indices start at 0 and follow a
208 /// lexicographical order.
209 ///
210 /// <ul>
211 /// <li>1st index: tile index, in lexicographical order</li>
212 /// <li>2nd index: component index </li>
213 /// <li>3rd index: resolution level </li>
214 /// <li>4th index: precinct index </li>
215 /// <li>5th index: subband index</li>
216 /// </ul>
217 ///
218 /// </summary>
219 private TagTreeEncoder[][][][][] ttMaxBP;
220  
221 /// <summary> The base number of bits for sending code-block length information
222 /// (referred as Lblock in the JPEG 2000 standard). The indexes are
223 /// outlined below. Note that the layer indexes start at 1, therefore, the
224 /// layer index minus 1 is used. The subband indices are used as they are
225 /// defined in the Subband class. The tile indices start at 0 and follow a
226 /// lexicographical order.
227 ///
228 /// <ul>
229 /// <li>1st index: tile index, in lexicographical order </li>
230 /// <li>2nd index: component index </li>
231 /// <li>3rd index: resolution level </li>
232 /// <li>4th index: subband index </li>
233 /// <li>5th index: code-block index, in lexicographical order</li>
234 /// </ul>
235 ///
236 /// </summary>
237 private int[][][][][] lblock;
238  
239 /// <summary> The last encoded truncation point for each code-block. A negative value
240 /// means that no information has been included for the block, yet. The
241 /// indexes are outlined below. The subband indices are used as they are
242 /// defined in the Subband class. The tile indices start at 0 and follow a
243 /// lexicographical order. The code-block indices follow a lexicographical
244 /// order within the subband tile.
245 ///
246 /// <P>What is actually stored is the index of the element in
247 /// CBlkRateDistStats.truncIdxs that gives the real truncation point.
248 ///
249 /// <ul>
250 /// <li>1st index: tile index, in lexicographical order </li>
251 /// <li>2nd index: component index </li>
252 /// <li>3rd index: resolution level </li>
253 /// <li>4th index: subband index</li>
254 /// <li>5th index: code-block index, in lexicographical order </li>
255 /// </ul>
256 ///
257 /// </summary>
258 private int[][][][][] prevtIdxs;
259  
260 /// <summary> The saved base number of bits for sending code-block length
261 /// information. It is used for restoring previous saved state by
262 /// restore(). The indexes are outlined below. Note that the layer indexes
263 /// start at 1, therefore, the layer index minus 1 is used. The subband
264 /// indices are used as they are defined in the Subband class. The tile
265 /// indices start at 0 and follow a lexicographical order.
266 ///
267 /// <ul>
268 /// <li>1st index: tile index, in lexicographical order </li>
269 /// <li>2nd index: component index </li>
270 /// <li>3rd index: resolution level </li>
271 /// <li>4th index: subband index </li>
272 /// <li>5th index: code-block index, in lexicographical order</li>
273 /// </ul>
274 ///
275 /// </summary>
276 private int[][][][][] bak_lblock;
277  
278 /// <summary> The saved last encoded truncation point for each code-block. It is used
279 /// for restoring previous saved state by restore(). A negative value means
280 /// that no information has been included for the block, yet. The indexes
281 /// are outlined below. The subband indices are used as they are defined in
282 /// the Subband class. The tile indices start at 0 and follow a
283 /// lexicographical order. The code-block indices follow a lexicographical
284 /// order within the subband tile.
285 ///
286 /// <ul>
287 /// <li>1st index: tile index, in lexicographical order </li>
288 /// <li>2nd index: component index </li>
289 /// <li>3rd index: resolution level </li>
290 /// <li>4th index: subband index </li>
291 /// <li>5th index: code-block index, in lexicographical order </li>
292 /// </ul>
293 ///
294 /// </summary>
295 private int[][][][][] bak_prevtIdxs;
296  
297 /// <summary>The body buffer of the last encoded packet </summary>
298 private byte[] lbbuf;
299  
300 /// <summary>The body length of the last encoded packet </summary>
301 private int lblen;
302  
303 /// <summary>The saved state </summary>
304 private bool saved;
305  
306 /// <summary>Whether or not there is ROI information in the last encoded Packet </summary>
307 private bool roiInPkt = false;
308  
309 /// <summary>Length to read in current packet body to get all the ROI information </summary>
310 private int roiLen = 0;
311  
312 /// <summary> Array containing the coordinates, width, height, indexes, ... of the
313 /// precincts.
314 ///
315 /// <ul>
316 /// <li> 1st dim: tile index.</li>
317 /// <li> 2nd dim: component index.</li>
318 /// <li> 3rd dim: resolution level index.</li>
319 /// <li> 4th dim: precinct index.</li>
320 /// </ul>
321 ///
322 /// </summary>
323 private PrecInfo[][][][] ppinfo;
324  
325 /// <summary>Whether or not the current packet is writable </summary>
326 private bool packetWritable;
327  
328 /// <summary> Creates a new packet encoder object, using the information from the
329 /// 'infoSrc' object.
330 ///
331 /// </summary>
332 /// <param name="infoSrc">The source of information to construct the object.
333 ///
334 /// </param>
335 /// <param name="encSpec">The encoding parameters.
336 ///
337 /// </param>
338 /// <param name="numPrec">Maximum number of precincts in each tile, component
339 /// and resolution level.
340 ///
341 /// </param>
342 /// <param name="pl">ParameterList instance that holds command line options
343 ///
344 /// </param>
345 public PktEncoder(CodedCBlkDataSrcEnc infoSrc, EncoderSpecs encSpec, Coord[][][] numPrec, ParameterList pl)
346 {
347 this.infoSrc = infoSrc;
348 this.encSpec = encSpec;
349  
350 // Check parameters
351 pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo));
352  
353 // Get number of components and tiles
354 int nc = infoSrc.NumComps;
355 int nt = infoSrc.getNumTiles();
356  
357 // Do initial allocation
358 ttIncl = new TagTreeEncoder[nt][][][][];
359 for (int i = 0; i < nt; i++)
360 {
361 ttIncl[i] = new TagTreeEncoder[nc][][][];
362 }
363 ttMaxBP = new TagTreeEncoder[nt][][][][];
364 for (int i2 = 0; i2 < nt; i2++)
365 {
366 ttMaxBP[i2] = new TagTreeEncoder[nc][][][];
367 }
368 lblock = new int[nt][][][][];
369 for (int i3 = 0; i3 < nt; i3++)
370 {
371 lblock[i3] = new int[nc][][][];
372 }
373 prevtIdxs = new int[nt][][][][];
374 for (int i4 = 0; i4 < nt; i4++)
375 {
376 prevtIdxs[i4] = new int[nc][][][];
377 }
378 ppinfo = new PrecInfo[nt][][][];
379 for (int i5 = 0; i5 < nt; i5++)
380 {
381 ppinfo[i5] = new PrecInfo[nc][][];
382 }
383  
384 // Finish allocation
385 SubbandAn root, sb;
386 int maxs, mins;
387 int mrl;
388 //Coord tmpCoord = null;
389 int numcb; // Number of code-blocks
390 //System.Collections.ArrayList cblks = null;
391 infoSrc.setTile(0, 0);
392 for (int t = 0; t < nt; t++)
393 {
394 // Loop on tiles
395 for (int c = 0; c < nc; c++)
396 {
397 // Loop on components
398 // Get number of resolution levels
399 root = infoSrc.getAnSubbandTree(t, c);
400 mrl = root.resLvl;
401  
402 lblock[t][c] = new int[mrl + 1][][];
403 ttIncl[t][c] = new TagTreeEncoder[mrl + 1][][];
404 ttMaxBP[t][c] = new TagTreeEncoder[mrl + 1][][];
405 prevtIdxs[t][c] = new int[mrl + 1][][];
406 ppinfo[t][c] = new PrecInfo[mrl + 1][];
407  
408 for (int r = 0; r <= mrl; r++)
409 {
410 // Loop on resolution levels
411 mins = (r == 0)?0:1;
412 maxs = (r == 0)?1:4;
413  
414 int maxPrec = numPrec[t][c][r].x * numPrec[t][c][r].y;
415  
416 ttIncl[t][c][r] = new TagTreeEncoder[maxPrec][];
417 for (int i6 = 0; i6 < maxPrec; i6++)
418 {
419 ttIncl[t][c][r][i6] = new TagTreeEncoder[maxs];
420 }
421 ttMaxBP[t][c][r] = new TagTreeEncoder[maxPrec][];
422 for (int i7 = 0; i7 < maxPrec; i7++)
423 {
424 ttMaxBP[t][c][r][i7] = new TagTreeEncoder[maxs];
425 }
426 prevtIdxs[t][c][r] = new int[maxs][];
427 lblock[t][c][r] = new int[maxs][];
428  
429 // Precincts and code-blocks
430 ppinfo[t][c][r] = new PrecInfo[maxPrec];
431 fillPrecInfo(t, c, r);
432  
433 for (int s = mins; s < maxs; s++)
434 {
435 // Loop on subbands
436 sb = (SubbandAn) root.getSubbandByIdx(r, s);
437 numcb = sb.numCb.x * sb.numCb.y;
438  
439 lblock[t][c][r][s] = new int[numcb];
440 ArrayUtil.intArraySet(lblock[t][c][r][s], INIT_LBLOCK);
441  
442 prevtIdxs[t][c][r][s] = new int[numcb];
443 ArrayUtil.intArraySet(prevtIdxs[t][c][r][s], - 1);
444 }
445 }
446 }
447 if (t != nt - 1)
448 infoSrc.nextTile();
449 }
450 }
451  
452 /// <summary> Retrives precincts and code-blocks coordinates in the given resolution,
453 /// component and tile. It terminates TagTreeEncoder initialization as
454 /// well.
455 ///
456 /// </summary>
457 /// <param name="t">Tile index.
458 ///
459 /// </param>
460 /// <param name="c">Component index.
461 ///
462 /// </param>
463 /// <param name="r">Resolution level index.
464 ///
465 /// </param>
466 private void fillPrecInfo(int t, int c, int r)
467 {
468 if (ppinfo[t][c][r].Length == 0)
469 return ; // No precinct in this
470 // resolution level
471  
472 Coord tileI = infoSrc.getTile(null);
473 Coord nTiles = infoSrc.getNumTiles(null);
474  
475 int x0siz = infoSrc.ImgULX;
476 int y0siz = infoSrc.ImgULY;
477 int xsiz = x0siz + infoSrc.ImgWidth;
478 int ysiz = y0siz + infoSrc.ImgHeight;
479 int xt0siz = infoSrc.TilePartULX;
480 int yt0siz = infoSrc.TilePartULY;
481 int xtsiz = infoSrc.NomTileWidth;
482 int ytsiz = infoSrc.NomTileHeight;
483  
484 int tx0 = (tileI.x == 0)?x0siz:xt0siz + tileI.x * xtsiz;
485 int ty0 = (tileI.y == 0)?y0siz:yt0siz + tileI.y * ytsiz;
486 int tx1 = (tileI.x != nTiles.x - 1)?xt0siz + (tileI.x + 1) * xtsiz:xsiz;
487 int ty1 = (tileI.y != nTiles.y - 1)?yt0siz + (tileI.y + 1) * ytsiz:ysiz;
488  
489 int xrsiz = infoSrc.getCompSubsX(c);
490 int yrsiz = infoSrc.getCompSubsY(c);
491  
492 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
493 int tcx0 = (int) System.Math.Ceiling(tx0 / (double) (xrsiz));
494 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
495 int tcy0 = (int) System.Math.Ceiling(ty0 / (double) (yrsiz));
496 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
497 int tcx1 = (int) System.Math.Ceiling(tx1 / (double) (xrsiz));
498 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
499 int tcy1 = (int) System.Math.Ceiling(ty1 / (double) (yrsiz));
500  
501 int ndl = infoSrc.getAnSubbandTree(t, c).resLvl - r;
502 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
503 int trx0 = (int) System.Math.Ceiling(tcx0 / (double) (1 << ndl));
504 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
505 int try0 = (int) System.Math.Ceiling(tcy0 / (double) (1 << ndl));
506 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
507 int trx1 = (int) System.Math.Ceiling(tcx1 / (double) (1 << ndl));
508 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
509 int try1 = (int) System.Math.Ceiling(tcy1 / (double) (1 << ndl));
510  
511 int cb0x = infoSrc.CbULX;
512 int cb0y = infoSrc.CbULY;
513  
514 double twoppx = (double) encSpec.pss.getPPX(t, c, r);
515 double twoppy = (double) encSpec.pss.getPPY(t, c, r);
516 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
517 int twoppx2 = (int) (twoppx / 2);
518 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
519 int twoppy2 = (int) (twoppy / 2);
520  
521 // Precincts are located at (cb0x+i*twoppx,cb0y+j*twoppy)
522 // Valid precincts are those which intersect with the current
523 // resolution level
524 int maxPrec = ppinfo[t][c][r].Length;
525 int nPrec = 0;
526  
527 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
528 int istart = (int) System.Math.Floor((try0 - cb0y) / twoppy);
529 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
530 int iend = (int) System.Math.Floor((try1 - 1 - cb0y) / twoppy);
531 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
532 int jstart = (int) System.Math.Floor((trx0 - cb0x) / twoppx);
533 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
534 int jend = (int) System.Math.Floor((trx1 - 1 - cb0x) / twoppx);
535  
536 int acb0x, acb0y;
537  
538 SubbandAn root = infoSrc.getAnSubbandTree(t, c);
539 SubbandAn sb = null;
540  
541 int p0x, p0y, p1x, p1y; // Precinct projection in subband
542 int s0x, s0y, s1x, s1y; // Active subband portion
543 int cw, ch;
544 int kstart, kend, lstart, lend, k0, l0;
545 int prg_ulx, prg_uly;
546 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
547 int prg_w = (int) twoppx << ndl;
548 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
549 int prg_h = (int) twoppy << ndl;
550  
551 CBlkCoordInfo cb;
552  
553 for (int i = istart; i <= iend; i++)
554 {
555 // Vertical precincts
556 for (int j = jstart; j <= jend; j++, nPrec++)
557 {
558 // Horizontal precincts
559 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
560 if (j == jstart && (trx0 - cb0x) % (xrsiz * ((int) twoppx)) != 0)
561 {
562 prg_ulx = tx0;
563 }
564 else
565 {
566 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
567 prg_ulx = cb0x + j * xrsiz * ((int) twoppx << ndl);
568 }
569 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
570 if (i == istart && (try0 - cb0y) % (yrsiz * ((int) twoppy)) != 0)
571 {
572 prg_uly = ty0;
573 }
574 else
575 {
576 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
577 prg_uly = cb0y + i * yrsiz * ((int) twoppy << ndl);
578 }
579  
580 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
581 ppinfo[t][c][r][nPrec] = new PrecInfo(r, (int) (cb0x + j * twoppx), (int) (cb0y + i * twoppy), (int) twoppx, (int) twoppy, prg_ulx, prg_uly, prg_w, prg_h);
582  
583 if (r == 0)
584 {
585 // LL subband
586 acb0x = cb0x;
587 acb0y = cb0y;
588  
589 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
590 p0x = acb0x + j * (int) twoppx;
591 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
592 p1x = p0x + (int) twoppx;
593 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
594 p0y = acb0y + i * (int) twoppy;
595 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
596 p1y = p0y + (int) twoppy;
597  
598 sb = (SubbandAn) root.getSubbandByIdx(0, 0);
599 s0x = (p0x < sb.ulcx)?sb.ulcx:p0x;
600 s1x = (p1x > sb.ulcx + sb.w)?sb.ulcx + sb.w:p1x;
601 s0y = (p0y < sb.ulcy)?sb.ulcy:p0y;
602 s1y = (p1y > sb.ulcy + sb.h)?sb.ulcy + sb.h:p1y;
603  
604 // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch)
605 cw = sb.nomCBlkW;
606 ch = sb.nomCBlkH;
607 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
608 k0 = (int) System.Math.Floor((sb.ulcy - acb0y) / (double) ch);
609 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
610 kstart = (int) System.Math.Floor((s0y - acb0y) / (double) ch);
611 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
612 kend = (int) System.Math.Floor((s1y - 1 - acb0y) / (double) ch);
613 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
614 l0 = (int) System.Math.Floor((sb.ulcx - acb0x) / (double) cw);
615 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
616 lstart = (int) System.Math.Floor((s0x - acb0x) / (double) cw);
617 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
618 lend = (int) System.Math.Floor((s1x - 1 - acb0x) / (double) cw);
619  
620 if (s1x - s0x <= 0 || s1y - s0y <= 0)
621 {
622 ppinfo[t][c][r][nPrec].nblk[0] = 0;
623 ttIncl[t][c][r][nPrec][0] = new TagTreeEncoder(0, 0);
624 ttMaxBP[t][c][r][nPrec][0] = new TagTreeEncoder(0, 0);
625 }
626 else
627 {
628 ttIncl[t][c][r][nPrec][0] = new TagTreeEncoder(kend - kstart + 1, lend - lstart + 1);
629 ttMaxBP[t][c][r][nPrec][0] = new TagTreeEncoder(kend - kstart + 1, lend - lstart + 1);
630 CBlkCoordInfo[][] tmpArray = new CBlkCoordInfo[kend - kstart + 1][];
631 for (int i2 = 0; i2 < kend - kstart + 1; i2++)
632 {
633 tmpArray[i2] = new CBlkCoordInfo[lend - lstart + 1];
634 }
635 ppinfo[t][c][r][nPrec].cblk[0] = tmpArray;
636 ppinfo[t][c][r][nPrec].nblk[0] = (kend - kstart + 1) * (lend - lstart + 1);
637  
638 for (int k = kstart; k <= kend; k++)
639 {
640 // Vertical cblks
641 for (int l = lstart; l <= lend; l++)
642 {
643 // Horiz. cblks
644  
645 cb = new CBlkCoordInfo(k - k0, l - l0);
646 ppinfo[t][c][r][nPrec].cblk[0][k - kstart][l - lstart] = cb;
647 } // Horizontal code-blocks
648 } // Vertical code-blocks
649 }
650 }
651 else
652 {
653 // HL, LH and HH subbands
654 // HL subband
655 acb0x = 0;
656 acb0y = cb0y;
657  
658 p0x = acb0x + j * twoppx2;
659 p1x = p0x + twoppx2;
660 p0y = acb0y + i * twoppy2;
661 p1y = p0y + twoppy2;
662  
663 sb = (SubbandAn) root.getSubbandByIdx(r, 1);
664 s0x = (p0x < sb.ulcx)?sb.ulcx:p0x;
665 s1x = (p1x > sb.ulcx + sb.w)?sb.ulcx + sb.w:p1x;
666 s0y = (p0y < sb.ulcy)?sb.ulcy:p0y;
667 s1y = (p1y > sb.ulcy + sb.h)?sb.ulcy + sb.h:p1y;
668  
669 // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch)
670 cw = sb.nomCBlkW;
671 ch = sb.nomCBlkH;
672 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
673 k0 = (int) System.Math.Floor((sb.ulcy - acb0y) / (double) ch);
674 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
675 kstart = (int) System.Math.Floor((s0y - acb0y) / (double) ch);
676 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
677 kend = (int) System.Math.Floor((s1y - 1 - acb0y) / (double) ch);
678 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
679 l0 = (int) System.Math.Floor((sb.ulcx - acb0x) / (double) cw);
680 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
681 lstart = (int) System.Math.Floor((s0x - acb0x) / (double) cw);
682 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
683 lend = (int) System.Math.Floor((s1x - 1 - acb0x) / (double) cw);
684  
685 if (s1x - s0x <= 0 || s1y - s0y <= 0)
686 {
687 ppinfo[t][c][r][nPrec].nblk[1] = 0;
688 ttIncl[t][c][r][nPrec][1] = new TagTreeEncoder(0, 0);
689 ttMaxBP[t][c][r][nPrec][1] = new TagTreeEncoder(0, 0);
690 }
691 else
692 {
693 ttIncl[t][c][r][nPrec][1] = new TagTreeEncoder(kend - kstart + 1, lend - lstart + 1);
694 ttMaxBP[t][c][r][nPrec][1] = new TagTreeEncoder(kend - kstart + 1, lend - lstart + 1);
695 CBlkCoordInfo[][] tmpArray2 = new CBlkCoordInfo[kend - kstart + 1][];
696 for (int i3 = 0; i3 < kend - kstart + 1; i3++)
697 {
698 tmpArray2[i3] = new CBlkCoordInfo[lend - lstart + 1];
699 }
700 ppinfo[t][c][r][nPrec].cblk[1] = tmpArray2;
701 ppinfo[t][c][r][nPrec].nblk[1] = (kend - kstart + 1) * (lend - lstart + 1);
702  
703 for (int k = kstart; k <= kend; k++)
704 {
705 // Vertical cblks
706 for (int l = lstart; l <= lend; l++)
707 {
708 // Horiz. cblks
709 cb = new CBlkCoordInfo(k - k0, l - l0);
710 ppinfo[t][c][r][nPrec].cblk[1][k - kstart][l - lstart] = cb;
711 } // Horizontal code-blocks
712 } // Vertical code-blocks
713 }
714  
715 // LH subband
716 acb0x = cb0x;
717 acb0y = 0;
718  
719 p0x = acb0x + j * twoppx2;
720 p1x = p0x + twoppx2;
721 p0y = acb0y + i * twoppy2;
722 p1y = p0y + twoppy2;
723  
724 sb = (SubbandAn) root.getSubbandByIdx(r, 2);
725 s0x = (p0x < sb.ulcx)?sb.ulcx:p0x;
726 s1x = (p1x > sb.ulcx + sb.w)?sb.ulcx + sb.w:p1x;
727 s0y = (p0y < sb.ulcy)?sb.ulcy:p0y;
728 s1y = (p1y > sb.ulcy + sb.h)?sb.ulcy + sb.h:p1y;
729  
730 // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch)
731 cw = sb.nomCBlkW;
732 ch = sb.nomCBlkH;
733 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
734 k0 = (int) System.Math.Floor((sb.ulcy - acb0y) / (double) ch);
735 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
736 kstart = (int) System.Math.Floor((s0y - acb0y) / (double) ch);
737 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
738 kend = (int) System.Math.Floor((s1y - 1 - acb0y) / (double) ch);
739 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
740 l0 = (int) System.Math.Floor((sb.ulcx - acb0x) / (double) cw);
741 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
742 lstart = (int) System.Math.Floor((s0x - acb0x) / (double) cw);
743 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
744 lend = (int) System.Math.Floor((s1x - 1 - acb0x) / (double) cw);
745  
746 if (s1x - s0x <= 0 || s1y - s0y <= 0)
747 {
748 ppinfo[t][c][r][nPrec].nblk[2] = 0;
749 ttIncl[t][c][r][nPrec][2] = new TagTreeEncoder(0, 0);
750 ttMaxBP[t][c][r][nPrec][2] = new TagTreeEncoder(0, 0);
751 }
752 else
753 {
754 ttIncl[t][c][r][nPrec][2] = new TagTreeEncoder(kend - kstart + 1, lend - lstart + 1);
755 ttMaxBP[t][c][r][nPrec][2] = new TagTreeEncoder(kend - kstart + 1, lend - lstart + 1);
756 CBlkCoordInfo[][] tmpArray3 = new CBlkCoordInfo[kend - kstart + 1][];
757 for (int i4 = 0; i4 < kend - kstart + 1; i4++)
758 {
759 tmpArray3[i4] = new CBlkCoordInfo[lend - lstart + 1];
760 }
761 ppinfo[t][c][r][nPrec].cblk[2] = tmpArray3;
762 ppinfo[t][c][r][nPrec].nblk[2] = (kend - kstart + 1) * (lend - lstart + 1);
763  
764 for (int k = kstart; k <= kend; k++)
765 {
766 // Vertical cblks
767 for (int l = lstart; l <= lend; l++)
768 {
769 // Horiz cblks
770 cb = new CBlkCoordInfo(k - k0, l - l0);
771 ppinfo[t][c][r][nPrec].cblk[2][k - kstart][l - lstart] = cb;
772 } // Horizontal code-blocks
773 } // Vertical code-blocks
774 }
775  
776 // HH subband
777 acb0x = 0;
778 acb0y = 0;
779  
780 p0x = acb0x + j * twoppx2;
781 p1x = p0x + twoppx2;
782 p0y = acb0y + i * twoppy2;
783 p1y = p0y + twoppy2;
784  
785 sb = (SubbandAn) root.getSubbandByIdx(r, 3);
786 s0x = (p0x < sb.ulcx)?sb.ulcx:p0x;
787 s1x = (p1x > sb.ulcx + sb.w)?sb.ulcx + sb.w:p1x;
788 s0y = (p0y < sb.ulcy)?sb.ulcy:p0y;
789 s1y = (p1y > sb.ulcy + sb.h)?sb.ulcy + sb.h:p1y;
790  
791 // Code-blocks are located at (acb0x+k*cw,acb0y+l*ch)
792 cw = sb.nomCBlkW;
793 ch = sb.nomCBlkH;
794 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
795 k0 = (int) System.Math.Floor((sb.ulcy - acb0y) / (double) ch);
796 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
797 kstart = (int) System.Math.Floor((s0y - acb0y) / (double) ch);
798 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
799 kend = (int) System.Math.Floor((s1y - 1 - acb0y) / (double) ch);
800 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
801 l0 = (int) System.Math.Floor((sb.ulcx - acb0x) / (double) cw);
802 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
803 lstart = (int) System.Math.Floor((s0x - acb0x) / (double) cw);
804 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
805 lend = (int) System.Math.Floor((s1x - 1 - acb0x) / (double) cw);
806  
807 if (s1x - s0x <= 0 || s1y - s0y <= 0)
808 {
809 ppinfo[t][c][r][nPrec].nblk[3] = 0;
810 ttIncl[t][c][r][nPrec][3] = new TagTreeEncoder(0, 0);
811 ttMaxBP[t][c][r][nPrec][3] = new TagTreeEncoder(0, 0);
812 }
813 else
814 {
815 ttIncl[t][c][r][nPrec][3] = new TagTreeEncoder(kend - kstart + 1, lend - lstart + 1);
816 ttMaxBP[t][c][r][nPrec][3] = new TagTreeEncoder(kend - kstart + 1, lend - lstart + 1);
817 CBlkCoordInfo[][] tmpArray4 = new CBlkCoordInfo[kend - kstart + 1][];
818 for (int i5 = 0; i5 < kend - kstart + 1; i5++)
819 {
820 tmpArray4[i5] = new CBlkCoordInfo[lend - lstart + 1];
821 }
822 ppinfo[t][c][r][nPrec].cblk[3] = tmpArray4;
823 ppinfo[t][c][r][nPrec].nblk[3] = (kend - kstart + 1) * (lend - lstart + 1);
824  
825 for (int k = kstart; k <= kend; k++)
826 {
827 // Vertical cblks
828 for (int l = lstart; l <= lend; l++)
829 {
830 // Horiz cblks
831 cb = new CBlkCoordInfo(k - k0, l - l0);
832 ppinfo[t][c][r][nPrec].cblk[3][k - kstart][l - lstart] = cb;
833 } // Horizontal code-blocks
834 } // Vertical code-blocks
835 }
836 }
837 } // Horizontal precincts
838 } // Vertical precincts
839 }
840  
841 /// <summary> Encodes a packet and returns the buffer containing the encoded packet
842 /// header. The code-blocks appear in a 3D array of CBlkRateDistStats,
843 /// 'cbs'. The first index is the tile index in lexicographical order, the
844 /// second index is the subband index (as defined in the Subband class),
845 /// and the third index is the code-block index (whithin the subband tile)
846 /// in lexicographical order as well. The indexes of the new truncation
847 /// points for each code-block are specified by the 3D array of int
848 /// 'tIndx'. The indices of this array are the same as for cbs. The
849 /// truncation point indices in 'tIndx' are the indices of the elements of
850 /// the 'truncIdxs' array, of the CBlkRateDistStats class, that give the
851 /// real truncation points. If a truncation point index is negative it
852 /// means that the code-block has not been included in any layer yet. If
853 /// the truncation point is less than or equal to the highest truncation
854 /// point used in previous layers then the code-block is not included in
855 /// the packet. Otherwise, if larger, the code-block is included in the
856 /// packet. The body of the packet can be obtained with the
857 /// getLastBodyBuf() and getLastBodyLen() methods.
858 ///
859 /// <p>Layers must be coded in increasing order, in consecutive manner, for
860 /// each tile, component and resolution level (e.g., layer 1, then layer 2,
861 /// etc.). For different tile, component and/or resolution level no
862 /// particular order must be followed.</p>
863 ///
864 /// </summary>
865 /// <param name="ly">The layer index (starts at 1).
866 ///
867 /// </param>
868 /// <param name="c">The component index.
869 ///
870 /// </param>
871 /// <param name="r">The resolution level
872 ///
873 /// </param>
874 /// <param name="t">Index of the current tile
875 ///
876 /// </param>
877 /// <param name="cbs">The 3D array of coded code-blocks.
878 ///
879 /// </param>
880 /// <param name="tIndx">The truncation point indices for each code-block.
881 ///
882 /// </param>
883 /// <param name="hbuf">The header buffer. If null a new BitOutputBuffer is created
884 /// and returned. This buffer is reset before anything is written to it.
885 ///
886 /// </param>
887 /// <param name="bbuf">The body buffer. If null a new one is created. If not large
888 /// enough a new one is created.
889 ///
890 /// </param>
891 /// <param name="pIdx">The precinct index.
892 ///
893 /// </param>
894 /// <returns> The buffer containing the packet header.
895 ///
896 /// </returns>
897 public virtual BitOutputBuffer encodePacket(int ly, int c, int r, int t, CBlkRateDistStats[][] cbs, int[][] tIndx, BitOutputBuffer hbuf, byte[] bbuf, int pIdx)
898 {
899 int b, i, maxi;
900 int ncb;
901 int thmax;
902 int newtp;
903 int cblen;
904 int prednbits, nbits; // deltabits removed
905 TagTreeEncoder cur_ttIncl, cur_ttMaxBP; // inclusion and bit-depth tag
906 // trees
907 int[] cur_prevtIdxs; // last encoded truncation points
908 CBlkRateDistStats[] cur_cbs;
909 int[] cur_tIndx; // truncation points to encode
910 int minsb = (r == 0)?0:1;
911 int maxsb = (r == 0)?1:4;
912 Coord cbCoord = null;
913 SubbandAn root = infoSrc.getAnSubbandTree(t, c);
914 SubbandAn sb;
915 roiInPkt = false;
916 roiLen = 0;
917 int mend, nend;
918  
919 // Checks if a precinct with such an index exists in this resolution
920 // level
921 if (pIdx >= ppinfo[t][c][r].Length)
922 {
923 packetWritable = false;
924 return hbuf;
925 }
926 PrecInfo prec = ppinfo[t][c][r][pIdx];
927  
928 // First, we check if packet is empty (i.e precinct 'pIdx' has no
929 // code-block in any of the subbands)
930 bool isPrecVoid = true;
931  
932 for (int s = minsb; s < maxsb; s++)
933 {
934 if (prec.nblk[s] == 0)
935 {
936 // The precinct has no code-block in this subband.
937 continue;
938 }
939 else
940 {
941 // The precinct is not empty in at least one subband ->
942 // stop
943 isPrecVoid = false;
944 break;
945 }
946 }
947  
948 if (isPrecVoid)
949 {
950 packetWritable = true;
951  
952 if (hbuf == null)
953 {
954 hbuf = new BitOutputBuffer();
955 }
956 else
957 {
958 hbuf.reset();
959 }
960 if (bbuf == null)
961 {
962 lbbuf = bbuf = new byte[1];
963 }
964 hbuf.writeBit(0);
965 lblen = 0;
966  
967 return hbuf;
968 }
969  
970 if (hbuf == null)
971 {
972 hbuf = new BitOutputBuffer();
973 }
974 else
975 {
976 hbuf.reset();
977 }
978  
979 // Invalidate last body buffer
980 lbbuf = null;
981 lblen = 0;
982  
983 // Signal that packet is present
984 hbuf.writeBit(1);
985  
986 for (int s = minsb; s < maxsb; s++)
987 {
988 // Loop on subbands
989 sb = (SubbandAn) root.getSubbandByIdx(r, s);
990  
991 // Go directly to next subband if the precinct has no code-block
992 // in the current one.
993 if (prec.nblk[s] == 0)
994 {
995 continue;
996 }
997  
998 cur_ttIncl = ttIncl[t][c][r][pIdx][s];
999 cur_ttMaxBP = ttMaxBP[t][c][r][pIdx][s];
1000 cur_prevtIdxs = prevtIdxs[t][c][r][s];
1001 cur_cbs = cbs[s];
1002 cur_tIndx = tIndx[s];
1003  
1004 // Set tag tree values for code-blocks in this precinct
1005 mend = (prec.cblk[s] == null)?0:prec.cblk[s].Length;
1006 for (int m = 0; m < mend; m++)
1007 {
1008 nend = (prec.cblk[s][m] == null)?0:prec.cblk[s][m].Length;
1009 for (int n = 0; n < nend; n++)
1010 {
1011 cbCoord = prec.cblk[s][m][n].idx;
1012 b = cbCoord.x + cbCoord.y * sb.numCb.x;
1013  
1014 if (cur_tIndx[b] > cur_prevtIdxs[b] && cur_prevtIdxs[b] < 0)
1015 {
1016 // First inclusion
1017 cur_ttIncl.setValue(m, n, ly - 1);
1018 }
1019 if (ly == 1)
1020 {
1021 // First layer, need to set the skip of MSBP
1022 cur_ttMaxBP.setValue(m, n, cur_cbs[b].skipMSBP);
1023 }
1024 }
1025 }
1026  
1027 // Now encode the information
1028 for (int m = 0; m < prec.cblk[s].Length; m++)
1029 {
1030 // Vertical code-blocks
1031 for (int n = 0; n < prec.cblk[s][m].Length; n++)
1032 {
1033 // Horiz. cblks
1034 cbCoord = prec.cblk[s][m][n].idx;
1035 b = cbCoord.x + cbCoord.y * sb.numCb.x;
1036  
1037 // 1) Inclusion information
1038 if (cur_tIndx[b] > cur_prevtIdxs[b])
1039 {
1040 // Code-block included in this layer
1041 if (cur_prevtIdxs[b] < 0)
1042 {
1043 // First inclusion
1044 // Encode layer info
1045 cur_ttIncl.encode(m, n, ly, hbuf);
1046  
1047 // 2) Max bitdepth info. Encode value
1048 thmax = cur_cbs[b].skipMSBP + 1;
1049 for (i = 1; i <= thmax; i++)
1050 {
1051 cur_ttMaxBP.encode(m, n, i, hbuf);
1052 }
1053  
1054 // Count body size for packet
1055 lblen += cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_tIndx[b]]];
1056 }
1057 else
1058 {
1059 // Already in previous layer
1060 // Send "1" bit
1061 hbuf.writeBit(1);
1062 // Count body size for packet
1063 lblen += cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_tIndx[b]]] - cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]];
1064 }
1065  
1066 // 3) Truncation point information
1067 if (cur_prevtIdxs[b] < 0)
1068 {
1069 newtp = cur_cbs[b].truncIdxs[cur_tIndx[b]];
1070 }
1071 else
1072 {
1073 newtp = cur_cbs[b].truncIdxs[cur_tIndx[b]] - cur_cbs[b].truncIdxs[cur_prevtIdxs[b]] - 1;
1074 }
1075  
1076 // Mix of switch and if is faster
1077 switch (newtp)
1078 {
1079  
1080 case 0:
1081 hbuf.writeBit(0); // Send one "0" bit
1082 break;
1083  
1084 case 1:
1085 hbuf.writeBits(2, 2); // Send one "1" and one "0"
1086 break;
1087  
1088 case 2:
1089 case 3:
1090 case 4:
1091 // Send two "1" bits followed by 2 bits
1092 // representation of newtp-2
1093 hbuf.writeBits((3 << 2) | (newtp - 2), 4);
1094 break;
1095  
1096 default:
1097 if (newtp <= 35)
1098 {
1099 // Send four "1" bits followed by a five bits
1100 // representation of newtp-5
1101 hbuf.writeBits((15 << 5) | (newtp - 5), 9);
1102 }
1103 else if (newtp <= 163)
1104 {
1105 // Send nine "1" bits followed by a seven bits
1106 // representation of newtp-36
1107 hbuf.writeBits((511 << 7) | (newtp - 36), 16);
1108 }
1109 else
1110 {
1111 throw new System.ArithmeticException("Maximum number " + "of truncation " + "points exceeded");
1112 }
1113 break;
1114  
1115 }
1116 }
1117 else
1118 {
1119 // Block not included in this layer
1120 if (cur_prevtIdxs[b] >= 0)
1121 {
1122 // Already in previous layer. Send "0" bit
1123 hbuf.writeBit(0);
1124 }
1125 else
1126 {
1127 // Not in any previous layers
1128 cur_ttIncl.encode(m, n, ly, hbuf);
1129 }
1130 // Go to the next one.
1131 continue;
1132 }
1133  
1134 // Code-block length
1135  
1136 // We need to compute the maximum number of bits needed to
1137 // signal the length of each terminated segment and the
1138 // final truncation point.
1139 newtp = 1;
1140 maxi = cur_cbs[b].truncIdxs[cur_tIndx[b]];
1141 cblen = (cur_prevtIdxs[b] < 0)?0:cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]];
1142  
1143 // Loop on truncation points
1144 i = (cur_prevtIdxs[b] < 0)?0:cur_cbs[b].truncIdxs[cur_prevtIdxs[b]] + 1;
1145 int minbits = 0;
1146 for (; i < maxi; i++, newtp++)
1147 {
1148 // If terminated truncation point calculate length
1149 if (cur_cbs[b].isTermPass != null && cur_cbs[b].isTermPass[i])
1150 {
1151  
1152 // Calculate length
1153 cblen = cur_cbs[b].truncRates[i] - cblen;
1154  
1155 // Calculate number of needed bits
1156 prednbits = lblock[t][c][r][s][b] + MathUtil.log2(newtp);
1157 minbits = ((cblen > 0)?MathUtil.log2(cblen):0) + 1;
1158  
1159 // Update Lblock increment if needed
1160 for (int j = prednbits; j < minbits; j++)
1161 {
1162 lblock[t][c][r][s][b]++;
1163 hbuf.writeBit(1);
1164 }
1165 // Initialize for next length
1166 newtp = 0;
1167 cblen = cur_cbs[b].truncRates[i];
1168 }
1169 }
1170  
1171 // Last truncation point length always sent
1172  
1173 // Calculate length
1174 cblen = cur_cbs[b].truncRates[i] - cblen;
1175  
1176 // Calculate number of bits
1177 prednbits = lblock[t][c][r][s][b] + MathUtil.log2(newtp);
1178 minbits = ((cblen > 0)?MathUtil.log2(cblen):0) + 1;
1179 // Update Lblock increment if needed
1180 for (int j = prednbits; j < minbits; j++)
1181 {
1182 lblock[t][c][r][s][b]++;
1183 hbuf.writeBit(1);
1184 }
1185  
1186 // End of comma-code increment
1187 hbuf.writeBit(0);
1188  
1189 // There can be terminated several segments, send length
1190 // info for all terminated truncation points in addition
1191 // to final one
1192 newtp = 1;
1193 maxi = cur_cbs[b].truncIdxs[cur_tIndx[b]];
1194 cblen = (cur_prevtIdxs[b] < 0)?0:cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]];
1195 // Loop on truncation points and count the groups
1196 i = (cur_prevtIdxs[b] < 0)?0:cur_cbs[b].truncIdxs[cur_prevtIdxs[b]] + 1;
1197 for (; i < maxi; i++, newtp++)
1198 {
1199 // If terminated truncation point, send length
1200 if (cur_cbs[b].isTermPass != null && cur_cbs[b].isTermPass[i])
1201 {
1202  
1203 cblen = cur_cbs[b].truncRates[i] - cblen;
1204 nbits = MathUtil.log2(newtp) + lblock[t][c][r][s][b];
1205 hbuf.writeBits(cblen, nbits);
1206  
1207 // Initialize for next length
1208 newtp = 0;
1209 cblen = cur_cbs[b].truncRates[i];
1210 }
1211 }
1212 // Last truncation point length is always signalled
1213 // First calculate number of bits needed to signal
1214 // Calculate length
1215 cblen = cur_cbs[b].truncRates[i] - cblen;
1216 nbits = MathUtil.log2(newtp) + lblock[t][c][r][s][b];
1217 hbuf.writeBits(cblen, nbits);
1218 } // End loop on horizontal code-blocks
1219 } // End loop on vertical code-blocks
1220 } // End loop on subband
1221  
1222 // -> Copy the data to the body buffer
1223  
1224 // Ensure size for body data
1225 if (bbuf == null || bbuf.Length < lblen)
1226 {
1227 bbuf = new byte[lblen];
1228 }
1229 lbbuf = bbuf;
1230 lblen = 0;
1231  
1232 for (int s = minsb; s < maxsb; s++)
1233 {
1234 // Loop on subbands
1235 sb = (SubbandAn) root.getSubbandByIdx(r, s);
1236  
1237 cur_prevtIdxs = prevtIdxs[t][c][r][s];
1238 cur_cbs = cbs[s];
1239 cur_tIndx = tIndx[s];
1240 ncb = cur_prevtIdxs.Length;
1241  
1242 mend = (prec.cblk[s] == null)?0:prec.cblk[s].Length;
1243 for (int m = 0; m < mend; m++)
1244 {
1245 // Vertical code-blocks
1246 nend = (prec.cblk[s][m] == null)?0:prec.cblk[s][m].Length;
1247 for (int n = 0; n < nend; n++)
1248 {
1249 // Horiz. cblks
1250 cbCoord = prec.cblk[s][m][n].idx;
1251 b = cbCoord.x + cbCoord.y * sb.numCb.x;
1252  
1253 if (cur_tIndx[b] > cur_prevtIdxs[b])
1254 {
1255  
1256 // Block included in this precinct -> Copy data to
1257 // body buffer and get code-size
1258 if (cur_prevtIdxs[b] < 0)
1259 {
1260 cblen = cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_tIndx[b]]];
1261 Array.Copy(cur_cbs[b].data, 0, lbbuf, lblen, cblen);
1262 }
1263 else
1264 {
1265 cblen = cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_tIndx[b]]] - cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]];
1266 Array.Copy(cur_cbs[b].data, cur_cbs[b].truncRates[cur_cbs[b].truncIdxs[cur_prevtIdxs[b]]], lbbuf, lblen, cblen);
1267 }
1268 lblen += cblen;
1269  
1270 // Verifies if this code-block contains new ROI
1271 // information
1272 if (cur_cbs[b].nROIcoeff != 0 && (cur_prevtIdxs[b] == - 1 || cur_cbs[b].truncIdxs[cur_prevtIdxs[b]] <= cur_cbs[b].nROIcp - 1))
1273 {
1274 roiInPkt = true;
1275 roiLen = lblen;
1276 }
1277  
1278 // Update truncation point
1279 cur_prevtIdxs[b] = cur_tIndx[b];
1280 }
1281 } // End loop on horizontal code-blocks
1282 } // End loop on vertical code-blocks
1283 } // End loop on subbands
1284  
1285 packetWritable = true;
1286  
1287 // Must never happen
1288 if (hbuf.Length == 0)
1289 {
1290 throw new System.ApplicationException("You have found a bug in PktEncoder, method:" + " encodePacket");
1291 }
1292  
1293 return hbuf;
1294 }
1295  
1296 /// <summary> Saves the current state of this object. The last saved state
1297 /// can be restored with the restore() method.
1298 ///
1299 /// </summary>
1300 /// <seealso cref="restore">
1301 ///
1302 /// </seealso>
1303 public virtual void save()
1304 {
1305 int maxsbi, minsbi;
1306  
1307 // Have we done any save yet?
1308 if (bak_lblock == null)
1309 {
1310 // Allocate backup buffers
1311 bak_lblock = new int[ttIncl.Length][][][][];
1312 bak_prevtIdxs = new int[ttIncl.Length][][][][];
1313 for (int t = ttIncl.Length - 1; t >= 0; t--)
1314 {
1315 bak_lblock[t] = new int[ttIncl[t].Length][][][];
1316 bak_prevtIdxs[t] = new int[ttIncl[t].Length][][][];
1317 for (int c = ttIncl[t].Length - 1; c >= 0; c--)
1318 {
1319 bak_lblock[t][c] = new int[lblock[t][c].Length][][];
1320 bak_prevtIdxs[t][c] = new int[ttIncl[t][c].Length][][];
1321 for (int r = lblock[t][c].Length - 1; r >= 0; r--)
1322 {
1323 bak_lblock[t][c][r] = new int[lblock[t][c][r].Length][];
1324 bak_prevtIdxs[t][c][r] = new int[prevtIdxs[t][c][r].Length][];
1325 minsbi = (r == 0)?0:1;
1326 maxsbi = (r == 0)?1:4;
1327 for (int s = minsbi; s < maxsbi; s++)
1328 {
1329 bak_lblock[t][c][r][s] = new int[lblock[t][c][r][s].Length];
1330 bak_prevtIdxs[t][c][r][s] = new int[prevtIdxs[t][c][r][s].Length];
1331 }
1332 }
1333 }
1334 }
1335 }
1336  
1337 //-- Save the data
1338  
1339 // Use reference caches to minimize array access overhead
1340 TagTreeEncoder[][][] ttIncl_t_c, ttMaxBP_t_c;
1341 TagTreeEncoder[][] ttIncl_t_c_r, ttMaxBP_t_c_r;
1342 int[][][] lblock_t_c, bak_lblock_t_c;
1343 int[][] prevtIdxs_t_c_r, bak_prevtIdxs_t_c_r;
1344  
1345 // Loop on tiles
1346 for (int t = ttIncl.Length - 1; t >= 0; t--)
1347 {
1348 // Loop on components
1349 for (int c = ttIncl[t].Length - 1; c >= 0; c--)
1350 {
1351 // Initialize reference caches
1352 lblock_t_c = lblock[t][c];
1353 bak_lblock_t_c = bak_lblock[t][c];
1354 ttIncl_t_c = ttIncl[t][c];
1355 ttMaxBP_t_c = ttMaxBP[t][c];
1356 // Loop on resolution levels
1357 for (int r = lblock_t_c.Length - 1; r >= 0; r--)
1358 {
1359 // Initialize reference caches
1360 ttIncl_t_c_r = ttIncl_t_c[r];
1361 ttMaxBP_t_c_r = ttMaxBP_t_c[r];
1362 prevtIdxs_t_c_r = prevtIdxs[t][c][r];
1363 bak_prevtIdxs_t_c_r = bak_prevtIdxs[t][c][r];
1364  
1365 // Loop on subbands
1366 minsbi = (r == 0)?0:1;
1367 maxsbi = (r == 0)?1:4;
1368 for (int s = minsbi; s < maxsbi; s++)
1369 {
1370 // Save 'lblock'
1371 Array.Copy(lblock_t_c[r][s], 0, bak_lblock_t_c[r][s], 0, lblock_t_c[r][s].Length);
1372 // Save 'prevtIdxs'
1373 Array.Copy(prevtIdxs_t_c_r[s], 0, bak_prevtIdxs_t_c_r[s], 0, prevtIdxs_t_c_r[s].Length);
1374 } // End loop on subbands
1375  
1376 // Loop on precincts
1377 for (int p = ppinfo[t][c][r].Length - 1; p >= 0; p--)
1378 {
1379 if (p < ttIncl_t_c_r.Length)
1380 {
1381 // Loop on subbands
1382 for (int s = minsbi; s < maxsbi; s++)
1383 {
1384 ttIncl_t_c_r[p][s].save();
1385 ttMaxBP_t_c_r[p][s].save();
1386 } // End loop on subbands
1387 }
1388 } // End loop on precincts
1389 } // End loop on resolutions
1390 } // End loop on components
1391 } // End loop on tiles
1392  
1393 // Set the saved state
1394 saved = true;
1395 }
1396  
1397 /// <summary> Restores the last saved state of this object. An
1398 /// IllegalArgumentException is thrown if no state has been saved.
1399 ///
1400 /// </summary>
1401 /// <seealso cref="save">
1402 ///
1403 /// </seealso>
1404 public virtual void restore()
1405 {
1406 int maxsbi, minsbi;
1407  
1408 if (!saved)
1409 {
1410 throw new System.ArgumentException();
1411 }
1412  
1413 // Invalidate last encoded body buffer
1414 lbbuf = null;
1415  
1416 //-- Restore tha data
1417  
1418 // Use reference caches to minimize array access overhead
1419 TagTreeEncoder[][][] ttIncl_t_c, ttMaxBP_t_c;
1420 TagTreeEncoder[][] ttIncl_t_c_r, ttMaxBP_t_c_r;
1421 int[][][] lblock_t_c, bak_lblock_t_c;
1422 int[][] prevtIdxs_t_c_r, bak_prevtIdxs_t_c_r;
1423  
1424 // Loop on tiles
1425 for (int t = ttIncl.Length - 1; t >= 0; t--)
1426 {
1427 // Loop on components
1428 for (int c = ttIncl[t].Length - 1; c >= 0; c--)
1429 {
1430 // Initialize reference caches
1431 lblock_t_c = lblock[t][c];
1432 bak_lblock_t_c = bak_lblock[t][c];
1433 ttIncl_t_c = ttIncl[t][c];
1434 ttMaxBP_t_c = ttMaxBP[t][c];
1435 // Loop on resolution levels
1436 for (int r = lblock_t_c.Length - 1; r >= 0; r--)
1437 {
1438 // Initialize reference caches
1439 ttIncl_t_c_r = ttIncl_t_c[r];
1440 ttMaxBP_t_c_r = ttMaxBP_t_c[r];
1441 prevtIdxs_t_c_r = prevtIdxs[t][c][r];
1442 bak_prevtIdxs_t_c_r = bak_prevtIdxs[t][c][r];
1443  
1444 // Loop on subbands
1445 minsbi = (r == 0)?0:1;
1446 maxsbi = (r == 0)?1:4;
1447 for (int s = minsbi; s < maxsbi; s++)
1448 {
1449 // Restore 'lblock'
1450 Array.Copy(bak_lblock_t_c[r][s], 0, lblock_t_c[r][s], 0, lblock_t_c[r][s].Length);
1451 // Restore 'prevtIdxs'
1452 Array.Copy(bak_prevtIdxs_t_c_r[s], 0, prevtIdxs_t_c_r[s], 0, prevtIdxs_t_c_r[s].Length);
1453 } // End loop on subbands
1454  
1455 // Loop on precincts
1456 for (int p = ppinfo[t][c][r].Length - 1; p >= 0; p--)
1457 {
1458 if (p < ttIncl_t_c_r.Length)
1459 {
1460 // Loop on subbands
1461 for (int s = minsbi; s < maxsbi; s++)
1462 {
1463 ttIncl_t_c_r[p][s].restore();
1464 ttMaxBP_t_c_r[p][s].restore();
1465 } // End loop on subbands
1466 }
1467 } // End loop on precincts
1468 } // End loop on resolution levels
1469 } // End loop on components
1470 } // End loop on tiles
1471 }
1472  
1473 /// <summary> Resets the state of the object to the initial state, as if the object
1474 /// was just created.
1475 ///
1476 /// </summary>
1477 public virtual void reset()
1478 {
1479 int maxsbi, minsbi;
1480  
1481 // Invalidate save
1482 saved = false;
1483 // Invalidate last encoded body buffer
1484 lbbuf = null;
1485  
1486 // Reinitialize each element in the arrays
1487  
1488 // Use reference caches to minimize array access overhead
1489 TagTreeEncoder[][][] ttIncl_t_c, ttMaxBP_t_c;
1490 TagTreeEncoder[][] ttIncl_t_c_r, ttMaxBP_t_c_r;
1491 int[][][] lblock_t_c;
1492 int[][] prevtIdxs_t_c_r;
1493  
1494 // Loop on tiles
1495 for (int t = ttIncl.Length - 1; t >= 0; t--)
1496 {
1497 // Loop on components
1498 for (int c = ttIncl[t].Length - 1; c >= 0; c--)
1499 {
1500 // Initialize reference caches
1501 lblock_t_c = lblock[t][c];
1502 ttIncl_t_c = ttIncl[t][c];
1503 ttMaxBP_t_c = ttMaxBP[t][c];
1504 // Loop on resolution levels
1505 for (int r = lblock_t_c.Length - 1; r >= 0; r--)
1506 {
1507 // Initialize reference caches
1508 ttIncl_t_c_r = ttIncl_t_c[r];
1509 ttMaxBP_t_c_r = ttMaxBP_t_c[r];
1510 prevtIdxs_t_c_r = prevtIdxs[t][c][r];
1511  
1512 // Loop on subbands
1513 minsbi = (r == 0)?0:1;
1514 maxsbi = (r == 0)?1:4;
1515 for (int s = minsbi; s < maxsbi; s++)
1516 {
1517 // Reset 'prevtIdxs'
1518 ArrayUtil.intArraySet(prevtIdxs_t_c_r[s], - 1);
1519 // Reset 'lblock'
1520 ArrayUtil.intArraySet(lblock_t_c[r][s], INIT_LBLOCK);
1521 } // End loop on subbands
1522  
1523 // Loop on precincts
1524 for (int p = ppinfo[t][c][r].Length - 1; p >= 0; p--)
1525 {
1526 if (p < ttIncl_t_c_r.Length)
1527 {
1528 // Loop on subbands
1529 for (int s = minsbi; s < maxsbi; s++)
1530 {
1531 ttIncl_t_c_r[p][s].reset();
1532 ttMaxBP_t_c_r[p][s].reset();
1533 } // End loop on subbands
1534 }
1535 } // End loop on precincts
1536 } // End loop on resolution levels
1537 } // End loop on components
1538 } // End loop on tiles
1539 }
1540  
1541 /// <summary> Returns information about a given precinct
1542 ///
1543 /// </summary>
1544 /// <param name="t">Tile index.
1545 ///
1546 /// </param>
1547 /// <param name="c">Component index.
1548 ///
1549 /// </param>
1550 /// <param name="r">Resolution level index.
1551 ///
1552 /// </param>
1553 /// <param name="p">Precinct index
1554 ///
1555 /// </param>
1556 public virtual PrecInfo getPrecInfo(int t, int c, int r, int p)
1557 {
1558 return ppinfo[t][c][r][p];
1559 }
1560 }
1561 }