corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * CVS identifier:
3 *
4 * $Id: StdEntropyCoder.java,v 1.41 2002/07/04 15:53:32 grosbois Exp $
5 *
6 * Class: StdEntropyCoder
7 *
8 * Description: Entropy coding engine of stripes in code-blocks
9 *
10 *
11 *
12 * COPYRIGHT:
13 *
14 * This software module was originally developed by Raphaël Grosbois and
15 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
16 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
17 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
18 * Centre France S.A) in the course of development of the JPEG2000
19 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
20 * software module is an implementation of a part of the JPEG 2000
21 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
22 * Systems AB and Canon Research Centre France S.A (collectively JJ2000
23 * Partners) agree not to assert against ISO/IEC and users of the JPEG
24 * 2000 Standard (Users) any of their rights under the copyright, not
25 * including other intellectual property rights, for this software module
26 * with respect to the usage by ISO/IEC and Users of this software module
27 * or modifications thereof for use in hardware or software products
28 * claiming conformance to the JPEG 2000 Standard. Those intending to use
29 * this software module in hardware or software products are advised that
30 * their use may infringe existing patents. The original developers of
31 * this software module, JJ2000 Partners and ISO/IEC assume no liability
32 * for use of this software module or modifications thereof. No license
33 * or right to this software module is granted for non JPEG 2000 Standard
34 * conforming products. JJ2000 Partners have full right to use this
35 * software module for his/her own purpose, assign or donate this
36 * software module to any third party and to inhibit third parties from
37 * using this software module for non JPEG 2000 Standard conforming
38 * products. This copyright notice must be included in all copies or
39 * derivative works of this software module.
40 *
41 * Copyright (c) 1999/2000 JJ2000 Partners.
42 * */
43 using System;
44 using CSJ2K.j2k.quantization.quantizer;
45 using CSJ2K.j2k.wavelet.analysis;
46 using CSJ2K.j2k.codestream;
47 using CSJ2K.j2k.wavelet;
48 using CSJ2K.j2k.encoder;
49 using CSJ2K.j2k.entropy;
50 using CSJ2K.j2k.image;
51 using CSJ2K.j2k.util;
52 using CSJ2K.j2k.io;
53 using CSJ2K.j2k;
54 namespace CSJ2K.j2k.entropy.encoder
55 {
56  
57 /// <summary> This class implements the JPEG 2000 entropy coder, which codes stripes in
58 /// code-blocks. This entropy coding engine can function in a single-threaded
59 /// mode where one code-block is encoded at a time, or in a multi-threaded mode
60 /// where multiple code-blocks are entropy coded in parallel. The interface
61 /// presented by this class is the same in both modes.
62 ///
63 /// <p>The number of threads used by this entropy coder is specified by the
64 /// "jj2000.j2k.entropy.encoder.StdEntropyCoder.nthreads" Java system
65 /// property. If set to "0" the single threaded implementation is used. If set
66 /// to 'n' ('n' larger than 0) then 'n' extra threads are started by this class
67 /// which are used to encode the code-blocks in parallel (i.e. ideally 'n'
68 /// code-blocks will be encoded in parallel at a time). On multiprocessor
69 /// machines under a "native threads" Java Virtual Machine implementation each
70 /// one of these threads can run on a separate processor speeding up the
71 /// encoding time. By default the single-threaded implementation is used. The
72 /// multi-threaded implementation currently assumes that the vast majority of
73 /// consecutive calls to 'getNextCodeBlock()' will be done on the same
74 /// component. If this is not the case, the speed-up that can be expected on
75 /// multiprocessor machines might be significantly decreased.</p>
76 ///
77 /// <p>The code-blocks are rectangular, with dimensions which must be powers of
78 /// 2. Each dimension has to be no smaller than 4 and no larger than 256. The
79 /// product of the two dimensions (i.e. area of the code-block) may not exceed
80 /// 4096.</p>
81 ///
82 /// <p>Context 0 of the MQ-coder is used as the uniform one (uniform,
83 /// non-adaptive probability distribution). Context 1 is used for RLC
84 /// coding. Contexts 2-10 are used for zero-coding (ZC), contexts 11-15 are
85 /// used for sign-coding (SC) and contexts 16-18 are used for
86 /// magnitude-refinement (MR).</p>
87 ///
88 /// <p>This implementation buffers the symbols and calls the MQ coder only once
89 /// per stripe and per coding pass, to reduce the method call overhead.</p>
90 ///
91 /// <p>This implementation also provides some timing features. They can be
92 /// enabled by setting the 'DO_TIMING' constant of this class to true and
93 /// recompiling. The timing uses the 'System.currentTimeMillis()' Java API
94 /// call, which returns wall clock time, not the actual CPU time used. The
95 /// timing results will be printed on the message output. Since the times
96 /// reported are wall clock times and not CPU usage times they can not be added
97 /// to find the total used time (i.e. some time might be counted in several
98 /// places). When timing is disabled ('DO_TIMING' is false) there is no penalty
99 /// if the compiler performs some basic optimizations. Even if not the penalty
100 /// should be negligeable.</p>
101 ///
102 /// <p>The source module must implement the CBlkQuantDataSrcEnc interface and
103 /// code-block's data is received in a CBlkWTData instance. This modules sends
104 /// code-block's information in a CBlkRateDistStats instance.</p>
105 ///
106 /// </summary>
107 /// <seealso cref="CBlkQuantDataSrcEnc">
108 /// </seealso>
109 /// <seealso cref="CBlkWTData">
110 /// </seealso>
111 /// <seealso cref="CBlkRateDistStats">
112 ///
113 /// </seealso>
114 public class StdEntropyCoder:EntropyCoder
115 {
116  
117 /// <summary>Whether to collect timing information or not: false. Used as a compile
118 /// time directive.
119 /// </summary>
120 private const bool DO_TIMING = false;
121  
122 /// <summary>The cumulative wall time for the entropy coding engine, for each
123 /// component. In the single-threaded implementation it is the total time,
124 /// in the multi-threaded implementation it is the time spent managing the
125 /// compressor threads only.
126 /// </summary>
127 //private long[] time;
128  
129 /// <summary>The Java system property name for the number of threads to use:
130 /// jj2000.j2k.entropy.encoder.StdEntropyCoder.nthreads
131 /// </summary>
132 public const System.String THREADS_PROP_NAME = "jj2000.j2k.entropy.encoder.StdEntropyCoder.nthreads";
133  
134 /// <summary>The default value for the property in THREADS_PROP_NAME: 0 </summary>
135 public const System.String DEF_THREADS_NUM = "0";
136  
137 /// <summary>The increase in priority for the compressor threads, currently 3. The
138 /// compressor threads will have a priority of THREADS_PRIORITY_INC more
139 /// than the priority of the thread calling this class constructor. Used
140 /// only in the multi-threaded implementation.
141 /// </summary>
142 public const int THREADS_PRIORITY_INC = 0;
143  
144 /// <summary>The pool of threads, for the threaded implementation. It is null, if
145 /// non threaded implementation is used
146 /// </summary>
147 private ThreadPool tPool;
148  
149 /// <summary>The queue of idle compressors. Used in multithreaded
150 /// implementation only
151 /// </summary>
152 private System.Collections.ArrayList idleComps;
153  
154 /// <summary>The queue of completed compressors, for each component. Used
155 /// in multithreaded implementation only.
156 /// </summary>
157 private System.Collections.ArrayList[] completedComps;
158  
159 /// <summary>The number of busy compressors, for each component. Used in
160 /// multithreaded implementation only.
161 /// </summary>
162 private int[] nBusyComps;
163  
164 /// <summary>A flag indicating for each component if all the code-blocks of the *
165 /// current tile have been returned. Used in multithreaded implementation
166 /// only.
167 /// </summary>
168 private bool[] finishedTileComponent;
169  
170 /// <summary>The MQ coder used, for each thread </summary>
171 private MQCoder[] mqT;
172  
173 /// <summary>The raw bit output used, for each thread </summary>
174 private BitToByteOutput[] boutT;
175  
176 /// <summary>The output stream used, for each thread </summary>
177 private ByteOutputBuffer[] outT;
178  
179 /// <summary>The code-block size specifications </summary>
180 private CBlkSizeSpec cblks;
181  
182 /// <summary>The precinct partition specifications </summary>
183 private PrecinctSizeSpec pss;
184  
185 /// <summary>By-pass mode specifications </summary>
186 public StringSpec bms;
187  
188 /// <summary>MQ reset specifications </summary>
189 public StringSpec mqrs;
190  
191 /// <summary>Regular termination specifications </summary>
192 public StringSpec rts;
193  
194 /// <summary>Causal stripes specifications </summary>
195 public StringSpec css;
196  
197 /// <summary>Error resilience segment symbol use specifications </summary>
198 public StringSpec sss;
199  
200 /// <summary>The length calculation specifications </summary>
201 public StringSpec lcs;
202  
203 /// <summary>The termination type specifications </summary>
204 public StringSpec tts;
205  
206 /// <summary>The options that are turned on, as flag bits. One element for each
207 /// tile-component. The options are 'OPT_TERM_PASS', 'OPT_RESET_MQ',
208 /// 'OPT_VERT_STR_CAUSAL', 'OPT_BYPASS' and 'OPT_SEG_SYMBOLS' as defined in
209 /// the StdEntropyCoderOptions interface
210 ///
211 /// </summary>
212 /// <seealso cref="StdEntropyCoderOptions">
213 ///
214 /// </seealso>
215 private int[][] opts = null;
216  
217 /// <summary>The length calculation type for each tile-component </summary>
218 private int[][] lenCalc = null;
219  
220 /// <summary>The termination type for each tile-component </summary>
221 private int[][] tType = null;
222  
223 /// <summary>Number of bits used for the Zero Coding lookup table </summary>
224 private const int ZC_LUT_BITS = 8;
225  
226 /// <summary>Zero Coding context lookup tables for the LH global orientation </summary>
227 //UPGRADE_NOTE: Final was removed from the declaration of 'ZC_LUT_LH '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
228 private static readonly int[] ZC_LUT_LH = new int[1 << ZC_LUT_BITS];
229  
230 /// <summary>Zero Coding context lookup tables for the HL global orientation </summary>
231 //UPGRADE_NOTE: Final was removed from the declaration of 'ZC_LUT_HL '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
232 private static readonly int[] ZC_LUT_HL = new int[1 << ZC_LUT_BITS];
233  
234 /// <summary>Zero Coding context lookup tables for the HH global orientation </summary>
235 //UPGRADE_NOTE: Final was removed from the declaration of 'ZC_LUT_HH '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
236 private static readonly int[] ZC_LUT_HH = new int[1 << ZC_LUT_BITS];
237  
238 /// <summary>Number of bits used for the Sign Coding lookup table </summary>
239 private const int SC_LUT_BITS = 9;
240  
241 /// <summary>Sign Coding context lookup table. The index into the table is a 9 bit
242 /// index, which correspond the the value in the 'state' array shifted by
243 /// 'SC_SHIFT'. Bits 8-5 are the signs of the horizontal-left,
244 /// horizontal-right, vertical-up and vertical-down neighbors,
245 /// respectively. Bit 4 is not used (0 or 1 makes no difference). Bits 3-0
246 /// are the significance of the horizontal-left, horizontal-right,
247 /// vertical-up and vertical-down neighbors, respectively. The least 4 bits
248 /// of the value in the lookup table define the context number and the sign
249 /// bit defines the "sign predictor".
250 /// </summary>
251 //UPGRADE_NOTE: Final was removed from the declaration of 'SC_LUT '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
252 private static readonly int[] SC_LUT = new int[1 << SC_LUT_BITS];
253  
254 /// <summary>The mask to obtain the context index from the 'SC_LUT' </summary>
255 private const int SC_LUT_MASK = (1 << 4) - 1;
256  
257 /// <summary>The shift to obtain the sign predictor from the 'SC_LUT'. It must be
258 /// an unsigned shift.
259 /// </summary>
260 private const int SC_SPRED_SHIFT = 31;
261  
262 /// <summary>The sign bit for int data </summary>
263 private const int INT_SIGN_BIT = 1 << 31;
264  
265 /// <summary>The number of bits used for the Magnitude Refinement lookup table </summary>
266 private const int MR_LUT_BITS = 9;
267  
268 /// <summary>Magnitude Refinement context lookup table </summary>
269 //UPGRADE_NOTE: Final was removed from the declaration of 'MR_LUT '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
270 private static readonly int[] MR_LUT = new int[1 << MR_LUT_BITS];
271  
272 /// <summary>The number of contexts used </summary>
273 private const int NUM_CTXTS = 19;
274  
275 /// <summary>The RLC context </summary>
276 private const int RLC_CTXT = 1;
277  
278 /// <summary>The UNIFORM context (with a uniform probability distribution which
279 /// does not adapt)
280 /// </summary>
281 private const int UNIF_CTXT = 0;
282  
283 /// <summary>The initial states for the MQ coder </summary>
284 //UPGRADE_NOTE: Final was removed from the declaration of 'MQ_INIT'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
285 private static readonly int[] MQ_INIT = new int[]{46, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
286  
287 /// <summary>The 4 bits of the error resilience segmentation symbol (1010) </summary>
288 //UPGRADE_NOTE: Final was removed from the declaration of 'SEG_SYMBOLS'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
289 private static readonly int[] SEG_SYMBOLS = new int[]{1, 0, 1, 0};
290  
291 /// <summary>The 4 contexts for the error resilience segmentation symbol (always
292 /// the UNIFORM context, UNIF_CTXT)
293 /// </summary>
294 //UPGRADE_NOTE: Final was removed from the declaration of 'SEG_SYMB_CTXTS '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
295 private static readonly int[] SEG_SYMB_CTXTS = new int[]{UNIF_CTXT, UNIF_CTXT, UNIF_CTXT, UNIF_CTXT};
296  
297 /// <summary> The state array for each thread. Each element of the state array stores
298 /// the state of two coefficients. The lower 16 bits store the state of a
299 /// coefficient in row 'i' and column 'j', while the upper 16 bits store
300 /// the state of a coefficient in row 'i+1' and column 'j'. The 'i' row is
301 /// either the first or the third row of a stripe. This packing of the
302 /// states into 32 bit words allows a faster scan of all coefficients on
303 /// each coding pass and diminished the amount of data transferred. The
304 /// size of the state array is increased by 1 on each side (top, bottom,
305 /// left, right) to handle boundary conditions without any special logic.
306 ///
307 /// <p>The state of a coefficient is stored in the following way in the
308 /// lower 16 bits, where bit 0 is the least significant bit. Bit 15 is the
309 /// significance of a coefficient (0 if non-significant, 1 otherwise). Bit
310 /// 14 is the visited state (i.e. if a coefficient has been coded in the
311 /// significance propagation pass of the current bit-plane). Bit 13 is the
312 /// "non zero-context" state (i.e. if one of the eight immediate neighbors
313 /// is significant it is 1, otherwise is 0). Bits 12 to 9 store the sign of
314 /// the already significant left, right, up and down neighbors (1 for
315 /// negative, 0 for positive or not yet significant). Bit 8 indicates if
316 /// the magnitude refinement has already been applied to the
317 /// coefficient. Bits 7 to 4 store the significance of the left, right, up
318 /// and down neighbors (1 for significant, 0 for non significant). Bits 3
319 /// to 0 store the significance of the diagonal coefficients (up-left,
320 /// up-right, down-left and down-right; 1 for significant, 0 for non
321 /// significant).</p>
322 ///
323 /// <p>The upper 16 bits the state is stored as in the lower 16 bits, but
324 /// with the bits shifted up by 16.</p>
325 ///
326 /// <p>The lower 16 bits are referred to as "row 1" ("R1") while the upper
327 /// 16 bits are referred to as "row 2" ("R2").</p>
328 ///
329 /// </summary>
330 private int[][] stateT;
331  
332 /* The separation between the upper and lower bits in the state array: 16
333 * */
334 private const int STATE_SEP = 16;
335  
336 /// <summary>The flag bit for the significance in the state array, for row 1. </summary>
337 private const int STATE_SIG_R1 = 1 << 15;
338  
339 /// <summary>The flag bit for the "visited" bit in the state array, for row 1. </summary>
340 private const int STATE_VISITED_R1 = 1 << 14;
341  
342 /// <summary>The flag bit for the "not zero context" bit in the state array, for
343 /// row 1. This bit is always the OR of bits STATE_H_L_R1, STATE_H_R_R1,
344 /// STATE_V_U_R1, STATE_V_D_R1, STATE_D_UL_R1, STATE_D_UR_R1, STATE_D_DL_R1
345 /// and STATE_D_DR_R1.
346 /// </summary>
347 private const int STATE_NZ_CTXT_R1 = 1 << 13;
348  
349 /// <summary>The flag bit for the horizontal-left sign in the state array, for row
350 /// 1. This bit can only be set if the STATE_H_L_R1 is also set.
351 /// </summary>
352 private const int STATE_H_L_SIGN_R1 = 1 << 12;
353  
354 /// <summary>The flag bit for the horizontal-right sign in the state array, for
355 /// row 1. This bit can only be set if the STATE_H_R_R1 is also set.
356 /// </summary>
357 private const int STATE_H_R_SIGN_R1 = 1 << 11;
358  
359 /// <summary>The flag bit for the vertical-up sign in the state array, for row
360 /// 1. This bit can only be set if the STATE_V_U_R1 is also set.
361 /// </summary>
362 private const int STATE_V_U_SIGN_R1 = 1 << 10;
363  
364 /// <summary>The flag bit for the vertical-down sign in the state array, for row
365 /// 1. This bit can only be set if the STATE_V_D_R1 is also set.
366 /// </summary>
367 private const int STATE_V_D_SIGN_R1 = 1 << 9;
368  
369 /// <summary>The flag bit for the previous MR primitive applied in the state array,
370 /// for row 1.
371 /// </summary>
372 private const int STATE_PREV_MR_R1 = 1 << 8;
373  
374 /// <summary>The flag bit for the horizontal-left significance in the state array,
375 /// for row 1.
376 /// </summary>
377 private const int STATE_H_L_R1 = 1 << 7;
378  
379 /// <summary>The flag bit for the horizontal-right significance in the state array,
380 /// for row 1.
381 /// </summary>
382 private const int STATE_H_R_R1 = 1 << 6;
383  
384 /// <summary>The flag bit for the vertical-up significance in the state array, for
385 /// row 1.
386 /// </summary>
387 private const int STATE_V_U_R1 = 1 << 5;
388  
389 /// <summary>The flag bit for the vertical-down significance in the state array,
390 /// for row 1.
391 /// </summary>
392 private const int STATE_V_D_R1 = 1 << 4;
393  
394 /// <summary>The flag bit for the diagonal up-left significance in the state array,
395 /// for row 1.
396 /// </summary>
397 private const int STATE_D_UL_R1 = 1 << 3;
398  
399 /// <summary>The flag bit for the diagonal up-right significance in the state
400 /// array, for row 1.
401 /// </summary>
402 private const int STATE_D_UR_R1 = 1 << 2;
403  
404 /// <summary>The flag bit for the diagonal down-left significance in the state
405 /// array, for row 1.
406 /// </summary>
407 private const int STATE_D_DL_R1 = 1 << 1;
408  
409 /// <summary>The flag bit for the diagonal down-right significance in the state
410 /// array , for row 1.
411 /// </summary>
412 private const int STATE_D_DR_R1 = 1;
413  
414 /// <summary>The flag bit for the significance in the state array, for row 2. </summary>
415 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_SIG_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
416 private static readonly int STATE_SIG_R2 = STATE_SIG_R1 << STATE_SEP;
417  
418 /// <summary>The flag bit for the "visited" bit in the state array, for row 2. </summary>
419 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_VISITED_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
420 private static readonly int STATE_VISITED_R2 = STATE_VISITED_R1 << STATE_SEP;
421  
422 /// <summary>The flag bit for the "not zero context" bit in the state array, for
423 /// row 2. This bit is always the OR of bits STATE_H_L_R2, STATE_H_R_R2,
424 /// STATE_V_U_R2, STATE_V_D_R2, STATE_D_UL_R2, STATE_D_UR_R2, STATE_D_DL_R2
425 /// and STATE_D_DR_R2.
426 /// </summary>
427 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_NZ_CTXT_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
428 private static readonly int STATE_NZ_CTXT_R2 = STATE_NZ_CTXT_R1 << STATE_SEP;
429  
430 /// <summary>The flag bit for the horizontal-left sign in the state array, for row
431 /// 2. This bit can only be set if the STATE_H_L_R2 is also set.
432 /// </summary>
433 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_H_L_SIGN_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
434 private static readonly int STATE_H_L_SIGN_R2 = STATE_H_L_SIGN_R1 << STATE_SEP;
435  
436 /// <summary>The flag bit for the horizontal-right sign in the state array, for
437 /// row 2. This bit can only be set if the STATE_H_R_R2 is also set.
438 /// </summary>
439 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_H_R_SIGN_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
440 private static readonly int STATE_H_R_SIGN_R2 = STATE_H_R_SIGN_R1 << STATE_SEP;
441  
442 /// <summary>The flag bit for the vertical-up sign in the state array, for row
443 /// 2. This bit can only be set if the STATE_V_U_R2 is also set.
444 /// </summary>
445 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_V_U_SIGN_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
446 private static readonly int STATE_V_U_SIGN_R2 = STATE_V_U_SIGN_R1 << STATE_SEP;
447  
448 /// <summary>The flag bit for the vertical-down sign in the state array, for row
449 /// 2. This bit can only be set if the STATE_V_D_R2 is also set.
450 /// </summary>
451 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_V_D_SIGN_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
452 private static readonly int STATE_V_D_SIGN_R2 = STATE_V_D_SIGN_R1 << STATE_SEP;
453  
454 /// <summary>The flag bit for the previous MR primitive applied in the state array,
455 /// for row 2.
456 /// </summary>
457 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_PREV_MR_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
458 private static readonly int STATE_PREV_MR_R2 = STATE_PREV_MR_R1 << STATE_SEP;
459  
460 /// <summary>The flag bit for the horizontal-left significance in the state array,
461 /// for row 2.
462 /// </summary>
463 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_H_L_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
464 private static readonly int STATE_H_L_R2 = STATE_H_L_R1 << STATE_SEP;
465  
466 /// <summary>The flag bit for the horizontal-right significance in the state array,
467 /// for row 2.
468 /// </summary>
469 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_H_R_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
470 private static readonly int STATE_H_R_R2 = STATE_H_R_R1 << STATE_SEP;
471  
472 /// <summary>The flag bit for the vertical-up significance in the state array, for
473 /// row 2.
474 /// </summary>
475 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_V_U_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
476 private static readonly int STATE_V_U_R2 = STATE_V_U_R1 << STATE_SEP;
477  
478 /// <summary>The flag bit for the vertical-down significance in the state array,
479 /// for row 2.
480 /// </summary>
481 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_V_D_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
482 private static readonly int STATE_V_D_R2 = STATE_V_D_R1 << STATE_SEP;
483  
484 /// <summary>The flag bit for the diagonal up-left significance in the state array,
485 /// for row 2.
486 /// </summary>
487 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_D_UL_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
488 private static readonly int STATE_D_UL_R2 = STATE_D_UL_R1 << STATE_SEP;
489  
490 /// <summary>The flag bit for the diagonal up-right significance in the state
491 /// array, for row 2.
492 /// </summary>
493 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_D_UR_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
494 private static readonly int STATE_D_UR_R2 = STATE_D_UR_R1 << STATE_SEP;
495  
496 /// <summary>The flag bit for the diagonal down-left significance in the state
497 /// array, for row 2.
498 /// </summary>
499 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_D_DL_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
500 private static readonly int STATE_D_DL_R2 = STATE_D_DL_R1 << STATE_SEP;
501  
502 /// <summary>The flag bit for the diagonal down-right significance in the state
503 /// array , for row 2.
504 /// </summary>
505 //UPGRADE_NOTE: Final was removed from the declaration of 'STATE_D_DR_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
506 private static readonly int STATE_D_DR_R2 = STATE_D_DR_R1 << STATE_SEP;
507  
508 /// <summary>The mask to isolate the significance bits for row 1 and 2 of the state
509 /// array.
510 /// </summary>
511 //UPGRADE_NOTE: Final was removed from the declaration of 'SIG_MASK_R1R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
512 private static readonly int SIG_MASK_R1R2 = STATE_SIG_R1 | STATE_SIG_R2;
513  
514 /// <summary>The mask to isolate the visited bits for row 1 and 2 of the state
515 /// array.
516 /// </summary>
517 //UPGRADE_NOTE: Final was removed from the declaration of 'VSTD_MASK_R1R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
518 private static readonly int VSTD_MASK_R1R2 = STATE_VISITED_R1 | STATE_VISITED_R2;
519  
520 /// <summary>The mask to isolate the bits necessary to identify RLC coding state
521 /// (significant, visited and non-zero context, for row 1 and 2).
522 /// </summary>
523 //UPGRADE_NOTE: Final was removed from the declaration of 'RLC_MASK_R1R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
524 private static readonly int RLC_MASK_R1R2 = STATE_SIG_R1 | STATE_SIG_R2 | STATE_VISITED_R1 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2;
525  
526 /// <summary>The mask to obtain the ZC_LUT index from the state information </summary>
527 // This is needed because of the STATE_V_D_SIGN_R1, STATE_V_U_SIGN_R1,
528 // STATE_H_R_SIGN_R1, and STATE_H_L_SIGN_R1 bits.
529 private const int ZC_MASK = (1 << 8) - 1;
530  
531 /// <summary>The shift to obtain the SC index to 'SC_LUT' from the state
532 /// information, for row 1.
533 /// </summary>
534 private const int SC_SHIFT_R1 = 4;
535  
536 /// <summary>The shift to obtain the SC index to 'SC_LUT' from the state
537 /// information, for row 2.
538 /// </summary>
539 //UPGRADE_NOTE: Final was removed from the declaration of 'SC_SHIFT_R2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
540 private static readonly int SC_SHIFT_R2 = SC_SHIFT_R1 + STATE_SEP;
541  
542 /// <summary>The bit mask to isolate the state bits relative to the sign coding
543 /// lookup table ('SC_LUT').
544 /// </summary>
545 //UPGRADE_NOTE: Final was removed from the declaration of 'SC_MASK '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
546 private static readonly int SC_MASK = (1 << SC_LUT_BITS) - 1;
547  
548 /// <summary>The mask to obtain the MR index to 'MR_LUT' from the 'state'
549 /// information. It is to be applied after the 'MR_SHIFT'.
550 /// </summary>
551 //UPGRADE_NOTE: Final was removed from the declaration of 'MR_MASK '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
552 private static readonly int MR_MASK = (1 << MR_LUT_BITS) - 1;
553  
554 /// <summary>The number of bits used to index in the 'fm' lookup table, 7. The 'fs'
555 /// table is indexed with one less bit.
556 /// </summary>
557 private const int MSE_LKP_BITS = 7;
558  
559 private const int MSE_LKP_BITS_M1 = 6;
560  
561 /// <summary>The number of fractional bits used to store data in the 'fm' and 'fs'
562 /// lookup tables.
563 /// </summary>
564 private const int MSE_LKP_FRAC_BITS = 13;
565  
566 /// <summary>Distortion estimation lookup table for bits coded using the sign-code
567 /// (SC) primative, for lossy coding (i.e. normal).
568 /// </summary>
569 //UPGRADE_NOTE: Final was removed from the declaration of 'FS_LOSSY '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
570 private static readonly int[] FS_LOSSY = new int[1 << MSE_LKP_BITS_M1];
571  
572 /// <summary>Distortion estimation lookup table for bits coded using the
573 /// magnitude-refinement (MR) primative, for lossy coding (i.e. normal)
574 /// </summary>
575 //UPGRADE_NOTE: Final was removed from the declaration of 'FM_LOSSY '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
576 private static readonly int[] FM_LOSSY = new int[1 << MSE_LKP_BITS];
577  
578 /// <summary>Distortion estimation lookup table for bits coded using the sign-code
579 /// (SC) primative, for lossless coding and last bit-plane. This table is
580 /// different from 'fs_lossy' since when doing lossless coding the residual
581 /// distortion after the last bit-plane is coded is strictly 0.
582 /// </summary>
583 //UPGRADE_NOTE: Final was removed from the declaration of 'FS_LOSSLESS '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
584 private static readonly int[] FS_LOSSLESS = new int[1 << MSE_LKP_BITS_M1];
585  
586 /// <summary>Distortion estimation lookup table for bits coded using the
587 /// magnitude-refinement (MR) primative, for lossless coding and last
588 /// bit-plane. This table is different from 'fs_lossless' since when doing
589 /// lossless coding the residual distortion after the last bit-plane is
590 /// coded is strictly 0.
591 /// </summary>
592 //UPGRADE_NOTE: Final was removed from the declaration of 'FM_LOSSLESS '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
593 private static readonly int[] FM_LOSSLESS = new int[1 << MSE_LKP_BITS];
594  
595 /// <summary>The buffer for distortion values (avoids reallocation for each
596 /// code-block), for each thread.
597 /// </summary>
598 private double[][] distbufT;
599  
600 /// <summary>The buffer for rate values (avoids reallocation for each
601 /// code-block), for each thread.
602 /// </summary>
603 private int[][] ratebufT;
604  
605 /// <summary>The buffer for indicating terminated passes (avoids reallocation for
606 /// each code-block), for each thread.
607 /// </summary>
608 private bool[][] istermbufT;
609  
610 /// <summary>The source code-block to entropy code (avoids reallocation for each
611 /// code-block), for each thread.
612 /// </summary>
613 private CBlkWTData[] srcblkT;
614  
615 /// <summary>Buffer for symbols to send to the MQ-coder, for each thread. Used to
616 /// reduce the number of calls to the MQ coder.
617 /// </summary>
618 // NOTE: The symbol buffer has not prooved to be of any great improvement
619 // in encoding time, but it does not hurt. It's performance should be
620 // better studied under different JVMs.
621 private int[][] symbufT;
622  
623 /// <summary>Buffer for the contexts to use when sending buffered symbols to the
624 /// MQ-coder, for each thread. Used to reduce the number of calls to the MQ
625 /// coder.
626 /// </summary>
627 private int[][] ctxtbufT;
628  
629 /// <summary>boolean used to signal if the precinct partition is used for
630 /// each component and each tile.
631 /// </summary>
632 private bool[][] precinctPartition;
633  
634 //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'Compressor' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'"
635 /// <summary> Class that takes care of running the 'compressCodeBlock()' method with
636 /// thread local arguments. Used only in multithreaded implementation.
637 ///
638 /// </summary>
639 private class Compressor : IThreadRunnable
640 {
641 private void InitBlock(StdEntropyCoder enclosingInstance)
642 {
643 this.enclosingInstance = enclosingInstance;
644 }
645 private StdEntropyCoder enclosingInstance;
646 /// <summary> Returns the index of this compressor.
647 ///
648 /// </summary>
649 /// <returns> The index of this compressor.
650 ///
651 /// </returns>
652 virtual public int Idx
653 {
654 get
655 {
656 return idx;
657 }
658  
659 }
660 public StdEntropyCoder Enclosing_Instance
661 {
662 get
663 {
664 return enclosingInstance;
665 }
666  
667 }
668 /// <summary>The index of this compressor. Used to access thread local
669 /// variables
670 /// </summary>
671 //UPGRADE_NOTE: Final was removed from the declaration of 'idx '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
672 private int idx;
673  
674 /// <summary>The object where to store the compressed code-block </summary>
675 // Should be private, but some buggy JDK 1.1 compilers complain
676 internal CBlkRateDistStats ccb;
677  
678 /// <summary>The component on which to compress </summary>
679 // Should be private, but some buggy JDK 1.1 compilers complain
680 internal int c;
681  
682 /// <summary>The options bitmask to use in compression </summary>
683 // Should be private, but some buggy JDK 1.1 compilers complain
684 internal int options;
685  
686 /// <summary>The reversible flag to use in compression </summary>
687 // Should be private, but some buggy JDK 1.1 compilers complain
688 internal bool rev;
689  
690 /// <summary>The length calculation type to use in compression </summary>
691 // Should be private, but some buggy JDK 1.1 compilers complain
692 internal int lcType;
693  
694 /// <summary>The MQ termination type to use in compression </summary>
695 // Should be private, but some buggy JDK 1.1 compilers complain
696 internal int tType;
697  
698 /// <summary>The cumulative wall time for this compressor, for each
699 /// component.
700 /// </summary>
701 //private long[] time;
702  
703 /// <summary> Creates a new compressor object with the given index.
704 ///
705 /// </summary>
706 /// <param name="idx">The index of this compressor.
707 ///
708 /// </param>
709 internal Compressor(StdEntropyCoder enclosingInstance, int idx)
710 {
711 InitBlock(enclosingInstance);
712 this.idx = idx;
713 #if DO_TIMING
714 time = new long[Enclosing_Instance.src.NumComps];
715 #endif
716 }
717  
718 /// <summary> Calls the 'compressCodeBlock()' method with thread local
719 /// arguments. Once completed it adds itself to the 'completedComps[c]'
720 /// stack, where 'c' is the component for which this compressor is
721 /// running. This last step occurs even if exceptions are thrown by the
722 /// 'compressCodeBlock()' method.
723 ///
724 /// </summary>
725 public virtual void Run()
726 {
727 // Start the code-block compression
728 try
729 {
730 #if DO_TIMING
731 long stime = 0L;
732 stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
733 #endif
734 CSJ2K.j2k.entropy.encoder.StdEntropyCoder.compressCodeBlock(c, ccb, Enclosing_Instance.srcblkT[idx], Enclosing_Instance.mqT[idx], Enclosing_Instance.boutT[idx], Enclosing_Instance.outT[idx], Enclosing_Instance.stateT[idx], Enclosing_Instance.distbufT[idx], Enclosing_Instance.ratebufT[idx], Enclosing_Instance.istermbufT[idx], Enclosing_Instance.symbufT[idx], Enclosing_Instance.ctxtbufT[idx], options, rev, lcType, tType);
735 #if DO_TIMING
736 time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
737 #endif
738 }
739 finally
740 {
741 // Join the queue of completed compression, even if exceptions
742 // occurred.
743 Enclosing_Instance.completedComps[c].Add(this);
744 }
745 }
746 }
747  
748 /// <summary> Instantiates a new entropy coder engine, with the specified source of
749 /// data, nominal block width and height.
750 ///
751 /// <p>If the 'OPT_PRED_TERM' option is given then the MQ termination must
752 /// be 'TERM_PRED_ER' or an exception is thrown.</p>
753 ///
754 /// </summary>
755 /// <param name="src">The source of data
756 ///
757 /// </param>
758 /// <param name="cbks">Code-block size specifications
759 ///
760 /// </param>
761 /// <param name="pss">Precinct partition specifications
762 ///
763 /// </param>
764 /// <param name="bms">By-pass mode specifications
765 ///
766 /// </param>
767 /// <param name="mqrs">MQ-reset specifications
768 ///
769 /// </param>
770 /// <param name="rts">Regular termination specifications
771 ///
772 /// </param>
773 /// <param name="css">Causal stripes specifications
774 ///
775 /// </param>
776 /// <param name="sss">Error resolution segment symbol use specifications
777 ///
778 /// </param>
779 /// <param name="lcs">Length computation specifications
780 ///
781 /// </param>
782 /// <param name="tts">Termination type specifications
783 ///
784 /// </param>
785 /// <seealso cref="MQCoder">
786 ///
787 /// </seealso>
788 public StdEntropyCoder(CBlkQuantDataSrcEnc src, CBlkSizeSpec cblks, PrecinctSizeSpec pss, StringSpec bms, StringSpec mqrs, StringSpec rts, StringSpec css, StringSpec sss, StringSpec lcs, StringSpec tts):base(src)
789 {
790 this.cblks = cblks;
791 this.pss = pss;
792 this.bms = bms;
793 this.mqrs = mqrs;
794 this.rts = rts;
795 this.css = css;
796 this.sss = sss;
797 this.lcs = lcs;
798 this.tts = tts;
799 int maxCBlkWidth, maxCBlkHeight;
800 int i; // Counter
801 int nt; // The number of threads
802 int tsl; // Size for thread structures
803  
804 // Get the biggest width/height for the code-blocks
805 maxCBlkWidth = cblks.MaxCBlkWidth;
806 maxCBlkHeight = cblks.MaxCBlkHeight;
807  
808 nt = Environment.ProcessorCount;
809 /*
810 // Get the number of threads to use, or default to one
811 try
812 {
813 //UPGRADE_ISSUE: Method 'java.lang.System.getProperty' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'"
814 nt = System.Int32.Parse(System_Renamed.getProperty(THREADS_PROP_NAME, DEF_THREADS_NUM));
815 if (nt < 0)
816 throw new System.FormatException();
817 }
818 catch (System.FormatException e)
819 {
820 throw new System.ArgumentException("Invalid number of threads " + "for " + "entropy coding in property " + THREADS_PROP_NAME);
821 }
822 */
823  
824 // If we do timing create necessary structures
825 #if DO_TIMING
826 time = new long[src.NumComps];
827 // If we are timing make sure that 'finalize' gets called.
828 //UPGRADE_ISSUE: Method 'java.lang.System.runFinalizersOnExit' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'"
829 // CONVERSION PROBLEM?
830 //System_Renamed.runFinalizersOnExit(true);
831 #endif
832 // If using multithreaded implementation get necessasry objects
833 if (nt > 0)
834 {
835 FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Using multithreaded entropy coder " + "with " + nt + " compressor threads.");
836 tsl = nt;
837 tPool = new ThreadPool(nt, (System.Int32) SupportClass.ThreadClass.Current().Priority + THREADS_PRIORITY_INC, "StdEntropyCoder");
838 idleComps = new System.Collections.ArrayList();
839 completedComps = new System.Collections.ArrayList[src.NumComps];
840 nBusyComps = new int[src.NumComps];
841 finishedTileComponent = new bool[src.NumComps];
842 for (i = src.NumComps - 1; i >= 0; i--)
843 {
844 completedComps[i] = new System.Collections.ArrayList();
845 }
846 for (i = 0; i < nt; i++)
847 {
848 idleComps.Add(new StdEntropyCoder.Compressor(this, i));
849 }
850 }
851 else
852 {
853 tsl = 1;
854 tPool = null;
855 idleComps = null;
856 completedComps = null;
857 nBusyComps = null;
858 finishedTileComponent = null;
859 }
860  
861 // Allocate data structures
862 outT = new ByteOutputBuffer[tsl];
863 mqT = new MQCoder[tsl];
864 boutT = new BitToByteOutput[tsl];
865 stateT = new int[tsl][];
866 for (int i2 = 0; i2 < tsl; i2++)
867 {
868 stateT[i2] = new int[(maxCBlkWidth + 2) * ((maxCBlkHeight + 1) / 2 + 2)];
869 }
870 symbufT = new int[tsl][];
871 for (int i3 = 0; i3 < tsl; i3++)
872 {
873 symbufT[i3] = new int[maxCBlkWidth * (CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT * 2 + 2)];
874 }
875 ctxtbufT = new int[tsl][];
876 for (int i4 = 0; i4 < tsl; i4++)
877 {
878 ctxtbufT[i4] = new int[maxCBlkWidth * (CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT * 2 + 2)];
879 }
880 distbufT = new double[tsl][];
881 for (int i5 = 0; i5 < tsl; i5++)
882 {
883 distbufT[i5] = new double[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
884 }
885 ratebufT = new int[tsl][];
886 for (int i6 = 0; i6 < tsl; i6++)
887 {
888 ratebufT[i6] = new int[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
889 }
890 istermbufT = new bool[tsl][];
891 for (int i7 = 0; i7 < tsl; i7++)
892 {
893 istermbufT[i7] = new bool[32 * CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES];
894 }
895 srcblkT = new CBlkWTData[tsl];
896 for (i = 0; i < tsl; i++)
897 {
898 outT[i] = new ByteOutputBuffer();
899 mqT[i] = new MQCoder(outT[i], NUM_CTXTS, MQ_INIT);
900 }
901 precinctPartition = new bool[src.NumComps][];
902 for (int i8 = 0; i8 < src.NumComps; i8++)
903 {
904 precinctPartition[i8] = new bool[src.getNumTiles()];
905 }
906  
907 // Create the subband description for each component and each tile
908 //Subband sb = null;
909 Coord numTiles = null;
910 int nc = NumComps;
911 numTiles = src.getNumTiles(numTiles);
912 initTileComp(getNumTiles(), nc);
913  
914 for (int c = 0; c < nc; c++)
915 {
916 for (int tY = 0; tY < numTiles.y; tY++)
917 {
918 for (int tX = 0; tX < numTiles.x; tX++)
919 {
920 precinctPartition[c][tIdx] = false;
921 }
922 }
923 }
924 }
925  
926 #if DO_TIMING
927 /// <summary> Prints the timing information, if collected, and calls 'finalize' on
928 /// the super class.
929 ///
930 /// </summary>
931 ~StdEntropyCoder()
932 {
933  
934 int c;
935 System.Text.StringBuilder sb;
936  
937 if (tPool == null)
938 {
939 // Single threaded implementation
940 sb = new System.Text.StringBuilder("StdEntropyCoder compression wall " + "clock time:");
941 for (c = 0; c < time.Length; c++)
942 {
943 sb.Append("\n component ");
944 sb.Append(c);
945 sb.Append(": ");
946 sb.Append(time[c]);
947 sb.Append(" ms");
948 }
949 FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, sb.ToString());
950 }
951 else
952 {
953 // Multithreaded implementation
954 Compressor compr;
955 MsgLogger msglog = FacilityManager.getMsgLogger();
956  
957 sb = new System.Text.StringBuilder("StdEntropyCoder manager thread " + "wall clock time:");
958 for (c = 0; c < time.Length; c++)
959 {
960 sb.Append("\n component ");
961 sb.Append(c);
962 sb.Append(": ");
963 sb.Append(time[c]);
964 sb.Append(" ms");
965 }
966 System.Collections.IEnumerator Enum = idleComps.GetEnumerator();
967 sb.Append("\nStdEntropyCoder compressor threads wall clock " + "time:");
968 //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
969 while (Enum.MoveNext())
970 {
971 //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
972 compr = (Compressor)(Enum.Current);
973 for (c = 0; c < time.Length; c++)
974 {
975 sb.Append("\n compressor ");
976 sb.Append(compr.Idx);
977 sb.Append(", component ");
978 sb.Append(c);
979 sb.Append(": ");
980 sb.Append(compr.getTiming(c));
981 sb.Append(" ms");
982 }
983 }
984 FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, sb.ToString());
985 }
986  
987 //UPGRADE_NOTE: Call to 'super.finalize()' was removed. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1124'"
988 }
989 #endif
990  
991 /// <summary> Returns the code-block width for the specified tile and component.
992 ///
993 /// </summary>
994 /// <param name="t">The tile index
995 ///
996 /// </param>
997 /// <param name="c">the component index
998 ///
999 /// </param>
1000 /// <returns> The code-block width for the specified tile and component
1001 ///
1002 /// </returns>
1003 public override int getCBlkWidth(int t, int c)
1004 {
1005 return cblks.getCBlkWidth(ModuleSpec.SPEC_TILE_COMP, t, c);
1006 }
1007  
1008 /// <summary> Returns the code-block height for the specified tile and component.
1009 ///
1010 /// </summary>
1011 /// <param name="t">The tile index
1012 ///
1013 /// </param>
1014 /// <param name="c">The component index
1015 ///
1016 /// </param>
1017 /// <returns> The code-block height for the specified tile and component.
1018 ///
1019 /// </returns>
1020 public override int getCBlkHeight(int t, int c)
1021 {
1022 return cblks.getCBlkHeight(ModuleSpec.SPEC_TILE_COMP, t, c);
1023 }
1024  
1025 /// <summary> Returns the next coded code-block in the current tile for the specified
1026 /// component, as a copy (see below). The order in which code-blocks are
1027 /// returned is not specified. However each code-block is returned only
1028 /// once and all code-blocks will be returned if the method is called 'N'
1029 /// times, where 'N' is the number of code-blocks in the tile. After all
1030 /// the code-blocks have been returned for the current tile calls to this
1031 /// method will return 'null'.
1032 ///
1033 /// <p>When changing the current tile (through 'setTile()' or 'nextTile()')
1034 /// this method will always return the first code-block, as if this method
1035 /// was never called before for the new current tile.</p>
1036 ///
1037 /// <p>The data returned by this method is always a copy of the internal
1038 /// data of this object, if any, and it can be modified "in place" without
1039 /// any problems after being returned.</p>
1040 ///
1041 /// </summary>
1042 /// <param name="c">The component for which to return the next code-block.
1043 ///
1044 /// </param>
1045 /// <param name="ccb">If non-null this object might be used in returning the coded
1046 /// code-block in this or any subsequent call to this method. If null a new
1047 /// one is created and returned. If the 'data' array of 'cbb' is not null
1048 /// it may be reused to return the compressed data.
1049 ///
1050 /// </param>
1051 /// <returns> The next coded code-block in the current tile for component
1052 /// 'n', or null if all code-blocks for the current tile have been
1053 /// returned.
1054 ///
1055 /// </returns>
1056 /// <seealso cref="CBlkRateDistStats">
1057 ///
1058 /// </seealso>
1059 public override CBlkRateDistStats getNextCodeBlock(int c, CBlkRateDistStats ccb)
1060 {
1061 #if DO_TIMING
1062 long stime = 0L; // Start time for timed sections
1063 #endif
1064 if (tPool == null)
1065 {
1066 // Use single threaded implementation
1067 // Get code-block data from source
1068 srcblkT[0] = src.getNextInternCodeBlock(c, srcblkT[0]);
1069  
1070 #if DO_TIMING
1071 stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
1072 #endif
1073  
1074 if (srcblkT[0] == null)
1075 {
1076 // We got all code-blocks
1077 return null;
1078 }
1079 // Initialize thread local variables
1080 if ((opts[tIdx][c] & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && boutT[0] == null)
1081 {
1082 boutT[0] = new BitToByteOutput(outT[0]);
1083 }
1084 // Initialize output code-block
1085 if (ccb == null)
1086 {
1087 ccb = new CBlkRateDistStats();
1088 }
1089 // Compress code-block
1090 compressCodeBlock(c, ccb, srcblkT[0], mqT[0], boutT[0], outT[0], stateT[0], distbufT[0], ratebufT[0], istermbufT[0], symbufT[0], ctxtbufT[0], opts[tIdx][c], isReversible(tIdx, c), lenCalc[tIdx][c], tType[tIdx][c]);
1091  
1092 #if DO_TIMING
1093 time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
1094 #endif
1095  
1096 // Return result
1097 return ccb;
1098 }
1099 else
1100 {
1101 // Use multiple threaded implementation
1102 int cIdx; // Compressor idx
1103 Compressor compr; // Compressor
1104  
1105 #if DO_TIMING
1106 stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
1107 #endif
1108 // Give data to all free compressors, using the current component
1109 while (!finishedTileComponent[c] && !(idleComps.Count == 0))
1110 {
1111 // Get an idle compressor
1112 compr = (Compressor) SupportClass.StackSupport.Pop(idleComps);
1113 cIdx = compr.Idx;
1114 // Get data for the compressor and wake it up
1115 #if DO_TIMING
1116 time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
1117 #endif
1118 srcblkT[cIdx] = src.getNextInternCodeBlock(c, srcblkT[cIdx]);
1119 #if DO_TIMING
1120 stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
1121 #endif
1122 if (srcblkT[cIdx] != null)
1123 {
1124 // Initialize thread local variables
1125 if ((opts[tIdx][c] & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && boutT[cIdx] == null)
1126 {
1127 boutT[cIdx] = new BitToByteOutput(outT[cIdx]);
1128 }
1129 // Initialize output code-block and compressor thread
1130 if (ccb == null)
1131 ccb = new CBlkRateDistStats();
1132 compr.ccb = ccb;
1133 compr.c = c;
1134 compr.options = opts[tIdx][c];
1135 compr.rev = isReversible(tIdx, c);
1136 compr.lcType = lenCalc[tIdx][c];
1137 compr.tType = tType[tIdx][c];
1138 nBusyComps[c]++;
1139 ccb = null;
1140 // Send compressor to execution in thread pool
1141 tPool.runTarget(compr, completedComps[c]);
1142 }
1143 else
1144 {
1145 // We finished with all the code-blocks in the current
1146 // tile component
1147 idleComps.Add(compr);
1148 finishedTileComponent[c] = true;
1149 }
1150 }
1151 // If there are threads for this component which result has not
1152 // been returned yet, get it
1153 if (nBusyComps[c] > 0)
1154 {
1155 lock (completedComps[c])
1156 {
1157 // If no compressor is done, wait until one is
1158 if ((completedComps[c].Count == 0))
1159 {
1160 try
1161 {
1162 #if DO_TIMING
1163 time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
1164 #endif
1165 System.Threading.Monitor.Wait(completedComps[c]);
1166 #if DO_TIMING
1167 stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
1168 #endif
1169 }
1170 catch (System.Threading.ThreadInterruptedException)
1171 {
1172 }
1173 }
1174 // Remove the thread from the completed queue and put it
1175 // on the idle queue
1176 compr = (Compressor) SupportClass.StackSupport.Pop(completedComps[c]);
1177 cIdx = compr.Idx;
1178 nBusyComps[c]--;
1179 idleComps.Add(compr);
1180 // Check targets error condition
1181 tPool.checkTargetErrors();
1182 // Get the result of compression and return that.
1183 #if DO_TIMING
1184 time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
1185 #endif
1186 return compr.ccb;
1187 }
1188 }
1189 else
1190 {
1191 // Check targets error condition
1192 tPool.checkTargetErrors();
1193 // Printing timing info if necessary
1194 #if DO_TIMING
1195 time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
1196 #endif
1197 // Nothing is running => no more code-blocks
1198 return null;
1199 }
1200 }
1201 }
1202  
1203 /// <summary> Changes the current tile, given the new indexes. An
1204 /// IllegalArgumentException is thrown if the indexes do not correspond to
1205 /// a valid tile.
1206 ///
1207 /// <p>This default implementation just changes the tile in the source.</p>
1208 ///
1209 /// </summary>
1210 /// <param name="x">The horizontal index of the tile.
1211 ///
1212 /// </param>
1213 /// <param name="y">The vertical index of the new tile.
1214 ///
1215 /// </param>
1216 public override void setTile(int x, int y)
1217 {
1218 base.setTile(x, y);
1219 // Reset the tile specific variables
1220 if (finishedTileComponent != null)
1221 {
1222 for (int c = src.NumComps - 1; c >= 0; c--)
1223 {
1224 finishedTileComponent[c] = false;
1225 }
1226 }
1227 }
1228  
1229 /// <summary> Advances to the next tile, in standard scan-line order (by rows then
1230 /// columns). An NoNextElementException is thrown if the current tile is
1231 /// the last one (i.e. there is no next tile).
1232 ///
1233 /// <p>This default implementation just advances to the next tile in the
1234 /// source.</p>
1235 ///
1236 /// </summary>
1237 public override void nextTile()
1238 {
1239 // Reset the tilespecific variables
1240 if (finishedTileComponent != null)
1241 {
1242 for (int c = src.NumComps - 1; c >= 0; c--)
1243 {
1244 finishedTileComponent[c] = false;
1245 }
1246 }
1247 base.nextTile();
1248 }
1249  
1250  
1251 /// <summary> Compresses the code-block in 'srcblk' and puts the results in 'ccb',
1252 /// using the specified options and temporary storage.
1253 ///
1254 /// </summary>
1255 /// <param name="c">The component for which to return the next code-block.
1256 ///
1257 /// </param>
1258 /// <param name="ccb">The object where the compressed data will be stored. If the
1259 /// 'data' array of 'cbb' is not null it may be reused to return the
1260 /// compressed data.
1261 ///
1262 /// </param>
1263 /// <param name="srcblk">The code-block data to code
1264 ///
1265 /// </param>
1266 /// <param name="mq">The MQ-coder to use
1267 ///
1268 /// </param>
1269 /// <param name="bout">The bit level output to use. Used only if 'OPT_BYPASS' is
1270 /// turned on in the 'options' argument.
1271 ///
1272 /// </param>
1273 /// <param name="out">The byte buffer trough which the compressed data is stored.
1274 ///
1275 /// </param>
1276 /// <param name="state">The state information for the code-block
1277 ///
1278 /// </param>
1279 /// <param name="distbuf">The buffer where to store the distortion at
1280 /// the end of each coding pass.
1281 ///
1282 /// </param>
1283 /// <param name="ratebuf">The buffer where to store the rate (i.e. coded lenth) at
1284 /// the end of each coding pass.
1285 ///
1286 /// </param>
1287 /// <param name="istermbuf">The buffer where to store the terminated flag for each
1288 /// coding pass.
1289 ///
1290 /// </param>
1291 /// <param name="symbuf">The buffer to hold symbols to send to the MQ coder
1292 ///
1293 /// </param>
1294 /// <param name="ctxtbuf">A buffer to hold the contexts to use in sending the
1295 /// buffered symbols to the MQ coder.
1296 ///
1297 /// </param>
1298 /// <param name="options">The options to use when coding this code-block
1299 ///
1300 /// </param>
1301 /// <param name="rev">The reversible flag. Should be true if the source of this
1302 /// code-block's data is reversible.
1303 ///
1304 /// </param>
1305 /// <param name="lcType">The type of length calculation to use with the MQ coder.
1306 ///
1307 /// </param>
1308 /// <param name="tType">The type of termination to use with the MQ coder.
1309 ///
1310 /// </param>
1311 /// <seealso cref="getNextCodeBlock">
1312 ///
1313 /// </seealso>
1314 static private void compressCodeBlock(int c, CBlkRateDistStats ccb, CBlkWTData srcblk, MQCoder mq, BitToByteOutput bout, ByteOutputBuffer out_Renamed, int[] state, double[] distbuf, int[] ratebuf, bool[] istermbuf, int[] symbuf, int[] ctxtbuf, int options, bool rev, int lcType, int tType)
1315 {
1316 // NOTE: This method should not access any non-final instance or
1317 // static variables, either directly or indirectly through other
1318 // methods in order to be sure that the method is thread safe.
1319  
1320 int[] zc_lut; // The ZC lookup table to use
1321 int skipbp; // The number of non-significant bit-planes to skip
1322 int curbp; // The current magnitude bit-plane (starts at 30)
1323 int[] fm; // The distortion estimation lookup table for MR
1324 int[] fs; // The distortion estimation lookup table for SC
1325 int lmb; // The least significant magnitude bit
1326 int npass; // The number of coding passes, for R-D statistics
1327 double msew; // The distortion (MSE weight) for the current bit-plane
1328 double totdist; // The total cumulative distortion decrease
1329 int ltpidx; // The index of the last pass which is terminated
1330  
1331 // Check error-resilient termination
1332 if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0 && tType != MQCoder.TERM_PRED_ER)
1333 {
1334 throw new System.ArgumentException("Embedded error-resilient info " + "in MQ termination option " + "specified but incorrect MQ " + "termination " + "policy specified");
1335 }
1336 // Set MQ flags
1337 mq.LenCalcType = lcType;
1338 mq.TermType = tType;
1339  
1340 lmb = 30 - srcblk.magbits + 1;
1341 // If there are more bit-planes to code than the implementation
1342 // bit-depth set lmb to 0
1343 lmb = (lmb < 0)?0:lmb;
1344  
1345 // Reset state
1346 ArrayUtil.intArraySet(state, 0);
1347  
1348 // Find the most significant bit-plane
1349 skipbp = calcSkipMSBP(srcblk, lmb);
1350  
1351 // Initialize output code-block
1352 ccb.m = srcblk.m;
1353 ccb.n = srcblk.n;
1354 ccb.sb = srcblk.sb;
1355 ccb.nROIcoeff = srcblk.nROIcoeff;
1356 ccb.skipMSBP = skipbp;
1357 if (ccb.nROIcoeff != 0)
1358 {
1359 ccb.nROIcp = 3 * (srcblk.nROIbp - skipbp - 1) + 1;
1360 }
1361 else
1362 {
1363 ccb.nROIcp = 0;
1364 }
1365  
1366 // Choose correct ZC lookup table for global orientation
1367 switch (srcblk.sb.orientation)
1368 {
1369  
1370 case Subband.WT_ORIENT_HL:
1371 zc_lut = ZC_LUT_HL;
1372 break;
1373  
1374 case Subband.WT_ORIENT_LL:
1375 case Subband.WT_ORIENT_LH:
1376 zc_lut = ZC_LUT_LH;
1377 break;
1378  
1379 case Subband.WT_ORIENT_HH:
1380 zc_lut = ZC_LUT_HH;
1381 break;
1382  
1383 default:
1384 throw new System.ApplicationException("JJ2000 internal error");
1385  
1386 }
1387  
1388 // Loop on significant magnitude bit-planes doing the 3 passes
1389 curbp = 30 - skipbp;
1390 fs = FS_LOSSY;
1391 fm = FM_LOSSY;
1392 msew = System.Math.Pow(2, ((curbp - lmb) << 1) - MSE_LKP_FRAC_BITS) * srcblk.sb.stepWMSE * srcblk.wmseScaling;
1393 totdist = 0f;
1394 npass = 0;
1395 ltpidx = - 1;
1396  
1397 // First significant bit-plane has only the pass pass
1398 if (curbp >= lmb)
1399 {
1400 // Do we need the "lossless" 'fs' table ?
1401 if (rev && curbp == lmb)
1402 {
1403 fs = FM_LOSSLESS;
1404 }
1405 // We terminate if regular termination, last bit-plane, or next
1406 // bit-plane is "raw".
1407 istermbuf[npass] = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || curbp == lmb || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp) >= curbp);
1408 totdist += cleanuppass(srcblk, mq, istermbuf[npass], curbp, state, fs, zc_lut, symbuf, ctxtbuf, ratebuf, npass, ltpidx, options) * msew;
1409 distbuf[npass] = totdist;
1410 if (istermbuf[npass])
1411 ltpidx = npass;
1412 npass++;
1413 msew *= 0.25;
1414 curbp--;
1415 }
1416 // Other bit-planes have all passes
1417 while (curbp >= lmb)
1418 {
1419 // Do we need the "lossless" 'fs' and 'fm' tables ?
1420 if (rev && curbp == lmb)
1421 {
1422 fs = FS_LOSSLESS;
1423 fm = FM_LOSSLESS;
1424 }
1425  
1426 // Do the significance propagation pass
1427 // We terminate if regular termination only
1428 istermbuf[npass] = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0;
1429 if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) == 0 || (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp <= curbp))
1430 {
1431 // No bypass coding
1432 totdist += sigProgPass(srcblk, mq, istermbuf[npass], curbp, state, fs, zc_lut, symbuf, ctxtbuf, ratebuf, npass, ltpidx, options) * msew;
1433 }
1434 else
1435 {
1436 // Bypass ("raw") coding
1437 bout.PredTerm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0;
1438 totdist += rawSigProgPass(srcblk, bout, istermbuf[npass], curbp, state, fs, ratebuf, npass, ltpidx, options) * msew;
1439 }
1440 distbuf[npass] = totdist;
1441 if (istermbuf[npass])
1442 ltpidx = npass;
1443 npass++;
1444  
1445 // Do the magnitude refinement pass
1446 // We terminate if regular termination or bypass ("raw") coding
1447 istermbuf[npass] = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp > curbp));
1448 if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) == 0 || (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp <= curbp))
1449 {
1450 // No bypass coding
1451 totdist += magRefPass(srcblk, mq, istermbuf[npass], curbp, state, fm, symbuf, ctxtbuf, ratebuf, npass, ltpidx, options) * msew;
1452 }
1453 else
1454 {
1455 // Bypass ("raw") coding
1456 bout.PredTerm = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0;
1457 totdist += rawMagRefPass(srcblk, bout, istermbuf[npass], curbp, state, fm, ratebuf, npass, ltpidx, options) * msew;
1458 }
1459 distbuf[npass] = totdist;
1460 if (istermbuf[npass])
1461 ltpidx = npass;
1462 npass++;
1463  
1464 // Do the clenup pass
1465 // We terminate if regular termination, last bit-plane, or next
1466 // bit-plane is "raw".
1467 istermbuf[npass] = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0 || curbp == lmb || ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && (31 - CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_NON_BYPASS_MS_BP - skipbp) >= curbp);
1468 totdist += cleanuppass(srcblk, mq, istermbuf[npass], curbp, state, fs, zc_lut, symbuf, ctxtbuf, ratebuf, npass, ltpidx, options) * msew;
1469 distbuf[npass] = totdist;
1470  
1471 if (istermbuf[npass])
1472 ltpidx = npass;
1473 npass++;
1474  
1475 // Goto next bit-plane
1476 msew *= 0.25;
1477 curbp--;
1478 }
1479  
1480 // Copy compressed data and rate-distortion statistics to output
1481 ccb.data = new byte[out_Renamed.size()];
1482 out_Renamed.toByteArray(0, out_Renamed.size(), ccb.data, 0);
1483 checkEndOfPassFF(ccb.data, ratebuf, istermbuf, npass);
1484 ccb.selectConvexHull(ratebuf, distbuf, (options & (CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS)) != 0?istermbuf:null, npass, rev);
1485  
1486 // Reset MQ coder and bit output for next code-block
1487 mq.reset();
1488 if (bout != null)
1489 bout.reset();
1490 }
1491  
1492 /// <summary> Calculates the number of magnitude bit-planes that are to be skipped,
1493 /// because they are non-significant. The algorithm looks for the largest
1494 /// magnitude and calculates the most significant bit-plane of it.
1495 ///
1496 /// </summary>
1497 /// <param name="cblk">The code-block of data to scan
1498 ///
1499 /// </param>
1500 /// <param name="lmb">The least significant magnitude bit in the data
1501 ///
1502 /// </param>
1503 /// <returns> The number of magnitude bit-planes to skip (i.e. all zero most
1504 /// significant bit-planes).
1505 ///
1506 /// </returns>
1507 static private int calcSkipMSBP(CBlkWTData cblk, int lmb)
1508 {
1509 int k, kmax, mask;
1510 int[] data;
1511 int maxmag;
1512 int mag;
1513 int w, h;
1514 int msbp;
1515 int l;
1516  
1517 data = (int[]) cblk.Data;
1518 w = cblk.w;
1519 h = cblk.h;
1520  
1521 // First look for the maximum magnitude in the code-block
1522 maxmag = 0;
1523 // Consider only magnitude bits that are in non-fractional bit-planes.
1524 mask = 0x7FFFFFFF & (~ ((1 << lmb) - 1));
1525 for (l = h - 1, k = cblk.offset; l >= 0; l--)
1526 {
1527 for (kmax = k + w; k < kmax; k++)
1528 {
1529 mag = data[k] & mask;
1530 if (mag > maxmag)
1531 maxmag = mag;
1532 }
1533 k += cblk.scanw - w;
1534 }
1535 // Now calculate the number of all zero most significant
1536 // bit-planes for the maximum magnitude.
1537 msbp = 30;
1538 do
1539 {
1540 if (((1 << msbp) & maxmag) != 0)
1541 break;
1542 msbp--;
1543 }
1544 while (msbp >= lmb);
1545  
1546 // Return the number of non-significant bit-planes to skip
1547 return 30 - msbp;
1548 }
1549  
1550 /// <summary> Performs the significance propagation pass on the specified data and
1551 /// bit-plane. It codes all insignificant samples which have, at least, one
1552 /// of its immediate eight neighbors already significant, using the ZC and
1553 /// SC primitives as needed. It toggles the "visited" state bit to 1 for
1554 /// all those samples.
1555 ///
1556 /// </summary>
1557 /// <param name="srcblk">The code-block data to code
1558 ///
1559 /// </param>
1560 /// <param name="mq">The MQ-coder to use
1561 ///
1562 /// </param>
1563 /// <param name="doterm">If true it performs an MQ-coder termination after the end
1564 /// of the pass
1565 ///
1566 /// </param>
1567 /// <param name="bp">The bit-plane to code
1568 ///
1569 /// </param>
1570 /// <param name="state">The state information for the code-block
1571 ///
1572 /// </param>
1573 /// <param name="fs">The distortion estimation lookup table for SC
1574 ///
1575 /// </param>
1576 /// <param name="zc_lut">The ZC lookup table to use in ZC.
1577 ///
1578 /// </param>
1579 /// <param name="symbuf">The buffer to hold symbols to send to the MQ coder
1580 ///
1581 /// </param>
1582 /// <param name="ctxtbuf">A buffer to hold the contexts to use in sending the
1583 /// buffered symbols to the MQ coder.
1584 ///
1585 /// </param>
1586 /// <param name="ratebuf">The buffer where to store the rate (i.e. coded lenth) at
1587 /// the end of this coding pass.
1588 ///
1589 /// </param>
1590 /// <param name="pidx">The coding pass index. Is the index in the 'ratebuf' array
1591 /// where to store the coded length after this coding pass.
1592 ///
1593 /// </param>
1594 /// <param name="ltpidx">The index of the last pass that was terminated, or
1595 /// negative if none.
1596 ///
1597 /// </param>
1598 /// <param name="options">The bitmask of entropy coding options to apply to the
1599 /// code-block
1600 ///
1601 /// </param>
1602 /// <returns> The decrease in distortion for this pass, in the fixed-point
1603 /// normalized representation of the 'FS_LOSSY' and 'FS_LOSSLESS' tables.
1604 ///
1605 /// </returns>
1606 static private int sigProgPass(CBlkWTData srcblk, MQCoder mq, bool doterm, int bp, int[] state, int[] fs, int[] zc_lut, int[] symbuf, int[] ctxtbuf, int[] ratebuf, int pidx, int ltpidx, int options)
1607 {
1608 int j, sj; // The state index for line and stripe
1609 int k, sk; // The data index for line and stripe
1610 int nsym = 0; // Symbol counter for symbol and context buffers
1611 int dscanw; // The data scan-width
1612 int sscanw; // The state and packed state scan-width
1613 int jstep; // Stripe to stripe step for 'sj'
1614 int kstep; // Stripe to stripe step for 'sk'
1615 int stopsk; // The loop limit on the variable sk
1616 int csj; // Local copy (i.e. cached) of 'state[j]'
1617 int mask; // The mask for the current bit-plane
1618 int sym; // The symbol to code
1619 int ctxt; // The context to use
1620 int[] data; // The data buffer
1621 int dist; // The distortion reduction for this pass
1622 int shift; // Shift amount for distortion
1623 int upshift; // Shift left amount for distortion
1624 int downshift; // Shift right amount for distortion
1625 int normval; // The normalized sample magnitude value
1626 int s; // The stripe index
1627 bool causal; // Flag to indicate if stripe-causal context
1628 // formation is to be used
1629 int nstripes; // The number of stripes in the code-block
1630 int sheight; // Height of the current stripe
1631 int off_ul, off_ur, off_dr, off_dl; // offsets
1632  
1633 // Initialize local variables
1634 dscanw = srcblk.scanw;
1635 sscanw = srcblk.w + 2;
1636 jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - srcblk.w;
1637 kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - srcblk.w;
1638 mask = 1 << bp;
1639 data = (int[]) srcblk.Data;
1640 nstripes = (srcblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
1641 dist = 0;
1642 // We use the MSE_LKP_BITS-1 bits below the bit just coded for
1643 // distortion estimation.
1644 shift = bp - MSE_LKP_BITS_M1;
1645 upshift = (shift >= 0)?0:- shift;
1646 downshift = (shift <= 0)?0:shift;
1647 causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0;
1648  
1649 // Pre-calculate offsets in 'state' for diagonal neighbors
1650 off_ul = - sscanw - 1; // up-left
1651 off_ur = - sscanw + 1; // up-right
1652 off_dr = sscanw + 1; // down-right
1653 off_dl = sscanw - 1; // down-left
1654  
1655 // Code stripe by stripe
1656 sk = srcblk.offset;
1657 sj = sscanw + 1;
1658 for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
1659 {
1660 sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:srcblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
1661 stopsk = sk + srcblk.w;
1662 // Scan by set of 1 stripe column at a time
1663 for (nsym = 0; sk < stopsk; sk++, sj++)
1664 {
1665 // Do half top of column
1666 j = sj;
1667 csj = state[j];
1668 // If any of the two samples is not significant and has a
1669 // non-zero context (i.e. some neighbor is significant) we can
1670 // not skip them
1671 if ((((~ csj) & (csj << 2)) & SIG_MASK_R1R2) != 0)
1672 {
1673 k = sk;
1674 // Scan first row
1675 if ((csj & (STATE_SIG_R1 | STATE_NZ_CTXT_R1)) == STATE_NZ_CTXT_R1)
1676 {
1677 // Apply zero coding
1678 ctxtbuf[nsym] = zc_lut[csj & ZC_MASK];
1679 if ((symbuf[nsym++] = SupportClass.URShift((data[k] & mask), bp)) != 0)
1680 {
1681 // Became significant
1682 // Apply sign coding
1683 sym = SupportClass.URShift(data[k], 31);
1684 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R1)) & SC_MASK];
1685 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
1686 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
1687 // Update state information (significant bit,
1688 // visited bit, neighbor significant bit of
1689 // neighbors, non zero context of neighbors, sign
1690 // of neighbors)
1691 if (!causal)
1692 {
1693 // If in causal mode do not change contexts of
1694 // previous stripe.
1695 state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
1696 state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
1697 }
1698 // Update sign state information of neighbors
1699 if (sym != 0)
1700 {
1701 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
1702 if (!causal)
1703 {
1704 // If in causal mode do not change
1705 // contexts of previous stripe.
1706 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
1707 }
1708 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
1709 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
1710 }
1711 else
1712 {
1713 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
1714 if (!causal)
1715 {
1716 // If in causal mode do not change
1717 // contexts of previous stripe.
1718 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
1719 }
1720 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
1721 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
1722 }
1723 // Update distortion
1724 normval = (data[k] >> downshift) << upshift;
1725 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
1726 }
1727 else
1728 {
1729 csj |= STATE_VISITED_R1;
1730 }
1731 }
1732 if (sheight < 2)
1733 {
1734 state[j] = csj;
1735 continue;
1736 }
1737 // Scan second row
1738 if ((csj & (STATE_SIG_R2 | STATE_NZ_CTXT_R2)) == STATE_NZ_CTXT_R2)
1739 {
1740 k += dscanw;
1741 // Apply zero coding
1742 ctxtbuf[nsym] = zc_lut[(SupportClass.URShift(csj, STATE_SEP)) & ZC_MASK];
1743 if ((symbuf[nsym++] = SupportClass.URShift((data[k] & mask), bp)) != 0)
1744 {
1745 // Became significant
1746 // Apply sign coding
1747 sym = SupportClass.URShift(data[k], 31);
1748 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
1749 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
1750 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
1751 // Update state information (significant bit,
1752 // visited bit, neighbor significant bit of
1753 // neighbors, non zero context of neighbors, sign
1754 // of neighbors)
1755 state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
1756 state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
1757 // Update sign state information of neighbors
1758 if (sym != 0)
1759 {
1760 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
1761 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
1762 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
1763 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
1764 }
1765 else
1766 {
1767 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
1768 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
1769 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
1770 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
1771 }
1772 // Update distortion
1773 normval = (data[k] >> downshift) << upshift;
1774 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
1775 }
1776 else
1777 {
1778 csj |= STATE_VISITED_R2;
1779 }
1780 }
1781 state[j] = csj;
1782 }
1783 // Do half bottom of column
1784 if (sheight < 3)
1785 continue;
1786 j += sscanw;
1787 csj = state[j];
1788 // If any of the two samples is not significant and has a
1789 // non-zero context (i.e. some neighbor is significant) we can
1790 // not skip them
1791 if ((((~ csj) & (csj << 2)) & SIG_MASK_R1R2) != 0)
1792 {
1793 k = sk + (dscanw << 1);
1794 // Scan first row
1795 if ((csj & (STATE_SIG_R1 | STATE_NZ_CTXT_R1)) == STATE_NZ_CTXT_R1)
1796 {
1797 // Apply zero coding
1798 ctxtbuf[nsym] = zc_lut[csj & ZC_MASK];
1799 if ((symbuf[nsym++] = SupportClass.URShift((data[k] & mask), bp)) != 0)
1800 {
1801 // Became significant
1802 // Apply sign coding
1803 sym = SupportClass.URShift(data[k], 31);
1804 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R1)) & SC_MASK];
1805 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
1806 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
1807 // Update state information (significant bit,
1808 // visited bit, neighbor significant bit of
1809 // neighbors, non zero context of neighbors, sign
1810 // of neighbors)
1811 state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
1812 state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
1813 // Update sign state information of neighbors
1814 if (sym != 0)
1815 {
1816 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
1817 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
1818 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
1819 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
1820 }
1821 else
1822 {
1823 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
1824 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
1825 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
1826 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
1827 }
1828 // Update distortion
1829 normval = (data[k] >> downshift) << upshift;
1830 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
1831 }
1832 else
1833 {
1834 csj |= STATE_VISITED_R1;
1835 }
1836 }
1837 if (sheight < 4)
1838 {
1839 state[j] = csj;
1840 continue;
1841 }
1842 // Scan second row
1843 if ((csj & (STATE_SIG_R2 | STATE_NZ_CTXT_R2)) == STATE_NZ_CTXT_R2)
1844 {
1845 k += dscanw;
1846 // Apply zero coding
1847 ctxtbuf[nsym] = zc_lut[(SupportClass.URShift(csj, STATE_SEP)) & ZC_MASK];
1848 if ((symbuf[nsym++] = SupportClass.URShift((data[k] & mask), bp)) != 0)
1849 {
1850 // Became significant
1851 // Apply sign coding
1852 sym = SupportClass.URShift(data[k], 31);
1853 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
1854 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
1855 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
1856 // Update state information (significant bit,
1857 // visited bit, neighbor significant bit of
1858 // neighbors, non zero context of neighbors, sign
1859 // of neighbors)
1860 state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
1861 state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
1862 // Update sign state information of neighbors
1863 if (sym != 0)
1864 {
1865 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
1866 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
1867 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
1868 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
1869 }
1870 else
1871 {
1872 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
1873 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
1874 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
1875 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
1876 }
1877 // Update distortion
1878 normval = (data[k] >> downshift) << upshift;
1879 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
1880 }
1881 else
1882 {
1883 csj |= STATE_VISITED_R2;
1884 }
1885 }
1886 state[j] = csj;
1887 }
1888 }
1889 // Code all buffered symbols
1890 mq.codeSymbols(symbuf, ctxtbuf, nsym);
1891 }
1892 // Reset the MQ context states if we need to
1893 if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ) != 0)
1894 {
1895 mq.resetCtxts();
1896 }
1897  
1898 // Terminate the MQ bit stream if we need to
1899 if (doterm)
1900 {
1901 ratebuf[pidx] = mq.terminate(); // Termination has special length
1902 }
1903 else
1904 {
1905 // Use normal length calculation
1906 ratebuf[pidx] = mq.NumCodedBytes;
1907 }
1908 // Add length of previous segments, if any
1909 if (ltpidx >= 0)
1910 {
1911 ratebuf[pidx] += ratebuf[ltpidx];
1912 }
1913 // Finish length calculation if needed
1914 if (doterm)
1915 {
1916 mq.finishLengthCalculation(ratebuf, pidx);
1917 }
1918  
1919 // Return the reduction in distortion
1920 return dist;
1921 }
1922  
1923 /// <summary> Performs the significance propagation pass on the specified data and
1924 /// bit-plane, without using the arithmetic coder. It codes all
1925 /// insignificant samples which have, at least, one of its immediate eight
1926 /// neighbors already significant, using the ZC and SC primitives as
1927 /// needed. It toggles the "visited" state bit to 1 for all those samples.
1928 ///
1929 /// <p>In this method, the arithmetic coder is bypassed, and raw bits are
1930 /// directly written in the bit stream (useful when distribution are close
1931 /// to uniform, for intance, at high bit-rates and at lossless
1932 /// compression).</p>
1933 ///
1934 /// </summary>
1935 /// <param name="srcblk">The code-block data to code
1936 ///
1937 /// </param>
1938 /// <param name="bout">The bit based output
1939 ///
1940 /// </param>
1941 /// <param name="doterm">If true the bit based output is byte aligned after the
1942 /// end of the pass.
1943 ///
1944 /// </param>
1945 /// <param name="bp">The bit-plane to code
1946 ///
1947 /// </param>
1948 /// <param name="state">The state information for the code-block
1949 ///
1950 /// </param>
1951 /// <param name="fs">The distortion estimation lookup table for SC
1952 ///
1953 /// </param>
1954 /// <param name="ratebuf">The buffer where to store the rate (i.e. coded lenth) at
1955 /// the end of this coding pass.
1956 ///
1957 /// </param>
1958 /// <param name="pidx">The coding pass index. Is the index in the 'ratebuf' array
1959 /// where to store the coded length after this coding pass.
1960 ///
1961 /// </param>
1962 /// <param name="ltpidx">The index of the last pass that was terminated, or
1963 /// negative if none.
1964 ///
1965 /// </param>
1966 /// <param name="options">The bitmask of entropy coding options to apply to the
1967 /// code-block
1968 ///
1969 /// </param>
1970 /// <returns> The decrease in distortion for this pass, in the fixed-point
1971 /// normalized representation of the 'FS_LOSSY' and 'FS_LOSSLESS' tables.
1972 ///
1973 /// </returns>
1974 static private int rawSigProgPass(CBlkWTData srcblk, BitToByteOutput bout, bool doterm, int bp, int[] state, int[] fs, int[] ratebuf, int pidx, int ltpidx, int options)
1975 {
1976 int j, sj; // The state index for line and stripe
1977 int k, sk; // The data index for line and stripe
1978 int dscanw; // The data scan-width
1979 int sscanw; // The state scan-width
1980 int jstep; // Stripe to stripe step for 'sj'
1981 int kstep; // Stripe to stripe step for 'sk'
1982 int stopsk; // The loop limit on the variable sk
1983 int csj; // Local copy (i.e. cached) of 'state[j]'
1984 int mask; // The mask for the current bit-plane
1985 int nsym = 0; // Number of symbol
1986 int sym; // The symbol to code
1987 int[] data; // The data buffer
1988 int dist; // The distortion reduction for this pass
1989 int shift; // Shift amount for distortion
1990 int upshift; // Shift left amount for distortion
1991 int downshift; // Shift right amount for distortion
1992 int normval; // The normalized sample magnitude value
1993 int s; // The stripe index
1994 bool causal; // Flag to indicate if stripe-causal context
1995 // formation is to be used
1996 int nstripes; // The number of stripes in the code-block
1997 int sheight; // Height of the current stripe
1998 int off_ul, off_ur, off_dr, off_dl; // offsets
1999  
2000 // Initialize local variables
2001 dscanw = srcblk.scanw;
2002 sscanw = srcblk.w + 2;
2003 jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - srcblk.w;
2004 kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - srcblk.w;
2005 mask = 1 << bp;
2006 data = (int[]) srcblk.Data;
2007 nstripes = (srcblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
2008 dist = 0;
2009 // We use the MSE_LKP_BITS-1 bits below the bit just coded for
2010 // distortion estimation.
2011 shift = bp - MSE_LKP_BITS_M1;
2012 upshift = (shift >= 0)?0:- shift;
2013 downshift = (shift <= 0)?0:shift;
2014 causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0;
2015  
2016 // Pre-calculate offsets in 'state' for neighbors
2017 off_ul = - sscanw - 1; // up-left
2018 off_ur = - sscanw + 1; // up-right
2019 off_dr = sscanw + 1; // down-right
2020 off_dl = sscanw - 1; // down-left
2021  
2022 // Code stripe by stripe
2023 sk = srcblk.offset;
2024 sj = sscanw + 1;
2025 for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
2026 {
2027 sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:srcblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
2028 stopsk = sk + srcblk.w;
2029 // Scan by set of 1 stripe column at a time
2030 for (; sk < stopsk; sk++, sj++)
2031 {
2032 // Do half top of column
2033 j = sj;
2034 csj = state[j];
2035 // If any of the two samples is not significant and has a
2036 // non-zero context (i.e. some neighbor is significant) we can
2037 // not skip them
2038 if ((((~ csj) & (csj << 2)) & SIG_MASK_R1R2) != 0)
2039 {
2040 k = sk;
2041 // Scan first row
2042 if ((csj & (STATE_SIG_R1 | STATE_NZ_CTXT_R1)) == STATE_NZ_CTXT_R1)
2043 {
2044 // Apply zero coding
2045 sym = SupportClass.URShift((data[k] & mask), bp);
2046 bout.writeBit(sym);
2047 nsym++;
2048 if (sym != 0)
2049 {
2050 // Became significant
2051 // Apply sign coding
2052 sym = SupportClass.URShift(data[k], 31);
2053 bout.writeBit(sym);
2054 nsym++;
2055 // Update state information (significant bit,
2056 // visited bit, neighbor significant bit of
2057 // neighbors, non zero context of neighbors, sign
2058 // of neighbors)
2059 if (!causal)
2060 {
2061 // If in causal mode do not change contexts of
2062 // previous stripe.
2063 state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
2064 state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
2065 }
2066 // Update sign state information of neighbors
2067 if (sym != 0)
2068 {
2069 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
2070 if (!causal)
2071 {
2072 // If in causal mode do not change
2073 // contexts of previous stripe.
2074 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
2075 }
2076 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
2077 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
2078 }
2079 else
2080 {
2081 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
2082 if (!causal)
2083 {
2084 // If in causal mode do not change
2085 // contexts of previous stripe.
2086 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
2087 }
2088 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
2089 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
2090 }
2091 // Update distortion
2092 normval = (data[k] >> downshift) << upshift;
2093 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
2094 }
2095 else
2096 {
2097 csj |= STATE_VISITED_R1;
2098 }
2099 }
2100 if (sheight < 2)
2101 {
2102 state[j] = csj;
2103 continue;
2104 }
2105 // Scan second row
2106 if ((csj & (STATE_SIG_R2 | STATE_NZ_CTXT_R2)) == STATE_NZ_CTXT_R2)
2107 {
2108 k += dscanw;
2109 // Apply zero coding
2110 sym = SupportClass.URShift((data[k] & mask), bp);
2111 bout.writeBit(sym);
2112 nsym++;
2113 if (sym != 0)
2114 {
2115 // Became significant
2116 // Apply sign coding
2117 sym = SupportClass.URShift(data[k], 31);
2118 bout.writeBit(sym);
2119 nsym++;
2120 // Update state information (significant bit,
2121 // visited bit, neighbor significant bit of
2122 // neighbors, non zero context of neighbors, sign
2123 // of neighbors)
2124 state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
2125 state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
2126 // Update sign state information of neighbors
2127 if (sym != 0)
2128 {
2129 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
2130 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
2131 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
2132 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
2133 }
2134 else
2135 {
2136 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
2137 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
2138 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
2139 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
2140 }
2141 // Update distortion
2142 normval = (data[k] >> downshift) << upshift;
2143 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
2144 }
2145 else
2146 {
2147 csj |= STATE_VISITED_R2;
2148 }
2149 }
2150 state[j] = csj;
2151 }
2152 // Do half bottom of column
2153 if (sheight < 3)
2154 continue;
2155 j += sscanw;
2156 csj = state[j];
2157 // If any of the two samples is not significant and has a
2158 // non-zero context (i.e. some neighbor is significant) we can
2159 // not skip them
2160 if ((((~ csj) & (csj << 2)) & SIG_MASK_R1R2) != 0)
2161 {
2162 k = sk + (dscanw << 1);
2163 // Scan first row
2164 if ((csj & (STATE_SIG_R1 | STATE_NZ_CTXT_R1)) == STATE_NZ_CTXT_R1)
2165 {
2166 sym = SupportClass.URShift((data[k] & mask), bp);
2167 bout.writeBit(sym);
2168 nsym++;
2169 if (sym != 0)
2170 {
2171 // Became significant
2172 // Apply sign coding
2173 sym = SupportClass.URShift(data[k], 31);
2174 bout.writeBit(sym);
2175 nsym++;
2176 // Update state information (significant bit,
2177 // visited bit, neighbor significant bit of
2178 // neighbors, non zero context of neighbors, sign
2179 // of neighbors)
2180 state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
2181 state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
2182 // Update sign state information of neighbors
2183 if (sym != 0)
2184 {
2185 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
2186 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
2187 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
2188 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
2189 }
2190 else
2191 {
2192 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
2193 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
2194 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
2195 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
2196 }
2197 // Update distortion
2198 normval = (data[k] >> downshift) << upshift;
2199 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
2200 }
2201 else
2202 {
2203 csj |= STATE_VISITED_R1;
2204 }
2205 }
2206 if (sheight < 4)
2207 {
2208 state[j] = csj;
2209 continue;
2210 }
2211 if ((csj & (STATE_SIG_R2 | STATE_NZ_CTXT_R2)) == STATE_NZ_CTXT_R2)
2212 {
2213 k += dscanw;
2214 // Apply zero coding
2215 sym = SupportClass.URShift((data[k] & mask), bp);
2216 bout.writeBit(sym);
2217 nsym++;
2218 if (sym != 0)
2219 {
2220 // Became significant
2221 // Apply sign coding
2222 sym = SupportClass.URShift(data[k], 31);
2223 bout.writeBit(sym);
2224 nsym++;
2225 // Update state information (significant bit,
2226 // visited bit, neighbor significant bit of
2227 // neighbors, non zero context of neighbors, sign
2228 // of neighbors)
2229 state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
2230 state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
2231 // Update sign state information of neighbors
2232 if (sym != 0)
2233 {
2234 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
2235 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
2236 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
2237 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
2238 }
2239 else
2240 {
2241 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
2242 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
2243 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
2244 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
2245 }
2246 // Update distortion
2247 normval = (data[k] >> downshift) << upshift;
2248 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
2249 }
2250 else
2251 {
2252 csj |= STATE_VISITED_R2;
2253 }
2254 }
2255 state[j] = csj;
2256 }
2257 }
2258 }
2259  
2260 // Get length and terminate if needed
2261 if (doterm)
2262 {
2263 ratebuf[pidx] = bout.terminate();
2264 }
2265 else
2266 {
2267 ratebuf[pidx] = bout.length();
2268 }
2269 // Add length of previous segments, if any
2270 if (ltpidx >= 0)
2271 {
2272 ratebuf[pidx] += ratebuf[ltpidx];
2273 }
2274  
2275 // Return the reduction in distortion
2276 return dist;
2277 }
2278  
2279 /// <summary> Performs the magnitude refinement pass on the specified data and
2280 /// bit-plane. It codes the samples which are significant and which do not
2281 /// have the "visited" state bit turned on, using the MR primitive. The
2282 /// "visited" state bit is not mofified for any samples.
2283 ///
2284 /// </summary>
2285 /// <param name="srcblk">The code-block data to code
2286 ///
2287 /// </param>
2288 /// <param name="mq">The MQ-coder to use
2289 ///
2290 /// </param>
2291 /// <param name="doterm">If true it performs an MQ-coder termination after the end
2292 /// of the pass
2293 ///
2294 /// </param>
2295 /// <param name="bp">The bit-plane to code
2296 ///
2297 /// </param>
2298 /// <param name="state">The state information for the code-block
2299 ///
2300 /// </param>
2301 /// <param name="fm">The distortion estimation lookup table for MR
2302 ///
2303 /// </param>
2304 /// <param name="symbuf">The buffer to hold symbols to send to the MQ coder
2305 ///
2306 /// </param>
2307 /// <param name="ctxtbuf">A buffer to hold the contexts to use in sending the
2308 /// buffered symbols to the MQ coder.
2309 ///
2310 /// </param>
2311 /// <param name="ratebuf">The buffer where to store the rate (i.e. coded lenth) at
2312 /// the end of this coding pass.
2313 ///
2314 /// </param>
2315 /// <param name="pidx">The coding pass index. Is the index in the 'ratebuf' array
2316 /// where to store the coded length after this coding pass.
2317 ///
2318 /// </param>
2319 /// <param name="ltpidx">The index of the last pass that was terminated, or
2320 /// negative if none.
2321 ///
2322 /// </param>
2323 /// <param name="options">The bitmask of entropy coding options to apply to the
2324 /// code-block
2325 ///
2326 /// </param>
2327 /// <returns> The decrease in distortion for this pass, in the fixed-point
2328 /// normalized representation of the 'FS_LOSSY' and 'FS_LOSSLESS' tables.
2329 ///
2330 /// </returns>
2331 static private int magRefPass(CBlkWTData srcblk, MQCoder mq, bool doterm, int bp, int[] state, int[] fm, int[] symbuf, int[] ctxtbuf, int[] ratebuf, int pidx, int ltpidx, int options)
2332 {
2333 int j, sj; // The state index for line and stripe
2334 int k, sk; // The data index for line and stripe
2335 int nsym = 0; // Symbol counter for symbol and context buffers
2336 int dscanw; // The data scan-width
2337 int sscanw; // The state scan-width
2338 int jstep; // Stripe to stripe step for 'sj'
2339 int kstep; // Stripe to stripe step for 'sk'
2340 int stopsk; // The loop limit on the variable sk
2341 int csj; // Local copy (i.e. cached) of 'state[j]'
2342 int mask; // The mask for the current bit-plane
2343 int[] data; // The data buffer
2344 int dist; // The distortion reduction for this pass
2345 int shift; // Shift amount for distortion
2346 int upshift; // Shift left amount for distortion
2347 int downshift; // Shift right amount for distortion
2348 int normval; // The normalized sample magnitude value
2349 int s; // The stripe index
2350 int nstripes; // The number of stripes in the code-block
2351 int sheight; // Height of the current stripe
2352  
2353 // Initialize local variables
2354 dscanw = srcblk.scanw;
2355 sscanw = srcblk.w + 2;
2356 jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - srcblk.w;
2357 kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - srcblk.w;
2358 mask = 1 << bp;
2359 data = (int[]) srcblk.Data;
2360 nstripes = (srcblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
2361 dist = 0;
2362 // We use the bit just coded plus MSE_LKP_BITS-1 bits below the bit
2363 // just coded for distortion estimation.
2364 shift = bp - MSE_LKP_BITS_M1;
2365 upshift = (shift >= 0)?0:- shift;
2366 downshift = (shift <= 0)?0:shift;
2367  
2368 // Code stripe by stripe
2369 sk = srcblk.offset;
2370 sj = sscanw + 1;
2371 for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
2372 {
2373 sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:srcblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
2374 stopsk = sk + srcblk.w;
2375 // Scan by set of 1 stripe column at a time
2376 for (nsym = 0; sk < stopsk; sk++, sj++)
2377 {
2378 // Do half top of column
2379 j = sj;
2380 csj = state[j];
2381 // If any of the two samples is significant and not yet
2382 // visited in the current bit-plane we can not skip them
2383 if ((((SupportClass.URShift(csj, 1)) & (~ csj)) & VSTD_MASK_R1R2) != 0)
2384 {
2385 k = sk;
2386 // Scan first row
2387 if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == STATE_SIG_R1)
2388 {
2389 // Apply MR primitive
2390 symbuf[nsym] = SupportClass.URShift((data[k] & mask), bp);
2391 ctxtbuf[nsym++] = MR_LUT[csj & MR_MASK];
2392 // Update the STATE_PREV_MR bit
2393 csj |= STATE_PREV_MR_R1;
2394 // Update distortion
2395 normval = (data[k] >> downshift) << upshift;
2396 dist += fm[normval & ((1 << MSE_LKP_BITS) - 1)];
2397 }
2398 if (sheight < 2)
2399 {
2400 state[j] = csj;
2401 continue;
2402 }
2403 // Scan second row
2404 if ((csj & (STATE_SIG_R2 | STATE_VISITED_R2)) == STATE_SIG_R2)
2405 {
2406 k += dscanw;
2407 // Apply MR primitive
2408 symbuf[nsym] = SupportClass.URShift((data[k] & mask), bp);
2409 ctxtbuf[nsym++] = MR_LUT[(SupportClass.URShift(csj, STATE_SEP)) & MR_MASK];
2410 // Update the STATE_PREV_MR bit
2411 csj |= STATE_PREV_MR_R2;
2412 // Update distortion
2413 normval = (data[k] >> downshift) << upshift;
2414 dist += fm[normval & ((1 << MSE_LKP_BITS) - 1)];
2415 }
2416 state[j] = csj;
2417 }
2418 // Do half bottom of column
2419 if (sheight < 3)
2420 continue;
2421 j += sscanw;
2422 csj = state[j];
2423 // If any of the two samples is significant and not yet
2424 // visited in the current bit-plane we can not skip them
2425 if ((((SupportClass.URShift(csj, 1)) & (~ csj)) & VSTD_MASK_R1R2) != 0)
2426 {
2427 k = sk + (dscanw << 1);
2428 // Scan first row
2429 if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == STATE_SIG_R1)
2430 {
2431 // Apply MR primitive
2432 symbuf[nsym] = SupportClass.URShift((data[k] & mask), bp);
2433 ctxtbuf[nsym++] = MR_LUT[csj & MR_MASK];
2434 // Update the STATE_PREV_MR bit
2435 csj |= STATE_PREV_MR_R1;
2436 // Update distortion
2437 normval = (data[k] >> downshift) << upshift;
2438 dist += fm[normval & ((1 << MSE_LKP_BITS) - 1)];
2439 }
2440 if (sheight < 4)
2441 {
2442 state[j] = csj;
2443 continue;
2444 }
2445 // Scan second row
2446 if ((state[j] & (STATE_SIG_R2 | STATE_VISITED_R2)) == STATE_SIG_R2)
2447 {
2448 k += dscanw;
2449 // Apply MR primitive
2450 symbuf[nsym] = SupportClass.URShift((data[k] & mask), bp);
2451 ctxtbuf[nsym++] = MR_LUT[(SupportClass.URShift(csj, STATE_SEP)) & MR_MASK];
2452 // Update the STATE_PREV_MR bit
2453 csj |= STATE_PREV_MR_R2;
2454 // Update distortion
2455 normval = (data[k] >> downshift) << upshift;
2456 dist += fm[normval & ((1 << MSE_LKP_BITS) - 1)];
2457 }
2458 state[j] = csj;
2459 }
2460 }
2461 // Code all buffered symbols, if any
2462 if (nsym > 0)
2463 mq.codeSymbols(symbuf, ctxtbuf, nsym);
2464 }
2465  
2466 // Reset the MQ context states if we need to
2467 if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ) != 0)
2468 {
2469 mq.resetCtxts();
2470 }
2471  
2472 // Terminate the MQ bit stream if we need to
2473 if (doterm)
2474 {
2475 ratebuf[pidx] = mq.terminate(); // Termination has special length
2476 }
2477 else
2478 {
2479 // Use normal length calculation
2480 ratebuf[pidx] = mq.NumCodedBytes;
2481 }
2482 // Add length of previous segments, if any
2483 if (ltpidx >= 0)
2484 {
2485 ratebuf[pidx] += ratebuf[ltpidx];
2486 }
2487 // Finish length calculation if needed
2488 if (doterm)
2489 {
2490 mq.finishLengthCalculation(ratebuf, pidx);
2491 }
2492  
2493 // Return the reduction in distortion
2494 return dist;
2495 }
2496  
2497 /// <summary> Performs the magnitude refinement pass on the specified data and
2498 /// bit-plane, without using the arithmetic coder. It codes the samples
2499 /// which are significant and which do not have the "visited" state bit
2500 /// turned on, using the MR primitive. The "visited" state bit is not
2501 /// mofified for any samples.
2502 ///
2503 /// <p>In this method, the arithmetic coder is bypassed, and raw bits are
2504 /// directly written in the bit stream (useful when distribution are close
2505 /// to uniform, for intance, at high bit-rates and at lossless
2506 /// compression). The 'STATE_PREV_MR_R1' and 'STATE_PREV_MR_R2' bits are
2507 /// not set because they are used only when the arithmetic coder is not
2508 /// bypassed.</p>
2509 ///
2510 /// </summary>
2511 /// <param name="srcblk">The code-block data to code
2512 ///
2513 /// </param>
2514 /// <param name="bout">The bit based output
2515 ///
2516 /// </param>
2517 /// <param name="doterm">If true the bit based output is byte aligned after the
2518 /// end of the pass.
2519 ///
2520 /// </param>
2521 /// <param name="bp">The bit-plane to code
2522 ///
2523 /// </param>
2524 /// <param name="state">The state information for the code-block
2525 ///
2526 /// </param>
2527 /// <param name="fm">The distortion estimation lookup table for MR
2528 ///
2529 /// </param>
2530 /// <param name="ratebuf">The buffer where to store the rate (i.e. coded lenth) at
2531 /// the end of this coding pass.
2532 ///
2533 /// </param>
2534 /// <param name="pidx">The coding pass index. Is the index in the 'ratebuf' array
2535 /// where to store the coded length after this coding pass.
2536 ///
2537 /// </param>
2538 /// <param name="ltpidx">The index of the last pass that was terminated, or
2539 /// negative if none.
2540 ///
2541 /// </param>
2542 /// <param name="options">The bitmask of entropy coding options to apply to the
2543 /// code-block
2544 ///
2545 /// </param>
2546 /// <returns> The decrease in distortion for this pass, in the fixed-point
2547 /// normalized representation of the 'FS_LOSSY' and 'FS_LOSSLESS' tables.
2548 ///
2549 /// </returns>
2550 static private int rawMagRefPass(CBlkWTData srcblk, BitToByteOutput bout, bool doterm, int bp, int[] state, int[] fm, int[] ratebuf, int pidx, int ltpidx, int options)
2551 {
2552 int j, sj; // The state index for line and stripe
2553 int k, sk; // The data index for line and stripe
2554 int dscanw; // The data scan-width
2555 int sscanw; // The state scan-width
2556 int jstep; // Stripe to stripe step for 'sj'
2557 int kstep; // Stripe to stripe step for 'sk'
2558 int stopsk; // The loop limit on the variable sk
2559 int csj; // Local copy (i.e. cached) of 'state[j]'
2560 int mask; // The mask for the current bit-plane
2561 int[] data; // The data buffer
2562 int dist; // The distortion reduction for this pass
2563 int shift; // Shift amount for distortion
2564 int upshift; // Shift left amount for distortion
2565 int downshift; // Shift right amount for distortion
2566 int normval; // The normalized sample magnitude value
2567 int s; // The stripe index
2568 int nstripes; // The number of stripes in the code-block
2569 int sheight; // Height of the current stripe
2570 int nsym = 0;
2571  
2572 // Initialize local variables
2573 dscanw = srcblk.scanw;
2574 sscanw = srcblk.w + 2;
2575 jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - srcblk.w;
2576 kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - srcblk.w;
2577 mask = 1 << bp;
2578 data = (int[]) srcblk.Data;
2579 nstripes = (srcblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
2580 dist = 0;
2581 // We use the bit just coded plus MSE_LKP_BITS-1 bits below the bit
2582 // just coded for distortion estimation.
2583 shift = bp - MSE_LKP_BITS_M1;
2584 upshift = (shift >= 0)?0:- shift;
2585 downshift = (shift <= 0)?0:shift;
2586  
2587 // Code stripe by stripe
2588 sk = srcblk.offset;
2589 sj = sscanw + 1;
2590 for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
2591 {
2592 sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:srcblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
2593 stopsk = sk + srcblk.w;
2594 // Scan by set of 1 stripe column at a time
2595 for (; sk < stopsk; sk++, sj++)
2596 {
2597 // Do half top of column
2598 j = sj;
2599 csj = state[j];
2600 // If any of the two samples is significant and not yet
2601 // visited in the current bit-plane we can not skip them
2602 if ((((SupportClass.URShift(csj, 1)) & (~ csj)) & VSTD_MASK_R1R2) != 0)
2603 {
2604 k = sk;
2605 // Scan first row
2606 if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == STATE_SIG_R1)
2607 {
2608 // Code bit "raw"
2609 bout.writeBit(SupportClass.URShift((data[k] & mask), bp));
2610 nsym++;
2611 // No need to set STATE_PREV_MR_R1 since all magnitude
2612 // refinement passes to follow are "raw"
2613 // Update distortion
2614 normval = (data[k] >> downshift) << upshift;
2615 dist += fm[normval & ((1 << MSE_LKP_BITS) - 1)];
2616 }
2617 if (sheight < 2)
2618 continue;
2619 // Scan second row
2620 if ((csj & (STATE_SIG_R2 | STATE_VISITED_R2)) == STATE_SIG_R2)
2621 {
2622 k += dscanw;
2623 // Code bit "raw"
2624 bout.writeBit(SupportClass.URShift((data[k] & mask), bp));
2625 nsym++;
2626 // No need to set STATE_PREV_MR_R2 since all magnitude
2627 // refinement passes to follow are "raw"
2628 // Update distortion
2629 normval = (data[k] >> downshift) << upshift;
2630 dist += fm[normval & ((1 << MSE_LKP_BITS) - 1)];
2631 }
2632 }
2633 // Do half bottom of column
2634 if (sheight < 3)
2635 continue;
2636 j += sscanw;
2637 csj = state[j];
2638 // If any of the two samples is significant and not yet
2639 // visited in the current bit-plane we can not skip them
2640 if ((((SupportClass.URShift(csj, 1)) & (~ csj)) & VSTD_MASK_R1R2) != 0)
2641 {
2642 k = sk + (dscanw << 1);
2643 // Scan first row
2644 if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == STATE_SIG_R1)
2645 {
2646 // Code bit "raw"
2647 bout.writeBit(SupportClass.URShift((data[k] & mask), bp));
2648 nsym++;
2649 // No need to set STATE_PREV_MR_R1 since all magnitude
2650 // refinement passes to follow are "raw"
2651 // Update distortion
2652 normval = (data[k] >> downshift) << upshift;
2653 dist += fm[normval & ((1 << MSE_LKP_BITS) - 1)];
2654 }
2655 if (sheight < 4)
2656 continue;
2657 // Scan second row
2658 if ((state[j] & (STATE_SIG_R2 | STATE_VISITED_R2)) == STATE_SIG_R2)
2659 {
2660 k += dscanw;
2661 // Code bit "raw"
2662 bout.writeBit(SupportClass.URShift((data[k] & mask), bp));
2663 nsym++;
2664 // No need to set STATE_PREV_MR_R2 since all magnitude
2665 // refinement passes to follow are "raw"
2666 // Update distortion
2667 normval = (data[k] >> downshift) << upshift;
2668 dist += fm[normval & ((1 << MSE_LKP_BITS) - 1)];
2669 }
2670 }
2671 }
2672 }
2673  
2674 // Get length and terminate if needed
2675 if (doterm)
2676 {
2677 ratebuf[pidx] = bout.terminate();
2678 }
2679 else
2680 {
2681 ratebuf[pidx] = bout.length();
2682 }
2683  
2684 // Add length of previous segments, if any
2685 if (ltpidx >= 0)
2686 {
2687 ratebuf[pidx] += ratebuf[ltpidx];
2688 }
2689  
2690 // Return the reduction in distortion
2691 return dist;
2692 }
2693  
2694 /// <summary> Performs the cleanup pass on the specified data and bit-plane. It codes
2695 /// all insignificant samples which have its "visited" state bit off, using
2696 /// the ZC, SC, and RLC primitives. It toggles the "visited" state bit to 0
2697 /// (off) for all samples in the code-block.
2698 ///
2699 /// </summary>
2700 /// <param name="srcblk">The code-block data to code
2701 ///
2702 /// </param>
2703 /// <param name="mq">The MQ-coder to use
2704 ///
2705 /// </param>
2706 /// <param name="doterm">If true it performs an MQ-coder termination after the end
2707 /// of the pass
2708 ///
2709 /// </param>
2710 /// <param name="bp">The bit-plane to code
2711 ///
2712 /// </param>
2713 /// <param name="state">The state information for the code-block
2714 ///
2715 /// </param>
2716 /// <param name="fs">The distortion estimation lookup table for SC
2717 ///
2718 /// </param>
2719 /// <param name="zc_lut">The ZC lookup table to use in ZC.
2720 ///
2721 /// </param>
2722 /// <param name="symbuf">The buffer to hold symbols to send to the MQ coder
2723 ///
2724 /// </param>
2725 /// <param name="ctxtbuf">A buffer to hold the contexts to use in sending the
2726 /// buffered symbols to the MQ coder.
2727 ///
2728 /// </param>
2729 /// <param name="ratebuf">The buffer where to store the rate (i.e. coded lenth) at
2730 /// the end of this coding pass.
2731 ///
2732 /// </param>
2733 /// <param name="pidx">The coding pass index. Is the index in the 'ratebuf' array
2734 /// where to store the coded length after this coding pass.
2735 ///
2736 /// </param>
2737 /// <param name="ltpidx">The index of the last pass that was terminated, or
2738 /// negative if none.
2739 ///
2740 /// </param>
2741 /// <param name="options">The bitmask of entropy coding options to apply to the
2742 /// code-block
2743 ///
2744 /// </param>
2745 /// <returns> The decrease in distortion for this pass, in the fixed-point
2746 /// normalized representation of the 'FS_LOSSY' and 'FS_LOSSLESS' tables.
2747 ///
2748 /// </returns>
2749 static private int cleanuppass(CBlkWTData srcblk, MQCoder mq, bool doterm, int bp, int[] state, int[] fs, int[] zc_lut, int[] symbuf, int[] ctxtbuf, int[] ratebuf, int pidx, int ltpidx, int options)
2750 {
2751 // NOTE: The speedup mode of the MQ coder has been briefly tried to
2752 // speed up the coding of insignificants RLCs, without any success
2753 // (i.e. no speedup whatsoever). The use of the speedup mode should be
2754 // revisisted more in depth and the implementationn of it in MQCoder
2755 // should be reviewed for optimization opportunities.
2756 int j, sj; // The state index for line and stripe
2757 int k, sk; // The data index for line and stripe
2758 int nsym = 0; // Symbol counter for symbol and context buffers
2759 int dscanw; // The data scan-width
2760 int sscanw; // The state scan-width
2761 int jstep; // Stripe to stripe step for 'sj'
2762 int kstep; // Stripe to stripe step for 'sk'
2763 int stopsk; // The loop limit on the variable sk
2764 int csj; // Local copy (i.e. cached) of 'state[j]'
2765 int mask; // The mask for the current bit-plane
2766 int sym; // The symbol to code
2767 int rlclen; // Length of RLC
2768 int ctxt; // The context to use
2769 int[] data; // The data buffer
2770 int dist; // The distortion reduction for this pass
2771 int shift; // Shift amount for distortion
2772 int upshift; // Shift left amount for distortion
2773 int downshift; // Shift right amount for distortion
2774 int normval; // The normalized sample magnitude value
2775 int s; // The stripe index
2776 bool causal; // Flag to indicate if stripe-causal context
2777 // formation is to be used
2778 int nstripes; // The number of stripes in the code-block
2779 int sheight; // Height of the current stripe
2780 int off_ul, off_ur, off_dr, off_dl; // offsets
2781  
2782 // Initialize local variables
2783 dscanw = srcblk.scanw;
2784 sscanw = srcblk.w + 2;
2785 jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - srcblk.w;
2786 kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - srcblk.w;
2787 mask = 1 << bp;
2788 data = (int[]) srcblk.Data;
2789 nstripes = (srcblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
2790 dist = 0;
2791 // We use the MSE_LKP_BITS-1 bits below the bit just coded for
2792 // distortion estimation.
2793 shift = bp - MSE_LKP_BITS_M1;
2794 upshift = (shift >= 0)?0:- shift;
2795 downshift = (shift <= 0)?0:shift;
2796 causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0;
2797  
2798 // Pre-calculate offsets in 'state' for diagonal neighbors
2799 off_ul = - sscanw - 1; // up-left
2800 off_ur = - sscanw + 1; // up-right
2801 off_dr = sscanw + 1; // down-right
2802 off_dl = sscanw - 1; // down-left
2803  
2804 // Code stripe by stripe
2805 sk = srcblk.offset;
2806 sj = sscanw + 1;
2807 for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
2808 {
2809 sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:srcblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
2810 stopsk = sk + srcblk.w;
2811 // Scan by set of 1 stripe column at a time
2812 for (nsym = 0; sk < stopsk; sk++, sj++)
2813 {
2814 // Start column
2815 j = sj;
2816 csj = state[j];
2817 {
2818 // Check for RLC: if all samples are not significant, not
2819 // visited and do not have a non-zero context, and column
2820 // is full height, we do RLC.
2821 if (csj == 0 && state[j + sscanw] == 0 && sheight == CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT)
2822 {
2823 k = sk;
2824 if ((data[k] & mask) != 0)
2825 {
2826 rlclen = 0;
2827 }
2828 else if ((data[k += dscanw] & mask) != 0)
2829 {
2830 rlclen = 1;
2831 }
2832 else if ((data[k += dscanw] & mask) != 0)
2833 {
2834 rlclen = 2;
2835 j += sscanw;
2836 csj = state[j];
2837 }
2838 else if ((data[k += dscanw] & mask) != 0)
2839 {
2840 rlclen = 3;
2841 j += sscanw;
2842 csj = state[j];
2843 }
2844 else
2845 {
2846 // Code insignificant RLC
2847 symbuf[nsym] = 0;
2848 ctxtbuf[nsym++] = RLC_CTXT;
2849 // Goto next column
2850 continue;
2851 }
2852 // Code significant RLC
2853 symbuf[nsym] = 1;
2854 ctxtbuf[nsym++] = RLC_CTXT;
2855 // Send MSB bit index
2856 symbuf[nsym] = rlclen >> 1;
2857 ctxtbuf[nsym++] = UNIF_CTXT;
2858 // Send LSB bit index
2859 symbuf[nsym] = rlclen & 0x01;
2860 ctxtbuf[nsym++] = UNIF_CTXT;
2861 // Code sign of sample that became significant
2862 // Update distortion
2863 normval = (data[k] >> downshift) << upshift;
2864 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
2865 // Apply sign coding
2866 sym = SupportClass.URShift(data[k], 31);
2867 if ((rlclen & 0x01) == 0)
2868 {
2869 // Sample that became significant is first row of
2870 // its column half
2871 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R1)) & SC_MASK];
2872 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
2873 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
2874 // Update state information (significant bit,
2875 // visited bit, neighbor significant bit of
2876 // neighbors, non zero context of neighbors, sign
2877 // of neighbors)
2878 if (rlclen != 0 || !causal)
2879 {
2880 // If in causal mode do not change contexts of
2881 // previous stripe.
2882 state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
2883 state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
2884 }
2885 // Update sign state information of neighbors
2886 if (sym != 0)
2887 {
2888 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
2889 if (rlclen != 0 || !causal)
2890 {
2891 // If in causal mode do not change
2892 // contexts of previous stripe.
2893 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
2894 }
2895 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
2896 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
2897 }
2898 else
2899 {
2900 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
2901 if (rlclen != 0 || !causal)
2902 {
2903 // If in causal mode do not change
2904 // contexts of previous stripe.
2905 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
2906 }
2907 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
2908 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
2909 }
2910 // Changes to csj are saved later
2911 if ((rlclen >> 1) != 0)
2912 {
2913 // Sample that became significant is in bottom
2914 // half of column => jump to bottom half
2915 //UPGRADE_NOTE: Labeled break statement was changed to a goto statement. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1012'"
2916 goto top_half_brk;
2917 }
2918 // Otherwise sample that became significant is in
2919 // top half of column => continue on top half
2920 }
2921 else
2922 {
2923 // Sample that became significant is second row of
2924 // its column half
2925 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
2926 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
2927 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
2928 // Update state information (significant bit,
2929 // neighbor significant bit of neighbors, non zero
2930 // context of neighbors, sign of neighbors)
2931 state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
2932 state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
2933 // Update sign state information of neighbors
2934 if (sym != 0)
2935 {
2936 csj |= STATE_SIG_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
2937 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
2938 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
2939 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
2940 }
2941 else
2942 {
2943 csj |= STATE_SIG_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
2944 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
2945 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
2946 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
2947 }
2948 // Save changes to csj
2949 state[j] = csj;
2950 if ((rlclen >> 1) != 0)
2951 {
2952 // Sample that became significant is in bottom
2953 // half of column => we're done with this
2954 // column
2955 continue;
2956 }
2957 // Otherwise sample that became significant is in
2958 // top half of column => we're done with top
2959 // column
2960 j += sscanw;
2961 csj = state[j];
2962 //UPGRADE_NOTE: Labeled break statement was changed to a goto statement. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1012'"
2963 goto top_half_brk;
2964 }
2965 }
2966 // Do half top of column
2967 // If any of the two samples is not significant and has
2968 // not been visited in the current bit-plane we can not
2969 // skip them
2970 if ((((csj >> 1) | csj) & VSTD_MASK_R1R2) != VSTD_MASK_R1R2)
2971 {
2972 k = sk;
2973 // Scan first row
2974 if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == 0)
2975 {
2976 // Apply zero coding
2977 ctxtbuf[nsym] = zc_lut[csj & ZC_MASK];
2978 if ((symbuf[nsym++] = SupportClass.URShift((data[k] & mask), bp)) != 0)
2979 {
2980 // Became significant
2981 // Apply sign coding
2982 sym = SupportClass.URShift(data[k], 31);
2983 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R1)) & SC_MASK];
2984 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
2985 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
2986 // Update state information (significant bit,
2987 // visited bit, neighbor significant bit of
2988 // neighbors, non zero context of neighbors,
2989 // sign of neighbors)
2990 if (!causal)
2991 {
2992 // If in causal mode do not change
2993 // contexts of previous stripe.
2994 state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
2995 state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
2996 }
2997 // Update sign state information of neighbors
2998 if (sym != 0)
2999 {
3000 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
3001 if (!causal)
3002 {
3003 // If in causal mode do not change
3004 // contexts of previous stripe.
3005 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
3006 }
3007 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
3008 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
3009 }
3010 else
3011 {
3012 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
3013 if (!causal)
3014 {
3015 // If in causal mode do not change
3016 // contexts of previous stripe.
3017 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
3018 }
3019 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
3020 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
3021 }
3022 // Update distortion
3023 normval = (data[k] >> downshift) << upshift;
3024 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
3025 }
3026 }
3027 if (sheight < 2)
3028 {
3029 csj &= ~ (STATE_VISITED_R1 | STATE_VISITED_R2);
3030 state[j] = csj;
3031 continue;
3032 }
3033 // Scan second row
3034 if ((csj & (STATE_SIG_R2 | STATE_VISITED_R2)) == 0)
3035 {
3036 k += dscanw;
3037 // Apply zero coding
3038 ctxtbuf[nsym] = zc_lut[(SupportClass.URShift(csj, STATE_SEP)) & ZC_MASK];
3039 if ((symbuf[nsym++] = SupportClass.URShift((data[k] & mask), bp)) != 0)
3040 {
3041 // Became significant
3042 // Apply sign coding
3043 sym = SupportClass.URShift(data[k], 31);
3044 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
3045 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
3046 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
3047 // Update state information (significant bit,
3048 // visited bit, neighbor significant bit of
3049 // neighbors, non zero context of neighbors,
3050 // sign of neighbors)
3051 state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
3052 state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
3053 // Update sign state information of neighbors
3054 if (sym != 0)
3055 {
3056 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
3057 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
3058 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
3059 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
3060 }
3061 else
3062 {
3063 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
3064 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
3065 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
3066 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
3067 }
3068 // Update distortion
3069 normval = (data[k] >> downshift) << upshift;
3070 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
3071 }
3072 }
3073 }
3074 csj &= ~ (STATE_VISITED_R1 | STATE_VISITED_R2);
3075 state[j] = csj;
3076 // Do half bottom of column
3077 if (sheight < 3)
3078 continue;
3079 j += sscanw;
3080 csj = state[j];
3081 }
3082 //UPGRADE_NOTE: Label 'top_half_brk' was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1011'"
3083  
3084 top_half_brk: ;
3085 // end of 'top_half' block
3086 // If any of the two samples is not significant and has
3087 // not been visited in the current bit-plane we can not
3088 // skip them
3089 if ((((csj >> 1) | csj) & VSTD_MASK_R1R2) != VSTD_MASK_R1R2)
3090 {
3091 k = sk + (dscanw << 1);
3092 // Scan first row
3093 if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == 0)
3094 {
3095 // Apply zero coding
3096 ctxtbuf[nsym] = zc_lut[csj & ZC_MASK];
3097 if ((symbuf[nsym++] = SupportClass.URShift((data[k] & mask), bp)) != 0)
3098 {
3099 // Became significant
3100 // Apply sign coding
3101 sym = SupportClass.URShift(data[k], 31);
3102 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R1)) & SC_MASK];
3103 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
3104 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
3105 // Update state information (significant bit,
3106 // visited bit, neighbor significant bit of
3107 // neighbors, non zero context of neighbors,
3108 // sign of neighbors)
3109 state[j + off_ul] |= STATE_NZ_CTXT_R2 | STATE_D_DR_R2;
3110 state[j + off_ur] |= STATE_NZ_CTXT_R2 | STATE_D_DL_R2;
3111 // Update sign state information of neighbors
3112 if (sym != 0)
3113 {
3114 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2 | STATE_V_U_SIGN_R2;
3115 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2 | STATE_V_D_SIGN_R2;
3116 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_H_L_SIGN_R1 | STATE_D_UL_R2;
3117 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_H_R_SIGN_R1 | STATE_D_UR_R2;
3118 }
3119 else
3120 {
3121 csj |= STATE_SIG_R1 | STATE_VISITED_R1 | STATE_NZ_CTXT_R2 | STATE_V_U_R2;
3122 state[j - sscanw] |= STATE_NZ_CTXT_R2 | STATE_V_D_R2;
3123 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_L_R1 | STATE_D_UL_R2;
3124 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_H_R_R1 | STATE_D_UR_R2;
3125 }
3126 // Update distortion
3127 normval = (data[k] >> downshift) << upshift;
3128 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
3129 }
3130 }
3131 if (sheight < 4)
3132 {
3133 csj &= ~ (STATE_VISITED_R1 | STATE_VISITED_R2);
3134 state[j] = csj;
3135 continue;
3136 }
3137 // Scan second row
3138 if ((csj & (STATE_SIG_R2 | STATE_VISITED_R2)) == 0)
3139 {
3140 k += dscanw;
3141 // Apply zero coding
3142 ctxtbuf[nsym] = zc_lut[(SupportClass.URShift(csj, STATE_SEP)) & ZC_MASK];
3143 if ((symbuf[nsym++] = SupportClass.URShift((data[k] & mask), bp)) != 0)
3144 {
3145 // Became significant
3146 // Apply sign coding
3147 sym = SupportClass.URShift(data[k], 31);
3148 ctxt = SC_LUT[(SupportClass.URShift(csj, SC_SHIFT_R2)) & SC_MASK];
3149 symbuf[nsym] = sym ^ (SupportClass.URShift(ctxt, SC_SPRED_SHIFT));
3150 ctxtbuf[nsym++] = ctxt & SC_LUT_MASK;
3151 // Update state information (significant bit,
3152 // visited bit, neighbor significant bit of
3153 // neighbors, non zero context of neighbors,
3154 // sign of neighbors)
3155 state[j + off_dl] |= STATE_NZ_CTXT_R1 | STATE_D_UR_R1;
3156 state[j + off_dr] |= STATE_NZ_CTXT_R1 | STATE_D_UL_R1;
3157 // Update sign state information of neighbors
3158 if (sym != 0)
3159 {
3160 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1 | STATE_V_D_SIGN_R1;
3161 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1 | STATE_V_U_SIGN_R1;
3162 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2 | STATE_H_L_SIGN_R2;
3163 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2 | STATE_H_R_SIGN_R2;
3164 }
3165 else
3166 {
3167 csj |= STATE_SIG_R2 | STATE_VISITED_R2 | STATE_NZ_CTXT_R1 | STATE_V_D_R1;
3168 state[j + sscanw] |= STATE_NZ_CTXT_R1 | STATE_V_U_R1;
3169 state[j + 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DL_R1 | STATE_H_L_R2;
3170 state[j - 1] |= STATE_NZ_CTXT_R1 | STATE_NZ_CTXT_R2 | STATE_D_DR_R1 | STATE_H_R_R2;
3171 }
3172 // Update distortion
3173 normval = (data[k] >> downshift) << upshift;
3174 dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)];
3175 }
3176 }
3177 }
3178 csj &= ~ (STATE_VISITED_R1 | STATE_VISITED_R2);
3179 state[j] = csj;
3180 }
3181 // Code all buffered symbols, if any
3182 if (nsym > 0)
3183 mq.codeSymbols(symbuf, ctxtbuf, nsym);
3184 }
3185  
3186 // Insert a segment marker if we need to
3187 if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS) != 0)
3188 {
3189 mq.codeSymbols(SEG_SYMBOLS, SEG_SYMB_CTXTS, SEG_SYMBOLS.Length);
3190 }
3191  
3192 // Reset the MQ context states if we need to
3193 if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ) != 0)
3194 {
3195 mq.resetCtxts();
3196 }
3197  
3198 // Terminate the MQ bit stream if we need to
3199 if (doterm)
3200 {
3201 ratebuf[pidx] = mq.terminate(); // Termination has special length
3202 }
3203 else
3204 {
3205 // Use normal length calculation
3206 ratebuf[pidx] = mq.NumCodedBytes;
3207 }
3208 // Add length of previous segments, if any
3209 if (ltpidx >= 0)
3210 {
3211 ratebuf[pidx] += ratebuf[ltpidx];
3212 }
3213 // Finish length calculation if needed
3214 if (doterm)
3215 {
3216 mq.finishLengthCalculation(ratebuf, pidx);
3217 }
3218 // Return the reduction in distortion
3219 return dist;
3220 }
3221  
3222 /// <summary> Ensures that at the end of a non-terminated coding pass there is not a
3223 /// 0xFF byte, modifying the stored rates if necessary.
3224 ///
3225 /// <p>Due to error resiliance reasons, a coding pass should never have its
3226 /// last byte be a 0xFF, since that can lead to the emulation of a resync
3227 /// marker. This method checks if that is the case, and reduces the rate
3228 /// for a given pass if necessary. The ommitted 0xFF will be synthetized by
3229 /// the decoder if necessary, as required by JPEG 2000. This method should
3230 /// only be called once that the entire code-block is coded.</p>
3231 ///
3232 /// <p>Passes that are terminated are not checked for the 0xFF byte, since
3233 /// it is assumed that the termination procedure does not output any
3234 /// trailing 0xFF. Checking the terminated segments would involve much more
3235 /// than just modifying the stored rates.</p>
3236 ///
3237 /// <p>NOTE: It is assumed by this method that the coded data does not
3238 /// contain consecutive 0xFF bytes, as is the case with the MQ and
3239 /// 'arithemetic coding bypass' bit stuffing policy. However, the
3240 /// termination policies used should also respect this requirement.</p>
3241 ///
3242 /// </summary>
3243 /// <param name="data">The coded data for the code-block
3244 ///
3245 /// </param>
3246 /// <param name="rates">The rate (i.e. accumulated number of bytes) for each
3247 /// coding pass
3248 ///
3249 /// </param>
3250 /// <param name="isterm">An array of flags indicating, for each pass, if it is
3251 /// terminated or not. If null it is assumed that no pass is terminated,
3252 /// except the last one.
3253 ///
3254 /// </param>
3255 /// <param name="n">The number of coding passes
3256 ///
3257 /// </param>
3258 static private void checkEndOfPassFF(byte[] data, int[] rates, bool[] isterm, int n)
3259 {
3260 int dp; // the position to test in 'data'
3261  
3262 // If a pass ends in 0xFF we need to reduce the number of bytes in it,
3263 // so that it does not end in 0xFF. We only need to go back one byte
3264 // since there can be no consecutive 0xFF bytes.
3265  
3266 // If there are no terminated passes avoid the test on 'isterm'
3267 if (isterm == null)
3268 {
3269 for (n--; n >= 0; n--)
3270 {
3271 dp = rates[n] - 1;
3272 if (dp >= 0 && (data[dp] == (byte)0xFF))
3273 {
3274 rates[n]--;
3275 }
3276 }
3277 }
3278 else
3279 {
3280 for (n--; n >= 0; n--)
3281 {
3282 if (!isterm[n])
3283 {
3284 dp = rates[n] - 1;
3285 if (dp >= 0 && (data[dp] == (byte)0xFF))
3286 {
3287 rates[n]--;
3288 }
3289 }
3290 }
3291 }
3292 }
3293  
3294 /// <summary> Load options, length calculation type and termination type for each
3295 /// tile-component.
3296 ///
3297 /// </summary>
3298 /// <param name="nt">The number of tiles
3299 ///
3300 /// </param>
3301 /// <param name="nc">The number of components
3302 ///
3303 /// </param>
3304 public virtual void initTileComp(int nt, int nc)
3305 {
3306  
3307 opts = new int[nt][];
3308 for (int i2 = 0; i2 < nt; i2++)
3309 {
3310 opts[i2] = new int[nc];
3311 }
3312 lenCalc = new int[nt][];
3313 for (int i3 = 0; i3 < nt; i3++)
3314 {
3315 lenCalc[i3] = new int[nc];
3316 }
3317 tType = new int[nt][];
3318 for (int i4 = 0; i4 < nt; i4++)
3319 {
3320 tType[i4] = new int[nc];
3321 }
3322  
3323 for (int t = 0; t < nt; t++)
3324 {
3325 for (int c = 0; c < nc; c++)
3326 {
3327 opts[t][c] = 0;
3328  
3329 // Bypass coding mode ?
3330 if (((System.String) bms.getTileCompVal(t, c)).ToUpper().Equals("on".ToUpper()))
3331 {
3332 opts[t][c] |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS;
3333 }
3334 // MQ reset after each coding pass ?
3335 if (((System.String) mqrs.getTileCompVal(t, c)).ToUpper().Equals("on".ToUpper()))
3336 {
3337 opts[t][c] |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ;
3338 }
3339 // MQ termination after each arithmetically coded coding pass ?
3340 if (((System.String) rts.getTileCompVal(t, c)).ToUpper().Equals("on".ToUpper()))
3341 {
3342 opts[t][c] |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS;
3343 }
3344 // Vertically stripe-causal context mode ?
3345 if (((System.String) css.getTileCompVal(t, c)).ToUpper().Equals("on".ToUpper()))
3346 {
3347 opts[t][c] |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL;
3348 }
3349 // Error resilience segmentation symbol insertion ?
3350 if (((System.String) sss.getTileCompVal(t, c)).ToUpper().Equals("on".ToUpper()))
3351 {
3352 opts[t][c] |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS;
3353 }
3354  
3355 // Set length calculation type of the MQ coder
3356 System.String lCalcType = (System.String) lcs.getTileCompVal(t, c);
3357 if (lCalcType.Equals("near_opt"))
3358 {
3359 lenCalc[t][c] = MQCoder.LENGTH_NEAR_OPT;
3360 }
3361 else if (lCalcType.Equals("lazy_good"))
3362 {
3363 lenCalc[t][c] = MQCoder.LENGTH_LAZY_GOOD;
3364 }
3365 else if (lCalcType.Equals("lazy"))
3366 {
3367 lenCalc[t][c] = MQCoder.LENGTH_LAZY;
3368 }
3369 else
3370 {
3371 throw new System.ArgumentException("Unrecognized or " + "unsupported MQ " + "length calculation.");
3372 }
3373  
3374 // Set termination type of MQ coder
3375 System.String termType = (System.String) tts.getTileCompVal(t, c);
3376 if (termType.ToUpper().Equals("easy".ToUpper()))
3377 {
3378 tType[t][c] = MQCoder.TERM_EASY;
3379 }
3380 else if (termType.ToUpper().Equals("full".ToUpper()))
3381 {
3382 tType[t][c] = MQCoder.TERM_FULL;
3383 }
3384 else if (termType.ToUpper().Equals("near_opt".ToUpper()))
3385 {
3386 tType[t][c] = MQCoder.TERM_NEAR_OPT;
3387 }
3388 else if (termType.ToUpper().Equals("predict".ToUpper()))
3389 {
3390 tType[t][c] = MQCoder.TERM_PRED_ER;
3391 opts[t][c] |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM;
3392 if ((opts[t][c] & (CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS | CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS)) == 0)
3393 {
3394 FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Using error resilient MQ" + " termination, but terminating only at " + "the end of code-blocks. The error " + "protection offered by this option will" + " be very weak. Specify the " + "'Cterminate' " + "and/or 'Cbypass' option for " + "increased error resilience.");
3395 }
3396 }
3397 else
3398 {
3399 throw new System.ArgumentException("Unrecognized or " + "unsupported " + "MQ coder " + "termination.");
3400 }
3401 } // End loop on components
3402 } // End loop on tiles
3403 }
3404  
3405 /// <summary> Returns the precinct partition width for the specified component, tile
3406 /// and resolution level.
3407 ///
3408 /// </summary>
3409 /// <param name="t">the tile index
3410 ///
3411 /// </param>
3412 /// <param name="c">the component
3413 ///
3414 /// </param>
3415 /// <param name="rl">the resolution level
3416 ///
3417 /// </param>
3418 /// <returns> The precinct partition width for the specified component, tile
3419 /// and resolution level
3420 ///
3421 /// </returns>
3422 public override int getPPX(int t, int c, int rl)
3423 {
3424 return pss.getPPX(t, c, rl);
3425 }
3426  
3427 /// <summary> Returns the precinct partition height for the specified component, tile
3428 /// and resolution level.
3429 ///
3430 /// </summary>
3431 /// <param name="t">the tile index
3432 ///
3433 /// </param>
3434 /// <param name="c">the component
3435 ///
3436 /// </param>
3437 /// <param name="rl">the resolution level
3438 ///
3439 /// </param>
3440 /// <returns> The precinct partition height for the specified component, tile
3441 /// and resolution level
3442 ///
3443 /// </returns>
3444 public override int getPPY(int t, int c, int rl)
3445 {
3446 return pss.getPPY(t, c, rl);
3447 }
3448  
3449 /// <summary> Returns true if precinct partition is used for the specified component
3450 /// and tile, returns false otherwise.
3451 ///
3452 /// </summary>
3453 /// <param name="c">The component
3454 ///
3455 /// </param>
3456 /// <param name="t">The tile
3457 ///
3458 /// </param>
3459 /// <returns> True if precinct partition is used for the specified component
3460 /// and tile, returns false otherwise.
3461 ///
3462 /// </returns>
3463 public override bool precinctPartitionUsed(int c, int t)
3464 {
3465 return precinctPartition[c][t];
3466 }
3467 /// <summary>Static initializer: initializes all the lookup tables. </summary>
3468 static StdEntropyCoder()
3469 {
3470 {
3471 int i, j;
3472 double val, deltaMSE;
3473 int[] inter_sc_lut;
3474 int ds, us, rs, ls;
3475 int dsgn, usgn, rsgn, lsgn;
3476 int h, v;
3477  
3478 // Initialize the zero coding lookup tables
3479  
3480 // LH
3481  
3482 // - No neighbors significant
3483 ZC_LUT_LH[0] = 2;
3484  
3485 // - No horizontal or vertical neighbors significant
3486 for (i = 1; i < 16; i++)
3487 {
3488 // Two or more diagonal coeffs significant
3489 ZC_LUT_LH[i] = 4;
3490 }
3491 for (i = 0; i < 4; i++)
3492 {
3493 // Only one diagonal coeff significant
3494 ZC_LUT_LH[1 << i] = 3;
3495 }
3496 // - No horizontal neighbors significant, diagonal irrelevant
3497 for (i = 0; i < 16; i++)
3498 {
3499 // Only one vertical coeff significant
3500 ZC_LUT_LH[STATE_V_U_R1 | i] = 5;
3501 ZC_LUT_LH[STATE_V_D_R1 | i] = 5;
3502 // The two vertical coeffs significant
3503 ZC_LUT_LH[STATE_V_U_R1 | STATE_V_D_R1 | i] = 6;
3504 }
3505 // - One horiz. neighbor significant, diagonal/vertical non-significant
3506 ZC_LUT_LH[STATE_H_L_R1] = 7;
3507 ZC_LUT_LH[STATE_H_R_R1] = 7;
3508 // - One horiz. significant, no vertical significant, one or more
3509 // diagonal significant
3510 for (i = 1; i < 16; i++)
3511 {
3512 ZC_LUT_LH[STATE_H_L_R1 | i] = 8;
3513 ZC_LUT_LH[STATE_H_R_R1 | i] = 8;
3514 }
3515 // - One horiz. significant, one or more vertical significant,
3516 // diagonal irrelevant
3517 for (i = 1; i < 4; i++)
3518 {
3519 for (j = 0; j < 16; j++)
3520 {
3521 ZC_LUT_LH[STATE_H_L_R1 | (i << 4) | j] = 9;
3522 ZC_LUT_LH[STATE_H_R_R1 | (i << 4) | j] = 9;
3523 }
3524 }
3525 // - Two horiz. significant, others irrelevant
3526 for (i = 0; i < 64; i++)
3527 {
3528 ZC_LUT_LH[STATE_H_L_R1 | STATE_H_R_R1 | i] = 10;
3529 }
3530  
3531 // HL
3532  
3533 // - No neighbors significant
3534 ZC_LUT_HL[0] = 2;
3535 // - No horizontal or vertical neighbors significant
3536 for (i = 1; i < 16; i++)
3537 {
3538 // Two or more diagonal coeffs significant
3539 ZC_LUT_HL[i] = 4;
3540 }
3541 for (i = 0; i < 4; i++)
3542 {
3543 // Only one diagonal coeff significant
3544 ZC_LUT_HL[1 << i] = 3;
3545 }
3546 // - No vertical significant, diagonal irrelevant
3547 for (i = 0; i < 16; i++)
3548 {
3549 // One horiz. significant
3550 ZC_LUT_HL[STATE_H_L_R1 | i] = 5;
3551 ZC_LUT_HL[STATE_H_R_R1 | i] = 5;
3552 // Two horiz. significant
3553 ZC_LUT_HL[STATE_H_L_R1 | STATE_H_R_R1 | i] = 6;
3554 }
3555 // - One vert. significant, diagonal/horizontal non-significant
3556 ZC_LUT_HL[STATE_V_U_R1] = 7;
3557 ZC_LUT_HL[STATE_V_D_R1] = 7;
3558 // - One vert. significant, horizontal non-significant, one or more
3559 // diag. significant
3560 for (i = 1; i < 16; i++)
3561 {
3562 ZC_LUT_HL[STATE_V_U_R1 | i] = 8;
3563 ZC_LUT_HL[STATE_V_D_R1 | i] = 8;
3564 }
3565 // - One vertical significant, one or more horizontal significant,
3566 // diagonal irrelevant
3567 for (i = 1; i < 4; i++)
3568 {
3569 for (j = 0; j < 16; j++)
3570 {
3571 ZC_LUT_HL[(i << 6) | STATE_V_U_R1 | j] = 9;
3572 ZC_LUT_HL[(i << 6) | STATE_V_D_R1 | j] = 9;
3573 }
3574 }
3575 // - Two vertical significant, others irrelevant
3576 for (i = 0; i < 4; i++)
3577 {
3578 for (j = 0; j < 16; j++)
3579 {
3580 ZC_LUT_HL[(i << 6) | STATE_V_U_R1 | STATE_V_D_R1 | j] = 10;
3581 }
3582 }
3583  
3584 // HH
3585 int[] twoBits = new int[]{3, 5, 6, 9, 10, 12}; // Figures (between 0 and 15)
3586 // countaning 2 and only 2 bits on in its binary representation.
3587  
3588 int[] oneBit = new int[]{1, 2, 4, 8}; // Figures (between 0 and 15)
3589 // countaning 1 and only 1 bit on in its binary representation.
3590  
3591 int[] twoLeast = new int[]{3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15}; // Figures
3592 // (between 0 and 15) countaining, at least, 2 bits on in its
3593 // binary representation.
3594  
3595 int[] threeLeast = new int[]{7, 11, 13, 14, 15}; // Figures
3596 // (between 0 and 15) countaining, at least, 3 bits on in its
3597 // binary representation.
3598  
3599 // - None significant
3600 ZC_LUT_HH[0] = 2;
3601  
3602 // - One horizontal+vertical significant, none diagonal
3603 for (i = 0; i < oneBit.Length; i++)
3604 ZC_LUT_HH[oneBit[i] << 4] = 3;
3605  
3606 // - Two or more horizontal+vertical significant, diagonal non-signif
3607 for (i = 0; i < twoLeast.Length; i++)
3608 ZC_LUT_HH[twoLeast[i] << 4] = 4;
3609  
3610 // - One diagonal significant, horiz./vert. non-significant
3611 for (i = 0; i < oneBit.Length; i++)
3612 ZC_LUT_HH[oneBit[i]] = 5;
3613  
3614 // - One diagonal significant, one horiz.+vert. significant
3615 for (i = 0; i < oneBit.Length; i++)
3616 for (j = 0; j < oneBit.Length; j++)
3617 ZC_LUT_HH[(oneBit[i] << 4) | oneBit[j]] = 6;
3618  
3619 // - One diag signif, two or more horiz+vert signif
3620 for (i = 0; i < twoLeast.Length; i++)
3621 for (j = 0; j < oneBit.Length; j++)
3622 ZC_LUT_HH[(twoLeast[i] << 4) | oneBit[j]] = 7;
3623  
3624 // - Two diagonal significant, none horiz+vert significant
3625 for (i = 0; i < twoBits.Length; i++)
3626 ZC_LUT_HH[twoBits[i]] = 8;
3627  
3628 // - Two diagonal significant, one or more horiz+vert significant
3629 for (j = 0; j < twoBits.Length; j++)
3630 for (i = 1; i < 16; i++)
3631 ZC_LUT_HH[(i << 4) | twoBits[j]] = 9;
3632  
3633 // - Three or more diagonal significant, horiz+vert irrelevant
3634 for (i = 0; i < 16; i++)
3635 for (j = 0; j < threeLeast.Length; j++)
3636 ZC_LUT_HH[(i << 4) | threeLeast[j]] = 10;
3637  
3638 // Initialize the SC lookup tables
3639  
3640 // Use an intermediate sign code lookup table that is similar to the
3641 // one in the VM text, in that it depends on the 'h' and 'v'
3642 // quantities. The index into this table is a 6 bit index, the top 3
3643 // bits are (h+1) and the low 3 bits (v+1).
3644 inter_sc_lut = new int[36];
3645 inter_sc_lut[(2 << 3) | 2] = 15;
3646 inter_sc_lut[(2 << 3) | 1] = 14;
3647 inter_sc_lut[(2 << 3) | 0] = 13;
3648 inter_sc_lut[(1 << 3) | 2] = 12;
3649 inter_sc_lut[(1 << 3) | 1] = 11;
3650 inter_sc_lut[(1 << 3) | 0] = 12 | INT_SIGN_BIT;
3651 inter_sc_lut[(0 << 3) | 2] = 13 | INT_SIGN_BIT;
3652 inter_sc_lut[(0 << 3) | 1] = 14 | INT_SIGN_BIT;
3653 inter_sc_lut[(0 << 3) | 0] = 15 | INT_SIGN_BIT;
3654  
3655 // Using the intermediate sign code lookup table create the final
3656 // one. The index into this table is a 9 bit index, the low 4 bits are
3657 // the significance of the 4 horizontal/vertical neighbors, while the
3658 // top 4 bits are the signs of those neighbors. The bit in the middle
3659 // is ignored. This index arrangement matches the state bits in the
3660 // 'state' array, thus direct addressing of the table can be done from
3661 // the sate information.
3662 for (i = 0; i < (1 << SC_LUT_BITS) - 1; i++)
3663 {
3664 ds = i & 0x01; // significance of down neighbor
3665 us = (i >> 1) & 0x01; // significance of up neighbor
3666 rs = (i >> 2) & 0x01; // significance of right neighbor
3667 ls = (i >> 3) & 0x01; // significance of left neighbor
3668 dsgn = (i >> 5) & 0x01; // sign of down neighbor
3669 usgn = (i >> 6) & 0x01; // sign of up neighbor
3670 rsgn = (i >> 7) & 0x01; // sign of right neighbor
3671 lsgn = (i >> 8) & 0x01; // sign of left neighbor
3672 // Calculate 'h' and 'v' as in VM text
3673 h = ls * (1 - 2 * lsgn) + rs * (1 - 2 * rsgn);
3674 h = (h >= - 1)?h:- 1;
3675 h = (h <= 1)?h:1;
3676 v = us * (1 - 2 * usgn) + ds * (1 - 2 * dsgn);
3677 v = (v >= - 1)?v:- 1;
3678 v = (v <= 1)?v:1;
3679 // Get context and sign predictor from 'inter_sc_lut'
3680 SC_LUT[i] = inter_sc_lut[(h + 1) << 3 | (v + 1)];
3681 }
3682 inter_sc_lut = null;
3683  
3684 // Initialize the MR lookup tables
3685  
3686 // None significant, prev MR off
3687 MR_LUT[0] = 16;
3688 // One or more significant, prev MR off
3689 for (i = 1; i < (1 << (MR_LUT_BITS - 1)); i++)
3690 {
3691 MR_LUT[i] = 17;
3692 }
3693 // Previous MR on, significance irrelevant
3694 for (; i < (1 << MR_LUT_BITS); i++)
3695 {
3696 MR_LUT[i] = 18;
3697 }
3698  
3699 // Initialize the distortion estimation lookup tables
3700  
3701 // fs tables
3702 for (i = 0; i < (1 << MSE_LKP_BITS_M1); i++)
3703 {
3704 // In fs we index by val-1, since val is really: 1 <= val < 2
3705 val = (double) i / (1 << MSE_LKP_BITS_M1) + 1.0;
3706 deltaMSE = val * val;
3707 //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'"
3708 FS_LOSSLESS[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5);
3709 val -= 1.5;
3710 deltaMSE -= val * val;
3711 //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'"
3712 FS_LOSSY[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5);
3713 }
3714  
3715 // fm tables
3716 for (i = 0; i < (1 << MSE_LKP_BITS); i++)
3717 {
3718 val = (double) i / (1 << MSE_LKP_BITS_M1);
3719 deltaMSE = (val - 1.0) * (val - 1.0);
3720 //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'"
3721 FM_LOSSLESS[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5);
3722 val -= ((i < (1 << MSE_LKP_BITS_M1))?0.5:1.5);
3723 deltaMSE -= val * val;
3724 //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'"
3725 FM_LOSSY[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5);
3726 }
3727 }
3728 }
3729 }
3730 }