JDK-4759386 : Color.HSBtoRGB inaccurate for small negative hue
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.3.1
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_98
  • CPU: x86
  • Submitted: 2002-10-08
  • Updated: 2014-03-18
Description

Name: jk109818			Date: 10/07/2002


FULL PRODUCT VERSION :
java version "1.3.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_02-b02)
Java HotSpot(TM) Client VM (build 1.3.1_02-b02, mixed mode)

Also on
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)

AND
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)

FULL OPERATING SYSTEM VERSION :

Windows 98 [Version 4.10.2222]
Mac OS X.2

ADDITIONAL OPERATING SYSTEMS :

Believed to apply to all OSes.

A DESCRIPTION OF THE PROBLEM :
For small negative values of hue, HSBtoRGB returns black when it
should return red.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Example:

import java.awt.Color;
public class Test
{
    public static void main(String[] args)
    {
        int rgb = 0xffffff & Color.HSBtoRGB(-0.00000002f, 1.0f, 1.0f);
        System.out.println(Integer.toString(rgb, 16));
    }
}

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected result: ff0000 (bright red)
Actual result: 0

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
See above.
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
1. (User) Create a wrapper:
    static int myHSBtoRGB(float hue, float saturation, float
brightness)
    {
        if (hue < 0.0f && hue >= -0.0000001f)
        {
            hue = 0.0f;
        }
        return Color.HSBtoRGB(hue, saturation, brightness);
    }


2. (Sun) The problem lies in the following line of code in the
HSBtoRGB source:
        float h = (hue - (float)Math.floor(hue)) * 6.0f;
    Math.floor(hue) returns -1.0f, which is sufficiently larger than the
hue that (hue - (float)Math.floor(hue)) evaluates to 1.0f. Thus the
later switch on (int)h, failing to find a case 6, defaults to leaving r, g,
b as zeroes.
    There are several possible fixes, and I'm not much of a
numerical analyst so won't venture an opinion on the best way.
One possibility is to insert a line immediately after the faulty line:
        if (h >= 6.0f) h -= 6.0f;
(Review ID: 165289) 
======================================================================

Comments
Please re-open if - if fix is in progress or on the plan to fix soon - if this is a P3 (file as P3, not P4)
18-03-2014