title: Why is SetDeviceGammaRamp failing when adjusting values below 50%?
body: <p>I am using <code>SetDeviceGammaRamp</code> to adjust the color temperature of my display (similar to a utility like f.lux.) It mostly works, except if I try to adjust the brightness of any channel bellow 50%, in which case the function fails and <code>GetLastError</code> returns <code>ERROR_INVALID_WINDOW_HANDLE</code>.</p>
  
  <p>Is it possible that my graphics driver is simply refusing the supplied LUT if it tries to adjust anything beyond 50% brightness?</p>
  
  <pre><code>#include &lt;windows.h&gt;
  
  int AdjustBrightness(float multiplier)
  {
      unsigned short LUT[3][256];
      for (int i = 0; i &lt; 256; i++)
      {
          LUT[0][i] = i * 256 * multiplier;
          LUT[1][i] = i * 256 * multiplier;
          LUT[2][i] = i * 256 * multiplier;
      }
      return SetDeviceGammaRamp(GetDC(0), LUT);
  }
  
  int main()
  {
      if (!AdjustBrightness(0.5f))
          MessageBox(0, "0.5 was not a good value.", "Error", 0);
      if (!AdjustBrightness(0.45f))
          MessageBox(0, "0.45 was not a good value.", "Error", 0);
      //I'm getting one message box telling me 0.45 is a bad value
  }
  </code></pre>
  
  <p>Edit: It seems even stranger now as the following code does seems to work fine despite producing LUT values bellow 50% of their original value.</p>
  
  <pre><code>#include &lt;math.h&gt;
  #include &lt;windows.h&gt;
  
  int AdjustGamma()
  {
      unsigned short LUT[3][256];
      for (int i = 0; i &lt; 256; i++)
      {
          //squaring will produce LUT values much smaller than 50% of their original value
          int value = pow(i / 255.0f, 2.0f) * 255.0f;
          LUT[0][i] = value * 256;
          LUT[1][i] = value * 256;
          LUT[2][i] = value * 256;
      }
      return SetDeviceGammaRamp(GetDC(0), LUT);
  }
  
  int main()
  {
      AdjustGamma(); //no complaints
  }
  </code></pre>
  
  <p>Perhaps the driver is using some sort of heuristic to validate the LUT as a particular type of adjustment, and then checking to see if it's within some limits? It doesn't seem that crazy for them to do this as you could imagine the carnage that would ensue if you filled the LUT with random values, for example. </p>