1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // api_colors.cpp //
15 // //
16 // Copyright (C) 2005 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Goettingen //
44 // Goldschmidtstr. 5 //
45 // 37077 Goettingen //
46 // Germany //
47 // //
48 // e-mail: oconrad@saga-gis.org //
49 // //
50 ///////////////////////////////////////////////////////////
51
52 //---------------------------------------------------------
53 #include <stdlib.h>
54 #include <string.h>
55
56 #include "api_core.h"
57 #include "mat_tools.h"
58
59
60 ///////////////////////////////////////////////////////////
61 // //
62 // //
63 // //
64 ///////////////////////////////////////////////////////////
65
66 //---------------------------------------------------------
SG_Colors_Get_Name(int Index)67 CSG_String SG_Colors_Get_Name (int Index)
68 {
69 return( CSG_Colors::Get_Predefined_Name(Index) );
70 }
71
72 //---------------------------------------------------------
SG_Color_Get_Random(void)73 long SG_Color_Get_Random (void)
74 {
75 return( SG_GET_RGB(CSG_Random::Get_Uniform(0, 255), CSG_Random::Get_Uniform(0, 255), CSG_Random::Get_Uniform(0, 255)) );
76 }
77
78 //---------------------------------------------------------
SG_Color_From_Text(const CSG_String & Text,long & Color)79 bool SG_Color_From_Text (const CSG_String &Text, long &Color)
80 { // from wx/colourmng.cpp, hexadecimal prefixed with # ("HTML syntax") see https://drafts.csswg.org/css-color/#hex-notation
81
82 const char *s = Text.b_str(); unsigned long c;
83
84 if( sscanf(s + 1, "%lx", &c) == 1 )
85 {
86 switch( Text.Length() - 1 )
87 {
88 case 6: // #rrggbb
89 Color = (long)((c << 8) + 0xFF);
90 return( true );
91
92 case 8: // #rrggbbaa
93 Color = SG_GET_RGBA(
94 (unsigned char)((c >> 24) & 0xFF),
95 (unsigned char)((c >> 16) & 0xFF),
96 (unsigned char)((c >> 8) & 0xFF),
97 (unsigned char)((c ) & 0xFF)
98 );
99 return( true );
100
101 case 3: // #rgb
102 Color = (long)((c << 4) + 0xF);
103 return( true );
104
105 case 4: // #rgba
106 Color = SG_GET_RGBA(
107 (unsigned char)(((c >> 12) & 0xF) * 0x11),
108 (unsigned char)(((c >> 8) & 0xF) * 0x11),
109 (unsigned char)(((c >> 4) & 0xF) * 0x11),
110 (unsigned char)(((c ) & 0xF) * 0x11)
111 );
112 return( true );
113 }
114 }
115
116 return( false );
117 }
118
119 //---------------------------------------------------------
SG_Color_To_Text(long Color,bool bHexadecimal)120 CSG_String SG_Color_To_Text (long Color, bool bHexadecimal)
121 {
122 CSG_String Text;
123
124 if( bHexadecimal )
125 {
126 Text.Printf("#%02X%02X%02X",
127 SG_GET_R(Color),
128 SG_GET_G(Color),
129 SG_GET_B(Color)
130 );
131 }
132 else
133 {
134 Text.Printf("%ld", Color);
135 }
136
137 return( Text );
138 }
139
140
141 ///////////////////////////////////////////////////////////
142 // //
143 // //
144 // //
145 ///////////////////////////////////////////////////////////
146
147 //---------------------------------------------------------
CSG_Colors(void)148 CSG_Colors::CSG_Colors(void)
149 {
150 m_Colors = NULL;
151 m_nColors = 0;
152
153 Create();
154 }
155
156 //---------------------------------------------------------
CSG_Colors(const CSG_Colors & Colors)157 CSG_Colors::CSG_Colors(const CSG_Colors &Colors)
158 {
159 m_Colors = NULL;
160 m_nColors = 0;
161
162 Create(Colors);
163 }
164
165 //---------------------------------------------------------
CSG_Colors(int nColors,int Palette,bool bRevert)166 CSG_Colors::CSG_Colors(int nColors, int Palette, bool bRevert)
167 {
168 m_Colors = NULL;
169 m_nColors = 0;
170
171 Create(nColors, Palette, bRevert);
172 }
173
174 //---------------------------------------------------------
~CSG_Colors(void)175 CSG_Colors::~CSG_Colors(void)
176 {
177 Destroy();
178 }
179
180
181 ///////////////////////////////////////////////////////////
182 // //
183 ///////////////////////////////////////////////////////////
184
185 //---------------------------------------------------------
Create(void)186 bool CSG_Colors::Create(void)
187 {
188 return( Create(11) );
189 }
190
191 //---------------------------------------------------------
Create(const CSG_Colors & Colors)192 bool CSG_Colors::Create(const CSG_Colors &Colors)
193 {
194 if( Colors.m_nColors > 0 )
195 {
196 m_nColors = Colors.m_nColors;
197 m_Colors = (long *)SG_Realloc(m_Colors, m_nColors * sizeof(long));
198
199 memcpy(m_Colors, Colors.m_Colors, m_nColors * sizeof(long));
200
201 return( true );
202 }
203
204 return( false );
205 }
206
207 //---------------------------------------------------------
Create(int nColors,int Palette,bool bRevert)208 bool CSG_Colors::Create(int nColors, int Palette, bool bRevert)
209 {
210 if( nColors <= 1 )
211 {
212 nColors = 11;
213 }
214
215 Set_Count(nColors);
216
217 Set_Palette(Palette, bRevert, nColors);
218
219 return( true );
220 }
221
222 //---------------------------------------------------------
Destroy(void)223 void CSG_Colors::Destroy(void)
224 {
225 if( m_nColors > 0 )
226 {
227 SG_Free(m_Colors);
228
229 m_Colors = NULL;
230 m_nColors = 0;
231 }
232 }
233
234
235 ///////////////////////////////////////////////////////////
236 // //
237 ///////////////////////////////////////////////////////////
238
239 //---------------------------------------------------------
Set_Count(int nColors)240 bool CSG_Colors::Set_Count(int nColors)
241 {
242 if( nColors == m_nColors )
243 {
244 return( true );
245 }
246
247 if( nColors < 1 )
248 {
249 return( false );
250 }
251
252 if( m_nColors == 0 )
253 {
254 return( Set_Default(nColors) );
255 }
256
257 //-----------------------------------------------------
258 CSG_Colors Colors(*this);
259
260 m_nColors = nColors;
261 m_Colors = (long *)SG_Realloc(m_Colors, m_nColors * sizeof(long));
262
263 double dStep = Get_Count() > 1 ? (Colors.Get_Count() - 1.0) / (Get_Count() - 1.0) : 0.0;
264
265 for(int i=0; i<Get_Count(); i++)
266 {
267 if( Get_Count() < Colors.Get_Count() )
268 {
269 m_Colors[i] = Colors[(int)(i * dStep)];
270 }
271 else // if( Get_Count() > Colors.Get_Count() )
272 {
273 m_Colors[i] = Colors.Get_Interpolated(i * dStep);
274 }
275 }
276
277 //---------------------------------------------
278 return( true );
279 }
280
281
282 ///////////////////////////////////////////////////////////
283 // //
284 ///////////////////////////////////////////////////////////
285
286 //---------------------------------------------------------
Set_Color(int Index,long Color)287 bool CSG_Colors::Set_Color(int Index, long Color)
288 {
289 if( Index >= 0 && Index < m_nColors )
290 {
291 m_Colors[Index] = Color;
292
293 return( true );
294 }
295
296 return( false );
297 }
298
299 //---------------------------------------------------------
Set_Color(int Index,int Red,int Green,int Blue)300 bool CSG_Colors::Set_Color(int Index, int Red, int Green, int Blue)
301 {
302 return( Set_Color(Index, SG_GET_RGB(Red, Green, Blue)) );
303 }
304
305 //---------------------------------------------------------
Set_Red(int Index,int Value)306 bool CSG_Colors::Set_Red(int Index, int Value)
307 {
308 return( Set_Color(Index, Value , Get_Green(Index) , Get_Blue(Index)) );
309 }
310
311 //---------------------------------------------------------
Set_Green(int Index,int Value)312 bool CSG_Colors::Set_Green(int Index, int Value)
313 {
314 return( Set_Color(Index, Get_Red(Index) , Value , Get_Blue(Index)) );
315 }
316
317 //---------------------------------------------------------
Set_Blue(int Index,int Value)318 bool CSG_Colors::Set_Blue(int Index, int Value)
319 {
320 return( Set_Color(Index, Get_Red(Index) , Get_Green(Index) , Value) );
321 }
322
323 //---------------------------------------------------------
Set_Brightness(int Index,int Value)324 bool CSG_Colors::Set_Brightness(int Index, int Value)
325 {
326 double r, g, b, ds;
327
328 //-----------------------------------------------------
329 if( Value < 0 )
330 {
331 Value = 0;
332 }
333 else if( Value > 255 )
334 {
335 Value = 255;
336 }
337
338 //-----------------------------------------------------
339 r = Get_Red (Index);
340 g = Get_Green(Index);
341 b = Get_Blue (Index);
342 ds = (r + g + b) / 3.0;
343
344 if( ds > 0.0 )
345 {
346 ds = Value / ds;
347 r *= ds;
348 g *= ds;
349 b *= ds;
350
351 _Set_Brightness(r, g, b);
352 }
353 else
354 {
355 r = g = b = Value / 3.0;
356 }
357
358 return( Set_Color(Index, (int)r, (int)g, (int)b) );
359 }
360
361 //---------------------------------------------------------
_Set_Brightness(double & a,double & b,double & c,int Pass)362 void CSG_Colors::_Set_Brightness(double &a, double &b, double &c, int Pass)
363 {
364 if( a > 255 )
365 {
366 int addSum;
367
368 addSum = (int)((a - 255) / 2.0);
369 a = 255;
370
371 b += addSum;
372 c += addSum;
373
374 if( b > 255 )
375 {
376 addSum = (int)(b - 255);
377 b = 255;
378
379 c += addSum;
380
381 if( c > 255 )
382 {
383 c = 255;
384 }
385 }
386 else if( c > 255 )
387 {
388 addSum = (int)(c - 255);
389 c = 255;
390
391 b += addSum;
392
393 if( b > 255 )
394 {
395 b = 255;
396 }
397 }
398 }
399 else if( Pass < 2 )
400 {
401 _Set_Brightness(b, c, a, Pass + 1);
402 }
403 }
404
405
406 ///////////////////////////////////////////////////////////
407 // //
408 ///////////////////////////////////////////////////////////
409
410 //---------------------------------------------------------
Get_Predefined_Count(void)411 int CSG_Colors::Get_Predefined_Count(void)
412 {
413 return( SG_COLORS_COUNT );
414 }
415
416 //---------------------------------------------------------
Get_Predefined_Name(int Index)417 const SG_Char * CSG_Colors::Get_Predefined_Name(int Index)
418 {
419 switch( Index )
420 {
421 case SG_COLORS_DEFAULT : return( _TL("default" ) );
422 case SG_COLORS_DEFAULT_BRIGHT : return( _TL("default (same brightness)") );
423 case SG_COLORS_BLACK_WHITE : return( _TL("greyscale" ) );
424 case SG_COLORS_BLACK_RED : return( _TL("black > red" ) );
425 case SG_COLORS_BLACK_GREEN : return( _TL("black > green" ) );
426 case SG_COLORS_BLACK_BLUE : return( _TL("black > blue" ) );
427 case SG_COLORS_WHITE_RED : return( _TL("white > red" ) );
428 case SG_COLORS_WHITE_GREEN : return( _TL("white > green" ) );
429 case SG_COLORS_WHITE_BLUE : return( _TL("white > blue" ) );
430 case SG_COLORS_YELLOW_RED : return( _TL("yellow > red" ) );
431 case SG_COLORS_YELLOW_GREEN : return( _TL("yellow > green" ) );
432 case SG_COLORS_YELLOW_BLUE : return( _TL("yellow > blue" ) );
433 case SG_COLORS_RED_GREEN : return( _TL("red > green" ) );
434 case SG_COLORS_RED_BLUE : return( _TL("red > blue" ) );
435 case SG_COLORS_GREEN_BLUE : return( _TL("green > blue" ) );
436 case SG_COLORS_RED_GREY_BLUE : return( _TL("red > grey > blue" ) );
437 case SG_COLORS_RED_GREY_GREEN : return( _TL("red > grey > green" ) );
438 case SG_COLORS_GREEN_GREY_BLUE: return( _TL("green > grey > blue" ) );
439 case SG_COLORS_RED_GREEN_BLUE : return( _TL("red > green > blue" ) );
440 case SG_COLORS_RED_BLUE_GREEN : return( _TL("red > blue > green" ) );
441 case SG_COLORS_GREEN_RED_BLUE : return( _TL("green > red > blue" ) );
442 case SG_COLORS_RAINBOW : return( _TL("rainbow" ) );
443 case SG_COLORS_NEON : return( _TL("neon" ) );
444 case SG_COLORS_TOPOGRAPHY : return( _TL("topography 1" ) );
445 case SG_COLORS_TOPOGRAPHY_2 : return( _TL("topography 2" ) );
446 case SG_COLORS_TOPOGRAPHY_3 : return( _TL("topography 3" ) );
447 case SG_COLORS_PRECIPITATION : return( _TL("precipitation" ) );
448 case SG_COLORS_ASPECT_1 : return( _TL("aspect 1" ) );
449 case SG_COLORS_ASPECT_2 : return( _TL("aspect 2" ) );
450 case SG_COLORS_ASPECT_3 : return( _TL("aspect 3" ) );
451 default : return( _TL("" ) );
452 }
453 }
454
455 //---------------------------------------------------------
Set_Predefined(int Index,bool bRevert,int nColors)456 bool CSG_Colors::Set_Predefined(int Index, bool bRevert, int nColors)
457 {
458 switch( Index )
459 {
460 case SG_COLORS_DEFAULT:
461 Set_Default(nColors);
462 break;
463
464 case SG_COLORS_DEFAULT_BRIGHT:
465 Set_Default(nColors);
466 Set_Ramp_Brighness(127, 127);
467 break;
468
469 case SG_COLORS_BLACK_WHITE:
470 Set_Ramp(SG_GET_RGB( 0, 0, 0), SG_GET_RGB(255, 255, 255));
471 break;
472
473 case SG_COLORS_BLACK_RED:
474 Set_Ramp(SG_GET_RGB( 0, 0, 0), SG_GET_RGB(255, 0, 0));
475 break;
476
477 case SG_COLORS_BLACK_GREEN:
478 Set_Ramp(SG_GET_RGB( 0, 0, 0), SG_GET_RGB( 0, 255, 0));
479 break;
480
481 case SG_COLORS_BLACK_BLUE:
482 Set_Ramp(SG_GET_RGB( 0, 0, 0), SG_GET_RGB( 0, 0, 255));
483 break;
484
485 case SG_COLORS_WHITE_RED:
486 Set_Count(3);
487 Set_Color(0, SG_GET_RGB(255, 255, 255));
488 Set_Color(1, SG_GET_RGB(255, 127, 0));
489 Set_Color(2, SG_GET_RGB(159, 0, 0));
490 break;
491
492 case SG_COLORS_WHITE_GREEN:
493 Set_Ramp(SG_GET_RGB(255, 255, 255), SG_GET_RGB( 0, 127, 0));
494 break;
495
496 case SG_COLORS_WHITE_BLUE:
497 Set_Count(3);
498 Set_Color(0, SG_GET_RGB(255, 255, 255));
499 Set_Color(1, SG_GET_RGB( 0, 127, 255));
500 Set_Color(2, SG_GET_RGB( 0, 0, 159));
501 break;
502
503 case SG_COLORS_YELLOW_RED:
504 Set_Ramp(SG_GET_RGB(255, 255, 0), SG_GET_RGB(191, 0, 0));
505 break;
506
507 case SG_COLORS_YELLOW_GREEN:
508 Set_Ramp(SG_GET_RGB(255, 255, 0), SG_GET_RGB( 0, 63, 0));
509 break;
510
511 case SG_COLORS_YELLOW_BLUE:
512 Set_Count(3);
513 Set_Color(2, SG_GET_RGB( 0, 64, 127));
514 Set_Color(1, SG_GET_RGB(127, 192, 255));
515 Set_Color(0, SG_GET_RGB(255, 255, 200));
516 break;
517
518 case SG_COLORS_RED_GREEN:
519 Set_Count(5);
520 Set_Color(0, SG_GET_RGB(159, 0, 0));
521 Set_Color(1, SG_GET_RGB(255, 159, 0));
522 Set_Color(2, SG_GET_RGB(255, 255, 0));
523 Set_Color(3, SG_GET_RGB(159, 255, 0));
524 Set_Color(4, SG_GET_RGB( 0, 159, 0));
525 break;
526
527 case SG_COLORS_RED_BLUE:
528 Set_Ramp(SG_GET_RGB(255, 0, 0), SG_GET_RGB( 0, 0, 255));
529 break;
530
531 case SG_COLORS_GREEN_BLUE:
532 Set_Ramp(SG_GET_RGB( 0, 255, 0), SG_GET_RGB( 0, 0, 255));
533 break;
534
535 case SG_COLORS_RED_GREY_BLUE:
536 Set_Count(5);
537 Set_Color(0, SG_GET_RGB(127, 0, 0));
538 Set_Color(1, SG_GET_RGB(255, 127, 0));
539 Set_Color(2, SG_GET_RGB(239, 239, 239));
540 Set_Color(3, SG_GET_RGB( 0, 127, 255));
541 Set_Color(4, SG_GET_RGB( 0, 0, 127));
542 break;
543
544 case SG_COLORS_RED_GREY_GREEN:
545 Set_Count(5);
546 Set_Color(0, SG_GET_RGB(127, 0, 0));
547 Set_Color(1, SG_GET_RGB(255, 127, 0));
548 Set_Color(2, SG_GET_RGB(239, 239, 239));
549 Set_Color(3, SG_GET_RGB( 0, 255, 127));
550 Set_Color(4, SG_GET_RGB( 0, 127, 0));
551 break;
552
553 case SG_COLORS_GREEN_GREY_BLUE:
554 Set_Count(5);
555 Set_Color(0, SG_GET_RGB( 0, 127, 0));
556 Set_Color(1, SG_GET_RGB(127, 255, 0));
557 Set_Color(2, SG_GET_RGB(239, 239, 239));
558 Set_Color(3, SG_GET_RGB( 0, 127, 255));
559 Set_Color(4, SG_GET_RGB( 0, 0, 127));
560 break;
561
562 case SG_COLORS_RED_GREEN_BLUE:
563 Set_Count(5);
564 Set_Color(0, SG_GET_RGB(127, 0, 127));
565 Set_Color(1, SG_GET_RGB(255, 0, 0));
566 Set_Color(2, SG_GET_RGB( 0, 255, 0));
567 Set_Color(3, SG_GET_RGB( 0, 0, 255));
568 Set_Color(4, SG_GET_RGB(127, 0, 127));
569 break;
570
571 case SG_COLORS_RED_BLUE_GREEN:
572 Set_Count(5);
573 Set_Color(0, SG_GET_RGB(127, 127, 0));
574 Set_Color(1, SG_GET_RGB(255, 0, 0));
575 Set_Color(2, SG_GET_RGB( 0, 0, 255));
576 Set_Color(3, SG_GET_RGB( 0, 255, 0));
577 Set_Color(4, SG_GET_RGB(127, 127, 0));
578 break;
579
580 case SG_COLORS_GREEN_RED_BLUE:
581 Set_Count(5);
582 Set_Color(0, SG_GET_RGB( 0, 127, 127));
583 Set_Color(1, SG_GET_RGB( 0, 255, 0));
584 Set_Color(2, SG_GET_RGB(255, 0, 0));
585 Set_Color(3, SG_GET_RGB( 0, 0, 255));
586 Set_Color(4, SG_GET_RGB( 0, 127, 127));
587 break;
588
589 case SG_COLORS_RAINBOW:
590 Set_Count(8);
591 Set_Color(0, SG_GET_RGB( 64, 0, 127));
592 Set_Color(1, SG_GET_RGB( 0, 0, 255));
593 Set_Color(2, SG_GET_RGB( 0, 255, 255));
594 Set_Color(3, SG_GET_RGB( 0, 191, 0));
595 Set_Color(4, SG_GET_RGB(255, 255, 0));
596 Set_Color(5, SG_GET_RGB(255, 127, 0));
597 Set_Color(6, SG_GET_RGB(255, 0, 0));
598 Set_Color(7, SG_GET_RGB(127, 0, 0));
599 break;
600
601 case SG_COLORS_NEON:
602 Set_Count(7);
603 Set_Color(0, SG_GET_RGB( 0, 0, 0));
604 Set_Color(1, SG_GET_RGB(255, 0, 0));
605 Set_Color(2, SG_GET_RGB( 0, 0, 0));
606 Set_Color(3, SG_GET_RGB(255, 255, 0));
607 Set_Color(4, SG_GET_RGB( 0, 0, 0));
608 Set_Color(5, SG_GET_RGB( 0, 255, 0));
609 Set_Color(6, SG_GET_RGB( 0, 0, 0));
610 break;
611
612 case SG_COLORS_TOPOGRAPHY:
613 Set_Count(5);
614 Set_Color(0, SG_GET_RGB( 0, 63, 127));
615 Set_Color(1, SG_GET_RGB(127, 255, 0));
616 Set_Color(2, SG_GET_RGB(255, 255, 127));
617 Set_Color(3, SG_GET_RGB(191, 127, 0));
618 Set_Color(4, SG_GET_RGB(127, 63, 0));
619 break;
620
621 case SG_COLORS_TOPOGRAPHY_2:
622 Set_Count(6);
623 Set_Color(0, SG_GET_RGB( 0, 191, 191));
624 Set_Color(1, SG_GET_RGB( 0, 255, 0));
625 Set_Color(2, SG_GET_RGB(255, 255, 0));
626 Set_Color(3, SG_GET_RGB(255, 127, 0));
627 Set_Color(4, SG_GET_RGB(191, 152, 110));
628 Set_Color(5, SG_GET_RGB(199, 199, 199));
629 break;
630
631 case SG_COLORS_TOPOGRAPHY_3:
632 Set_Count(9);
633 Set_Color(0, SG_GET_RGB(177, 242, 212));
634 Set_Color(1, SG_GET_RGB(248, 252, 179));
635 Set_Color(2, SG_GET_RGB( 11, 128, 064));
636 Set_Color(3, SG_GET_RGB(248, 202, 80));
637 Set_Color(4, SG_GET_RGB(158, 30, 0));
638 Set_Color(5, SG_GET_RGB(128, 064, 064));
639 Set_Color(6, SG_GET_RGB(185, 121, 076));
640 Set_Color(7, SG_GET_RGB(179, 179, 179));
641 Set_Color(8, SG_GET_RGB(255, 255, 255));
642 break;
643
644 case SG_COLORS_PRECIPITATION: // juergen's favorite precipition colour ramp
645 Set_Count(22);
646 Set_Color( 0, SG_GET_RGB(216, 204, 131));
647 Set_Color( 1, SG_GET_RGB(196, 208, 111));
648 Set_Color( 2, SG_GET_RGB(184, 210, 101));
649 Set_Color( 3, SG_GET_RGB(172, 212, 91));
650 Set_Color( 4, SG_GET_RGB(139, 212, 99));
651 Set_Color( 5, SG_GET_RGB(107, 212, 107));
652 Set_Color( 6, SG_GET_RGB( 75, 212, 119));
653 Set_Color( 7, SG_GET_RGB( 42, 212, 131));
654 Set_Color( 8, SG_GET_RGB( 26, 212, 151));
655 Set_Color( 9, SG_GET_RGB( 10, 212, 172));
656 Set_Color(10, SG_GET_RGB( 30, 192, 192));
657 Set_Color(11, SG_GET_RGB( 50, 172, 212));
658 Set_Color(12, SG_GET_RGB( 70, 151, 214));
659 Set_Color(13, SG_GET_RGB( 91, 131, 216));
660 Set_Color(14, SG_GET_RGB( 75, 115, 198));
661 Set_Color(15, SG_GET_RGB( 58, 99, 180));
662 Set_Color(16, SG_GET_RGB( 42, 83, 184));
663 Set_Color(17, SG_GET_RGB( 26, 066, 188));
664 Set_Color(18, SG_GET_RGB( 26, 046, 180));
665 Set_Color(19, SG_GET_RGB( 26, 026, 166));
666 Set_Color(20, SG_GET_RGB( 38, 18, 151));
667 Set_Color(21, SG_GET_RGB( 50, 010, 131));
668 break;
669
670 case SG_COLORS_ASPECT_1:
671 Set_Count(5);
672 Set_Color(0, SG_GET_RGB(225, 225, 225));
673 Set_Color(1, SG_GET_RGB(127, 127, 255));
674 Set_Color(2, SG_GET_RGB( 20, 20, 20));
675 Set_Color(3, SG_GET_RGB(127, 255, 127));
676 Set_Color(4, SG_GET_RGB(225, 225, 225));
677 break;
678
679 case SG_COLORS_ASPECT_2:
680 Set_Count(5);
681 Set_Color(0, SG_GET_RGB(225, 225, 225));
682 Set_Color(1, SG_GET_RGB(255, 127, 127));
683 Set_Color(2, SG_GET_RGB( 20, 20, 20));
684 Set_Color(3, SG_GET_RGB(127, 255, 127));
685 Set_Color(4, SG_GET_RGB(225, 225, 225));
686 break;
687
688 case SG_COLORS_ASPECT_3:
689 Set_Count(5);
690 Set_Color(0, SG_GET_RGB(225, 225, 225));
691 Set_Color(1, SG_GET_RGB(255, 127, 127));
692 Set_Color(2, SG_GET_RGB( 20, 20, 20));
693 Set_Color(3, SG_GET_RGB(127, 127, 255));
694 Set_Color(4, SG_GET_RGB(225, 225, 225));
695 break;
696
697 case SG_COLORS_COUNT + 0:
698 Set_Count(3);
699 Set_Color(0, SG_GET_RGB( 0, 128, 0));
700 Set_Color(1, SG_GET_RGB(255, 255, 127));
701 Set_Color(2, SG_GET_RGB(127, 63, 63));
702 break;
703
704 case SG_COLORS_COUNT + 1:
705 Set_Count(3);
706 Set_Color(0, SG_GET_RGB( 0, 0, 255));
707 Set_Color(1, SG_GET_RGB(255, 255, 0));
708 Set_Color(2, SG_GET_RGB(255, 0, 0));
709 break;
710
711 case SG_COLORS_COUNT + 2:
712 Set_Count(3);
713 Set_Color(0, SG_GET_RGB( 0, 127, 0));
714 Set_Color(1, SG_GET_RGB(255, 255, 255));
715 Set_Color(2, SG_GET_RGB(255, 0, 0));
716 break;
717
718 case SG_COLORS_COUNT + 3:
719 Set_Count(3);
720 Set_Color(0, SG_GET_RGB( 0, 0, 255));
721 Set_Color(1, SG_GET_RGB(255, 255, 255));
722 Set_Color(2, SG_GET_RGB( 0, 127, 0));
723 break;
724
725 case SG_COLORS_COUNT + 4:
726 Set_Count(4);
727 Set_Color(0, SG_GET_RGB( 0, 0, 255));
728 Set_Color(1, SG_GET_RGB( 0, 255, 0));
729 Set_Color(2, SG_GET_RGB(255, 255, 0));
730 Set_Color(3, SG_GET_RGB(255, 0, 0));
731 break;
732
733 case SG_COLORS_COUNT + 5:
734 Set_Count(11);
735 Set_Color( 0, SG_GET_RGB( 37, 57, 175));
736 Set_Color( 1, SG_GET_RGB( 40, 127, 251));
737 Set_Color( 2, SG_GET_RGB( 50, 190, 255));
738 Set_Color( 3, SG_GET_RGB(106, 235, 255));
739 Set_Color( 4, SG_GET_RGB(138, 236, 174));
740 Set_Color( 5, SG_GET_RGB(205, 255, 162));
741 Set_Color( 6, SG_GET_RGB(240, 236, 121));
742 Set_Color( 7, SG_GET_RGB(255, 189, 87));
743 Set_Color( 8, SG_GET_RGB(255, 161, 68));
744 Set_Color( 9, SG_GET_RGB(255, 186, 133));
745 Set_Color(10, SG_GET_RGB(255, 255, 255));
746 break;
747
748 case SG_COLORS_COUNT + 6:
749 Set_Count(8);
750 Set_Color(0, SG_GET_RGB(171, 43, 0));
751 Set_Color(1, SG_GET_RGB(255, 127, 0));
752 Set_Color(2, SG_GET_RGB(255, 255, 0));
753 Set_Color(3, SG_GET_RGB( 0, 255, 0));
754 Set_Color(4, SG_GET_RGB( 0, 255, 255));
755 Set_Color(5, SG_GET_RGB( 0, 0, 255));
756 Set_Color(6, SG_GET_RGB(255, 0, 255));
757 Set_Color(7, SG_GET_RGB(255, 255, 255));
758 break;
759
760 case SG_COLORS_COUNT + 7:
761 Set_Count(5);
762 Set_Color(0, SG_GET_RGB( 0, 0, 191));
763 Set_Color(1, SG_GET_RGB(255, 0, 255));
764 Set_Color(2, SG_GET_RGB(255, 0, 0));
765 Set_Color(3, SG_GET_RGB(255, 255, 0));
766 Set_Color(4, SG_GET_RGB(245, 245, 163));
767 break;
768
769 case SG_COLORS_COUNT + 8:
770 Set_Count(6);
771 Set_Color(0, SG_GET_RGB(127, 255, 255));
772 Set_Color(1, SG_GET_RGB( 0, 0, 255));
773 Set_Color(2, SG_GET_RGB(127, 0, 255));
774 Set_Color(3, SG_GET_RGB(255, 0, 0));
775 Set_Color(4, SG_GET_RGB(255, 255, 0));
776 Set_Color(5, SG_GET_RGB(255, 255, 127));
777 break;
778
779 case SG_COLORS_COUNT + 9:
780 Set_Count(5);
781 Set_Color(0, SG_GET_RGB( 0, 0, 127));
782 Set_Color(1, SG_GET_RGB( 0, 127, 255));
783 Set_Color(2, SG_GET_RGB( 0, 191, 0));
784 Set_Color(3, SG_GET_RGB(191, 255, 0));
785 Set_Color(4, SG_GET_RGB(255, 255, 127));
786 break;
787
788 case SG_COLORS_COUNT + 10:
789 Set_Count(nColors);
790 Random();
791 break;
792
793 default:
794 return( false );
795 }
796
797 //-----------------------------------------------------
798 if( bRevert )
799 {
800 Revert();
801 }
802
803 return( Set_Count(nColors) );
804 }
805
806 //---------------------------------------------------------
Set_Default(int nColors)807 bool CSG_Colors::Set_Default(int nColors)
808 {
809 if( nColors > 0 )
810 {
811 m_nColors = nColors;
812 m_Colors = (long *)SG_Realloc(m_Colors, m_nColors * sizeof(long));
813
814 double d = 0., dStep = 2. * M_PI / (double)Get_Count();
815
816 for(int i=0; i<Get_Count(); i++, d+=dStep)
817 {
818 Set_Color(i,
819 (int)(d < M_PI / 2 ? 0 : 128 - 127 * sin(M_PI - d)),
820 (int)(128 - 127 * cos(d)),
821 (int)(d > M_PI * 3 / 2 ? 0 : 128 + 127 * sin(d))
822 );
823 }
824
825 return( true );
826 }
827
828 return( false );
829 }
830
831 //---------------------------------------------------------
Set_Ramp(long Color_A,long Color_B)832 bool CSG_Colors::Set_Ramp(long Color_A, long Color_B)
833 {
834 return( Set_Ramp(Color_A, Color_B, 0, Get_Count() - 1) );
835 }
836
837 //---------------------------------------------------------
Set_Ramp(long Color_A,long Color_B,int iColor_A,int iColor_B)838 bool CSG_Colors::Set_Ramp(long Color_A, long Color_B, int iColor_A, int iColor_B)
839 {
840 if( iColor_A > iColor_B )
841 {
842 int i = iColor_A;
843 iColor_A = iColor_B;
844 iColor_B = i;
845 }
846
847 if( iColor_A < 0 )
848 {
849 iColor_A = 0;
850 }
851
852 if( iColor_B >= Get_Count() )
853 {
854 iColor_B = Get_Count() - 1;
855 }
856
857 //-----------------------------------------------------
858 int n = iColor_B - iColor_A;
859
860 if( n > 0 )
861 {
862 int ar = SG_GET_R(Color_A);
863 double dr = (double)(SG_GET_R(Color_B) - ar) / (double)n;
864
865 int ag = SG_GET_G(Color_A);
866 double dg = (double)(SG_GET_G(Color_B) - ag) / (double)n;
867
868 int ab = SG_GET_B(Color_A);
869 double db = (double)(SG_GET_B(Color_B) - ab) / (double)n;
870
871 for(int i=0; i<=n; i++)
872 {
873 Set_Color(iColor_A + i,
874 (int)(ar + i * dr),
875 (int)(ag + i * dg),
876 (int)(ab + i * db)
877 );
878 }
879
880 return( true );
881 }
882
883 return( false );
884 }
885
886 //---------------------------------------------------------
Set_Ramp_Brighness(int Brightness_A,int Brightness_B)887 bool CSG_Colors::Set_Ramp_Brighness(int Brightness_A, int Brightness_B)
888 {
889 return( Set_Ramp_Brighness(Brightness_A, Brightness_B, 0, Get_Count() - 1) );
890 }
891
892 //---------------------------------------------------------
Set_Ramp_Brighness(int Brightness_A,int Brightness_B,int iColor_A,int iColor_B)893 bool CSG_Colors::Set_Ramp_Brighness(int Brightness_A, int Brightness_B, int iColor_A, int iColor_B)
894 {
895 if( iColor_A > iColor_B )
896 {
897 int i = iColor_A;
898 iColor_A = iColor_B;
899 iColor_B = i;
900 }
901
902 if( iColor_A < 0 )
903 {
904 iColor_A = 0;
905 }
906
907 if( iColor_B >= Get_Count() )
908 {
909 iColor_B = Get_Count() - 1;
910 }
911
912 //-----------------------------------------------------
913 int n = iColor_B - iColor_A;
914
915 if( n > 0 )
916 {
917 double dBrightness = (double)(Brightness_B - Brightness_A) / (double)n;
918
919 for(int i=0; i<=n; i++)
920 {
921 Set_Brightness(iColor_A + i, (int)(Brightness_A + i * dBrightness));
922 }
923
924 return( true );
925 }
926
927 return( false );
928 }
929
930
931 ///////////////////////////////////////////////////////////
932 // //
933 ///////////////////////////////////////////////////////////
934
935 //---------------------------------------------------------
Random(void)936 bool CSG_Colors::Random(void)
937 {
938 for(int i=0; i<Get_Count(); i++)
939 {
940 Set_Color(i,
941 (int)(255.0 * (double)rand() / (double)RAND_MAX),
942 (int)(255.0 * (double)rand() / (double)RAND_MAX),
943 (int)(255.0 * (double)rand() / (double)RAND_MAX)
944 );
945 }
946
947 return( Get_Count() > 0 );
948 }
949
950 //---------------------------------------------------------
Invert(void)951 bool CSG_Colors::Invert(void)
952 {
953 for(int i=0; i<Get_Count(); i++)
954 {
955 Set_Color(i, 255 - Get_Red(i), 255 - Get_Green(i), 255 - Get_Blue(i));
956 }
957
958 return( Get_Count() > 0 );
959 }
960
961 //---------------------------------------------------------
Revert(void)962 bool CSG_Colors::Revert(void)
963 {
964 for(int i=0, j=Get_Count()-1; i<j; i++, j--)
965 {
966 long c = Get_Color(j);
967 Set_Color(j, Get_Color(i));
968 Set_Color(i, c);
969 }
970
971 return( Get_Count() > 0 );
972 }
973
974 //---------------------------------------------------------
Greyscale(void)975 bool CSG_Colors::Greyscale(void)
976 {
977 for(int i=0; i<Get_Count(); i++)
978 {
979 long c = Get_Brightness(i);
980
981 Set_Color(i, c, c, c);
982 }
983
984 return( Get_Count() > 0 );
985 }
986
987
988 ///////////////////////////////////////////////////////////
989 // //
990 ///////////////////////////////////////////////////////////
991
992 //---------------------------------------------------------
operator =(const CSG_Colors & Colors)993 CSG_Colors & CSG_Colors::operator = (const CSG_Colors &Colors)
994 {
995 Create(Colors);
996
997 return( *this );
998 }
999
1000 //---------------------------------------------------------
Assign(const CSG_Colors & Colors)1001 bool CSG_Colors::Assign(const CSG_Colors &Colors)
1002 {
1003 return( Create(Colors) );
1004 }
1005
1006 //---------------------------------------------------------
Assign(CSG_Colors * pColors)1007 bool CSG_Colors::Assign(CSG_Colors *pColors)
1008 {
1009 return( pColors ? Create(*pColors) : false );
1010 }
1011
1012
1013 ///////////////////////////////////////////////////////////
1014 // //
1015 ///////////////////////////////////////////////////////////
1016
1017 //---------------------------------------------------------
1018 #define COLORS_SERIAL_VERSION_BINARY "SAGA_COLORPALETTE_VERSION_0.100_BINARY"
1019 #define COLORS_SERIAL_VERSION__ASCII "SAGA_COLORPALETTE_VERSION_0.100__ASCII"
1020
1021 //---------------------------------------------------------
Load(const CSG_String & File_Name)1022 bool CSG_Colors::Load(const CSG_String &File_Name)
1023 {
1024 CSG_File Stream;
1025
1026 if( !Stream.Open(File_Name, SG_FILE_R, true) )
1027 {
1028 return( false );
1029 }
1030
1031 CSG_String Version;
1032
1033 Stream.Read(Version, sizeof(COLORS_SERIAL_VERSION__ASCII));
1034
1035 //-----------------------------------------------------
1036 if( Version.Find(COLORS_SERIAL_VERSION__ASCII) == 0 )
1037 {
1038 return( Serialize(Stream, false, false) );
1039 }
1040
1041 //-----------------------------------------------------
1042 Stream.Seek_Start();
1043 Stream.Read(Version, sizeof(COLORS_SERIAL_VERSION_BINARY));
1044
1045 if( Version.Find(COLORS_SERIAL_VERSION_BINARY) == 0 )
1046 {
1047 int nColors;
1048
1049 Stream.Read(&nColors, sizeof(nColors));
1050
1051 if( Set_Count(nColors) ) // different os, different sizeof(long) !!
1052 {
1053 size_t ValueSize = (size_t)((Stream.Length() - (sizeof(COLORS_SERIAL_VERSION_BINARY) + sizeof(int))) / nColors);
1054
1055 if( ValueSize > 0 )
1056 {
1057 BYTE *c = (BYTE *)SG_Malloc(ValueSize);
1058
1059 for(int i=0; i<nColors; i++)
1060 {
1061 Stream.Read(c, ValueSize);
1062
1063 Set_Color(i, c[0], c[1], c[2]);
1064 }
1065
1066 SG_Free(c);
1067 }
1068
1069 return( true );
1070 }
1071 }
1072
1073 //-----------------------------------------------------
1074 else // SAGA 1.x compatibility...
1075 {
1076 short nColors;
1077
1078 Stream.Seek_Start();
1079 Stream.Read(&nColors, sizeof(short));
1080
1081 if( Stream.Length() == (int)(sizeof(short) + 3 * nColors) && Set_Count(nColors) )
1082 {
1083 BYTE *R = (BYTE *)SG_Malloc(nColors * sizeof(BYTE)); Stream.Read(R, nColors * sizeof(BYTE));
1084 BYTE *G = (BYTE *)SG_Malloc(nColors * sizeof(BYTE)); Stream.Read(G, nColors * sizeof(BYTE));
1085 BYTE *B = (BYTE *)SG_Malloc(nColors * sizeof(BYTE)); Stream.Read(B, nColors * sizeof(BYTE));
1086
1087 for(int i=0; i<nColors; i++)
1088 {
1089 Set_Color(i, R[i], G[i], B[i]);
1090 }
1091
1092 SG_Free(R); SG_Free(G); SG_Free(B);
1093
1094 return( true );
1095 }
1096 }
1097
1098 //-----------------------------------------------------
1099 return( false );
1100 }
1101
1102 //---------------------------------------------------------
Save(const CSG_String & File_Name,bool bBinary)1103 bool CSG_Colors::Save(const CSG_String &File_Name, bool bBinary)
1104 {
1105 CSG_File Stream;
1106
1107 if( Stream.Open(File_Name, SG_FILE_W, bBinary) )
1108 {
1109 if( bBinary )
1110 {
1111 Stream.Write((void *)COLORS_SERIAL_VERSION_BINARY, sizeof(COLORS_SERIAL_VERSION_BINARY));
1112 }
1113 else
1114 {
1115 Stream.Write(COLORS_SERIAL_VERSION__ASCII); Stream.Write("\n");
1116 }
1117
1118 Serialize(Stream, true, bBinary);
1119
1120 return( true );
1121 }
1122
1123 return( false );
1124 }
1125
1126
1127 ///////////////////////////////////////////////////////////
1128 // //
1129 ///////////////////////////////////////////////////////////
1130
1131 //---------------------------------------------------------
Serialize(CSG_File & Stream,bool bSave,bool bBinary)1132 bool CSG_Colors::Serialize(CSG_File &Stream, bool bSave, bool bBinary)
1133 {
1134 if( Stream.is_Open() )
1135 {
1136 //-------------------------------------------------
1137 if( bBinary )
1138 {
1139 if( bSave )
1140 {
1141 if( m_nColors > 0 )
1142 {
1143 Stream.Write(&m_nColors, sizeof(m_nColors));
1144 Stream.Write(m_Colors, sizeof(long), m_nColors);
1145 }
1146 }
1147 else
1148 {
1149 int nColors;
1150
1151 Stream.Read(&nColors, sizeof(m_nColors));
1152
1153 if( Set_Count(nColors) )
1154 {
1155 Stream.Read(m_Colors, sizeof(long), m_nColors);
1156 }
1157 }
1158
1159 return( true );
1160 }
1161
1162 //-------------------------------------------------
1163 else
1164 {
1165 if( bSave )
1166 {
1167 if( Get_Count() > 0 )
1168 {
1169 Stream.Printf("%d\n", Get_Count());
1170
1171 for(int i=0; i<Get_Count(); i++)
1172 {
1173 Stream.Printf("%03d %03d %03d\n", (int)Get_Red(i), (int)Get_Green(i), (int)Get_Blue(i));
1174 }
1175 }
1176 }
1177 else
1178 {
1179 CSG_String sLine;
1180
1181 while( Stream.Read_Line(sLine) && sLine.is_Empty() ) {} // skip empty lines
1182
1183 if( Set_Count(sLine.asInt()) )
1184 {
1185 for(int i=0; i<Get_Count(); i++)
1186 {
1187 Stream.Read_Line(sLine);
1188
1189 Set_Color(i,
1190 sLine .asInt(),
1191 sLine.AfterFirst(' ').asInt(),
1192 sLine.AfterLast (' ').asInt()
1193 );
1194 }
1195 }
1196 }
1197
1198 return( true );
1199 }
1200 }
1201
1202 return( false );
1203 }
1204
1205 //---------------------------------------------------------
to_Text(CSG_String & String)1206 bool CSG_Colors::to_Text(CSG_String &String)
1207 {
1208 if( Get_Count() > 0 )
1209 {
1210 String.Clear();
1211
1212 for(int i=0; i<Get_Count(); i++)
1213 {
1214 String += CSG_String::Format("%03d %03d %03d;", (int)Get_Red(i), (int)Get_Green(i), (int)Get_Blue(i));
1215 }
1216
1217 return( true );
1218 }
1219
1220 return( false );
1221 }
1222
1223 //---------------------------------------------------------
from_Text(const CSG_String & String)1224 bool CSG_Colors::from_Text(const CSG_String &String)
1225 {
1226 if( Set_Count((int)String.Length() / 12) )
1227 {
1228 for(int i=0, j=0; i<Get_Count(); i++, j+=12)
1229 {
1230 Set_Color(i,
1231 String.Mid(j + 0, 4).asInt(),
1232 String.Mid(j + 4, 4).asInt(),
1233 String.Mid(j + 8, 4).asInt()
1234 );
1235 }
1236
1237 return( true );
1238 }
1239
1240 return( false );
1241 }
1242
1243
1244 ///////////////////////////////////////////////////////////
1245 // //
1246 // //
1247 // //
1248 ///////////////////////////////////////////////////////////
1249
1250 //---------------------------------------------------------
1251