CSJ2K.j2k.wavelet.analysis.ForwWTFull.getNextInternCodeBlock C# (CSharp) Method

getNextInternCodeBlock() public method

Returns the next code-block in the current tile for the specified component. The order in which code-blocks are returned is not specified. However each code-block is returned only once and all code-blocks will be returned if the method is called 'N' times, where 'N' is the number of code-blocks in the tile. After all the code-blocks have been returned for the current tile calls to this method will return 'null'.

When changing the current tile (through 'setTile()' or 'nextTile()') this method will always return the first code-block, as if this method was never called before for the new current tile.

The data returned by this method is the data in the internal buffer of this object, and thus can not be modified by the caller. The 'offset' and 'scanw' of the returned data have, in general, some non-zero value. The 'magbits' of the returned data is not set by this method and should be ignored. See the 'CBlkWTData' class.

The 'ulx' and 'uly' members of the returned 'CBlkWTData' object contain the coordinates of the top-left corner of the block, with respect to the tile, not the subband.

public getNextInternCodeBlock ( int c, CSJ2K.j2k.wavelet.analysis.CBlkWTData cblk ) : CSJ2K.j2k.wavelet.analysis.CBlkWTData
c int The component for which to return the next code-block. /// ///
cblk CSJ2K.j2k.wavelet.analysis.CBlkWTData If non-null this object will be used to return the new /// code-block. If null a new one will be allocated and returned. /// ///
return CSJ2K.j2k.wavelet.analysis.CBlkWTData
        public override CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk)
        {
            int cbm, cbn, cn, cm;
            int acb0x, acb0y;
            SubbandAn sb;
            intData = (filters.getWTDataType(tIdx, c) == DataBlk.TYPE_INT);

            //If the source image has not been decomposed
            if (decomposedComps[c] == null)
            {
                int k, w, h;
                DataBlk bufblk;
                System.Object dst_data;

                w = getTileCompWidth(tIdx, c);
                h = getTileCompHeight(tIdx, c);

                //Get the source image data
                if (intData)
                {
                    decomposedComps[c] = new DataBlkInt(0, 0, w, h);
                    bufblk = new DataBlkInt();
                }
                else
                {
                    decomposedComps[c] = new DataBlkFloat(0, 0, w, h);
                    bufblk = new DataBlkFloat();
                }

                // Get data from source line by line (this diminishes the memory
                // requirements on the data source)
                dst_data = decomposedComps[c].Data;
                int lstart = getCompULX(c);
                bufblk.ulx = lstart;
                bufblk.w = w;
                bufblk.h = 1;
                int kk = getCompULY(c);
                for (k = 0; k < h; k++, kk++)
                {
                    bufblk.uly = kk;
                    bufblk.ulx = lstart;
                    bufblk = src.getInternCompData(bufblk, c);
                    // CONVERSION PROBLEM?
                    Array.Copy((System.Array)bufblk.Data, bufblk.offset, (System.Array)dst_data, k * w, w);
                }

                //Decompose source image
                waveletTreeDecomposition(decomposedComps[c], getAnSubbandTree(tIdx, c), c);

                // Make the first subband the current one
                currentSubband[c] = getNextSubband(c);

                lastn[c] = - 1;
                lastm[c] = 0;
            }

            // Get the next code-block to "send"
            do
            {
                // Calculate number of code-blocks in current subband
                ncblks = currentSubband[c].numCb;
                // Goto next code-block
                lastn[c]++;
                if (lastn[c] == ncblks.x)
                {
                    // Got to end of this row of
                    // code-blocks
                    lastn[c] = 0;
                    lastm[c]++;
                }
                if (lastm[c] < ncblks.y)
                {
                    // Not past the last code-block in the subband, we can return
                    // this code-block
                    break;
                }
                // If we get here we already sent all code-blocks in this subband,
                // goto next subband
                currentSubband[c] = getNextSubband(c);
                lastn[c] = - 1;
                lastm[c] = 0;
                if (currentSubband[c] == null)
                {
                    // We don't need the transformed data any more (a priori)
                    decomposedComps[c] = null;
                    // All code-blocks from all subbands in the current
                    // tile have been returned so we return a null
                    // reference
                    return null;
                }
                // Loop to find the next code-block
            }
            while (true);

            // Project code-block partition origin to subband. Since the origin is
            // always 0 or 1, it projects to the low-pass side (throught the ceil
            // operator) as itself (i.e. no change) and to the high-pass side
            // (through the floor operator) as 0, always.
            acb0x = cb0x;
            acb0y = cb0y;
            switch (currentSubband[c].sbandIdx)
            {

                case Subband.WT_ORIENT_LL:
                    // No need to project since all low-pass => nothing to do
                    break;

                case Subband.WT_ORIENT_HL:
                    acb0x = 0;
                    break;

                case Subband.WT_ORIENT_LH:
                    acb0y = 0;
                    break;

                case Subband.WT_ORIENT_HH:
                    acb0x = 0;
                    acb0y = 0;
                    break;

                default:
                    throw new System.InvalidOperationException("Internal JJ2000 error");

            }

            // Initialize output code-block
            if (cblk == null)
            {
                if (intData)
                {
                    cblk = new CBlkWTDataInt();
                }
                else
                {
                    cblk = new CBlkWTDataFloat();
                }
            }
            cbn = lastn[c];
            cbm = lastm[c];
            sb = currentSubband[c];
            cblk.n = cbn;
            cblk.m = cbm;
            cblk.sb = sb;
            // Calculate the indexes of first code-block in subband with respect
            // to the partitioning origin, to then calculate the position and size
            // NOTE: when calculating "floor()" by integer division the dividend
            // and divisor must be positive, we ensure that by adding the divisor
            // to the dividend and then substracting 1 to the result of the
            // division
            cn = (sb.ulcx - acb0x + sb.nomCBlkW) / sb.nomCBlkW - 1;
            cm = (sb.ulcy - acb0y + sb.nomCBlkH) / sb.nomCBlkH - 1;
            if (cbn == 0)
            {
                // Left-most code-block, starts where subband starts
                cblk.ulx = sb.ulx;
            }
            else
            {
                // Calculate starting canvas coordinate and convert to subb. coords
                cblk.ulx = (cn + cbn) * sb.nomCBlkW - (sb.ulcx - acb0x) + sb.ulx;
            }
            if (cbm == 0)
            {
                // Bottom-most code-block, starts where subband starts
                cblk.uly = sb.uly;
            }
            else
            {
                cblk.uly = (cm + cbm) * sb.nomCBlkH - (sb.ulcy - acb0y) + sb.uly;
            }
            if (cbn < ncblks.x - 1)
            {
                // Calculate where next code-block starts => width
                cblk.w = (cn + cbn + 1) * sb.nomCBlkW - (sb.ulcx - acb0x) + sb.ulx - cblk.ulx;
            }
            else
            {
                // Right-most code-block, ends where subband ends
                cblk.w = sb.ulx + sb.w - cblk.ulx;
            }
            if (cbm < ncblks.y - 1)
            {
                // Calculate where next code-block starts => height
                cblk.h = (cm + cbm + 1) * sb.nomCBlkH - (sb.ulcy - acb0y) + sb.uly - cblk.uly;
            }
            else
            {
                // Bottom-most code-block, ends where subband ends
                cblk.h = sb.uly + sb.h - cblk.uly;
            }
            cblk.wmseScaling = 1f;

            // Since we are in getNextInternCodeBlock() we can return a
            // reference to the internal buffer, no need to copy. Just initialize
            // the 'offset' and 'scanw'
            cblk.offset = cblk.uly * decomposedComps[c].w + cblk.ulx;
            cblk.scanw = decomposedComps[c].w;

            // For the data just put a reference to our buffer
            cblk.Data = decomposedComps[c].Data;
            // Return code-block
            return cblk;
        }