Пример #1
0
        /// <summary> Decodes information for the specified element of the tree, given the
        /// threshold, and updates its value. The information that can be decoded
        /// is whether or not the value of the element is greater than, or equal
        /// to, the value of the threshold.
        ///
        /// </summary>
        /// <param name="m">The vertical index of the element.
        ///
        /// </param>
        /// <param name="n">The horizontal index of the element.
        ///
        /// </param>
        /// <param name="t">The threshold to use in decoding. It must be non-negative.
        ///
        /// </param>
        /// <param name="in">The stream from where to read the coded information.
        ///
        /// </param>
        /// <returns> The updated value at position (m,n).
        ///
        /// </returns>
        /// <exception cref="IOException">If an I/O error occurs while reading from 'in'.
        ///
        /// </exception>
        /// <exception cref="EOFException">If the ned of the 'in' stream is reached before
        /// getting all the necessary data.
        ///
        /// </exception>
        public virtual int update(int m, int n, int t, PktHeaderBitReader in_Renamed)
        {
            int k, tmin;
            int idx, ts, tv;

            // Check arguments
            if (m >= h || n >= w || t < 0)
            {
                throw new System.ArgumentException();
            }

            // Initialize
            k    = lvls - 1;
            tmin = treeS[k][0];

            // Loop on levels
            idx = (m >> k) * ((w + (1 << k) - 1) >> k) + (n >> k);
            while (true)
            {
                // Cache state and value
                ts = treeS[k][idx];
                tv = treeV[k][idx];
                if (ts < tmin)
                {
                    ts = tmin;
                }
                while (t > ts)
                {
                    if (tv >= ts)
                    {
                        // We are not done yet
                        if (in_Renamed.readBit() == 0)
                        {
                            // '0' bit
                            // We know that 'value' > treeS[k][idx]
                            ts++;
                        }
                        else
                        {
                            // '1' bit
                            // We know that 'value' = treeS[k][idx]
                            tv = ts++;
                        }
                        // Increment of treeS[k][idx] done above
                    }
                    else
                    {
                        // We are done, we can set ts and get out
                        ts = t;
                        break;                         // get out of this while
                    }
                }
                // Update state and value
                treeS[k][idx] = ts;
                treeV[k][idx] = tv;
                // Update tmin or terminate
                if (k > 0)
                {
                    tmin = ts < tv?ts:tv;
                    k--;
                    // Index of element for next iteration
                    idx = (m >> k) * ((w + (1 << k) - 1) >> k) + (n >> k);
                }
                else
                {
                    // Return the updated value
                    return(tv);
                }
            }
        }
Пример #2
0
		/// <summary> Read specified packet head and found length of each code-block's piece
		/// of codewords as well as number of skipped most significant bit-planes.
		/// 
		/// </summary>
		/// <param name="l">layer index
		/// 
		/// </param>
		/// <param name="r">Resolution level index
		/// 
		/// </param>
		/// <param name="c">Component index
		/// 
		/// </param>
		/// <param name="p">Precinct index
		/// 
		/// </param>
		/// <param name="cbI">CBlkInfo array of relevant component and resolution
		/// level.
		/// 
		/// </param>
		/// <param name="nb">The number of bytes to read in each tile before reaching
		/// output rate (used by truncation mode)
		/// 
		/// </param>
		/// <returns> True if specified output rate or EOF is reached.
		/// 
		/// </returns>
		public virtual bool readPktHead(int l, int r, int c, int p, CBlkInfo[][][] cbI, int[] nb)
		{
			
			CBlkInfo ccb;
			int nSeg; // number of segment to read
			int cbLen; // Length of cblk's code-words
			int ltp; // last truncation point index
			int passtype; // coding pass type
			TagTreeDecoder tdIncl, tdBD;
			int tmp, tmp2, totnewtp, lblockCur, tpidx;
			int sumtotnewtp = 0;
			Coord cbc;
			int startPktHead = ehs.Pos;
			if (startPktHead >= ehs.length())
			{
				// EOF reached at the beginning of this packet head
				return true;
			}
			int tIdx = src.TileIdx;
			PktHeaderBitReader bin;
			int mend, nend;
			int b;
			SubbandSyn sb;
			SubbandSyn root = src.getSynSubbandTree(tIdx, c);
			
			// If packed packet headers was used, use separate stream for reading
			// of packet headers
			if (pph)
			{
				bin = new PktHeaderBitReader(pphbais);
			}
			else
			{
				bin = this.bin;
			}
			
			int mins = (r == 0)?0:1;
			int maxs = (r == 0)?1:4;
			
			bool precFound = false;
			for (int s = mins; s < maxs; s++)
			{
				if (p < ppinfo[c][r].Length)
				{
					precFound = true;
				}
			}
			if (!precFound)
			{
				return false;
			}
			
			PrecInfo prec = ppinfo[c][r][p];
			
			// Synchronize for bit reading
			bin.sync();
			
			// If packet is empty there is no info in it (i.e. no code-blocks)
			if (bin.readBit() == 0)
			{
				// No code-block is included
				cblks = new System.Collections.ArrayList[maxs + 1];
				for (int s = mins; s < maxs; s++)
				{
					cblks[s] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
				}
				pktIdx++;
				
				// If truncation mode, checks if output rate is reached
				// unless ncb quit condition is used in which case headers
				// are not counted
				if (isTruncMode && maxCB == - 1)
				{
					tmp = ehs.Pos - startPktHead;
					if (tmp > nb[tIdx])
					{
						nb[tIdx] = 0;
						return true;
					}
					else
					{
						nb[tIdx] -= tmp;
					}
				}
				
				// Read EPH marker if needed
				if (ephUsed)
				{
					readEPHMarker(bin);
				}
				return false;
			}
			
			// Packet is not empty => decode info
			// Loop on each subband in this resolution level
			if (cblks == null || cblks.Length < maxs + 1)
			{
				cblks = new System.Collections.ArrayList[maxs + 1];
			}
			
			for (int s = mins; s < maxs; s++)
			{
				if (cblks[s] == null)
				{
					cblks[s] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
				}
				else
				{
					cblks[s].Clear();
				}
				sb = (SubbandSyn) root.getSubbandByIdx(r, s);
				// No code-block in this precinct
				if (prec.nblk[s] == 0)
				{
					// Go to next subband
					continue;
				}
				
				tdIncl = ttIncl[c][r][p][s];
				tdBD = ttMaxBP[c][r][p][s];
				
				mend = (prec.cblk[s] == null)?0:prec.cblk[s].Length;
				for (int m = 0; m < mend; m++)
				{
					// Vertical code-blocks
					nend = (prec.cblk[s][m] == null)?0:prec.cblk[s][m].Length;
					for (int n = 0; n < nend; n++)
					{
						// Horizontal code-blocks
						cbc = prec.cblk[s][m][n].idx;
						b = cbc.x + cbc.y * sb.numCb.x;
						
						ccb = cbI[s][cbc.y][cbc.x];
						
						try
						{
							// If code-block not included in previous layer(s)
							if (ccb == null || ccb.ctp == 0)
							{
								if (ccb == null)
								{
									ccb = cbI[s][cbc.y][cbc.x] = new CBlkInfo(prec.cblk[s][m][n].ulx, prec.cblk[s][m][n].uly, prec.cblk[s][m][n].w, prec.cblk[s][m][n].h, nl);
								}
								ccb.pktIdx[l] = pktIdx;
								
								// Read inclusion using tag-tree
								tmp = tdIncl.update(m, n, l + 1, bin);
								if (tmp > l)
								{
									// Not included
									continue;
								}
								
								// Read bitdepth using tag-tree
								tmp = 1; // initialization
								for (tmp2 = 1; tmp >= tmp2; tmp2++)
								{
									tmp = tdBD.update(m, n, tmp2, bin);
								}
								ccb.msbSkipped = tmp2 - 2;
								
								// New code-block => at least one truncation point
								totnewtp = 1;
								ccb.addNTP(l, 0);
								
								// Check whether ncb quit condition is reached
								ncb++;
								
								if (maxCB != - 1 && !ncbQuit && ncb == maxCB)
								{
									// ncb quit contidion reached
									ncbQuit = true;
									tQuit = tIdx;
									cQuit = c;
									sQuit = s;
									rQuit = r;
									xQuit = cbc.x;
									yQuit = cbc.y;
								}
							}
							else
							{
								// If code-block already included in one of
								// the previous layers.
								
								ccb.pktIdx[l] = pktIdx;
								
								// If not inclused
								if (bin.readBit() != 1)
								{
									continue;
								}
								
								// At least 1 more truncation point than
								// prev. packet
								totnewtp = 1;
							}
							
							// Read new truncation points
							if (bin.readBit() == 1)
							{
								// if bit is 1
								totnewtp++;
								
								// if next bit is 0 do nothing
								if (bin.readBit() == 1)
								{
									//if is 1
									totnewtp++;
									
									tmp = bin.readBits(2);
									totnewtp += tmp;
									
									// If next 2 bits are not 11 do nothing
									if (tmp == 0x3)
									{
										//if 11
										tmp = bin.readBits(5);
										totnewtp += tmp;
										
										// If next 5 bits are not 11111 do nothing
										if (tmp == 0x1F)
										{
											//if 11111
											totnewtp += bin.readBits(7);
										}
									}
								}
							}
							ccb.addNTP(l, totnewtp);
							sumtotnewtp += totnewtp;
							cblks[s].Add(prec.cblk[s][m][n]);
							
							// Code-block length
							
							// -- Compute the number of bit to read to obtain
							// code-block length.  
							// numBits = betaLamda + log2(totnewtp);
							
							// The length is signalled for each segment in
							// addition to the final one. The total length is the
							// sum of all segment lengths.
							
							// If regular termination in use, then there is one
							// segment per truncation point present. Otherwise, if
							// selective arithmetic bypass coding mode is present,
							// then there is one termination per bypass/MQ and
							// MQ/bypass transition. Otherwise the only
							// termination is at the end of the code-block.
							int options = ((System.Int32) decSpec.ecopts.getTileCompVal(tIdx, c));
							
							if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
							{
								// Regular termination in use, one segment per new
								// pass (i.e. truncation point)
								nSeg = totnewtp;
							}
							else if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0)
							{
								// Selective arithmetic coding bypass coding mode
								// in use, but no regular termination 1 segment up
								// to the end of the last pass of the 4th most
								// significant bit-plane, and, in each following
								// bit-plane, one segment upto the end of the 2nd
								// pass and one upto the end of the 3rd pass.
								
								if (ccb.ctp <= CSJ2K.j2k.entropy.StdEntropyCoderOptions.FIRST_BYPASS_PASS_IDX)
								{
									nSeg = 1;
								}
								else
								{
									nSeg = 1; // One at least for last pass
									// And one for each other terminated pass
									for (tpidx = ccb.ctp - totnewtp; tpidx < ccb.ctp - 1; tpidx++)
									{
										if (tpidx >= CSJ2K.j2k.entropy.StdEntropyCoderOptions.FIRST_BYPASS_PASS_IDX - 1)
										{
											passtype = (tpidx + CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_EMPTY_PASSES_IN_MS_BP) % CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES;
											if (passtype == 1 || passtype == 2)
											{
												// bypass coding just before MQ
												// pass or MQ pass just before
												// bypass coding => terminated
												nSeg++;
											}
										}
									}
								}
							}
							else
							{
								// Nothing special in use, just one segment
								nSeg = 1;
							}
							
							// Reads lblock increment (common to all segments)
							while (bin.readBit() != 0)
							{
								lblock[c][r][s][cbc.y][cbc.x]++;
							}
							
							if (nSeg == 1)
							{
								// Only one segment in packet
								cbLen = bin.readBits(lblock[c][r][s][cbc.y][cbc.x] + MathUtil.log2(totnewtp));
							}
							else
							{
								// We must read one length per segment
								ccb.segLen[l] = new int[nSeg];
								cbLen = 0;
								int j;
								if ((options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_TERM_PASS) != 0)
								{
									// Regular termination: each pass is terminated
									for (tpidx = ccb.ctp - totnewtp, j = 0; tpidx < ccb.ctp; tpidx++, j++)
									{
										
										lblockCur = lblock[c][r][s][cbc.y][cbc.x];
										
										tmp = bin.readBits(lblockCur);
										ccb.segLen[l][j] = tmp;
										cbLen += tmp;
									}
								}
								else
								{
									// Bypass coding: only some passes are
									// terminated
									ltp = ccb.ctp - totnewtp - 1;
									for (tpidx = ccb.ctp - totnewtp, j = 0; tpidx < ccb.ctp - 1; tpidx++)
									{
										if (tpidx >= CSJ2K.j2k.entropy.StdEntropyCoderOptions.FIRST_BYPASS_PASS_IDX - 1)
										{
											passtype = (tpidx + CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_EMPTY_PASSES_IN_MS_BP) % CSJ2K.j2k.entropy.StdEntropyCoderOptions.NUM_PASSES;
											if (passtype == 0)
												continue;
											
											lblockCur = lblock[c][r][s][cbc.y][cbc.x];
											tmp = bin.readBits(lblockCur + MathUtil.log2(tpidx - ltp));
											ccb.segLen[l][j] = tmp;
											cbLen += tmp;
											ltp = tpidx;
											j++;
										}
									}
									// Last pass has always the length sent
									lblockCur = lblock[c][r][s][cbc.y][cbc.x];
									tmp = bin.readBits(lblockCur + MathUtil.log2(tpidx - ltp));
									cbLen += tmp;
									ccb.segLen[l][j] = tmp;
								}
							}
							ccb.len[l] = cbLen;
							
							// If truncation mode, checks if output rate is reached
							// unless ncb and lbody quit contitions used.
							if (isTruncMode && maxCB == - 1)
							{
								tmp = ehs.Pos - startPktHead;
								if (tmp > nb[tIdx])
								{
									nb[tIdx] = 0;
									// Remove found information in this code-block
									if (l == 0)
									{
										cbI[s][cbc.y][cbc.x] = null;
									}
									else
									{
										ccb.off[l] = ccb.len[l] = 0;
										ccb.ctp -= ccb.ntp[l];
										ccb.ntp[l] = 0;
										ccb.pktIdx[l] = - 1;
									}
									return true;
								}
							}
						}
						catch (System.IO.EndOfStreamException)
						{
							// Remove found information in this code-block
							if (l == 0)
							{
								cbI[s][cbc.y][cbc.x] = null;
							}
							else
							{
								ccb.off[l] = ccb.len[l] = 0;
								ccb.ctp -= ccb.ntp[l];
								ccb.ntp[l] = 0;
								ccb.pktIdx[l] = - 1;
							}
							//                         throw new EOFException();
							return true;
						}
					} // End loop on horizontal code-blocks
				} // End loop on vertical code-blocks
			} // End loop on subbands
			
			// Read EPH marker if needed
			if (ephUsed)
			{
				readEPHMarker(bin);
			}
			
			pktIdx++;
			
			// If truncation mode, checks if output rate is reached
			if (isTruncMode && maxCB == - 1)
			{
				tmp = ehs.Pos - startPktHead;
				if (tmp > nb[tIdx])
				{
					nb[tIdx] = 0;
					return true;
				}
				else
				{
					nb[tIdx] -= tmp;
				}
			}
			return false;
		}
Пример #3
0
		/// <summary> Try to read an EPH marker. If it is not possible then an Error is
		/// thrown.
		/// 
		/// </summary>
		/// <param name="bin">The packet header reader to read the EPH marker from
		/// 
		/// </param>
		public virtual void  readEPHMarker(PktHeaderBitReader bin)
		{
			int val;
			byte[] ephArray = new byte[2];
			
			if (bin.usebais)
			{
				bin.bais.Read(ephArray, 0, CSJ2K.j2k.codestream.Markers.EPH_LENGTH);
			}
			else
			{
				bin.in_Renamed.readFully(ephArray, 0, CSJ2K.j2k.codestream.Markers.EPH_LENGTH);
			}
			
			// Check if this is the correct marker
			val = ephArray[0];
			val <<= 8;
			val |= ephArray[1];
			if (val != CSJ2K.j2k.codestream.Markers.EPH)
			{
				throw new System.ApplicationException("Corrupted Bitstream: Could not parse EPH " + "marker ! ");
			}
		}
Пример #4
0
		/// <summary> Creates an empty PktDecoder object associated with given decoder
		/// specifications and HeaderDecoder. This object must be initialized
		/// thanks to the restart method before being used.
		/// 
		/// </summary>
		/// <param name="decSpec">The decoder specifications.
		/// 
		/// </param>
		/// <param name="hd">The HeaderDecoder instance.
		/// 
		/// </param>
		/// <param name="ehs">The stream where to read data from.
		/// 
		/// </param>
		/// <param name="src">The bit stream reader agent.
		/// 
		/// </param>
		/// <param name="isTruncMode">Whether or not truncation mode is required.
		/// 
		/// </param>
		/// <param name="maxCB">The maximum number of code-blocks to read before ncbquit
		/// 
		/// 
		/// </param>
		public PktDecoder(DecoderSpecs decSpec, HeaderDecoder hd, RandomAccessIO ehs, BitstreamReaderAgent src, bool isTruncMode, int maxCB)
		{
			this.decSpec = decSpec;
			this.hd = hd;
			this.ehs = ehs;
			this.isTruncMode = isTruncMode;
			bin = new PktHeaderBitReader(ehs);
			this.src = src;
			ncb = 0;
			ncbQuit = false;
			this.maxCB = maxCB;
		}
Пример #5
0
		/// <summary> Decodes information for the specified element of the tree, given the
		/// threshold, and updates its value. The information that can be decoded
		/// is whether or not the value of the element is greater than, or equal
		/// to, the value of the threshold.
		/// 
		/// </summary>
		/// <param name="m">The vertical index of the element.
		/// 
		/// </param>
		/// <param name="n">The horizontal index of the element.
		/// 
		/// </param>
		/// <param name="t">The threshold to use in decoding. It must be non-negative.
		/// 
		/// </param>
		/// <param name="in">The stream from where to read the coded information.
		/// 
		/// </param>
		/// <returns> The updated value at position (m,n).
		/// 
		/// </returns>
		/// <exception cref="IOException">If an I/O error occurs while reading from 'in'.
		/// 
		/// </exception>
		/// <exception cref="EOFException">If the ned of the 'in' stream is reached before
		/// getting all the necessary data.
		/// 
		/// </exception>
		public virtual int update(int m, int n, int t, PktHeaderBitReader in_Renamed)
		{
			int k, tmin;
			int idx, ts, tv;
			
			// Check arguments
			if (m >= h || n >= w || t < 0)
			{
				throw new System.ArgumentException();
			}
			
			// Initialize
			k = lvls - 1;
			tmin = treeS[k][0];
			
			// Loop on levels
			idx = (m >> k) * ((w + (1 << k) - 1) >> k) + (n >> k);
			while (true)
			{
				// Cache state and value
				ts = treeS[k][idx];
				tv = treeV[k][idx];
				if (ts < tmin)
				{
					ts = tmin;
				}
				while (t > ts)
				{
					if (tv >= ts)
					{
						// We are not done yet
						if (in_Renamed.readBit() == 0)
						{
							// '0' bit
							// We know that 'value' > treeS[k][idx]
							ts++;
						}
						else
						{
							// '1' bit
							// We know that 'value' = treeS[k][idx]
							tv = ts++;
						}
						// Increment of treeS[k][idx] done above
					}
					else
					{
						// We are done, we can set ts and get out
						ts = t;
						break; // get out of this while
					}
				}
				// Update state and value
				treeS[k][idx] = ts;
				treeV[k][idx] = tv;
				// Update tmin or terminate
				if (k > 0)
				{
					tmin = ts < tv?ts:tv;
					k--;
					// Index of element for next iteration
					idx = (m >> k) * ((w + (1 << k) - 1) >> k) + (n >> k);
				}
				else
				{
					// Return the updated value
					return tv;
				}
			}
		}