added 3dengfx into the repo, probably not the correct version for this
[summerhack] / src / 3dengfx / src / gfx / color.cpp
1 /*
2 Copyright 2004 John Tsiombikas <nuclear@siggraph.org>
3
4 This file is part of the graphics core library.
5
6 the graphics core library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 the graphics core library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with the graphics core library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 /* colors
22  * author: John Tsiombikas 2004
23  */
24
25 #include "3dengfx_config.h"
26
27 #include <cmath>
28 #include "color.hpp"
29
30 template <class T>
31 const T &clamp(const T &val, const T &low, const T &high) {
32         if(val > high) return high;
33         if(val < low) return low;
34         return val;
35 }
36
37 Color::Color(scalar_t intensity) {
38         r = g = b = clamp<scalar_t>(intensity, 0.0f, 1.0f);
39         a = 1.0f;
40 }
41
42 Color::Color(scalar_t r, scalar_t g, scalar_t b, scalar_t a) {
43         this->r = clamp<scalar_t>(r, 0.0f, 1.0f);
44         this->g = clamp<scalar_t>(g, 0.0f, 1.0f);
45         this->b = clamp<scalar_t>(b, 0.0f, 1.0f);
46         this->a = clamp<scalar_t>(a, 0.0f, 1.0f);
47 }
48
49 unsigned long Color::get_packed32() const {
50         return pack_color32(*this);
51 }
52
53 unsigned short Color::get_packed16() const {
54         return pack_color16(*this);
55 }
56
57 unsigned short Color::get_packed15() const {
58         return pack_color15(*this);
59 }
60
61 unsigned char Color::get_nearest8(const unsigned char **pal) const {
62         return match_nearest8(*this, pal);
63 }
64
65 Color Color::operator +(const Color &col) const {
66         return Color(r + col.r, g + col.g, b + col.b, a + col.a);
67 }
68
69 Color Color::operator -(const Color &col) const {
70         return Color(r - col.r, g - col.g, b - col.b, a - col.a);
71 }
72
73 Color Color::operator *(const Color &col) const {
74         return Color(r * col.r, g * col.g, b * col.b, a * col.a);
75 }
76         
77 Color Color::operator *(scalar_t scalar) const {
78         return Color(r * scalar, g * scalar, b * scalar, a);
79 }
80
81
82 void Color::operator +=(const Color &col) {
83         *this = Color(r + col.r, g + col.g, b + col.b, a + col.a);
84 }
85
86 void Color::operator -=(const Color &col) {
87         *this = Color(r - col.r, g - col.g, b - col.b, a - col.a);
88 }
89
90 void Color::operator *=(const Color &col) {
91         *this = Color(r * col.r, g * col.g, b * col.b, a * col.a);
92 }
93
94 void Color::operator *=(scalar_t scalar) {
95         *this = Color(r * scalar, g * scalar, b * scalar, a);
96 }
97
98 unsigned char match_nearest8(const Color &col, const unsigned char **pal) {
99         static const scalar_t half_pi = 1.5707963268;
100
101         scalar_t score[256];
102         for(int i=0; i<256; i++) {
103                 Color palcol = lookup_color8(i, pal);
104                 scalar_t near_r = (scalar_t)cos(fabs(col.r - palcol.r) * half_pi);
105                 scalar_t near_g = (scalar_t)cos(fabs(col.g - palcol.g) * half_pi);
106                 scalar_t near_b = (scalar_t)cos(fabs(col.b - palcol.b) * half_pi);
107                 score[i] = near_r + near_g + near_b;
108         }
109
110         int nearest = 0;
111         for(int i=0; i<256; i++) {
112                 if(score[i] > score[nearest]) nearest = i;
113         }
114         return nearest;
115 }