Der Martin: (C) Was bedeutet (char *)?

Beitrag lesen

Hallo Markus,

Ist mir im Grunde genommen auch klar, aber dennoch weiß ich nicht ganz, was es im Code eigentlich bewirkt, wenn die dazugehörende Funktion, die ein Pixel am Bildschirm zeichnet, folgendermaßen aussieht:

void setpixel(SDL_Surface *surface, int x, int y, Uint8 R, Uint8 G, Uint8 B)

Scheint eine Funktion zu sein, die ein Pixel auf einen virtuellen Bildschirm pinselt.

int bbp = surface->format->BytesPerPixel;
Uint32 pixel = SDL_MapRGB(surface->format, R, G, B);
//pixaddr ist die Adresse zum Pixel, das wir setzen wollen
Uint8 *pixaddr = (Uint8 *)surface->pixels + y *surface->pitch + x * bbp;

Okay, pixaddr ist ein Zeiger auf die Position in den Bitmap-Daten, die dem gewünschten Pixel (X,Y) entspricht, und pixel enthält nun den zur gewünschten Farbe (R,G,B) gehörenden Farbwert.

switch (bbp)    {
{ case 1:
      *pixaddr = pixel;
      break;

case 2:
      *(Uint16 *)pixaddr = pixel;
      break;

case 4:
      *(Uint32 *)pixaddr = pixel;
      break;

Diese drei Fälle (1/2/4 Bytes pro Pixel) sind trivial. Es wird entweder ein Byte (pixaddr ist ja als Uint8 deklariert) oder ein Wort (Uint16) oder ein Doppelwort (Uint32) kopiert.

Desweiteren glaube ich sogar, dass die Verzweigung case 3 fehlerhaft ist. Es wird zwischen big endian, und offensichtlich little endian unterschieden, aber dennoch wird den Indizes 2 x dasselbe zugewiesen.

case 3: // langsamer 24-Bit-Modus, selten verwendet
      if (SDL_BYTEORDER==SDL_BIG_ENDIAN)
       { pixaddr[0] = (pixel >> 16) & 0xff;
         pixaddr[1] = (pixel >> 8) & 0xff;
         pixaddr[2] = pixel & 0xff;
       }
      else
       { pixaddr[2] = pixel & 0xff;
         pixaddr[1] = (pixel >> 8) & 0xff;
         pixaddr[0] = (pixel >> 16) & 0xff;
       }

Gut beobachtet. Dieser Abschnitt scheint tatsächlich fehlerhaft zu sein, es wird in beiden Zweigen dem Motorola-Format (MSB auf niedrigster Adresse) entsprechend kopiert. Auf einer Intel-CPU (LSB zuerst) käme Unsinn raus. In diesem Anwendungsbeispiel würden wohl die Rot- und Blaukanäle vertauscht.

Schönen Tag noch,

Martin