Path: blob/master/3rdparty/openexr/Imath/ImathColorAlgo.h
16337 views
///////////////////////////////////////////////////////////////////////////1//2// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas3// Digital Ltd. LLC4//5// All rights reserved.6//7// Redistribution and use in source and binary forms, with or without8// modification, are permitted provided that the following conditions are9// met:10// * Redistributions of source code must retain the above copyright11// notice, this list of conditions and the following disclaimer.12// * Redistributions in binary form must reproduce the above13// copyright notice, this list of conditions and the following disclaimer14// in the documentation and/or other materials provided with the15// distribution.16// * Neither the name of Industrial Light & Magic nor the names of17// its contributors may be used to endorse or promote products derived18// from this software without specific prior written permission.19//20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31//32///////////////////////////////////////////////////////////////////////////33343536#ifndef INCLUDED_IMATHCOLORALGO_H37#define INCLUDED_IMATHCOLORALGO_H383940#include "ImathColor.h"41#include "ImathMath.h"42#include "ImathLimits.h"4344namespace Imath {454647//48// Non-templated helper routines for color conversion.49// These routines eliminate type warnings under g++.50//5152Vec3<double> hsv2rgb_d(const Vec3<double> &hsv);5354Color4<double> hsv2rgb_d(const Color4<double> &hsv);555657Vec3<double> rgb2hsv_d(const Vec3<double> &rgb);5859Color4<double> rgb2hsv_d(const Color4<double> &rgb);606162//63// Color conversion functions and general color algorithms64//65// hsv2rgb(), rgb2hsv(), rgb2packed(), packed2rgb()66// see each funtion definition for details.67//6869template<class T>70Vec3<T>71hsv2rgb(const Vec3<T> &hsv)72{73if ( limits<T>::isIntegral() )74{75Vec3<double> v = Vec3<double>(hsv.x / double(limits<T>::max()),76hsv.y / double(limits<T>::max()),77hsv.z / double(limits<T>::max()));78Vec3<double> c = hsv2rgb_d(v);79return Vec3<T>((T) (c.x * limits<T>::max()),80(T) (c.y * limits<T>::max()),81(T) (c.z * limits<T>::max()));82}83else84{85Vec3<double> v = Vec3<double>(hsv.x, hsv.y, hsv.z);86Vec3<double> c = hsv2rgb_d(v);87return Vec3<T>((T) c.x, (T) c.y, (T) c.z);88}89}909192template<class T>93Color4<T>94hsv2rgb(const Color4<T> &hsv)95{96if ( limits<T>::isIntegral() )97{98Color4<double> v = Color4<double>(hsv.r / float(limits<T>::max()),99hsv.g / float(limits<T>::max()),100hsv.b / float(limits<T>::max()),101hsv.a / float(limits<T>::max()));102Color4<double> c = hsv2rgb_d(v);103return Color4<T>((T) (c.r * limits<T>::max()),104(T) (c.g * limits<T>::max()),105(T) (c.b * limits<T>::max()),106(T) (c.a * limits<T>::max()));107}108else109{110Color4<double> v = Color4<double>(hsv.r, hsv.g, hsv.b, hsv.a);111Color4<double> c = hsv2rgb_d(v);112return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);113}114}115116117template<class T>118Vec3<T>119rgb2hsv(const Vec3<T> &rgb)120{121if ( limits<T>::isIntegral() )122{123Vec3<double> v = Vec3<double>(rgb.x / double(limits<T>::max()),124rgb.y / double(limits<T>::max()),125rgb.z / double(limits<T>::max()));126Vec3<double> c = rgb2hsv_d(v);127return Vec3<T>((T) (c.x * limits<T>::max()),128(T) (c.y * limits<T>::max()),129(T) (c.z * limits<T>::max()));130}131else132{133Vec3<double> v = Vec3<double>(rgb.x, rgb.y, rgb.z);134Vec3<double> c = rgb2hsv_d(v);135return Vec3<T>((T) c.x, (T) c.y, (T) c.z);136}137}138139140template<class T>141Color4<T>142rgb2hsv(const Color4<T> &rgb)143{144if ( limits<T>::isIntegral() )145{146Color4<double> v = Color4<double>(rgb.r / float(limits<T>::max()),147rgb.g / float(limits<T>::max()),148rgb.b / float(limits<T>::max()),149rgb.a / float(limits<T>::max()));150Color4<double> c = rgb2hsv_d(v);151return Color4<T>((T) (c.r * limits<T>::max()),152(T) (c.g * limits<T>::max()),153(T) (c.b * limits<T>::max()),154(T) (c.a * limits<T>::max()));155}156else157{158Color4<double> v = Color4<double>(rgb.r, rgb.g, rgb.b, rgb.a);159Color4<double> c = rgb2hsv_d(v);160return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);161}162}163164template <class T>165PackedColor166rgb2packed(const Vec3<T> &c)167{168if ( limits<T>::isIntegral() )169{170float x = c.x / float(limits<T>::max());171float y = c.y / float(limits<T>::max());172float z = c.z / float(limits<T>::max());173return rgb2packed( V3f(x,y,z) );174}175else176{177return ( (PackedColor) (c.x * 255) |178(((PackedColor) (c.y * 255)) << 8) |179(((PackedColor) (c.z * 255)) << 16) | 0xFF000000 );180}181}182183template <class T>184PackedColor185rgb2packed(const Color4<T> &c)186{187if ( limits<T>::isIntegral() )188{189float r = c.r / float(limits<T>::max());190float g = c.g / float(limits<T>::max());191float b = c.b / float(limits<T>::max());192float a = c.a / float(limits<T>::max());193return rgb2packed( C4f(r,g,b,a) );194}195else196{197return ( (PackedColor) (c.r * 255) |198(((PackedColor) (c.g * 255)) << 8) |199(((PackedColor) (c.b * 255)) << 16) |200(((PackedColor) (c.a * 255)) << 24));201}202}203204//205// This guy can't return the result because the template206// parameter would not be in the function signiture. So instead,207// its passed in as an argument.208//209210template <class T>211void212packed2rgb(PackedColor packed, Vec3<T> &out)213{214if ( limits<T>::isIntegral() )215{216T f = limits<T>::max() / ((PackedColor)0xFF);217out.x = (packed & 0xFF) * f;218out.y = ((packed & 0xFF00) >> 8) * f;219out.z = ((packed & 0xFF0000) >> 16) * f;220}221else222{223T f = T(1) / T(255);224out.x = (packed & 0xFF) * f;225out.y = ((packed & 0xFF00) >> 8) * f;226out.z = ((packed & 0xFF0000) >> 16) * f;227}228}229230template <class T>231void232packed2rgb(PackedColor packed, Color4<T> &out)233{234if ( limits<T>::isIntegral() )235{236T f = limits<T>::max() / ((PackedColor)0xFF);237out.r = (packed & 0xFF) * f;238out.g = ((packed & 0xFF00) >> 8) * f;239out.b = ((packed & 0xFF0000) >> 16) * f;240out.a = ((packed & 0xFF000000) >> 24) * f;241}242else243{244T f = T(1) / T(255);245out.r = (packed & 0xFF) * f;246out.g = ((packed & 0xFF00) >> 8) * f;247out.b = ((packed & 0xFF0000) >> 16) * f;248out.a = ((packed & 0xFF000000) >> 24) * f;249}250}251252253} // namespace Imath254255#endif256257258