Ok, dann nochmal langsam.
SDL verwendet zur Farbdarstellung (wie du sicher weißt) das RGB-Farbsystem. In diesem System werden die Farben Rot, Grün und Blau durch jeweils 1 Byte (8 Bit -> 2^8 = 256 verschiedene Werte) dargestellt. Insgesamt sind das also 3 * 8 Bit pro Pixel (eventuell hast du noch einen Alpha-Channel, dann wären es 4 * 8, aber das vernachlässige ich an dieser Stelle).
Auf älteren oder exotischeren Geräten kannst du aber vielleicht nur 2^16 (65.636) Farben darstellen. In diesem Fall musst du also deine 24 Bit auf 16 zusammenfassen. Natürlich ist das nicht verlustfrei möglich, dabei gehen Informationen verloren. Logischerweise interessieren dich die höherwertigen Bits mehr als die niederwertigen, also werden letztere bevorzugt weggelassen. Du musst nun also deine 3 * 8 Bit zu 16 Bit zusammenfassen. Dabei bekommt Rot üblicherweise die höchsten 5 Bit, Blau die niederwertigsten 5 Bit und Grün die 6 Bit in der Mitte. Die Struktur sieht also so aus: RRRRRGGGGGGBBBBB
Jetzt weißt du wie du Daten hinbekommen willst, aber nicht wie du sie in diesen Zustand bekommst.
Sieh dir folgendes Programm an:
Code: Alles auswählen
#include <SDL/SDL.h>
#include <stdio.h>
int main()
{
SDL_Init( SDL_INIT_VIDEO );
SDL_Surface *screen = SDL_SetVideoMode( 640, 480, 16, SDL_SWSURFACE );
SDL_PixelFormat *format = screen->format;
printf( "bitsperpixel: %d\n", format->BitsPerPixel );
printf( "rmask: %d rloss: %d rshift: %d\n", format->Rmask, format->Rloss, format->Rshift );
printf( "gmask: %d gloss: %d gshift: %d\n", format->Gmask, format->Gloss, format->Gshift );
printf( "bmask: %d bloss: %d bshift: %d\n", format->Bmask, format->Bloss, format->Bshift );
SDL_Quit();
return 0;
}
Ausgabe:
bitsperpixel: 16
rmask: 63488 rloss: 3 rshift: 11
gmask: 2016 gloss: 2 gshift: 5
bmask: 31 bloss: 3 bshift: 0
Wandelst du deine Masken binär um, erkennst du das obige Muster.
Code: Alles auswählen
63488 = 1111100000000000
2016 = 0000011111100000
31 = 0000000000011111
Es stehen genau dort Einsen, wo die Bits der entsprechenden Farbe hin sollen.
loss gibt dir an wie viele Bits du verlierst. Für Rot hast du 5 Bit zur Verfügung. Also verlierst du von den ursprünglichen 8 genau die 3 niederwertigsten. Bei Blau ist es genau das gleiche. Grün hat ein Bit mehr zur Verfügung, deswegen verlierst du auch eines weniger. Um diesen loss-Wert werden die Bits deiner ursprünglichen 8 Bit Darstellung nach rechts verschoben, um sie auf das neue Format zu kürzen.
shift gibt an wie weit du deine Bits nach links verschieben musst, um sie an der in deiner Maske mit Einsen angegebenen Stellen zu platzieren.
Um den Zusammenhang nochmal deutlich zu machen, noch die Erklärung wie du von deiner Maske auf loss und shift zurückrechnest:
Du schiebst nun einfach deine Maske so lang nach rechts, bis du eine 1 an der niederwertigsten Stelle hast. Dann weißt du, wie weit du deinen gekürzten Wert nach links verschieben musstest, um ihn an die richtige Position zu bekommen. Die Maske hat ja nur dort gesetzte Bits, wo die entsprechende Farbe hin soll.
Wenn du jetzt weiter nach rechts shiftest und zählst wie viele Einsen du im Muster hattest (du shiftest also bis du an der niedrigsten Stelle eine 0 hast), dann weißt du wie viele Bits die jeweilige Farbe in deinem neuen Format zu Verfügung hat. Dein loss ist dann die ursprüngliche Anzahl an Bits (normalerweise 8), abzüglich der im neuen Format vorhandenen Bits. Im obigen Beispiel sind das für Rot 3, weil du ursprünglich 8 Bit hattest, im neuen Format aber nur mehr 5, also gingen 3 verloren.
Eine ähnliche (allgemeinere) Erklärung findest du hier:
http://www.proggen.org/doku.php?id=c:article:shiftops
Ich hoffe das war verständlich
Noch Fragen?