Grayscale image: Difference between revisions

Content added Content deleted
Line 395: Line 395:
implement {}
implement {}
rgb24_to_gray8 rgb =
rgb24_to_gray8 rgb =
(* There is no need for floating point here, although equivalent
integer calculations are a bit longer to write out. *)
let
let
extern castfn u8_to_dbl : uint8 -<> double
extern castfn i2u32 : int -<> uint32
extern castfn dbl_to_u8 : double -<> uint8
extern castfn u8_to_u32 : uint8 -<> uint32
extern castfn u32_to_u8 : uint32 -<> uint8


val @(r, g, b) = rgb24_values rgb
val @(r, g, b) = rgb24_values rgb
val r : double = u8_to_dbl r
val r = u8_to_u32 r
and g : double = u8_to_dbl g
and g = u8_to_u32 g
and b : double = u8_to_dbl b
and b = u8_to_u32 b


val Y = (0.2126 * r) + (0.7152 * g) + (0.0722 * b)
val Y = (i2u32 2126 * r) + (i2u32 7152 * g) + (i2u32 722 * b)
val Yi = dbl_to_u8 ($extfcall (double, "rint", Y))
val Y1 = Y / i2u32 10000
and Y0 = Y mod (i2u32 10000)
in
in
if Y0 < i2u32 5000 then
gray8_make Yi
gray8_make (u32_to_u8 Y1)
else if i2u32 5000 < Y0 then
gray8_make (succ (u32_to_u8 Y1))
else if Y0 mod (i2u32 2) = i2u32 0 then
gray8_make (u32_to_u8 Y1)
else
gray8_make (succ (u32_to_u8 Y1))
end
end