Exemplo n.º 1
0
		/// <summary> Re-initialize the PktDecoder instance at the beginning of a new tile.
		/// 
		/// </summary>
		/// <param name="nc">The number of components in this tile
		/// 
		/// </param>
		/// <param name="mdl">The maximum number of decomposition level in each component
		/// of this tile
		/// 
		/// </param>
		/// <param name="nl">The number of layers in  this tile
		/// 
		/// </param>
		/// <param name="cbI">The code-blocks array
		/// 
		/// </param>
		/// <param name="pph">Flag indicating whether packed packet headers was used
		/// 
		/// </param>
		/// <param name="pphbais">Stream containing the packed packet headers
		/// 
		/// </param>
		public virtual CBlkInfo[][][][][] restart(int nc, int[] mdl, int nl, CBlkInfo[][][][][] cbI, bool pph, System.IO.MemoryStream pphbais)
		{
			this.nc = nc;
			this.nl = nl;
			this.tIdx = src.TileIdx;
			this.pph = pph;
			this.pphbais = pphbais;
			
			sopUsed = ((System.Boolean) decSpec.sops.getTileDef(tIdx));
			pktIdx = 0;
			ephUsed = ((System.Boolean) decSpec.ephs.getTileDef(tIdx));
			
			cbI = new CBlkInfo[nc][][][][];
			lblock = new int[nc][][][][];
			ttIncl = new TagTreeDecoder[nc][][][];
			ttMaxBP = new TagTreeDecoder[nc][][][];
			numPrec = new Coord[nc][];
			ppinfo = new PrecInfo[nc][][];
			
			// Used to compute the maximum number of precincts for each resolution
			// level
			int tcx0, tcy0, tcx1, tcy1; // Current tile position in the domain of
			// the image component
			int trx0, try0, trx1, try1; // Current tile position in the reduced
			// resolution image domain
			//int xrsiz, yrsiz; // Component sub-sampling factors
			
			SubbandSyn root, sb;
			int mins, maxs;
			Coord nBlk = null;
			int cb0x = src.CbULX;
			int cb0y = src.CbULY;
			
			for (int c = 0; c < nc; c++)
			{
				cbI[c] = new CBlkInfo[mdl[c] + 1][][][];
				lblock[c] = new int[mdl[c] + 1][][][];
				ttIncl[c] = new TagTreeDecoder[mdl[c] + 1][][];
				ttMaxBP[c] = new TagTreeDecoder[mdl[c] + 1][][];
				numPrec[c] = new Coord[mdl[c] + 1];
				ppinfo[c] = new PrecInfo[mdl[c] + 1][];
				
				// Get the tile-component coordinates on the reference grid
				tcx0 = src.getResULX(c, mdl[c]);
				tcy0 = src.getResULY(c, mdl[c]);
				tcx1 = tcx0 + src.getTileCompWidth(tIdx, c, mdl[c]);
				tcy1 = tcy0 + src.getTileCompHeight(tIdx, c, mdl[c]);
				
				for (int r = 0; r <= mdl[c]; r++)
				{
					
					// Tile's coordinates in the reduced resolution image domain
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					trx0 = (int) System.Math.Ceiling(tcx0 / (double) (1 << (mdl[c] - r)));
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					try0 = (int) System.Math.Ceiling(tcy0 / (double) (1 << (mdl[c] - r)));
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					trx1 = (int) System.Math.Ceiling(tcx1 / (double) (1 << (mdl[c] - r)));
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					try1 = (int) System.Math.Ceiling(tcy1 / (double) (1 << (mdl[c] - r)));
					
					// Calculate the maximum number of precincts for each
					// resolution level taking into account tile specific options.
					double twoppx = (double) getPPX(tIdx, c, r);
					double twoppy = (double) getPPY(tIdx, c, r);
					numPrec[c][r] = new Coord();
					if (trx1 > trx0)
					{
						//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
						numPrec[c][r].x = (int) System.Math.Ceiling((trx1 - cb0x) / twoppx) - (int) System.Math.Floor((trx0 - cb0x) / twoppx);
					}
					else
					{
						numPrec[c][r].x = 0;
					}
					if (try1 > try0)
					{
						//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
						numPrec[c][r].y = (int) System.Math.Ceiling((try1 - cb0y) / twoppy) - (int) System.Math.Floor((try0 - cb0y) / twoppy);
					}
					else
					{
						numPrec[c][r].y = 0;
					}
					
					// First and last subbands indexes
					mins = (r == 0)?0:1;
					maxs = (r == 0)?1:4;
					
					int maxPrec = numPrec[c][r].x * numPrec[c][r].y;
					
					ttIncl[c][r] = new TagTreeDecoder[maxPrec][];
					for (int i = 0; i < maxPrec; i++)
					{
						ttIncl[c][r][i] = new TagTreeDecoder[maxs + 1];
					}
					ttMaxBP[c][r] = new TagTreeDecoder[maxPrec][];
					for (int i2 = 0; i2 < maxPrec; i2++)
					{
						ttMaxBP[c][r][i2] = new TagTreeDecoder[maxs + 1];
					}
					cbI[c][r] = new CBlkInfo[maxs + 1][][];
					lblock[c][r] = new int[maxs + 1][][];
					
					ppinfo[c][r] = new PrecInfo[maxPrec];
					fillPrecInfo(c, r, mdl[c]);
					
					root = (SubbandSyn) src.getSynSubbandTree(tIdx, c);
					for (int s = mins; s < maxs; s++)
					{
						sb = (SubbandSyn) root.getSubbandByIdx(r, s);
						nBlk = sb.numCb;
						
						cbI[c][r][s] = new CBlkInfo[nBlk.y][];
						for (int i3 = 0; i3 < nBlk.y; i3++)
						{
							cbI[c][r][s][i3] = new CBlkInfo[nBlk.x];
						}
						lblock[c][r][s] = new int[nBlk.y][];
						for (int i4 = 0; i4 < nBlk.y; i4++)
						{
							lblock[c][r][s][i4] = new int[nBlk.x];
						}
						
						for (int i = nBlk.y - 1; i >= 0; i--)
						{
							ArrayUtil.intArraySet(lblock[c][r][s][i], INIT_LBLOCK);
						}
					} // loop on subbands
				} // End loop on resolution levels
			} // End loop on components
			
			return cbI;
		}
Exemplo n.º 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;
		}
Exemplo n.º 3
0
		/// <summary> Reads specificied packet body in order to find offset of each
		/// code-block's piece of codeword. This use the list of found code-blocks
		/// in previous red packet head.
		/// 
		/// </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 remainding number of bytes to read from the bit stream in
		/// each tile before reaching the decoding rate (in truncation mode)
		/// 
		/// </param>
		/// <returns> True if decoding rate is reached 
		/// 
		/// </returns>
		public virtual bool readPktBody(int l, int r, int c, int p, CBlkInfo[][][] cbI, int[] nb)
		{
			int curOff = ehs.Pos;
			//Coord curCB;
			CBlkInfo ccb;
			bool stopRead = false;
			int tIdx = src.TileIdx;
			Coord cbc;
			
			bool precFound = false;
			int mins = (r == 0)?0:1;
			int maxs = (r == 0)?1:4;
			for (int s = mins; s < maxs; s++)
			{
				if (p < ppinfo[c][r].Length)
				{
					precFound = true;
				}
			}
			if (!precFound)
			{
				return false;
			}
			
			for (int s = mins; s < maxs; s++)
			{
				for (int numCB = 0; numCB < cblks[s].Count; numCB++)
				{
					cbc = ((CBlkCoordInfo) cblks[s][numCB]).idx;
					ccb = cbI[s][cbc.y][cbc.x];
					ccb.off[l] = curOff;
					curOff += ccb.len[l];
					try
					{
						ehs.seek(curOff);
					}
					catch (System.IO.EndOfStreamException)
					{
						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 System.IO.EndOfStreamException();
					}
					
					// If truncation mode
					if (isTruncMode)
					{
						if (stopRead || ccb.len[l] > nb[tIdx])
						{
							// 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;
							}
							stopRead = true;
						}
						if (!stopRead)
						{
							nb[tIdx] -= ccb.len[l];
						}
					}
					// If ncb quit condition reached
					if (ncbQuit && r == rQuit && s == sQuit && cbc.x == xQuit && cbc.y == yQuit && tIdx == tQuit && c == cQuit)
					{
						cbI[s][cbc.y][cbc.x] = null;
						stopRead = true;
					}
				} // Loop on code-blocks
			} // End loop on subbands
			
			// Seek to the end of the packet
			ehs.seek(curOff);
			
			if (stopRead)
			{
				return true;
			}
			else
			{
				return false;
			}
		}