/// <summary> This function gets a datablk from the entropy coder. The sample sin the /// block, which consists of the quantized coefficients from the quantizer, /// are scaled by the values given for any ROIs specified. /// /// <p>The function calls on a ROIMaskGenerator to get the mask for scaling /// the coefficients in the current block.</p> /// /// </summary> /// <param name="c">The component for which to return the next code-block. /// /// </param> /// <param name="cblk">If non-null this object will be used to return the new /// code-block. If null a new one will be allocated and returned. If the /// "data" array of the object is non-null it will be reused, if possible, /// to return the data. /// /// </param> /// <returns> The next code-block in the current tile for component 'n', or /// null if all code-blocks for the current tile have been returned. /// /// </returns> /// <seealso cref="CBlkWTData"> /// /// </seealso> public virtual CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk) { int mi, i, j, k, wrap; int ulx, uly, w, h; DataBlkInt mask = roiMask; // local copy of mask int[] maskData; // local copy of mask data int[] data; // local copy of quantized data int tmp; int bitMask = 0x7FFFFFFF; SubbandAn root, sb; int maxBits = 0; // local copy bool roiInTile; bool sbInMask; int nROIcoeff = 0; // Get codeblock's data from quantizer cblk = src.getNextCodeBlock(c, cblk); // If there is no ROI in the image, or if we already got all // code-blocks if (!roi || cblk == null) { return(cblk); } data = (int[])cblk.Data; sb = cblk.sb; ulx = cblk.ulx; uly = cblk.uly; w = cblk.w; h = cblk.h; sbInMask = (sb.resLvl <= useStartLevel); // Check that there is an array for the mask and set it to zero maskData = mask.DataInt; // local copy of mask data if (maskData == null || w * h > maskData.Length) { maskData = new int[w * h]; mask.DataInt = maskData; } else { for (i = w * h - 1; i >= 0; i--) { maskData[i] = 0; } } mask.ulx = ulx; mask.uly = uly; mask.w = w; mask.h = h; // Get ROI mask from generator root = src.getAnSubbandTree(tIdx, c); maxBits = maxMagBits[tIdx][c]; roiInTile = mg.getROIMask(mask, root, maxBits, c); // If there is no ROI in this tile, return the code-block untouched if (!roiInTile && (!sbInMask)) { cblk.nROIbp = 0; return(cblk); } // Update field containing the number of ROI magnitude bit-planes cblk.nROIbp = cblk.magbits; // If the entire subband belongs to the ROI mask, The code-block is // set to belong entirely to the ROI with the highest scaling value if (sbInMask) { // Scale the wmse so that instead of scaling the coefficients, the // wmse is scaled. //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'" cblk.wmseScaling *= (float)(1 << (maxBits << 1)); cblk.nROIcoeff = w * h; return(cblk); } // In 'block aligned' mode, the code-block is set to belong entirely // to the ROI with the highest scaling value if one coefficient, at // least, belongs to the ROI if (blockAligned) { wrap = cblk.scanw - w; mi = h * w - 1; i = cblk.offset + cblk.scanw * (h - 1) + w - 1; int nroicoeff = 0; for (j = h; j > 0; j--) { for (k = w - 1; k >= 0; k--, i--, mi--) { if (maskData[mi] != 0) { nroicoeff++; } } i -= wrap; } if (nroicoeff != 0) { // Include the subband //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'" cblk.wmseScaling *= (float)(1 << (maxBits << 1)); cblk.nROIcoeff = w * h; } return(cblk); } // Scale background coefficients bitMask = (((1 << cblk.magbits) - 1) << (31 - cblk.magbits)); wrap = cblk.scanw - w; mi = h * w - 1; i = cblk.offset + cblk.scanw * (h - 1) + w - 1; for (j = h; j > 0; j--) { for (k = w; k > 0; k--, i--, mi--) { tmp = data[i]; if (maskData[mi] != 0) { // ROI coeff. We need to erase fractional bits to ensure // that they do not conflict with BG coeffs. This is only // strictly necessary for ROI coeffs. which non-fractional // magnitude is zero, but much better BG quality can be // achieved if done if reset to zero since coding zeros is // much more efficient (the entropy coder knows nothing // about ROI and cannot avoid coding the ROI fractional // bits, otherwise this would not be necessary). data[i] = (unchecked ((int)0x80000000) & tmp) | (tmp & bitMask); nROIcoeff++; } else { // BG coeff. it is not necessary to erase fractional bits data[i] = (unchecked ((int)0x80000000) & tmp) | ((tmp & 0x7FFFFFFF) >> maxBits); } } i -= wrap; } // Modify the number of significant bit-planes in the code-block cblk.magbits += maxBits; // Store the number of ROI coefficients present in the code-block cblk.nROIcoeff = nROIcoeff; return(cblk); }