109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/*
209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (c) 2008, Google Inc. All rights reserved.
309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * modification, are permitted provided that the following conditions are
809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * met:
909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
1009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
1109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
1209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
1309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
1409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * in the documentation and/or other materials provided with the
1509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * distribution.
1609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
1709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
1809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * this software without specific prior written permission.
1909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
2009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "config.h"
3409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/ColorSpace.h"
3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/MathExtras.h"
3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)namespace WebCore {
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)namespace ColorSpaceUtilities {
4109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static const uint8_t* getLinearRgbLUT()
4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static uint8_t linearRgbLUT[256];
4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static bool initialized;
4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!initialized) {
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (unsigned i = 0; i < 256; i++) {
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            float color = i  / 255.0f;
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            color = (color <= 0.04045f ? color / 12.92f : pow((color + 0.055f) / 1.055f, 2.4f));
5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            color = std::max(0.0f, color);
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            color = std::min(1.0f, color);
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            linearRgbLUT[i] = static_cast<uint8_t>(round(color * 255));
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
5409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        initialized = true;
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return linearRgbLUT;
5709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static const uint8_t* getDeviceRgbLUT()
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static uint8_t deviceRgbLUT[256];
6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static bool initialized;
6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!initialized) {
6409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (unsigned i = 0; i < 256; i++) {
6509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            float color = i / 255.0f;
6609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            color = (powf(color, 1.0f / 2.4f) * 1.055f) - 0.055f;
6709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            color = std::max(0.0f, color);
6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            color = std::min(1.0f, color);
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            deviceRgbLUT[i] = static_cast<uint8_t>(round(color * 255));
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        initialized = true;
7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return deviceRgbLUT;
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)const uint8_t* getConversionLUT(ColorSpace dstColorSpace, ColorSpace srcColorSpace)
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Identity.
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (srcColorSpace == dstColorSpace)
8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return 0;
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Only sRGB/DeviceRGB <-> linearRGB are supported at the moment.
8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if ((srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceDeviceRGB)
8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceDeviceRGB))
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return 0;
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (dstColorSpace == ColorSpaceLinearRGB)
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return getLinearRgbLUT();
8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (dstColorSpace == ColorSpaceDeviceRGB)
9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return getDeviceRgbLUT();
9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
9209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_NOT_REACHED();
9309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return 0;
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)Color convertColor(const Color& srcColor, ColorSpace dstColorSpace, ColorSpace srcColorSpace)
9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const uint8_t* lookupTable = getConversionLUT(dstColorSpace, srcColorSpace);
9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!lookupTable)
10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return srcColor;
10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return Color(lookupTable[srcColor.red()], lookupTable[srcColor.green()], lookupTable[srcColor.blue()], srcColor.alpha());
10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} // namespace ColorSpaceUtilities
10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} // namespace WebCore
108