corrade-vassal – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | /* |
2 | * CVS identifier: |
||
3 | * |
||
4 | * $Id: HeaderEncoder.java,v 1.43 2001/10/12 09:02:14 grosbois Exp $ |
||
5 | * |
||
6 | * Class: HeaderEncoder |
||
7 | * |
||
8 | * Description: Write codestream headers. |
||
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.entropy.encoder; |
||
47 | using CSJ2K.j2k.quantization; |
||
48 | using CSJ2K.j2k.image.input; |
||
49 | using CSJ2K.j2k.roi.encoder; |
||
50 | using CSJ2K.j2k.codestream; |
||
51 | using CSJ2K.j2k.wavelet; |
||
52 | using CSJ2K.j2k.encoder; |
||
53 | using CSJ2K.j2k.entropy; |
||
54 | using CSJ2K.j2k.image; |
||
55 | using CSJ2K.j2k.util; |
||
56 | using CSJ2K.j2k.io; |
||
57 | using CSJ2K.j2k; |
||
58 | namespace CSJ2K.j2k.codestream.writer |
||
59 | { |
||
60 | |||
61 | /// <summary> This class writes almost of the markers and marker segments in main header |
||
62 | /// and in tile-part headers. It is created by the run() method of the Encoder |
||
63 | /// instance. |
||
64 | /// |
||
65 | /// <p>A marker segment includes a marker and eventually marker segment |
||
66 | /// parameters. It is designed by the three letter code of the marker |
||
67 | /// associated with the marker segment. JPEG 2000 part I defines 6 types of |
||
68 | /// markers: |
||
69 | /// <ul> |
||
70 | /// <li>Delimiting : SOC,SOT,SOD,EOC (written in FileCodestreamWriter).</li> |
||
71 | /// <li>Fixed information: SIZ.</li> |
||
72 | /// <li>Functional: COD,COC,RGN,QCD,QCC,POC.</li> |
||
73 | /// <li> In bit-stream: SOP,EPH.</li> |
||
74 | /// <li> Pointer: TLM,PLM,PLT,PPM,PPT.</li> |
||
75 | /// <li> Informational: CRG,COM.</li> |
||
76 | /// </ul></p> |
||
77 | /// |
||
78 | /// <p>Main Header is written when Encoder instance calls encodeMainHeader |
||
79 | /// whereas tile-part headers are written when the EBCOTRateAllocator instance |
||
80 | /// calls encodeTilePartHeader.</p> |
||
81 | /// |
||
82 | /// </summary> |
||
83 | /// <seealso cref="Encoder"> |
||
84 | /// </seealso> |
||
85 | /// <seealso cref="Markers"> |
||
86 | /// </seealso> |
||
87 | /// <seealso cref="EBCOTRateAllocator"> |
||
88 | /// |
||
89 | /// </seealso> |
||
90 | public class HeaderEncoder |
||
91 | { |
||
92 | /// <summary> Returns the parameters that are used in this class and implementing |
||
93 | /// classes. It returns a 2D String array. Each of the 1D arrays is for a |
||
94 | /// different option, and they have 3 elements. The first element is the |
||
95 | /// option name, the second one is the synopsis, the third one is a long |
||
96 | /// description of what the parameter is and the fourth is its default |
||
97 | /// value. The synopsis or description may be 'null', in which case it is |
||
98 | /// assumed that there is no synopsis or description of the option, |
||
99 | /// respectively. Null may be returned if no options are supported. |
||
100 | /// |
||
101 | /// </summary> |
||
102 | /// <returns> the options name, their synopsis and their explanation, or null |
||
103 | /// if no options are supported. |
||
104 | /// |
||
105 | /// </returns> |
||
106 | public static System.String[][] ParameterInfo |
||
107 | { |
||
108 | get |
||
109 | { |
||
110 | return pinfo; |
||
111 | } |
||
112 | |||
113 | } |
||
114 | /// <summary> Returns the byte-buffer used to store the codestream header. |
||
115 | /// |
||
116 | /// </summary> |
||
117 | /// <returns> A byte array countaining codestream header |
||
118 | /// |
||
119 | /// </returns> |
||
120 | virtual protected internal byte[] Buffer |
||
121 | { |
||
122 | get |
||
123 | { |
||
124 | return baos.ToArray(); |
||
125 | } |
||
126 | |||
127 | } |
||
128 | /// <summary> Returns the length of the header. |
||
129 | /// |
||
130 | /// </summary> |
||
131 | /// <returns> The length of the header in bytes |
||
132 | /// |
||
133 | /// </returns> |
||
134 | virtual public int Length |
||
135 | { |
||
136 | get |
||
137 | { |
||
138 | return (int)hbuf.BaseStream.Length; |
||
139 | } |
||
140 | |||
141 | } |
||
142 | /// <summary> Returns the number of bytes used in the codestream header's buffer. |
||
143 | /// |
||
144 | /// </summary> |
||
145 | /// <returns> Header length in buffer (without any header overhead) |
||
146 | /// |
||
147 | /// </returns> |
||
148 | virtual protected internal int BufferLength |
||
149 | { |
||
150 | get |
||
151 | { |
||
152 | return (int)baos.Length; |
||
153 | } |
||
154 | |||
155 | } |
||
156 | |||
157 | /// <summary>The prefix for the header encoder options: 'H' </summary> |
||
158 | public const char OPT_PREFIX = 'H'; |
||
159 | |||
160 | /// <summary>The list of parameters that are accepted for the header encoder |
||
161 | /// module. Options for this modules start with 'H'. |
||
162 | /// </summary> |
||
163 | //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" |
||
164 | private static readonly System.String[][] pinfo = new System.String[][]{new System.String[]{"Hjj2000_COM", null, "Writes or not the JJ2000 COM marker in the " + "codestream", "off"}, new System.String[]{"HCOM", "<Comment 1>[#<Comment 2>[#<Comment3...>]]", "Adds COM marker segments in the codestream. Comments must be " + "separated with '#' and are written into distinct maker segments.", null}}; |
||
165 | |||
166 | /// <summary>Nominal range bit of the component defining default values in QCD for |
||
167 | /// main header |
||
168 | /// </summary> |
||
169 | private int defimgn; |
||
170 | |||
171 | /// <summary>Nominal range bit of the component defining default values in QCD for |
||
172 | /// tile headers |
||
173 | /// </summary> |
||
174 | private int deftilenr; |
||
175 | |||
176 | /// <summary>The number of components in the image </summary> |
||
177 | private int nComp; |
||
178 | |||
179 | /// <summary>Whether or not to write the JJ2000 COM marker segment </summary> |
||
180 | private bool enJJ2KMarkSeg = true; |
||
181 | |||
182 | /// <summary>Other COM marker segments specified in the command line </summary> |
||
183 | private System.String otherCOMMarkSeg = null; |
||
184 | |||
185 | /// <summary>The ByteArrayOutputStream to store header data. This handler is kept |
||
186 | /// in order to use methods not accessible from a general |
||
187 | /// DataOutputStream. For the other methods, it's better to use variable |
||
188 | /// hbuf. |
||
189 | /// |
||
190 | /// </summary> |
||
191 | /// <seealso cref="hbuf"> |
||
192 | /// </seealso> |
||
193 | protected internal System.IO.MemoryStream baos; |
||
194 | |||
195 | /// <summary>The DataOutputStream to store header data. This kind of object is |
||
196 | /// useful to write short, int, .... It's constructor takes baos as |
||
197 | /// parameter. |
||
198 | /// |
||
199 | /// </summary> |
||
200 | /// <seealso cref="baos"> |
||
201 | /// |
||
202 | /// </seealso> |
||
203 | //UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'" |
||
204 | protected internal System.IO.BinaryWriter hbuf; |
||
205 | |||
206 | /// <summary>The image data reader. Source of original data info </summary> |
||
207 | protected internal ImgData origSrc; |
||
208 | |||
209 | /// <summary>An array specifying, for each component,if the data was signed or not |
||
210 | /// |
||
211 | /// </summary> |
||
212 | protected internal bool[] isOrigSig; |
||
213 | |||
214 | /// <summary>Reference to the rate allocator </summary> |
||
215 | protected internal PostCompRateAllocator ralloc; |
||
216 | |||
217 | /// <summary>Reference to the DWT module </summary> |
||
218 | protected internal ForwardWT dwt; |
||
219 | |||
220 | /// <summary>Reference to the tiler module </summary> |
||
221 | protected internal Tiler tiler; |
||
222 | |||
223 | /// <summary>Reference to the ROI module </summary> |
||
224 | protected internal ROIScaler roiSc; |
||
225 | |||
226 | /// <summary>The encoder specifications </summary> |
||
227 | protected internal EncoderSpecs encSpec; |
||
228 | |||
229 | /// <summary> Initializes the header writer with the references to the coding chain. |
||
230 | /// |
||
231 | /// </summary> |
||
232 | /// <param name="origsrc">The original image data (before any component mixing, |
||
233 | /// tiling, etc.) |
||
234 | /// |
||
235 | /// </param> |
||
236 | /// <param name="isorigsig">An array specifying for each component if it was |
||
237 | /// originally signed or not. |
||
238 | /// |
||
239 | /// </param> |
||
240 | /// <param name="dwt">The discrete wavelet transform module. |
||
241 | /// |
||
242 | /// </param> |
||
243 | /// <param name="tiler">The tiler module. |
||
244 | /// |
||
245 | /// </param> |
||
246 | /// <param name="encSpec">The encoder specifications |
||
247 | /// |
||
248 | /// </param> |
||
249 | /// <param name="roiSc">The ROI scaler module. |
||
250 | /// |
||
251 | /// </param> |
||
252 | /// <param name="ralloc">The post compression rate allocator. |
||
253 | /// |
||
254 | /// </param> |
||
255 | /// <param name="pl">ParameterList instance. |
||
256 | /// |
||
257 | /// </param> |
||
258 | public HeaderEncoder(ImgData origsrc, bool[] isorigsig, ForwardWT dwt, Tiler tiler, EncoderSpecs encSpec, ROIScaler roiSc, PostCompRateAllocator ralloc, ParameterList pl) |
||
259 | { |
||
260 | pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo)); |
||
261 | if (origsrc.NumComps != isorigsig.Length) |
||
262 | { |
||
263 | throw new System.ArgumentException(); |
||
264 | } |
||
265 | this.origSrc = origsrc; |
||
266 | this.isOrigSig = isorigsig; |
||
267 | this.dwt = dwt; |
||
268 | this.tiler = tiler; |
||
269 | this.encSpec = encSpec; |
||
270 | this.roiSc = roiSc; |
||
271 | this.ralloc = ralloc; |
||
272 | |||
273 | baos = new System.IO.MemoryStream(); |
||
274 | //UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'" |
||
275 | hbuf = new CSJ2K.Util.EndianBinaryWriter(baos, true); |
||
276 | nComp = origsrc.NumComps; |
||
277 | enJJ2KMarkSeg = pl.getBooleanParameter("Hjj2000_COM"); |
||
278 | otherCOMMarkSeg = pl.getParameter("HCOM"); |
||
279 | } |
||
280 | |||
281 | /// <summary> Resets the contents of this HeaderEncoder to its initial state. It |
||
282 | /// erases all the data in the header buffer and reactualizes the |
||
283 | /// headerLength field of the bit stream writer. |
||
284 | /// |
||
285 | /// </summary> |
||
286 | public virtual void reset() |
||
287 | { |
||
288 | //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" |
||
289 | // CONVERSION PROBLEM? |
||
290 | //baos.reset(); |
||
291 | baos.SetLength(0); |
||
292 | //UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'" |
||
293 | hbuf = new CSJ2K.Util.EndianBinaryWriter(baos, true); //new System.IO.BinaryWriter(baos); |
||
294 | } |
||
295 | |||
296 | /// <summary> Writes the header to the specified BinaryDataOutput. |
||
297 | /// |
||
298 | /// </summary> |
||
299 | /// <param name="out">Where to write the header. |
||
300 | /// |
||
301 | /// </param> |
||
302 | public virtual void writeTo(BinaryDataOutput out_Renamed) |
||
303 | { |
||
304 | int i, len; |
||
305 | byte[] buf; |
||
306 | |||
307 | buf = Buffer; |
||
308 | len = Length; |
||
309 | |||
310 | for (i = 0; i < len; i++) |
||
311 | { |
||
312 | out_Renamed.writeByte(buf[i]); |
||
313 | } |
||
314 | } |
||
315 | |||
316 | /// <summary> Writes the header to the specified OutputStream. |
||
317 | /// |
||
318 | /// </summary> |
||
319 | /// <param name="out">Where to write the header. |
||
320 | /// |
||
321 | /// </param> |
||
322 | public virtual void writeTo(System.IO.Stream out_Renamed) |
||
323 | { |
||
324 | out_Renamed.Write(Buffer, 0, BufferLength); |
||
325 | } |
||
326 | |||
327 | /// <summary> Start Of Codestream marker (SOC) signalling the beginning of a |
||
328 | /// codestream. |
||
329 | /// |
||
330 | /// </summary> |
||
331 | private void writeSOC() |
||
332 | { |
||
333 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.SOC); |
||
334 | } |
||
335 | |||
336 | /// <summary> Writes SIZ marker segment of the codestream header. It is a fixed |
||
337 | /// information marker segment containing informations about image and tile |
||
338 | /// sizes. It is required in the main header immediately after SOC marker |
||
339 | /// segment. |
||
340 | /// |
||
341 | /// </summary> |
||
342 | private void writeSIZ() |
||
343 | { |
||
344 | int tmp; |
||
345 | |||
346 | // SIZ marker |
||
347 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.SIZ); |
||
348 | |||
349 | // Lsiz (Marker length) corresponding to |
||
350 | // Lsiz(2 bytes)+Rsiz(2)+Xsiz(4)+Ysiz(4)+XOsiz(4)+YOsiz(4)+ |
||
351 | // XTsiz(4)+YTsiz(4)+XTOsiz(4)+YTOsiz(4)+Csiz(2)+ |
||
352 | // (Ssiz(1)+XRsiz(1)+YRsiz(1))*nComp |
||
353 | // markSegLen = 38 + 3*nComp; |
||
354 | int markSegLen = 38 + 3 * nComp; |
||
355 | hbuf.Write((System.Int16) markSegLen); |
||
356 | |||
357 | // Rsiz (codestream capabilities) |
||
358 | hbuf.Write((System.Int16) 0); // JPEG 2000 - Part I |
||
359 | |||
360 | // Xsiz (original image width) |
||
361 | hbuf.Write(tiler.ImgWidth + tiler.ImgULX); |
||
362 | |||
363 | // Ysiz (original image height) |
||
364 | hbuf.Write(tiler.ImgHeight + tiler.ImgULY); |
||
365 | |||
366 | // XOsiz (horizontal offset from the origin of the reference |
||
367 | // grid to the left side of the image area) |
||
368 | hbuf.Write(tiler.ImgULX); |
||
369 | |||
370 | // YOsiz (vertical offset from the origin of the reference |
||
371 | // grid to the top side of the image area) |
||
372 | hbuf.Write(tiler.ImgULY); |
||
373 | |||
374 | // XTsiz (nominal tile width) |
||
375 | hbuf.Write(tiler.NomTileWidth); |
||
376 | |||
377 | // YTsiz (nominal tile height) |
||
378 | hbuf.Write(tiler.NomTileHeight); |
||
379 | |||
380 | Coord torig = tiler.getTilingOrigin(null); |
||
381 | // XTOsiz (Horizontal offset from the origin of the reference |
||
382 | // grid to the left side of the first tile) |
||
383 | hbuf.Write(torig.x); |
||
384 | |||
385 | // YTOsiz (Vertical offset from the origin of the reference |
||
386 | // grid to the top side of the first tile) |
||
387 | hbuf.Write(torig.y); |
||
388 | |||
389 | // Csiz (number of components) |
||
390 | hbuf.Write((System.Int16) nComp); |
||
391 | |||
392 | // Bit-depth and downsampling factors. |
||
393 | for (int c = 0; c < nComp; c++) |
||
394 | { |
||
395 | // Loop on each component |
||
396 | |||
397 | // Ssiz bit-depth before mixing |
||
398 | tmp = origSrc.getNomRangeBits(c) - 1; |
||
399 | |||
400 | tmp |= ((isOrigSig[c]?1:0) << CSJ2K.j2k.codestream.Markers.SSIZ_DEPTH_BITS); |
||
401 | hbuf.Write((System.Byte) tmp); |
||
402 | |||
403 | // XRsiz (component sub-sampling value x-wise) |
||
404 | hbuf.Write((System.Byte) tiler.getCompSubsX(c)); |
||
405 | |||
406 | // YRsiz (component sub-sampling value y-wise) |
||
407 | hbuf.Write((System.Byte) tiler.getCompSubsY(c)); |
||
408 | } // End loop on each component |
||
409 | } |
||
410 | |||
411 | /// <summary> Writes COD marker segment. COD is a functional marker segment |
||
412 | /// containing the code style default (coding style, decomposition, |
||
413 | /// layering) used for compressing all the components in an image. |
||
414 | /// |
||
415 | /// <p>The values can be overriden for an individual component by a COC |
||
416 | /// marker in either the main or the tile header.</p> |
||
417 | /// |
||
418 | /// </summary> |
||
419 | /// <param name="mh">Flag indicating whether this marker belongs to the main |
||
420 | /// header |
||
421 | /// |
||
422 | /// </param> |
||
423 | /// <param name="tileIdx">Tile index if the marker belongs to a tile-part header |
||
424 | /// |
||
425 | /// </param> |
||
426 | /// <seealso cref="writeCOC"> |
||
427 | /// |
||
428 | /// </seealso> |
||
429 | protected internal virtual void writeCOD(bool mh, int tileIdx) |
||
430 | { |
||
431 | AnWTFilter[][] filt; |
||
432 | bool precinctPartitionUsed; |
||
433 | int tmp; |
||
434 | int mrl = 0, a = 0; |
||
435 | int ppx = 0, ppy = 0; |
||
436 | Progression[] prog; |
||
437 | |||
438 | if (mh) |
||
439 | { |
||
440 | mrl = ((System.Int32) encSpec.dls.getDefault()); |
||
441 | // get default precinct size |
||
442 | ppx = encSpec.pss.getPPX(- 1, - 1, mrl); |
||
443 | ppy = encSpec.pss.getPPY(- 1, - 1, mrl); |
||
444 | prog = (Progression[]) (encSpec.pocs.getDefault()); |
||
445 | } |
||
446 | else |
||
447 | { |
||
448 | mrl = ((System.Int32) encSpec.dls.getTileDef(tileIdx)); |
||
449 | // get precinct size for specified tile |
||
450 | ppx = encSpec.pss.getPPX(tileIdx, - 1, mrl); |
||
451 | ppy = encSpec.pss.getPPY(tileIdx, - 1, mrl); |
||
452 | prog = (Progression[]) (encSpec.pocs.getTileDef(tileIdx)); |
||
453 | } |
||
454 | |||
455 | if (ppx != CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE || ppy != CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE) |
||
456 | { |
||
457 | precinctPartitionUsed = true; |
||
458 | } |
||
459 | else |
||
460 | { |
||
461 | precinctPartitionUsed = false; |
||
462 | } |
||
463 | |||
464 | if (precinctPartitionUsed) |
||
465 | { |
||
466 | // If precinct partition is used we add one byte per resolution |
||
467 | // level i.e. mrl+1 (+1 for resolution 0). |
||
468 | a = mrl + 1; |
||
469 | } |
||
470 | |||
471 | // Write COD marker |
||
472 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.COD); |
||
473 | |||
474 | // Lcod (marker segment length (in bytes)) Basic : Lcod(2 |
||
475 | // bytes)+Scod(1)+SGcod(4)+SPcod(5+a) where: |
||
476 | // a=0 if no precinct partition is used |
||
477 | // a=mrl+1 if precinct partition used |
||
478 | int markSegLen = 12 + a; |
||
479 | hbuf.Write((System.Int16) markSegLen); |
||
480 | |||
481 | // Scod (coding style parameter) |
||
482 | tmp = 0; |
||
483 | if (precinctPartitionUsed) |
||
484 | { |
||
485 | tmp = CSJ2K.j2k.codestream.Markers.SCOX_PRECINCT_PARTITION; |
||
486 | } |
||
487 | |||
488 | // Are SOP markers used ? |
||
489 | if (mh) |
||
490 | { |
||
491 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
492 | if (((System.String) encSpec.sops.getDefault().ToString()).ToUpper().Equals("on".ToUpper())) |
||
493 | { |
||
494 | tmp |= CSJ2K.j2k.codestream.Markers.SCOX_USE_SOP; |
||
495 | } |
||
496 | } |
||
497 | else |
||
498 | { |
||
499 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
500 | if (((System.String) encSpec.sops.getTileDef(tileIdx).ToString()).ToUpper().Equals("on".ToUpper())) |
||
501 | { |
||
502 | tmp |= CSJ2K.j2k.codestream.Markers.SCOX_USE_SOP; |
||
503 | } |
||
504 | } |
||
505 | |||
506 | // Are EPH markers used ? |
||
507 | if (mh) |
||
508 | { |
||
509 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
510 | if (((System.String) encSpec.ephs.getDefault().ToString()).ToUpper().Equals("on".ToUpper())) |
||
511 | { |
||
512 | tmp |= CSJ2K.j2k.codestream.Markers.SCOX_USE_EPH; |
||
513 | } |
||
514 | } |
||
515 | else |
||
516 | { |
||
517 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
518 | if (((System.String) encSpec.ephs.getTileDef(tileIdx).ToString()).ToUpper().Equals("on".ToUpper())) |
||
519 | { |
||
520 | tmp |= CSJ2K.j2k.codestream.Markers.SCOX_USE_EPH; |
||
521 | } |
||
522 | } |
||
523 | if (dwt.CbULX != 0) |
||
524 | tmp |= CSJ2K.j2k.codestream.Markers.SCOX_HOR_CB_PART; |
||
525 | if (dwt.CbULY != 0) |
||
526 | tmp |= CSJ2K.j2k.codestream.Markers.SCOX_VER_CB_PART; |
||
527 | hbuf.Write((System.Byte) tmp); |
||
528 | |||
529 | // SGcod |
||
530 | // Progression order |
||
531 | hbuf.Write((System.Byte) prog[0].type); |
||
532 | |||
533 | // Number of layers |
||
534 | hbuf.Write((System.Int16) ralloc.NumLayers); |
||
535 | |||
536 | // Multiple component transform |
||
537 | // CSsiz (Color transform) |
||
538 | System.String str = null; |
||
539 | if (mh) |
||
540 | { |
||
541 | str = ((System.String) encSpec.cts.getDefault()); |
||
542 | } |
||
543 | else |
||
544 | { |
||
545 | str = ((System.String) encSpec.cts.getTileDef(tileIdx)); |
||
546 | } |
||
547 | |||
548 | if (str.Equals("none")) |
||
549 | { |
||
550 | hbuf.Write((System.Byte) 0); |
||
551 | } |
||
552 | else |
||
553 | { |
||
554 | hbuf.Write((System.Byte) 1); |
||
555 | } |
||
556 | |||
557 | // SPcod |
||
558 | // Number of decomposition levels |
||
559 | hbuf.Write((System.Byte) mrl); |
||
560 | |||
561 | // Code-block width and height |
||
562 | if (mh) |
||
563 | { |
||
564 | // main header, get default values |
||
565 | tmp = encSpec.cblks.getCBlkWidth(ModuleSpec.SPEC_DEF, - 1, - 1); |
||
566 | hbuf.Write((System.Byte) (MathUtil.log2(tmp) - 2)); |
||
567 | tmp = encSpec.cblks.getCBlkHeight(ModuleSpec.SPEC_DEF, - 1, - 1); |
||
568 | hbuf.Write((System.Byte) (MathUtil.log2(tmp) - 2)); |
||
569 | } |
||
570 | else |
||
571 | { |
||
572 | // tile header, get tile default values |
||
573 | tmp = encSpec.cblks.getCBlkWidth(ModuleSpec.SPEC_TILE_DEF, tileIdx, - 1); |
||
574 | hbuf.Write((System.Byte) (MathUtil.log2(tmp) - 2)); |
||
575 | tmp = encSpec.cblks.getCBlkHeight(ModuleSpec.SPEC_TILE_DEF, tileIdx, - 1); |
||
576 | hbuf.Write((System.Byte) (MathUtil.log2(tmp) - 2)); |
||
577 | } |
||
578 | |||
579 | // Style of the code-block coding passes |
||
580 | tmp = 0; |
||
581 | if (mh) |
||
582 | { |
||
583 | // Main header |
||
584 | // Selective arithmetic coding bypass ? |
||
585 | if (((System.String) encSpec.bms.getDefault()).Equals("on")) |
||
586 | { |
||
587 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS; |
||
588 | } |
||
589 | // MQ reset after each coding pass ? |
||
590 | if (((System.String) encSpec.mqrs.getDefault()).Equals("on")) |
||
591 | { |
||
592 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ; |
||
593 | } |
||
594 | // MQ termination after each arithmetically coded coding pass ? |
||
595 | if (((System.String) encSpec.rts.getDefault()).Equals("on")) |
||
596 | { |
||
597 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS; |
||
598 | } |
||
599 | // Vertically stripe-causal context mode ? |
||
600 | if (((System.String) encSpec.css.getDefault()).Equals("on")) |
||
601 | { |
||
602 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL; |
||
603 | } |
||
604 | // Predictable termination ? |
||
605 | if (((System.String) encSpec.tts.getDefault()).Equals("predict")) |
||
606 | { |
||
607 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM; |
||
608 | } |
||
609 | // Error resilience segmentation symbol insertion ? |
||
610 | if (((System.String) encSpec.sss.getDefault()).Equals("on")) |
||
611 | { |
||
612 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS; |
||
613 | } |
||
614 | } |
||
615 | else |
||
616 | { |
||
617 | // Tile header |
||
618 | // Selective arithmetic coding bypass ? |
||
619 | if (((System.String) encSpec.bms.getTileDef(tileIdx)).Equals("on")) |
||
620 | { |
||
621 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS; |
||
622 | } |
||
623 | // MQ reset after each coding pass ? |
||
624 | if (((System.String) encSpec.mqrs.getTileDef(tileIdx)).Equals("on")) |
||
625 | { |
||
626 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ; |
||
627 | } |
||
628 | // MQ termination after each arithmetically coded coding pass ? |
||
629 | if (((System.String) encSpec.rts.getTileDef(tileIdx)).Equals("on")) |
||
630 | { |
||
631 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS; |
||
632 | } |
||
633 | // Vertically stripe-causal context mode ? |
||
634 | if (((System.String) encSpec.css.getTileDef(tileIdx)).Equals("on")) |
||
635 | { |
||
636 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL; |
||
637 | } |
||
638 | // Predictable termination ? |
||
639 | if (((System.String) encSpec.tts.getTileDef(tileIdx)).Equals("predict")) |
||
640 | { |
||
641 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM; |
||
642 | } |
||
643 | // Error resilience segmentation symbol insertion ? |
||
644 | if (((System.String) encSpec.sss.getTileDef(tileIdx)).Equals("on")) |
||
645 | { |
||
646 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS; |
||
647 | } |
||
648 | } |
||
649 | hbuf.Write((System.Byte) tmp); |
||
650 | |||
651 | // Wavelet transform |
||
652 | // Wavelet Filter |
||
653 | if (mh) |
||
654 | { |
||
655 | filt = ((AnWTFilter[][]) encSpec.wfs.getDefault()); |
||
656 | hbuf.Write((System.Byte) filt[0][0].FilterType); |
||
657 | } |
||
658 | else |
||
659 | { |
||
660 | filt = ((AnWTFilter[][]) encSpec.wfs.getTileDef(tileIdx)); |
||
661 | hbuf.Write((System.Byte) filt[0][0].FilterType); |
||
662 | } |
||
663 | |||
664 | // Precinct partition |
||
665 | if (precinctPartitionUsed) |
||
666 | { |
||
667 | // Write the precinct size for each resolution level + 1 |
||
668 | // (resolution 0) if precinct partition is used. |
||
669 | System.Collections.ArrayList[] v = null; |
||
670 | if (mh) |
||
671 | { |
||
672 | v = (System.Collections.ArrayList[]) encSpec.pss.getDefault(); |
||
673 | } |
||
674 | else |
||
675 | { |
||
676 | v = (System.Collections.ArrayList[]) encSpec.pss.getTileDef(tileIdx); |
||
677 | } |
||
678 | for (int r = mrl; r >= 0; r--) |
||
679 | { |
||
680 | if (r >= v[1].Count) |
||
681 | { |
||
682 | tmp = ((System.Int32) v[1][v[1].Count - 1]); |
||
683 | } |
||
684 | else |
||
685 | { |
||
686 | tmp = ((System.Int32) v[1][r]); |
||
687 | } |
||
688 | int yExp = (MathUtil.log2(tmp) << 4) & 0x00F0; |
||
689 | |||
690 | if (r >= v[0].Count) |
||
691 | { |
||
692 | tmp = ((System.Int32) v[0][v[0].Count - 1]); |
||
693 | } |
||
694 | else |
||
695 | { |
||
696 | tmp = ((System.Int32) v[0][r]); |
||
697 | } |
||
698 | int xExp = MathUtil.log2(tmp) & 0x000F; |
||
699 | hbuf.Write((System.Byte) (yExp | xExp)); |
||
700 | } |
||
701 | } |
||
702 | } |
||
703 | |||
704 | /// <summary> Writes COC marker segment . It is a functional marker containing the |
||
705 | /// coding style for one component (coding style, decomposition, layering). |
||
706 | /// |
||
707 | /// <p>Its values overrides any value previously set in COD in the main |
||
708 | /// header or in the tile header.</p> |
||
709 | /// |
||
710 | /// </summary> |
||
711 | /// <param name="mh">Flag indicating whether the main header is to be written. |
||
712 | /// |
||
713 | /// </param> |
||
714 | /// <param name="tileIdx">Tile index. |
||
715 | /// |
||
716 | /// </param> |
||
717 | /// <param name="compIdx">index of the component which need use of the COC marker |
||
718 | /// segment. |
||
719 | /// |
||
720 | /// </param> |
||
721 | /// <seealso cref="writeCOD"> |
||
722 | /// |
||
723 | /// </seealso> |
||
724 | protected internal virtual void writeCOC(bool mh, int tileIdx, int compIdx) |
||
725 | { |
||
726 | AnWTFilter[][] filt; |
||
727 | bool precinctPartitionUsed; |
||
728 | int tmp; |
||
729 | int mrl = 0, a = 0; |
||
730 | int ppx = 0, ppy = 0; |
||
731 | Progression[] prog; |
||
732 | |||
733 | if (mh) |
||
734 | { |
||
735 | mrl = ((System.Int32) encSpec.dls.getCompDef(compIdx)); |
||
736 | // Get precinct size for specified component |
||
737 | ppx = encSpec.pss.getPPX(- 1, compIdx, mrl); |
||
738 | ppy = encSpec.pss.getPPY(- 1, compIdx, mrl); |
||
739 | prog = (Progression[]) (encSpec.pocs.getCompDef(compIdx)); |
||
740 | } |
||
741 | else |
||
742 | { |
||
743 | mrl = ((System.Int32) encSpec.dls.getTileCompVal(tileIdx, compIdx)); |
||
744 | // Get precinct size for specified component/tile |
||
745 | ppx = encSpec.pss.getPPX(tileIdx, compIdx, mrl); |
||
746 | ppy = encSpec.pss.getPPY(tileIdx, compIdx, mrl); |
||
747 | prog = (Progression[]) (encSpec.pocs.getTileCompVal(tileIdx, compIdx)); |
||
748 | } |
||
749 | |||
750 | if (ppx != CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE || ppy != CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE) |
||
751 | { |
||
752 | precinctPartitionUsed = true; |
||
753 | } |
||
754 | else |
||
755 | { |
||
756 | precinctPartitionUsed = false; |
||
757 | } |
||
758 | if (precinctPartitionUsed) |
||
759 | { |
||
760 | // If precinct partition is used we add one byte per resolution |
||
761 | // level i.e. mrl+1 (+1 for resolution 0). |
||
762 | a = mrl + 1; |
||
763 | } |
||
764 | |||
765 | // COC marker |
||
766 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.COC); |
||
767 | |||
768 | // Lcoc (marker segment length (in bytes)) |
||
769 | // Basic: Lcoc(2 bytes)+Scoc(1)+ Ccoc(1 or 2)+SPcod(5+a) |
||
770 | int markSegLen = 8 + ((nComp < 257)?1:2) + a; |
||
771 | |||
772 | // Rounded to the nearest even value greater or equals |
||
773 | hbuf.Write((System.Int16) markSegLen); |
||
774 | |||
775 | // Ccoc |
||
776 | if (nComp < 257) |
||
777 | { |
||
778 | hbuf.Write((System.Byte) compIdx); |
||
779 | } |
||
780 | else |
||
781 | { |
||
782 | hbuf.Write((System.Int16) compIdx); |
||
783 | } |
||
784 | |||
785 | // Scod (coding style parameter) |
||
786 | tmp = 0; |
||
787 | if (precinctPartitionUsed) |
||
788 | { |
||
789 | tmp = CSJ2K.j2k.codestream.Markers.SCOX_PRECINCT_PARTITION; |
||
790 | } |
||
791 | hbuf.Write((System.Byte) tmp); |
||
792 | |||
793 | |||
794 | // SPcoc |
||
795 | |||
796 | // Number of decomposition levels |
||
797 | hbuf.Write((System.Byte) mrl); |
||
798 | |||
799 | // Code-block width and height |
||
800 | if (mh) |
||
801 | { |
||
802 | // main header, get component default values |
||
803 | tmp = encSpec.cblks.getCBlkWidth(ModuleSpec.SPEC_COMP_DEF, - 1, compIdx); |
||
804 | hbuf.Write((System.Byte) (MathUtil.log2(tmp) - 2)); |
||
805 | tmp = encSpec.cblks.getCBlkHeight(ModuleSpec.SPEC_COMP_DEF, - 1, compIdx); |
||
806 | hbuf.Write((System.Byte) (MathUtil.log2(tmp) - 2)); |
||
807 | } |
||
808 | else |
||
809 | { |
||
810 | // tile header, get tile component values |
||
811 | tmp = encSpec.cblks.getCBlkWidth(ModuleSpec.SPEC_TILE_COMP, tileIdx, compIdx); |
||
812 | hbuf.Write((System.Byte) (MathUtil.log2(tmp) - 2)); |
||
813 | tmp = encSpec.cblks.getCBlkHeight(ModuleSpec.SPEC_TILE_COMP, tileIdx, compIdx); |
||
814 | hbuf.Write((System.Byte) (MathUtil.log2(tmp) - 2)); |
||
815 | } |
||
816 | |||
817 | // Entropy coding mode options |
||
818 | tmp = 0; |
||
819 | if (mh) |
||
820 | { |
||
821 | // Main header |
||
822 | // Lazy coding mode ? |
||
823 | if (((System.String) encSpec.bms.getCompDef(compIdx)).Equals("on")) |
||
824 | { |
||
825 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS; |
||
826 | } |
||
827 | // MQ reset after each coding pass ? |
||
828 | if (((System.String) encSpec.mqrs.getCompDef(compIdx)).ToUpper().Equals("on".ToUpper())) |
||
829 | { |
||
830 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ; |
||
831 | } |
||
832 | // MQ termination after each arithmetically coded coding pass ? |
||
833 | if (((System.String) encSpec.rts.getCompDef(compIdx)).Equals("on")) |
||
834 | { |
||
835 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS; |
||
836 | } |
||
837 | // Vertically stripe-causal context mode ? |
||
838 | if (((System.String) encSpec.css.getCompDef(compIdx)).Equals("on")) |
||
839 | { |
||
840 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL; |
||
841 | } |
||
842 | // Predictable termination ? |
||
843 | if (((System.String) encSpec.tts.getCompDef(compIdx)).Equals("predict")) |
||
844 | { |
||
845 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM; |
||
846 | } |
||
847 | // Error resilience segmentation symbol insertion ? |
||
848 | if (((System.String) encSpec.sss.getCompDef(compIdx)).Equals("on")) |
||
849 | { |
||
850 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS; |
||
851 | } |
||
852 | } |
||
853 | else |
||
854 | { |
||
855 | // Tile Header |
||
856 | if (((System.String) encSpec.bms.getTileCompVal(tileIdx, compIdx)).Equals("on")) |
||
857 | { |
||
858 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS; |
||
859 | } |
||
860 | // MQ reset after each coding pass ? |
||
861 | if (((System.String) encSpec.mqrs.getTileCompVal(tileIdx, compIdx)).Equals("on")) |
||
862 | { |
||
863 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_RESET_MQ; |
||
864 | } |
||
865 | // MQ termination after each arithmetically coded coding pass ? |
||
866 | if (((System.String) encSpec.rts.getTileCompVal(tileIdx, compIdx)).Equals("on")) |
||
867 | { |
||
868 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS; |
||
869 | } |
||
870 | // Vertically stripe-causal context mode ? |
||
871 | if (((System.String) encSpec.css.getTileCompVal(tileIdx, compIdx)).Equals("on")) |
||
872 | { |
||
873 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL; |
||
874 | } |
||
875 | // Predictable termination ? |
||
876 | if (((System.String) encSpec.tts.getTileCompVal(tileIdx, compIdx)).Equals("predict")) |
||
877 | { |
||
878 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM; |
||
879 | } |
||
880 | // Error resilience segmentation symbol insertion ? |
||
881 | if (((System.String) encSpec.sss.getTileCompVal(tileIdx, compIdx)).Equals("on")) |
||
882 | { |
||
883 | tmp |= CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_SEG_SYMBOLS; |
||
884 | } |
||
885 | } |
||
886 | hbuf.Write((System.Byte) tmp); |
||
887 | |||
888 | // Wavelet transform |
||
889 | // Wavelet Filter |
||
890 | if (mh) |
||
891 | { |
||
892 | filt = ((AnWTFilter[][]) encSpec.wfs.getCompDef(compIdx)); |
||
893 | hbuf.Write((System.Byte) filt[0][0].FilterType); |
||
894 | } |
||
895 | else |
||
896 | { |
||
897 | filt = ((AnWTFilter[][]) encSpec.wfs.getTileCompVal(tileIdx, compIdx)); |
||
898 | hbuf.Write((System.Byte) filt[0][0].FilterType); |
||
899 | } |
||
900 | |||
901 | // Precinct partition |
||
902 | if (precinctPartitionUsed) |
||
903 | { |
||
904 | // Write the precinct size for each resolution level + 1 |
||
905 | // (resolution 0) if precinct partition is used. |
||
906 | System.Collections.ArrayList[] v = null; |
||
907 | if (mh) |
||
908 | { |
||
909 | v = (System.Collections.ArrayList[]) encSpec.pss.getCompDef(compIdx); |
||
910 | } |
||
911 | else |
||
912 | { |
||
913 | v = (System.Collections.ArrayList[]) encSpec.pss.getTileCompVal(tileIdx, compIdx); |
||
914 | } |
||
915 | for (int r = mrl; r >= 0; r--) |
||
916 | { |
||
917 | if (r >= v[1].Count) |
||
918 | { |
||
919 | tmp = ((System.Int32) v[1][v[1].Count - 1]); |
||
920 | } |
||
921 | else |
||
922 | { |
||
923 | tmp = ((System.Int32) v[1][r]); |
||
924 | } |
||
925 | int yExp = (MathUtil.log2(tmp) << 4) & 0x00F0; |
||
926 | |||
927 | if (r >= v[0].Count) |
||
928 | { |
||
929 | tmp = ((System.Int32) v[0][v[0].Count - 1]); |
||
930 | } |
||
931 | else |
||
932 | { |
||
933 | tmp = ((System.Int32) v[0][r]); |
||
934 | } |
||
935 | int xExp = MathUtil.log2(tmp) & 0x000F; |
||
936 | hbuf.Write((System.Byte) (yExp | xExp)); |
||
937 | } |
||
938 | } |
||
939 | } |
||
940 | |||
941 | /// <summary> Writes QCD marker segment in main header. QCD is a functional marker |
||
942 | /// segment countaining the quantization default used for compressing all |
||
943 | /// the components in an image. The values can be overriden for an |
||
944 | /// individual component by a QCC marker in either the main or the tile |
||
945 | /// header. |
||
946 | /// |
||
947 | /// </summary> |
||
948 | protected internal virtual void writeMainQCD() |
||
949 | { |
||
950 | int mrl; |
||
951 | int qstyle; |
||
952 | |||
953 | float step; |
||
954 | |||
955 | System.String qType = (System.String) encSpec.qts.getDefault(); |
||
956 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
957 | float baseStep = (float) ((System.Single) encSpec.qsss.getDefault()); |
||
958 | int gb = ((System.Int32) encSpec.gbs.getDefault()); |
||
959 | |||
960 | bool isDerived = qType.Equals("derived"); |
||
961 | bool isReversible = qType.Equals("reversible"); |
||
962 | |||
963 | mrl = ((System.Int32) encSpec.dls.getDefault()); |
||
964 | |||
965 | int nt = dwt.getNumTiles(); |
||
966 | int nc = dwt.NumComps; |
||
967 | int tmpI; |
||
968 | int[] tcIdx = new int[2]; |
||
969 | System.String tmpStr; |
||
970 | bool notFound = true; |
||
971 | for (int t = 0; t < nt && notFound; t++) |
||
972 | { |
||
973 | for (int c = 0; c < nc && notFound; c++) |
||
974 | { |
||
975 | tmpI = ((System.Int32) encSpec.dls.getTileCompVal(t, c)); |
||
976 | tmpStr = ((System.String) encSpec.qts.getTileCompVal(t, c)); |
||
977 | if (tmpI == mrl && tmpStr.Equals(qType)) |
||
978 | { |
||
979 | tcIdx[0] = t; tcIdx[1] = c; |
||
980 | notFound = false; |
||
981 | } |
||
982 | } |
||
983 | } |
||
984 | if (notFound) |
||
985 | { |
||
986 | throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCD marker segment. " + "You have found a JJ2000 bug."); |
||
987 | } |
||
988 | SubbandAn sb, csb, sbRoot = dwt.getAnSubbandTree(tcIdx[0], tcIdx[1]); |
||
989 | defimgn = dwt.getNomRangeBits(tcIdx[1]); |
||
990 | |||
991 | int nqcd; // Number of quantization step-size to transmit |
||
992 | |||
993 | // Get the quantization style |
||
994 | qstyle = (isReversible)?CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:((isDerived)?CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED); |
||
995 | |||
996 | // QCD marker |
||
997 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.QCD); |
||
998 | |||
999 | // Compute the number of steps to send |
||
1000 | switch (qstyle) |
||
1001 | { |
||
1002 | |||
1003 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: |
||
1004 | nqcd = 1; // Just the LL value |
||
1005 | break; |
||
1006 | |||
1007 | case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: |
||
1008 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: |
||
1009 | // One value per subband |
||
1010 | nqcd = 0; |
||
1011 | |||
1012 | sb = sbRoot; |
||
1013 | |||
1014 | // Get the subband at first resolution level |
||
1015 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1016 | |||
1017 | // Count total number of subbands |
||
1018 | for (int j = 0; j <= mrl; j++) |
||
1019 | { |
||
1020 | csb = sb; |
||
1021 | while (csb != null) |
||
1022 | { |
||
1023 | nqcd++; |
||
1024 | csb = (SubbandAn) csb.nextSubband(); |
||
1025 | } |
||
1026 | // Go up one resolution level |
||
1027 | sb = (SubbandAn) sb.NextResLevel; |
||
1028 | } |
||
1029 | break; |
||
1030 | |||
1031 | default: |
||
1032 | throw new System.ApplicationException("Internal JJ2000 error"); |
||
1033 | |||
1034 | } |
||
1035 | |||
1036 | // Lqcd (marker segment length (in bytes)) |
||
1037 | // Lqcd(2 bytes)+Sqcd(1)+ SPqcd (2*Nqcd) |
||
1038 | int markSegLen = 3 + ((isReversible)?nqcd:2 * nqcd); |
||
1039 | |||
1040 | // Rounded to the nearest even value greater or equals |
||
1041 | hbuf.Write((System.Int16) markSegLen); |
||
1042 | |||
1043 | // Sqcd |
||
1044 | hbuf.Write((System.Byte) (qstyle + (gb << CSJ2K.j2k.codestream.Markers.SQCX_GB_SHIFT))); |
||
1045 | |||
1046 | // SPqcd |
||
1047 | switch (qstyle) |
||
1048 | { |
||
1049 | |||
1050 | case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: |
||
1051 | sb = sbRoot; |
||
1052 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1053 | |||
1054 | // Output one exponent per subband |
||
1055 | for (int j = 0; j <= mrl; j++) |
||
1056 | { |
||
1057 | csb = sb; |
||
1058 | while (csb != null) |
||
1059 | { |
||
1060 | int tmp = (defimgn + csb.anGainExp); |
||
1061 | hbuf.Write((System.Byte) (tmp << CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT)); |
||
1062 | |||
1063 | csb = (SubbandAn) csb.nextSubband(); |
||
1064 | // Go up one resolution level |
||
1065 | } |
||
1066 | sb = (SubbandAn) sb.NextResLevel; |
||
1067 | } |
||
1068 | break; |
||
1069 | |||
1070 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: |
||
1071 | sb = sbRoot; |
||
1072 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1073 | |||
1074 | // Calculate subband step (normalized to unit |
||
1075 | // dynamic range) |
||
1076 | step = baseStep / (1 << sb.level); |
||
1077 | |||
1078 | // Write exponent-mantissa, 16 bits |
||
1079 | hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step)); |
||
1080 | break; |
||
1081 | |||
1082 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: |
||
1083 | sb = sbRoot; |
||
1084 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1085 | |||
1086 | // Output one step per subband |
||
1087 | for (int j = 0; j <= mrl; j++) |
||
1088 | { |
||
1089 | csb = sb; |
||
1090 | while (csb != null) |
||
1091 | { |
||
1092 | // Calculate subband step (normalized to unit |
||
1093 | // dynamic range) |
||
1094 | step = baseStep / (csb.l2Norm * (1 << csb.anGainExp)); |
||
1095 | |||
1096 | // Write exponent-mantissa, 16 bits |
||
1097 | hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step)); |
||
1098 | |||
1099 | csb = (SubbandAn) csb.nextSubband(); |
||
1100 | } |
||
1101 | // Go up one resolution level |
||
1102 | sb = (SubbandAn) sb.NextResLevel; |
||
1103 | } |
||
1104 | break; |
||
1105 | |||
1106 | default: |
||
1107 | throw new System.ApplicationException("Internal JJ2000 error"); |
||
1108 | |||
1109 | } |
||
1110 | } |
||
1111 | |||
1112 | /// <summary> Writes QCC marker segment in main header. It is a functional marker |
||
1113 | /// segment countaining the quantization used for compressing the specified |
||
1114 | /// component in an image. The values override for the specified component |
||
1115 | /// what was defined by a QCC marker in either the main or the tile header. |
||
1116 | /// |
||
1117 | /// </summary> |
||
1118 | /// <param name="compIdx">Index of the component which needs QCC marker segment. |
||
1119 | /// |
||
1120 | /// </param> |
||
1121 | protected internal virtual void writeMainQCC(int compIdx) |
||
1122 | { |
||
1123 | |||
1124 | int mrl; |
||
1125 | int qstyle; |
||
1126 | int tIdx = 0; |
||
1127 | float step; |
||
1128 | |||
1129 | SubbandAn sb, sb2; |
||
1130 | SubbandAn sbRoot; |
||
1131 | |||
1132 | int imgnr = dwt.getNomRangeBits(compIdx); |
||
1133 | System.String qType = (System.String) encSpec.qts.getCompDef(compIdx); |
||
1134 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
1135 | float baseStep = (float) ((System.Single) encSpec.qsss.getCompDef(compIdx)); |
||
1136 | int gb = ((System.Int32) encSpec.gbs.getCompDef(compIdx)); |
||
1137 | |||
1138 | bool isReversible = qType.Equals("reversible"); |
||
1139 | bool isDerived = qType.Equals("derived"); |
||
1140 | |||
1141 | mrl = ((System.Int32) encSpec.dls.getCompDef(compIdx)); |
||
1142 | |||
1143 | int nt = dwt.getNumTiles(); |
||
1144 | int nc = dwt.NumComps; |
||
1145 | int tmpI; |
||
1146 | System.String tmpStr; |
||
1147 | bool notFound = true; |
||
1148 | for (int t = 0; t < nt && notFound; t++) |
||
1149 | { |
||
1150 | for (int c = 0; c < nc && notFound; c++) |
||
1151 | { |
||
1152 | tmpI = ((System.Int32) encSpec.dls.getTileCompVal(t, c)); |
||
1153 | tmpStr = ((System.String) encSpec.qts.getTileCompVal(t, c)); |
||
1154 | if (tmpI == mrl && tmpStr.Equals(qType)) |
||
1155 | { |
||
1156 | tIdx = t; |
||
1157 | notFound = false; |
||
1158 | } |
||
1159 | } |
||
1160 | } |
||
1161 | if (notFound) |
||
1162 | { |
||
1163 | throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCC (c=" + compIdx + ") marker segment. " + "You have found a JJ2000 bug."); |
||
1164 | } |
||
1165 | sbRoot = dwt.getAnSubbandTree(tIdx, compIdx); |
||
1166 | |||
1167 | int nqcc; // Number of quantization step-size to transmit |
||
1168 | |||
1169 | // Get the quantization style |
||
1170 | if (isReversible) |
||
1171 | { |
||
1172 | qstyle = CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION; |
||
1173 | } |
||
1174 | else if (isDerived) |
||
1175 | { |
||
1176 | qstyle = CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED; |
||
1177 | } |
||
1178 | else |
||
1179 | { |
||
1180 | qstyle = CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED; |
||
1181 | } |
||
1182 | |||
1183 | // QCC marker |
||
1184 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.QCC); |
||
1185 | |||
1186 | // Compute the number of steps to send |
||
1187 | switch (qstyle) |
||
1188 | { |
||
1189 | |||
1190 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: |
||
1191 | nqcc = 1; // Just the LL value |
||
1192 | break; |
||
1193 | |||
1194 | case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: |
||
1195 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: |
||
1196 | // One value per subband |
||
1197 | nqcc = 0; |
||
1198 | |||
1199 | sb = sbRoot; |
||
1200 | mrl = sb.resLvl; |
||
1201 | |||
1202 | // Get the subband at first resolution level |
||
1203 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1204 | |||
1205 | // Find root element for LL subband |
||
1206 | while (sb.resLvl != 0) |
||
1207 | { |
||
1208 | sb = sb.subb_LL; |
||
1209 | } |
||
1210 | |||
1211 | // Count total number of subbands |
||
1212 | for (int j = 0; j <= mrl; j++) |
||
1213 | { |
||
1214 | sb2 = sb; |
||
1215 | while (sb2 != null) |
||
1216 | { |
||
1217 | nqcc++; |
||
1218 | sb2 = (SubbandAn) sb2.nextSubband(); |
||
1219 | } |
||
1220 | // Go up one resolution level |
||
1221 | sb = (SubbandAn) sb.NextResLevel; |
||
1222 | } |
||
1223 | break; |
||
1224 | |||
1225 | default: |
||
1226 | throw new System.ApplicationException("Internal JJ2000 error"); |
||
1227 | |||
1228 | } |
||
1229 | |||
1230 | // Lqcc (marker segment length (in bytes)) |
||
1231 | // Lqcc(2 bytes)+Cqcc(1 or 2)+Sqcc(1)+ SPqcc (2*Nqcc) |
||
1232 | int markSegLen = 3 + ((nComp < 257)?1:2) + ((isReversible)?nqcc:2 * nqcc); |
||
1233 | hbuf.Write((System.Int16) markSegLen); |
||
1234 | |||
1235 | // Cqcc |
||
1236 | if (nComp < 257) |
||
1237 | { |
||
1238 | hbuf.Write((System.Byte) compIdx); |
||
1239 | } |
||
1240 | else |
||
1241 | { |
||
1242 | hbuf.Write((System.Int16) compIdx); |
||
1243 | } |
||
1244 | |||
1245 | // Sqcc (quantization style) |
||
1246 | hbuf.Write((System.Byte) (qstyle + (gb << CSJ2K.j2k.codestream.Markers.SQCX_GB_SHIFT))); |
||
1247 | |||
1248 | // SPqcc |
||
1249 | switch (qstyle) |
||
1250 | { |
||
1251 | |||
1252 | case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: |
||
1253 | // Get resolution level 0 subband |
||
1254 | sb = sbRoot; |
||
1255 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1256 | |||
1257 | // Output one exponent per subband |
||
1258 | for (int j = 0; j <= mrl; j++) |
||
1259 | { |
||
1260 | sb2 = sb; |
||
1261 | while (sb2 != null) |
||
1262 | { |
||
1263 | int tmp = (imgnr + sb2.anGainExp); |
||
1264 | hbuf.Write((System.Byte) (tmp << CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT)); |
||
1265 | |||
1266 | sb2 = (SubbandAn) sb2.nextSubband(); |
||
1267 | } |
||
1268 | // Go up one resolution level |
||
1269 | sb = (SubbandAn) sb.NextResLevel; |
||
1270 | } |
||
1271 | break; |
||
1272 | |||
1273 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: |
||
1274 | // Get resolution level 0 subband |
||
1275 | sb = sbRoot; |
||
1276 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1277 | |||
1278 | // Calculate subband step (normalized to unit |
||
1279 | // dynamic range) |
||
1280 | step = baseStep / (1 << sb.level); |
||
1281 | |||
1282 | // Write exponent-mantissa, 16 bits |
||
1283 | hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step)); |
||
1284 | break; |
||
1285 | |||
1286 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: |
||
1287 | // Get resolution level 0 subband |
||
1288 | sb = sbRoot; |
||
1289 | mrl = sb.resLvl; |
||
1290 | |||
1291 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1292 | |||
1293 | for (int j = 0; j <= mrl; j++) |
||
1294 | { |
||
1295 | sb2 = sb; |
||
1296 | while (sb2 != null) |
||
1297 | { |
||
1298 | // Calculate subband step (normalized to unit |
||
1299 | // dynamic range) |
||
1300 | step = baseStep / (sb2.l2Norm * (1 << sb2.anGainExp)); |
||
1301 | |||
1302 | // Write exponent-mantissa, 16 bits |
||
1303 | hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step)); |
||
1304 | sb2 = (SubbandAn) sb2.nextSubband(); |
||
1305 | } |
||
1306 | // Go up one resolution level |
||
1307 | sb = (SubbandAn) sb.NextResLevel; |
||
1308 | } |
||
1309 | break; |
||
1310 | |||
1311 | default: |
||
1312 | throw new System.ApplicationException("Internal JJ2000 error"); |
||
1313 | |||
1314 | } |
||
1315 | } |
||
1316 | |||
1317 | /// <summary> Writes QCD marker segment in tile header. QCD is a functional marker |
||
1318 | /// segment countaining the quantization default used for compressing all |
||
1319 | /// the components in an image. The values can be overriden for an |
||
1320 | /// individual component by a QCC marker in either the main or the tile |
||
1321 | /// header. |
||
1322 | /// |
||
1323 | /// </summary> |
||
1324 | /// <param name="tIdx">Tile index |
||
1325 | /// |
||
1326 | /// </param> |
||
1327 | protected internal virtual void writeTileQCD(int tIdx) |
||
1328 | { |
||
1329 | int mrl; |
||
1330 | int qstyle; |
||
1331 | |||
1332 | float step; |
||
1333 | SubbandAn sb, csb, sbRoot; |
||
1334 | |||
1335 | System.String qType = (System.String) encSpec.qts.getTileDef(tIdx); |
||
1336 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
1337 | float baseStep = (float) ((System.Single) encSpec.qsss.getTileDef(tIdx)); |
||
1338 | mrl = ((System.Int32) encSpec.dls.getTileDef(tIdx)); |
||
1339 | |||
1340 | int nc = dwt.NumComps; |
||
1341 | int tmpI; |
||
1342 | System.String tmpStr; |
||
1343 | bool notFound = true; |
||
1344 | int compIdx = 0; |
||
1345 | for (int c = 0; c < nc && notFound; c++) |
||
1346 | { |
||
1347 | tmpI = ((System.Int32) encSpec.dls.getTileCompVal(tIdx, c)); |
||
1348 | tmpStr = ((System.String) encSpec.qts.getTileCompVal(tIdx, c)); |
||
1349 | if (tmpI == mrl && tmpStr.Equals(qType)) |
||
1350 | { |
||
1351 | compIdx = c; |
||
1352 | notFound = false; |
||
1353 | } |
||
1354 | } |
||
1355 | if (notFound) |
||
1356 | { |
||
1357 | throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in tile QCD (t=" + tIdx + ") marker segment. " + "You have found a JJ2000 bug."); |
||
1358 | } |
||
1359 | |||
1360 | sbRoot = dwt.getAnSubbandTree(tIdx, compIdx); |
||
1361 | deftilenr = dwt.getNomRangeBits(compIdx); |
||
1362 | int gb = ((System.Int32) encSpec.gbs.getTileDef(tIdx)); |
||
1363 | |||
1364 | bool isDerived = qType.Equals("derived"); |
||
1365 | bool isReversible = qType.Equals("reversible"); |
||
1366 | |||
1367 | int nqcd; // Number of quantization step-size to transmit |
||
1368 | |||
1369 | // Get the quantization style |
||
1370 | qstyle = (isReversible)?CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:((isDerived)?CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED); |
||
1371 | |||
1372 | // QCD marker |
||
1373 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.QCD); |
||
1374 | |||
1375 | // Compute the number of steps to send |
||
1376 | switch (qstyle) |
||
1377 | { |
||
1378 | |||
1379 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: |
||
1380 | nqcd = 1; // Just the LL value |
||
1381 | break; |
||
1382 | |||
1383 | case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: |
||
1384 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: |
||
1385 | // One value per subband |
||
1386 | nqcd = 0; |
||
1387 | |||
1388 | sb = sbRoot; |
||
1389 | |||
1390 | // Get the subband at first resolution level |
||
1391 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1392 | |||
1393 | // Count total number of subbands |
||
1394 | for (int j = 0; j <= mrl; j++) |
||
1395 | { |
||
1396 | csb = sb; |
||
1397 | while (csb != null) |
||
1398 | { |
||
1399 | nqcd++; |
||
1400 | csb = (SubbandAn) csb.nextSubband(); |
||
1401 | } |
||
1402 | // Go up one resolution level |
||
1403 | sb = (SubbandAn) sb.NextResLevel; |
||
1404 | } |
||
1405 | break; |
||
1406 | |||
1407 | default: |
||
1408 | throw new System.ApplicationException("Internal JJ2000 error"); |
||
1409 | |||
1410 | } |
||
1411 | |||
1412 | // Lqcd (marker segment length (in bytes)) |
||
1413 | // Lqcd(2 bytes)+Sqcd(1)+ SPqcd (2*Nqcd) |
||
1414 | int markSegLen = 3 + ((isReversible)?nqcd:2 * nqcd); |
||
1415 | |||
1416 | // Rounded to the nearest even value greater or equals |
||
1417 | hbuf.Write((System.Int16) markSegLen); |
||
1418 | |||
1419 | // Sqcd |
||
1420 | hbuf.Write((System.Byte) (qstyle + (gb << CSJ2K.j2k.codestream.Markers.SQCX_GB_SHIFT))); |
||
1421 | |||
1422 | // SPqcd |
||
1423 | switch (qstyle) |
||
1424 | { |
||
1425 | |||
1426 | case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: |
||
1427 | sb = sbRoot; |
||
1428 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1429 | |||
1430 | // Output one exponent per subband |
||
1431 | for (int j = 0; j <= mrl; j++) |
||
1432 | { |
||
1433 | csb = sb; |
||
1434 | while (csb != null) |
||
1435 | { |
||
1436 | int tmp = (deftilenr + csb.anGainExp); |
||
1437 | hbuf.Write((System.Byte) (tmp << CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT)); |
||
1438 | |||
1439 | csb = (SubbandAn) csb.nextSubband(); |
||
1440 | // Go up one resolution level |
||
1441 | } |
||
1442 | sb = (SubbandAn) sb.NextResLevel; |
||
1443 | } |
||
1444 | break; |
||
1445 | |||
1446 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: |
||
1447 | sb = sbRoot; |
||
1448 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1449 | |||
1450 | // Calculate subband step (normalized to unit |
||
1451 | // dynamic range) |
||
1452 | step = baseStep / (1 << sb.level); |
||
1453 | |||
1454 | // Write exponent-mantissa, 16 bits |
||
1455 | hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step)); |
||
1456 | break; |
||
1457 | |||
1458 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: |
||
1459 | sb = sbRoot; |
||
1460 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1461 | |||
1462 | // Output one step per subband |
||
1463 | for (int j = 0; j <= mrl; j++) |
||
1464 | { |
||
1465 | csb = sb; |
||
1466 | while (csb != null) |
||
1467 | { |
||
1468 | // Calculate subband step (normalized to unit |
||
1469 | // dynamic range) |
||
1470 | step = baseStep / (csb.l2Norm * (1 << csb.anGainExp)); |
||
1471 | |||
1472 | // Write exponent-mantissa, 16 bits |
||
1473 | hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step)); |
||
1474 | |||
1475 | csb = (SubbandAn) csb.nextSubband(); |
||
1476 | } |
||
1477 | // Go up one resolution level |
||
1478 | sb = (SubbandAn) sb.NextResLevel; |
||
1479 | } |
||
1480 | break; |
||
1481 | |||
1482 | default: |
||
1483 | throw new System.ApplicationException("Internal JJ2000 error"); |
||
1484 | |||
1485 | } |
||
1486 | } |
||
1487 | |||
1488 | /// <summary> Writes QCC marker segment in tile header. It is a functional marker |
||
1489 | /// segment countaining the quantization used for compressing the specified |
||
1490 | /// component in an image. The values override for the specified component |
||
1491 | /// what was defined by a QCC marker in either the main or the tile header. |
||
1492 | /// |
||
1493 | /// </summary> |
||
1494 | /// <param name="t">Tile index |
||
1495 | /// |
||
1496 | /// </param> |
||
1497 | /// <param name="compIdx">Index of the component which needs QCC marker segment. |
||
1498 | /// |
||
1499 | /// </param> |
||
1500 | protected internal virtual void writeTileQCC(int t, int compIdx) |
||
1501 | { |
||
1502 | |||
1503 | int mrl; |
||
1504 | int qstyle; |
||
1505 | float step; |
||
1506 | |||
1507 | SubbandAn sb, sb2; |
||
1508 | int nqcc; // Number of quantization step-size to transmit |
||
1509 | |||
1510 | SubbandAn sbRoot = dwt.getAnSubbandTree(t, compIdx); |
||
1511 | int imgnr = dwt.getNomRangeBits(compIdx); |
||
1512 | System.String qType = (System.String) encSpec.qts.getTileCompVal(t, compIdx); |
||
1513 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
1514 | float baseStep = (float) ((System.Single) encSpec.qsss.getTileCompVal(t, compIdx)); |
||
1515 | int gb = ((System.Int32) encSpec.gbs.getTileCompVal(t, compIdx)); |
||
1516 | |||
1517 | bool isReversible = qType.Equals("reversible"); |
||
1518 | bool isDerived = qType.Equals("derived"); |
||
1519 | |||
1520 | mrl = ((System.Int32) encSpec.dls.getTileCompVal(t, compIdx)); |
||
1521 | |||
1522 | // Get the quantization style |
||
1523 | if (isReversible) |
||
1524 | { |
||
1525 | qstyle = CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION; |
||
1526 | } |
||
1527 | else if (isDerived) |
||
1528 | { |
||
1529 | qstyle = CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED; |
||
1530 | } |
||
1531 | else |
||
1532 | { |
||
1533 | qstyle = CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED; |
||
1534 | } |
||
1535 | |||
1536 | // QCC marker |
||
1537 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.QCC); |
||
1538 | |||
1539 | // Compute the number of steps to send |
||
1540 | switch (qstyle) |
||
1541 | { |
||
1542 | |||
1543 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: |
||
1544 | nqcc = 1; // Just the LL value |
||
1545 | break; |
||
1546 | |||
1547 | case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: |
||
1548 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: |
||
1549 | // One value per subband |
||
1550 | nqcc = 0; |
||
1551 | |||
1552 | sb = sbRoot; |
||
1553 | mrl = sb.resLvl; |
||
1554 | |||
1555 | // Get the subband at first resolution level |
||
1556 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1557 | |||
1558 | // Find root element for LL subband |
||
1559 | while (sb.resLvl != 0) |
||
1560 | { |
||
1561 | sb = sb.subb_LL; |
||
1562 | } |
||
1563 | |||
1564 | // Count total number of subbands |
||
1565 | for (int j = 0; j <= mrl; j++) |
||
1566 | { |
||
1567 | sb2 = sb; |
||
1568 | while (sb2 != null) |
||
1569 | { |
||
1570 | nqcc++; |
||
1571 | sb2 = (SubbandAn) sb2.nextSubband(); |
||
1572 | } |
||
1573 | // Go up one resolution level |
||
1574 | sb = (SubbandAn) sb.NextResLevel; |
||
1575 | } |
||
1576 | break; |
||
1577 | |||
1578 | default: |
||
1579 | throw new System.ApplicationException("Internal JJ2000 error"); |
||
1580 | |||
1581 | } |
||
1582 | |||
1583 | // Lqcc (marker segment length (in bytes)) |
||
1584 | // Lqcc(2 bytes)+Cqcc(1 or 2)+Sqcc(1)+ SPqcc (2*Nqcc) |
||
1585 | int markSegLen = 3 + ((nComp < 257)?1:2) + ((isReversible)?nqcc:2 * nqcc); |
||
1586 | hbuf.Write((System.Int16) markSegLen); |
||
1587 | |||
1588 | // Cqcc |
||
1589 | if (nComp < 257) |
||
1590 | { |
||
1591 | hbuf.Write((System.Byte) compIdx); |
||
1592 | } |
||
1593 | else |
||
1594 | { |
||
1595 | hbuf.Write((System.Int16) compIdx); |
||
1596 | } |
||
1597 | |||
1598 | // Sqcc (quantization style) |
||
1599 | hbuf.Write((System.Byte) (qstyle + (gb << CSJ2K.j2k.codestream.Markers.SQCX_GB_SHIFT))); |
||
1600 | |||
1601 | // SPqcc |
||
1602 | switch (qstyle) |
||
1603 | { |
||
1604 | |||
1605 | case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION: |
||
1606 | // Get resolution level 0 subband |
||
1607 | sb = sbRoot; |
||
1608 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1609 | |||
1610 | // Output one exponent per subband |
||
1611 | for (int j = 0; j <= mrl; j++) |
||
1612 | { |
||
1613 | sb2 = sb; |
||
1614 | while (sb2 != null) |
||
1615 | { |
||
1616 | int tmp = (imgnr + sb2.anGainExp); |
||
1617 | hbuf.Write((System.Byte) (tmp << CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT)); |
||
1618 | |||
1619 | sb2 = (SubbandAn) sb2.nextSubband(); |
||
1620 | } |
||
1621 | // Go up one resolution level |
||
1622 | sb = (SubbandAn) sb.NextResLevel; |
||
1623 | } |
||
1624 | break; |
||
1625 | |||
1626 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED: |
||
1627 | // Get resolution level 0 subband |
||
1628 | sb = sbRoot; |
||
1629 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1630 | |||
1631 | // Calculate subband step (normalized to unit |
||
1632 | // dynamic range) |
||
1633 | step = baseStep / (1 << sb.level); |
||
1634 | |||
1635 | // Write exponent-mantissa, 16 bits |
||
1636 | hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step)); |
||
1637 | break; |
||
1638 | |||
1639 | case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED: |
||
1640 | // Get resolution level 0 subband |
||
1641 | sb = sbRoot; |
||
1642 | mrl = sb.resLvl; |
||
1643 | |||
1644 | sb = (SubbandAn) sb.getSubbandByIdx(0, 0); |
||
1645 | |||
1646 | for (int j = 0; j <= mrl; j++) |
||
1647 | { |
||
1648 | sb2 = sb; |
||
1649 | while (sb2 != null) |
||
1650 | { |
||
1651 | // Calculate subband step (normalized to unit |
||
1652 | // dynamic range) |
||
1653 | step = baseStep / (sb2.l2Norm * (1 << sb2.anGainExp)); |
||
1654 | |||
1655 | // Write exponent-mantissa, 16 bits |
||
1656 | hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step)); |
||
1657 | sb2 = (SubbandAn) sb2.nextSubband(); |
||
1658 | } |
||
1659 | // Go up one resolution level |
||
1660 | sb = (SubbandAn) sb.NextResLevel; |
||
1661 | } |
||
1662 | break; |
||
1663 | |||
1664 | default: |
||
1665 | throw new System.ApplicationException("Internal JJ2000 error"); |
||
1666 | |||
1667 | } |
||
1668 | } |
||
1669 | |||
1670 | /// <summary> Writes POC marker segment. POC is a functional marker segment |
||
1671 | /// containing the bounds and progression order for any progression order |
||
1672 | /// other than default in the codestream. |
||
1673 | /// |
||
1674 | /// </summary> |
||
1675 | /// <param name="mh">Flag indicating whether the main header is to be written |
||
1676 | /// |
||
1677 | /// </param> |
||
1678 | /// <param name="tileIdx">Tile index |
||
1679 | /// |
||
1680 | /// </param> |
||
1681 | protected internal virtual void writePOC(bool mh, int tileIdx) |
||
1682 | { |
||
1683 | int markSegLen = 0; // Segment marker length |
||
1684 | int lenCompField; // Holds the size of any component field as |
||
1685 | // this size depends on the number of |
||
1686 | //components |
||
1687 | Progression[] prog = null; // Holds the progression(s) |
||
1688 | int npoc; // Number of progression order changes |
||
1689 | |||
1690 | // Get the progression order changes, their number and checks |
||
1691 | // if it is ok |
||
1692 | if (mh) |
||
1693 | { |
||
1694 | prog = (Progression[]) (encSpec.pocs.getDefault()); |
||
1695 | } |
||
1696 | else |
||
1697 | { |
||
1698 | prog = (Progression[]) (encSpec.pocs.getTileDef(tileIdx)); |
||
1699 | } |
||
1700 | |||
1701 | // Calculate the length of a component field (depends on the number of |
||
1702 | // components) |
||
1703 | lenCompField = (nComp < 257?1:2); |
||
1704 | |||
1705 | // POC marker |
||
1706 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.POC); |
||
1707 | |||
1708 | // Lpoc (marker segment length (in bytes)) |
||
1709 | // Basic: Lpoc(2 bytes) + npoc * [ RSpoc(1) + CSpoc(1 or 2) + |
||
1710 | // LYEpoc(2) + REpoc(1) + CEpoc(1 or 2) + Ppoc(1) ] |
||
1711 | npoc = prog.Length; |
||
1712 | markSegLen = 2 + npoc * (1 + lenCompField + 2 + 1 + lenCompField + 1); |
||
1713 | hbuf.Write((System.Int16) markSegLen); |
||
1714 | |||
1715 | // Write each progression order change |
||
1716 | for (int i = 0; i < npoc; i++) |
||
1717 | { |
||
1718 | // RSpoc(i) |
||
1719 | hbuf.Write((System.Byte) prog[i].rs); |
||
1720 | // CSpoc(i) |
||
1721 | if (lenCompField == 2) |
||
1722 | { |
||
1723 | hbuf.Write((System.Int16) prog[i].cs); |
||
1724 | } |
||
1725 | else |
||
1726 | { |
||
1727 | hbuf.Write((System.Byte) prog[i].cs); |
||
1728 | } |
||
1729 | // LYEpoc(i) |
||
1730 | hbuf.Write((System.Int16) prog[i].lye); |
||
1731 | // REpoc(i) |
||
1732 | hbuf.Write((System.Byte) prog[i].re); |
||
1733 | // CEpoc(i) |
||
1734 | if (lenCompField == 2) |
||
1735 | { |
||
1736 | hbuf.Write((System.Int16) prog[i].ce); |
||
1737 | } |
||
1738 | else |
||
1739 | { |
||
1740 | hbuf.Write((System.Byte) prog[i].ce); |
||
1741 | } |
||
1742 | // Ppoc(i) |
||
1743 | hbuf.Write((System.Byte) prog[i].type); |
||
1744 | } |
||
1745 | } |
||
1746 | |||
1747 | |||
1748 | /// <summary> Write main header. JJ2000 main header corresponds to the following |
||
1749 | /// sequence of marker segments: |
||
1750 | /// |
||
1751 | /// <ol> |
||
1752 | /// <li>SOC</li> |
||
1753 | /// <li>SIZ</li> |
||
1754 | /// <li>COD</li> |
||
1755 | /// <li>COC (if needed)</li> |
||
1756 | /// <li>QCD</li> |
||
1757 | /// <li>QCC (if needed)</li> |
||
1758 | /// <li>POC (if needed)</li> |
||
1759 | /// </ol> |
||
1760 | /// |
||
1761 | /// </summary> |
||
1762 | public virtual void encodeMainHeader() |
||
1763 | { |
||
1764 | int i; |
||
1765 | |||
1766 | |||
1767 | // +---------------------------------+ |
||
1768 | // | SOC marker segment | |
||
1769 | // +---------------------------------+ |
||
1770 | writeSOC(); |
||
1771 | |||
1772 | // +---------------------------------+ |
||
1773 | // | Image and tile SIZe (SIZ) | |
||
1774 | // +---------------------------------+ |
||
1775 | writeSIZ(); |
||
1776 | |||
1777 | // +-------------------------------+ |
||
1778 | // | COding style Default (COD) | |
||
1779 | // +-------------------------------+ |
||
1780 | bool isEresUsed = ((System.String) encSpec.tts.getDefault()).Equals("predict"); |
||
1781 | writeCOD(true, 0); |
||
1782 | |||
1783 | // +---------------------------------+ |
||
1784 | // | COding style Component (COC) | |
||
1785 | // +---------------------------------+ |
||
1786 | for (i = 0; i < nComp; i++) |
||
1787 | { |
||
1788 | bool isEresUsedinComp = ((System.String) encSpec.tts.getCompDef(i)).Equals("predict"); |
||
1789 | if (encSpec.wfs.isCompSpecified(i) || encSpec.dls.isCompSpecified(i) || encSpec.bms.isCompSpecified(i) || encSpec.mqrs.isCompSpecified(i) || encSpec.rts.isCompSpecified(i) || encSpec.sss.isCompSpecified(i) || encSpec.css.isCompSpecified(i) || encSpec.pss.isCompSpecified(i) || encSpec.cblks.isCompSpecified(i) || (isEresUsed != isEresUsedinComp)) |
||
1790 | // Some component non-default stuff => need COC |
||
1791 | writeCOC(true, 0, i); |
||
1792 | } |
||
1793 | |||
1794 | // +-------------------------------+ |
||
1795 | // | Quantization Default (QCD) | |
||
1796 | // +-------------------------------+ |
||
1797 | writeMainQCD(); |
||
1798 | |||
1799 | // +-------------------------------+ |
||
1800 | // | Quantization Component (QCC) | |
||
1801 | // +-------------------------------+ |
||
1802 | // Write needed QCC markers |
||
1803 | for (i = 0; i < nComp; i++) |
||
1804 | { |
||
1805 | if (dwt.getNomRangeBits(i) != defimgn || encSpec.qts.isCompSpecified(i) || encSpec.qsss.isCompSpecified(i) || encSpec.dls.isCompSpecified(i) || encSpec.gbs.isCompSpecified(i)) |
||
1806 | { |
||
1807 | writeMainQCC(i); |
||
1808 | } |
||
1809 | } |
||
1810 | |||
1811 | // +--------------------------+ |
||
1812 | // | POC maker segment | |
||
1813 | // +--------------------------+ |
||
1814 | Progression[] prog = (Progression[]) (encSpec.pocs.getDefault()); |
||
1815 | if (prog.Length > 1) |
||
1816 | writePOC(true, 0); |
||
1817 | |||
1818 | // +---------------------------+ |
||
1819 | // | Comments (COM) | |
||
1820 | // +---------------------------+ |
||
1821 | writeCOM(); |
||
1822 | } |
||
1823 | |||
1824 | /// <summary> Write COM marker segment(s) to the codestream. |
||
1825 | /// |
||
1826 | /// <p>This marker is currently written in main header and indicates the |
||
1827 | /// JJ2000 encoder's version that has created the codestream.</p> |
||
1828 | /// |
||
1829 | /// </summary> |
||
1830 | private void writeCOM() |
||
1831 | { |
||
1832 | // JJ2000 COM marker segment |
||
1833 | if (enJJ2KMarkSeg) |
||
1834 | { |
||
1835 | System.String str = "Created by: CSJ2K version " + JJ2KInfo.version; |
||
1836 | int markSegLen; // the marker segment length |
||
1837 | |||
1838 | // COM marker |
||
1839 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.COM); |
||
1840 | |||
1841 | // Calculate length: Lcom(2) + Rcom (2) + string's length; |
||
1842 | markSegLen = 2 + 2 + str.Length; |
||
1843 | hbuf.Write((System.Int16) markSegLen); |
||
1844 | |||
1845 | // Rcom |
||
1846 | hbuf.Write((System.Int16) 1); // General use (IS 8859-15:1999(Latin) values) |
||
1847 | |||
1848 | byte[] chars = System.Text.ASCIIEncoding.ASCII.GetBytes(str); |
||
1849 | for (int i = 0; i < chars.Length; i++) |
||
1850 | { |
||
1851 | hbuf.Write((byte) chars[i]); |
||
1852 | } |
||
1853 | } |
||
1854 | // other COM marker segments |
||
1855 | if (otherCOMMarkSeg != null) |
||
1856 | { |
||
1857 | SupportClass.Tokenizer stk = new SupportClass.Tokenizer(otherCOMMarkSeg, "#"); |
||
1858 | while (stk.HasMoreTokens()) |
||
1859 | { |
||
1860 | System.String str = stk.NextToken(); |
||
1861 | int markSegLen; // the marker segment length |
||
1862 | |||
1863 | // COM marker |
||
1864 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.COM); |
||
1865 | |||
1866 | // Calculate length: Lcom(2) + Rcom (2) + string's length; |
||
1867 | markSegLen = 2 + 2 + str.Length; |
||
1868 | hbuf.Write((System.Int16) markSegLen); |
||
1869 | |||
1870 | // Rcom |
||
1871 | hbuf.Write((System.Int16) 1); // General use (IS 8859-15:1999(Latin) |
||
1872 | // values) |
||
1873 | |||
1874 | byte[] chars = System.Text.ASCIIEncoding.ASCII.GetBytes(str); |
||
1875 | for (int i = 0; i < chars.Length; i++) |
||
1876 | { |
||
1877 | hbuf.Write((byte) chars[i]); |
||
1878 | } |
||
1879 | } |
||
1880 | } |
||
1881 | } |
||
1882 | |||
1883 | /// <summary> Writes the RGN marker segment in the tile header. It describes the |
||
1884 | /// scaling value in each tile component |
||
1885 | /// |
||
1886 | /// <p>May be used in tile or main header. If used in main header, it |
||
1887 | /// refers to a ROI of the whole image, regardless of tiling. When used in |
||
1888 | /// tile header, only the particular tile is affected.</p> |
||
1889 | /// |
||
1890 | /// </summary> |
||
1891 | /// <param name="tIdx">The tile index |
||
1892 | /// |
||
1893 | /// </param> |
||
1894 | /// <exception cref="IOException">If an I/O error occurs while reading from the |
||
1895 | /// encoder header stream |
||
1896 | /// |
||
1897 | /// </exception> |
||
1898 | private void writeRGN(int tIdx) |
||
1899 | { |
||
1900 | int i; |
||
1901 | int markSegLen; // the marker length |
||
1902 | |||
1903 | // Write one RGN marker per component |
||
1904 | for (i = 0; i < nComp; i++) |
||
1905 | { |
||
1906 | // RGN marker |
||
1907 | hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.RGN); |
||
1908 | |||
1909 | // Calculate length (Lrgn) |
||
1910 | // Basic: Lrgn (2) + Srgn (1) + SPrgn + one byte |
||
1911 | // or two for component number |
||
1912 | markSegLen = 4 + ((nComp < 257)?1:2); |
||
1913 | hbuf.Write((System.Int16) markSegLen); |
||
1914 | |||
1915 | // Write component (Crgn) |
||
1916 | if (nComp < 257) |
||
1917 | { |
||
1918 | hbuf.Write((System.Byte) i); |
||
1919 | } |
||
1920 | else |
||
1921 | { |
||
1922 | hbuf.Write((System.Int16) i); |
||
1923 | } |
||
1924 | |||
1925 | // Write type of ROI (Srgn) |
||
1926 | hbuf.Write((System.Byte) CSJ2K.j2k.codestream.Markers.SRGN_IMPLICIT); |
||
1927 | |||
1928 | // Write ROI info (SPrgn) |
||
1929 | hbuf.Write((System.Byte) ((System.Int32) (encSpec.rois.getTileCompVal(tIdx, i)))); |
||
1930 | } |
||
1931 | } |
||
1932 | /// <summary> Writes tile-part header. JJ2000 tile-part header corresponds to the |
||
1933 | /// following sequence of marker segments: |
||
1934 | /// |
||
1935 | /// <ol> |
||
1936 | /// <li>SOT</li> |
||
1937 | /// <li>COD (if needed)</li> |
||
1938 | /// <li>COC (if needed)</li> |
||
1939 | /// <li>QCD (if needed)</li> |
||
1940 | /// <li>QCC (if needed)</li> |
||
1941 | /// <li>RGN (if needed)</li> |
||
1942 | /// <li>POC (if needed)</li> |
||
1943 | /// <li>SOD</li> |
||
1944 | /// </ol> |
||
1945 | /// |
||
1946 | /// </summary> |
||
1947 | /// <param name="length">The length of the current tile-part. |
||
1948 | /// |
||
1949 | /// </param> |
||
1950 | /// <param name="tileIdx">Index of the tile to write |
||
1951 | /// |
||
1952 | /// </param> |
||
1953 | public virtual void encodeTilePartHeader(int tileLength, int tileIdx) |
||
1954 | { |
||
1955 | |||
1956 | int tmp; |
||
1957 | Coord numTiles = ralloc.getNumTiles(null); |
||
1958 | ralloc.setTile(tileIdx % numTiles.x, tileIdx / numTiles.x); |
||
1959 | |||
1960 | // +--------------------------+ |
||
1961 | // | SOT maker segment | |
||
1962 | // +--------------------------+ |
||
1963 | // SOT marker |
||
1964 | hbuf.Write((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.SOT, 8)); |
||
1965 | hbuf.Write((System.Byte) (CSJ2K.j2k.codestream.Markers.SOT & 0x00FF)); |
||
1966 | |||
1967 | // Lsot (10 bytes) |
||
1968 | hbuf.Write((System.Byte) 0); |
||
1969 | hbuf.Write((System.Byte) 10); |
||
1970 | |||
1971 | // Isot |
||
1972 | if (tileIdx > 65534) |
||
1973 | { |
||
1974 | throw new System.ArgumentException("Trying to write a tile-part " + "header whose tile index is " + "too high"); |
||
1975 | } |
||
1976 | hbuf.Write((System.Byte) (tileIdx >> 8)); |
||
1977 | hbuf.Write((System.Byte) tileIdx); |
||
1978 | |||
1979 | // Psot |
||
1980 | tmp = tileLength; |
||
1981 | hbuf.Write((System.Byte) (tmp >> 24)); |
||
1982 | hbuf.Write((System.Byte) (tmp >> 16)); |
||
1983 | hbuf.Write((System.Byte) (tmp >> 8)); |
||
1984 | hbuf.Write((System.Byte) tmp); |
||
1985 | |||
1986 | // TPsot |
||
1987 | hbuf.Write((System.Byte) 0); // Only one tile-part currently supported ! |
||
1988 | |||
1989 | // TNsot |
||
1990 | hbuf.Write((System.Byte) 1); // Only one tile-part currently supported ! |
||
1991 | |||
1992 | // +--------------------------+ |
||
1993 | // | COD maker segment | |
||
1994 | // +--------------------------+ |
||
1995 | bool isEresUsed = ((System.String) encSpec.tts.getDefault()).Equals("predict"); |
||
1996 | bool isEresUsedInTile = ((System.String) encSpec.tts.getTileDef(tileIdx)).Equals("predict"); |
||
1997 | bool tileCODwritten = false; |
||
1998 | if (encSpec.wfs.isTileSpecified(tileIdx) || encSpec.cts.isTileSpecified(tileIdx) || encSpec.dls.isTileSpecified(tileIdx) || encSpec.bms.isTileSpecified(tileIdx) || encSpec.mqrs.isTileSpecified(tileIdx) || encSpec.rts.isTileSpecified(tileIdx) || encSpec.css.isTileSpecified(tileIdx) || encSpec.pss.isTileSpecified(tileIdx) || encSpec.sops.isTileSpecified(tileIdx) || encSpec.sss.isTileSpecified(tileIdx) || encSpec.pocs.isTileSpecified(tileIdx) || encSpec.ephs.isTileSpecified(tileIdx) || encSpec.cblks.isTileSpecified(tileIdx) || (isEresUsed != isEresUsedInTile)) |
||
1999 | { |
||
2000 | writeCOD(false, tileIdx); |
||
2001 | tileCODwritten = true; |
||
2002 | } |
||
2003 | |||
2004 | // +--------------------------+ |
||
2005 | // | COC maker segment | |
||
2006 | // +--------------------------+ |
||
2007 | for (int c = 0; c < nComp; c++) |
||
2008 | { |
||
2009 | bool isEresUsedInTileComp = ((System.String) encSpec.tts.getTileCompVal(tileIdx, c)).Equals("predict"); |
||
2010 | |||
2011 | if (encSpec.wfs.isTileCompSpecified(tileIdx, c) || encSpec.dls.isTileCompSpecified(tileIdx, c) || encSpec.bms.isTileCompSpecified(tileIdx, c) || encSpec.mqrs.isTileCompSpecified(tileIdx, c) || encSpec.rts.isTileCompSpecified(tileIdx, c) || encSpec.css.isTileCompSpecified(tileIdx, c) || encSpec.pss.isTileCompSpecified(tileIdx, c) || encSpec.sss.isTileCompSpecified(tileIdx, c) || encSpec.cblks.isTileCompSpecified(tileIdx, c) || (isEresUsedInTileComp != isEresUsed)) |
||
2012 | { |
||
2013 | writeCOC(false, tileIdx, c); |
||
2014 | } |
||
2015 | else if (tileCODwritten) |
||
2016 | { |
||
2017 | if (encSpec.wfs.isCompSpecified(c) || encSpec.dls.isCompSpecified(c) || encSpec.bms.isCompSpecified(c) || encSpec.mqrs.isCompSpecified(c) || encSpec.rts.isCompSpecified(c) || encSpec.sss.isCompSpecified(c) || encSpec.css.isCompSpecified(c) || encSpec.pss.isCompSpecified(c) || encSpec.cblks.isCompSpecified(c) || (encSpec.tts.isCompSpecified(c) && ((System.String) encSpec.tts.getCompDef(c)).Equals("predict"))) |
||
2018 | { |
||
2019 | writeCOC(false, tileIdx, c); |
||
2020 | } |
||
2021 | } |
||
2022 | } |
||
2023 | |||
2024 | // +--------------------------+ |
||
2025 | // | QCD maker segment | |
||
2026 | // +--------------------------+ |
||
2027 | bool tileQCDwritten = false; |
||
2028 | if (encSpec.qts.isTileSpecified(tileIdx) || encSpec.qsss.isTileSpecified(tileIdx) || encSpec.dls.isTileSpecified(tileIdx) || encSpec.gbs.isTileSpecified(tileIdx)) |
||
2029 | { |
||
2030 | writeTileQCD(tileIdx); |
||
2031 | tileQCDwritten = true; |
||
2032 | } |
||
2033 | else |
||
2034 | { |
||
2035 | deftilenr = defimgn; |
||
2036 | } |
||
2037 | |||
2038 | // +--------------------------+ |
||
2039 | // | QCC maker segment | |
||
2040 | // +--------------------------+ |
||
2041 | for (int c = 0; c < nComp; c++) |
||
2042 | { |
||
2043 | if (dwt.getNomRangeBits(c) != deftilenr || encSpec.qts.isTileCompSpecified(tileIdx, c) || encSpec.qsss.isTileCompSpecified(tileIdx, c) || encSpec.dls.isTileCompSpecified(tileIdx, c) || encSpec.gbs.isTileCompSpecified(tileIdx, c)) |
||
2044 | { |
||
2045 | writeTileQCC(tileIdx, c); |
||
2046 | } |
||
2047 | else if (tileQCDwritten) |
||
2048 | { |
||
2049 | if (encSpec.qts.isCompSpecified(c) || encSpec.qsss.isCompSpecified(c) || encSpec.dls.isCompSpecified(c) || encSpec.gbs.isCompSpecified(c)) |
||
2050 | { |
||
2051 | writeTileQCC(tileIdx, c); |
||
2052 | } |
||
2053 | } |
||
2054 | } |
||
2055 | |||
2056 | // +--------------------------+ |
||
2057 | // | RGN maker segment | |
||
2058 | // +--------------------------+ |
||
2059 | if (roiSc.useRoi() && (!roiSc.BlockAligned)) |
||
2060 | writeRGN(tileIdx); |
||
2061 | |||
2062 | // +--------------------------+ |
||
2063 | // | POC maker segment | |
||
2064 | // +--------------------------+ |
||
2065 | Progression[] prog; |
||
2066 | if (encSpec.pocs.isTileSpecified(tileIdx)) |
||
2067 | { |
||
2068 | prog = (Progression[]) (encSpec.pocs.getTileDef(tileIdx)); |
||
2069 | if (prog.Length > 1) |
||
2070 | writePOC(false, tileIdx); |
||
2071 | } |
||
2072 | |||
2073 | // +--------------------------+ |
||
2074 | // | SOD maker | |
||
2075 | // +--------------------------+ |
||
2076 | hbuf.Write((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.SOD, 8)); |
||
2077 | hbuf.Write((System.Byte) (CSJ2K.j2k.codestream.Markers.SOD & 0x00FF)); |
||
2078 | } |
||
2079 | } |
||
2080 | } |