/*
License:
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Use:
Some usefull color code.
Author:
Unai Landa (unai_landa#eresmas·com)
Notes:
My english is really bad, I allready now that so dont tell me.
The original code was nice comented in spanish, but I translated this "on the fly" so I hope you can understand :-)
*/
// --------------------------------------------------------------------------------------------------------------------
// Some 565 Color space defines.
// --------------------------------------------------------------------------------------------------------------------
enum
{
COLORSPACE_565_RED_MASK = (0xF800),
COLORSPACE_565_GREEN_MASK = (0x07E0),
COLORSPACE_565_BLUE_MASK = (0x001F),
COLORSPACE_565_SATURATE_RED_BIT = (0x10000),
COLORSPACE_565_SATURATE_GREEN_BIT = (0x0800),
COLORSPACE_565_SATURATE_BLUE_BIT = (0x0020),
};
//----------------------------------------------------------------------------
// Some more defines
//----------------------------------------------------------------------------
enum
{
MAXIMO_NUM_BITS_COLOR = 6 ,
BITS_BAJOS = 5 ,
MASCARA_A =(COLORSPACE_565_GREEN_MASK) ,
MASCARA_B =(COLORSPACE_565_RED_MASK|COLORSPACE_565_BLUE_MASK) ,
MASCARA_SAT_A =(COLORSPACE_565_SATURATE_GREEN_BIT ) ,
MASCARA_SAT_B =(COLORSPACE_565_SATURATE_RED_BIT|COLORSPACE_565_SATURATE_BLUE_BIT) ,
MASCARA_A_TWICE =( ((COLORSPACE_565_RED_MASK|COLORSPACE_565_BLUE_MASK)<<16)|(COLORSPACE_565_GREEN_MASK<<0 )) ,
MASCARA_B_TWICE =( ((COLORSPACE_565_RED_MASK|COLORSPACE_565_BLUE_MASK)<<0 )|(COLORSPACE_565_GREEN_MASK<<16)) ,
MASCARA_SAT_A_TWICE =( ((COLORSPACE_565_SATURATE_RED_BIT|COLORSPACE_565_SATURATE_BLUE_BIT)<<(16-BITS_BAJOS))|(COLORSPACE_565_SATURATE_GREEN_BIT>>BITS_BAJOS) ) ,
MASCARA_SAT_B_TWICE =((((COLORSPACE_565_SATURATE_RED_BIT|COLORSPACE_565_SATURATE_BLUE_BIT) )|(COLORSPACE_565_SATURATE_GREEN_BIT<<16))<<(MAXIMO_NUM_BITS_COLOR-BITS_BAJOS) )
};
//----------------------------------------------------------------------
// Use: Adds two 565 colours with saturation and no lose.
// Returns: The added colour.
// Parameters: Two colours.
//----------------------------------------------------------------------
__inline unsigned GE_AddColors565( const unsigned c1, const unsigned c2)
{
// Separacion:
// SetUp:
unsigned t1_a = (c1 & MASCARA_A); // 0000__g1__
unsigned t2_a = (c2 & MASCARA_A); // 0000__g2__
unsigned t1_b = (c1 & MASCARA_B); // 0000r1__b1
unsigned t2_b = (c2 & MASCARA_B); // 0000r2__b2
// Suma_A:
// Suma_B:
t1_a = t2_a = t1_a + t2_a; // 00__gT__ * T means Total
t1_b = t2_b = t1_b + t2_b; // 00rT__bT
t2_a &= MASCARA_SAT_A; // 00_1____ *** 1 appears ONLY where saturation happened.
t2_b &= MASCARA_SAT_B; // 01___1__ *** 1 appears ONLY where saturation happened.
t2_a -= (t2_a>>MAXIMO_NUM_BITS_COLOR); // 00__11__ *** 1 appears ONLY where saturation happened.
t2_b -= (t2_b>>BITS_BAJOS); // 0011__11 *** 1 appears ONLY where saturation happened.
t1_a |= t2_a; // 00__gS__ * S means Saturated
t1_b |= t2_b; // 00rS__bS
// Comoposicion:
return(t1_a | t1_b);
}
//----------------------------------------------------------------------
// Use: Adds two 565 colours TWICE with saturation and no lose.
// Returns: The two added colours.
// Parameters: Four 565 colours, The first parameter colurs are added to the second parameter colours..
//----------------------------------------------------------------------
__inline unsigned GE_AddColors565Twice( const unsigned c1, const unsigned c2)
{
// Separacion:
// SetUp:
unsigned t1_a = (c1 & MASCARA_A_TWICE) >> BITS_BAJOS; // __R1__B1__g1
unsigned t2_a = (c2 & MASCARA_A_TWICE) >> BITS_BAJOS; // __R2__B2__g2
unsigned t1_b = (c1 & MASCARA_B_TWICE) << (MAXIMO_NUM_BITS_COLOR-BITS_BAJOS); // __G1__r1__b1
unsigned t2_b = (c2 & MASCARA_B_TWICE) << (MAXIMO_NUM_BITS_COLOR-BITS_BAJOS); // __G2__r2__b2
// Suma_A:
// Suma_B:
t1_a = t2_a = t1_a + t2_a; // __RT__BT__gT * T means Total
t1_b = t2_b = t1_b + t2_b; // __GT__rT__bT
t2_a &= MASCARA_SAT_A_TWICE; // _1___1___1__ *** 1 appears ONLY where saturation happened.
t2_b &= MASCARA_SAT_B_TWICE; // _1___1___1__ *** 1 appears ONLY where saturation happened.
t2_a -= (t2_a>>MAXIMO_NUM_BITS_COLOR); // __11__11__11 *** 1 appears ONLY where saturation happened.
t2_b -= (t2_b>>MAXIMO_NUM_BITS_COLOR); // __11__11__11 *** 1 appears ONLY where saturation happened.
t1_a |= t2_a; // __RSxxBSxxgS * S means Saturated
t1_b |= t2_b; // __GSxxrSxxbS * xx Garbage that appeared betwen the color components.
t1_a = (t1_a<<BITS_BAJOS) & (MASCARA_A_TWICE); // 11xx11xx11xx * Moves all to its correct place.
// 11__11__11__ * Cleans the space betwen components.
t1_b = (t1_b>>MAXIMO_NUM_BITS_COLOR-BITS_BAJOS) & (MASCARA_B_TWICE); // 11xx11xx11xx * Moves all to its correct place.
// __11__11__11 * Cleans the space betwen components.
// Comoposicion:
return(t1_a | t1_b);
}
//----------------------------------------------------------------------
// Use: Subs two 565 colours with saturation and no lose.
// Returns: The Sub colour.
// Parameters: Two colours.
//----------------------------------------------------------------------
__inline unsigned GE_SubColors565( unsigned c1, const unsigned c2)
{
// Separacion:
unsigned t1_a = (c1 & MASCARA_A) | MASCARA_SAT_A; // 0000_1g1__ // I set the bit so later I can check underflow.
unsigned t2_a = (c2 & MASCARA_A); // 0000__g2__
unsigned t1_b = (c1 & MASCARA_B) | MASCARA_SAT_B; // 0001r1_1b1 // I set the bit so later I can check underflow.
unsigned t2_b = (c2 & MASCARA_B); // 0000r2__b2
// Resta_A:
// Resta_B:
t1_a = t2_a = (t1_a - t2_a); // 00__gT__ * T means Total
t1_b = t2_b = (t1_b - t2_b); // 00rT__bT
t2_a &= (MASCARA_SAT_A); // 00_1____ I test sign change.
t2_b &= (MASCARA_SAT_B); // 01___1__ 1 appears ONLY where no underflow happened.
t2_a -= (t2_a>>MAXIMO_NUM_BITS_COLOR); // 00__11__ I create the 1filled mask on the colours the didn't underflow.
t2_b -= (t2_b>>BITS_BAJOS); // 0011__11
t1_a &= t2_a; // 00__gU__ * U means UnderFlow
t1_b &= t2_b; // 00rU__bU
// Comoposicion:
return(t1_a | t1_b);
}
//----------------------------------------------------------------------
// Use: Subs two 565 colours TWICE with saturation and no lose.
// Returns: The two added colours.
// Parameters: Four 565 colours, The second parameter colurs are sub from the first parameter colours..
//----------------------------------------------------------------------
__inline unsigned GE_SubColors565Twice( unsigned c1, const unsigned c2)
{
// Separacion:
// SetUp:
unsigned t1_a = ((c1 & MASCARA_A_TWICE) >> BITS_BAJOS) | MASCARA_SAT_A_TWICE; // _1R1_1B1_1g1
unsigned t2_a = ((c2 & MASCARA_A_TWICE) >> BITS_BAJOS); // __R2__B2__g2
unsigned t1_b = ((c1 & MASCARA_B_TWICE) << (MAXIMO_NUM_BITS_COLOR-BITS_BAJOS)) | MASCARA_SAT_B_TWICE; // _1G1_1r1_1b1
unsigned t2_b = ((c2 & MASCARA_B_TWICE) << (MAXIMO_NUM_BITS_COLOR-BITS_BAJOS)); // __G2__r2__b2
// Suma_A:
// Suma_B:
t1_a = t2_a = t1_a - t2_a; // __RT__BT__gT * T means Total
t1_b = t2_b = t1_b - t2_b; // __GT__rT__bT
t2_a &= MASCARA_SAT_A_TWICE; // _1___1___1__ *** 1 appears ONLY where no underflow happened.
t2_b &= MASCARA_SAT_B_TWICE; // _1___1___1__ *** 1 appears ONLY where no underflow happened.
t2_a -= (t2_a>>MAXIMO_NUM_BITS_COLOR); // __11__11__11 *** 1 appears ONLY where no underflow happened.
t2_b -= (t2_b>>MAXIMO_NUM_BITS_COLOR); // __11__11__11 *** 1 appears ONLY where no underflow happened.
t1_a &= t2_a; // __RUxxBUxxgU * U means Underflow
t1_b &= t2_b; // __GUxxrSxxbU * xx Garbage that appeared betwen the color components.
t1_a = (t1_a<<BITS_BAJOS) & (MASCARA_A_TWICE); // 11xx11xx11xx * Moves all to its correct place.
// 11__11__11__ * Cleans the space betwen components.
t1_b = (t1_b>>MAXIMO_NUM_BITS_COLOR-BITS_BAJOS) & (MASCARA_B_TWICE); // 11xx11xx11xx * Moves all to its correct place.
// __11__11__11 * Cleans the space betwen components.
// Comoposicion:
return(t1_a | t1_b);
}
//----------------------------------------------------------------------
// Use: Make a 32 levels alfa blend betwen two 565 colours.
// Returns: The blended colour.
// Parameters: iAlfa=0 Only c1 is set, iAlfa=32 only c2 is set
//----------------------------------------------------------------------
__inline unsigned GE_BlendColors565( const unsigned c1, const unsigned c2, int iAlfa)
{
unsigned ta = c1 & MASCARA_A; // 0000__g1__
unsigned tb = c2 & MASCARA_B; // 0000r2__b2
ta *= (32-iAlfa);
tb *= ( iAlfa);
ta += ( iAlfa) *(c2 & MASCARA_A); // 0000__g2__
tb += (32-iAlfa) *(c1 & MASCARA_B); // 0000r1__b1
ta = (ta>>BITS_BAJOS) & MASCARA_A;
ta += (tb>>BITS_BAJOS) & MASCARA_B;
return(ta);
}
//----------------------------------------------------------------------
// Use: Make a 32 levels alfa blend betwen two 565 colours TWICE
// Returns: The two blended colours.
// Parameters: iAlfa=0 Only c1 is set, iAlfa=32 only c2 is set
// c1; two 565 Colours thar will blend with c2 that contains anothe two 565 colours.
//----------------------------------------------------------------------
__inline unsigned GE_BlendColors565Twice( const unsigned c1, const unsigned c2, int iAlfa)
{
unsigned ta = (c1 & MASCARA_A_TWICE)>>BITS_BAJOS; // __R1__B1__g1
unsigned tb = (c1 & MASCARA_B_TWICE); // __G1__r1__b1
ta *= (32-iAlfa);
tb *= (32-iAlfa);
ta += iAlfa *((c2 & MASCARA_A_TWICE)>>(BITS_BAJOS)); // __R2__B2__g2
tb += iAlfa * (c2 & MASCARA_B_TWICE); // __G2__r2__b2
ta &= MASCARA_A_TWICE; // R2__B2__g2__
ta += (tb>>BITS_BAJOS) & MASCARA_B_TWICE; // __G2__r2__b2
return(ta);
}
|