// Quantise a subband in in-place transform order // This version of quantise_subbands assumes multiple quantisers per subband. // It may be used for either quantising slices or for quantising subbands with codeblocks const Array2D quantise_subbands(const Array2D& coefficients, const BlockVector& qIndices) { const Index transformHeight = coefficients.shape()[0]; const Index transformWidth = coefficients.shape()[1]; // TO DO: Check numberOfSubbands=3n+1 ? const int numberOfSubbands = qIndices.size(); const int waveletDepth = (numberOfSubbands-1)/3; Index stride, offset; // stride is subsampling factor, offset is subsampling phase Array2D result(coefficients.ranges()); // Create a view of the coefficients, representing the LL subband, quantise it, // then assign the result a view of the results array. This puts the quantised // LL subband into the result array in in-place transform order. // ArrayIndices2D objects specify the subset of array elements within a view, // that is they specify the subsampling factor and subsampling phase. stride = pow(2, waveletDepth); const ArrayIndices2D LLindices = // LLindices specifies the samples in the LL subband indices[Range(0,transformHeight,stride)][Range(0,transformWidth,stride)]; result[LLindices] = quantise_LLSubband(coefficients[LLindices], qIndices[0]); // Next quantise the other subbands // Note: Level numbers go from zero for the lowest ("DC") frequencies to depth for // the high frequencies. This corresponds to the convention in the VC-2 specification. // Subands go from zero ("DC") to numberOfSubbands-1 for HH at the highest level for (char level=1, band=1; level<=waveletDepth; ++level) { stride = pow(2, waveletDepth+1-level); offset = stride/2; // Create a view of coefficients corresponding to a subband, then quantise it //Quantise HL subband const ArrayIndices2D HLindices = // HLindices specifies the samples in the HL subband indices[Range(0,transformHeight,stride)][Range(offset,transformWidth,stride)]; result[HLindices] = quantise_block(coefficients[HLindices], qIndices[band++]); //Quantise LH subband const ArrayIndices2D LHindices = // LHindices specifies the samples in the LH subband indices[Range(offset,transformHeight,stride)][Range(0,transformWidth,stride)]; result[LHindices] = quantise_block(coefficients[LHindices], qIndices[band++]); //Quantise HH subband const ArrayIndices2D HHindices = // HHindices specifies the samples in the HH subband indices[Range(offset,transformHeight,stride)][Range(offset,transformWidth,stride)]; result[HHindices] = quantise_block(coefficients[HHindices], qIndices[band++]); } return result; }