Skip to content

Tweak float dither calculates positive DC bias for luma #53

Description

@msg7086

Analysis attribution: This issue analysis was created by Gemini 3.7 Flash.
The GitHub user who submits this issue does not claim authorship of the analysis.

Finding

  • Finding ID: F33-tweak-float-dither-luma-bias
  • Status: Reproduced defect
  • Severity: Medium
  • Affected component: Tweak
  • Source location: avs_core/filters/levels.cpp:1642-1666

Summary

In Tweak::Tweak(), bias_dither_luma subtracts 1 unconditionally when dither == true. For 32-bit float clips (pixelsize == 4), where dither_strength has been scaled down by 65536, the unscaled -1 term produces a large positive DC offset (+0.498046875), causing all luma pixels to be brightened by ~ +0.001945 in float dithering.

Affected Code

  if (pixelsize == 4)
    dither_strength /= 65536.0f; // same dither range as for a 16 bit clip

  if (dither) {
    // lut scale settings
    scale_dither_luma = 256; // lower 256 is dither value
    divisor_dither_luma *= 256;
    bias_dither_luma = -(256.0f * dither_strength - 1) / 2;
...
    scale_dither_chroma = 16; // lower 16 is dither value
    divisor_dither_chroma *= 16;
    bias_dither_chroma = -(16.0f * dither_strength - (pixelsize==4 ? 1/256.0f : 1)) / 2; // -7.5
  }
void Tweak::tweak_calc_luma(BYTE *srcp, int src_pitch, float minY, float maxY, int width, int height)
{
  float ditherval = 0.0f;
  for (int y = 0; y < height; ++y) {
    const int _y = (y << 4) & 0xf0;
    for (int x = 0; x < width; ++x) {
      if (dither)
        ditherval = (ditherMap[(x & 0x0f) | _y] * dither_strength + bias_dither_luma) / (float)scale_dither_luma;

Correct Behavior

Adjust bias_dither_luma for 32-bit float similarly to chroma ((pixelsize == 4 ? 1/256.0f : 1) or appropriate float scaling), centering ditherval around zero.

Reproduction

Call Tweak(clip, hue=0.0, sat=1.0, bright=0.0, cont=1.0, dither=true) on a 32-bit float clip (CS_YUV444PS).

Observed Result

observed: output luma is shifted upwards by ~ +0.00195 due to unbalanced positive dither bias
expected: output luma dither is zero-centered and preserves overall average brightness

Impact

Applying Tweak(dither=true) on float video introduces a visible whitening/brightening artifact across the luma plane.

Validation Criteria

Float luma dithering values are symmetric and zero-centered without introducing a DC bias offset.

Version and Environment

  • AviSynthPlus revision: 80da03a5ee437c2b103dbebc9fab43480a9d97c6
  • Platform and compiler: Linux x86_64 / Windows x64 GCC/MSVC
  • CPU features used: host-default build.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions