private void writeCoeffAbsLevel(MEncoder encoder, BlockType blockType, int numDecodAbsLevelGt1, int numDecodAbsLevelEq1, int absLev) { int incB0 = ((numDecodAbsLevelGt1 != 0) ? 0 : Math.Min(4, 1 + numDecodAbsLevelEq1)); int incBN = 5 + Math.Min(4 - blockType.coeffAbsLevelAdjust, numDecodAbsLevelGt1); if (absLev == 0) { encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incB0, 0); } else { encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incB0, 1); if (absLev < 14) { for (int i = 1; i < absLev; i++) { encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incBN, 1); } encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incBN, 0); } else { for (int i = 1; i < 14; i++) { encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incBN, 1); } absLev -= 14; int sufLen, pow; for (sufLen = 0, pow = 1; absLev >= pow; sufLen++, pow = (1 << sufLen)) { encoder.encodeBinBypass(1); absLev -= pow; } encoder.encodeBinBypass(0); for (sufLen--; sufLen >= 0; sufLen--) { encoder.encodeBinBypass((absLev >> sufLen) & 1); } } } }
public void writeCoeffs(MEncoder encoder, BlockType blockType, int[] _out, int first, int num, int[] reorder) { for (int i = 0; i < num; i++) { tmp[i] = _out[reorder[first + i]]; } int numCoeff = 0; for (int i = 0; i < num; i++) { if (tmp[i] != 0) { numCoeff = i + 1; } } for (int i = 0; i < Math.Min(numCoeff, num - 1); i++) { if (tmp[i] != 0) { encoder.encodeBin(blockType.sigCoeffFlagCtxOff + i, 1); encoder.encodeBin(blockType.lastSigCoeffCtxOff + i, i == numCoeff - 1 ? 1 : 0); } else { encoder.encodeBin(blockType.sigCoeffFlagCtxOff + i, 0); } } int numGt1 = 0, numEq1 = 0; for (int j = numCoeff - 1; j >= 0; j--) { if (tmp[j] == 0) { continue; } int absLev = Math.Abs(tmp[j]) - 1; writeCoeffAbsLevel(encoder, blockType, numGt1, numEq1, absLev); if (absLev == 0) { ++numEq1; } else { ++numGt1; } encoder.encodeBinBypass(sign(tmp[j])); } }