32 bit binärdaten spezifisch als rgb+x auswerten



  • ja und deine bitmask sieht anders aus:

    Willst du die Bits 24 - 16 auslesen dann: 0x00ff0000
    für die Bits 22-12 : 0x00ff6000

    Die shifts musst du dann anpassen aber nach dem was Du schreibst ist dieser Teil schon so gut wie verstanden 🙂



  • muli schrieb:

    ja und deine bitmask sieht anders aus:

    Willst du die Bits 24 - 16 auslesen dann: 0x00ff0000
    für die Bits 22-12 : 0x00ff6000

    Ich bin verwirrt. 10 bit sind 1024 Werte, in Hex wäre das 400, ff6 dagegen wäre 4096 = 12 bit.

    Müsste dann die Maske nicht eher so aussehen:

    32-22: 0x40000000
    22-12: 0x00400000
    12-10: 0x00001000

    Nicht das ich mit Hexzahlen gut umgehen könnte...



  • Also die Zahl die dadurch beschrieben wird ist nun erstmal irrelevant.

    Du hast bsw.: eine 32-bit wert mit deinen rgb werten der so aussieht:

    11110000111100001111000011110000 diese Zahl als hex ist die folgende 0xf0f0f0f0.

    So du willst jetzt die ersten 10 bits haben also machst du ein bitweises UND :

    11110000111100001111000011110000 // deine rgbx Werte
    &
    11111111110000000000000000000000 // und deine Maske 0xff600000
    ------------------------------------------
    das Ergebnis ist eine Zahl die dort eine 1 hat wo beide eine 1 haben und 0 sonnst.

    also bekommst du :
    11110000110000000000000000000000 das sind deine ersten 10 Bits.

    Dann der shift und du hast 1111000011 als dein Ergebnis.

    Die bei der Maske ist es wichtig die Einsen an der richtigen Stelle zu haben.
    und ff6 sind 10 einsen in Folge...



  • malen wirs doch mal auf:

    so sieht das in 10 bit aus (hab mal big und litte endian ignoriert)

    rrrr rrrr rrgg gggg gggg bbbb bbbb bbxx

    r: 1111 1111 1100 0000 0000 0000 0000 0000 hex: ffc00000
    g: 0000 0000 0011 1111 1111 0000 0000 0000 hex: 003ff000
    b: 0000 0000 0000 0000 0000 1111 1111 1100 hex: 00000ffc

    Jetzt sollen aus den 10-bit werten 8 bit werte werden, wo man erstmal definieren muß welche beiden bits wegfallen sollen (most oder least significant). Ich würde auf letzte tippen, also sähe das so aus:

    (zwischenwerte)

    r1 = wert & 0xff000000
    g1 = wert & 0x003fc000
    b1 = wert & 0x00000ff0

    Jetzt sollen die ja in r8g8b8x8 umgewandelt werden:

    rrrr rrrr gggg gggg bbbb bbbb xxxx xxxx
    also schieben wir:

    ergebnis = r1 | (g1 << 2) | (b1 << 4);

    Natürlich müste man jetzt noch big- und littel endian berücksichtigen...



  • muli schrieb:

    ff6 sind 10 einsen in Folge...

    Fast.

    f: 1111
    6: 0110 (2 + 4)

    ff6 = 1111 1111 0110



  • #include <cassert>
    
    template<int bits>
    struct rgb
    {
    	unsigned int r : bits;
    	unsigned int g : bits;
    	unsigned int b : bits;
    };
    
    int main()
    {
    	rgb<8> grau8bit;
    	grau8bit.r = 127;
    	grau8bit.g = 127;
    	grau8bit.b = 127;
    
    	assert(sizeof(grau8bit)== sizeof(int));
    
    	rgb<10> grau10bit;
    	grau10bit.r = 511;
    	grau10bit.g = 511;
    	grau10bit.b = 511;
    
    	assert(sizeof(grau10bit)== sizeof(int));
    	return 0;
    }}
    

    Gruß
    Drehleiter



  • Ok dann versuch ich es mal mit 'ffc' statt dessen 🙂



  • Drehleiter schrieb:

    template<int bits>
    struct rgb
    {
    	unsigned int r : bits;
    	unsigned int g : bits;
    	unsigned int b : bits;
    };
    

    Wie ist den diese Syntax zu verstehen? Gibt das Speicher mit exakt 'bits' Speicherbreite?



  • Google mal nach C++ und bitset

    Die Lösung von Drehleiter dürfte auf den meisten Rechnern funktionieren. Aber ich finde es besser, das alignment explizit zu machen.

    template<int bits, int offset>
    struct rgb
    {
        unsigned int r : bits;
        unsigned int g : bits;
        unsigned int b : bits;
        unsigned int x : offset;
    };
    
    int main()
    {
        rgb<8, 8> grau8bit; // rgbxrgbx
        grau8bit.r = 127;
        grau8bit.g = 127;
        grau8bit.b = 127;
    
        assert(sizeof(grau8bit)== sizeof(int));
    
        rgb<10, 2> grau10bit;
        grau10bit.r = 511;
        grau10bit.g = 511;
        grau10bit.b = 511;
    
        assert(sizeof(grau10bit)== sizeof(int));
        return 0;
    }}
    

    Aber Achtung: M.W. sind bitsets nicht sehr genau im Standard definiert, sprich: Vieles ist implementierungsabhänging. Das betrifft IIRC insbesondere das Alignment der einzelnen Elemente.



  • pospiech schrieb:

    Wie ist den diese Syntax zu verstehen? Gibt das Speicher mit exakt 'bits' Speicherbreite?

    Ja, das sind "bitfields". Aber das Layout ist nicht standardisiert und daher kannst du das so nicht portabel benutzen. Geh auf Nummer sicher: shift/and


Anmelden zum Antworten