<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Fragen zu Windows Bitmap einlesen #2]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe ein ähnliches Thema vor Monaten eröffnet, eine Riesenpause gemacht und mich die Sache nun wieder abgenommen. Zum besseren Verständnis zeige ich den damaligen Eingangsbeitrag.<br />
<a href="https://www.c-plusplus.net/forum/335804">https://www.c-plusplus.net/forum/335804</a><br />
Der alte Thread uferte etwas zu einer Grundsatzdiskussion aus, deshalb dieser neue.</p>
<blockquote>
<p>Hallo,</p>
<p>ich möchte damit anfangen, kleine einfache Bilder zu verarbeiten. Als Format habe ich mir Windows Bitmap ausgewählt.</p>
<p>Um da besser durchzusteigen, will ich die Bytes der Datei erst mal nur ausgeben. Beschränke mich zum Anfang aber nur auf den Kopf und die Eigenschaften. Denn dort fangen schon genug Fragen an.</p>
<p>Als Grundlage habe ich den entsprechenden wiki-Artikel genommen.</p>
<p><a href="https://de.wikipedia.org/" rel="nofollow">https://de.wikipedia.org/</a> ....... teiformat_.28Version_3.29</p>
<pre><code>struct Head
{
    static const int Size = 4;
    std::array &lt;std::string, Size&gt; bName {{ &quot;bfType&quot;, &quot;bfSize&quot;, &quot;bfReserved&quot;, &quot;bfOffbits&quot; }};
    std::array &lt;int, Size&gt; bName_size {{ 2,4,4,4, }};
}head;
 
struct Info
{
    static const int Size = 11;
    std::array &lt;std::string, Size&gt; bName {{ &quot;biSize&quot;, &quot;biWidth&quot;, &quot;biHeight&quot;, &quot;biPlanes&quot;, &quot;biBitCount&quot;, &quot;biCompression&quot;, &quot;biSizeImage&quot;, &quot;biXPelsPerMeter&quot;, &quot;biYPelsPerMeter&quot;, &quot;biClrUsed&quot;, &quot;biClrImportant&quot; }};
    std::array &lt;int, Size&gt; bName_size {{ 4,4,4,2,2, 4,4,4,4,4,4 }};
}info;
 
struct dummy //nur ein dummy-struct für spätere Inhalte
{
    std::vector &lt;char&gt; dValue;
};
 
 
 
int main()
{
 
 
    std::vector &lt;char&gt; picmap;
    char byte;
    size_t offset = 0;
 
    std::string file_name = &quot;WOLKEN.bmp&quot;;
    std::ifstream file (file_name.c_str(), std::ios::binary|std::ios::in);
    while (file.get(byte)) picmap.push_back(byte);
 
 
    std::cout &lt;&lt; &quot;_Head_&quot; &lt;&lt; '\n';
    for (int i=0; i&lt;head.Size; i++)
    {
        std::cout &lt;&lt; '#' &lt;&lt; std::dec &lt;&lt; offset &lt;&lt; &quot;  &quot; &lt;&lt; head.bName.at(i) &lt;&lt; std::setw(11);
        for (int j=0; j&lt;head.bName_size.at(i); j++)
        {
            std::cout &lt;&lt; std::hex &lt;&lt; int(picmap.at(offset)) &lt;&lt; ' ';
            offset ++;
        }
        std::cout &lt;&lt; '\n';
    }
 
    std::cout &lt;&lt; '\n' &lt;&lt; &quot;_Info_&quot; &lt;&lt; '\n';
    for (int i=0; i&lt;info.Size; i++)
    {
        std::cout &lt;&lt; '#' &lt;&lt; std::dec &lt;&lt; offset &lt;&lt; &quot;  &quot; &lt;&lt; info.bName.at(i) &lt;&lt; std::setw(11);
        for (int j=0; j&lt;info.bName_size.at(i); j++)
        {
            std::cout &lt;&lt; std::hex &lt;&lt; int(picmap.at(offset)) &lt;&lt; ' ';
            offset ++;
        }
        std::cout &lt;&lt; '\n';
    }
 
 
}
</code></pre>
<p>Nun meine Fragen:</p>
<p>1 - ist es möglich die structs zu etwas größeren zusammenzufassen? Habe etwas über struct in einem struct nachgeschlagen, wollte aber wissen, ob es etwas besseres gibt.</p>
<p>2 - Ich wollte setw() für einen übersichtlichen Ausdruck nehmen, nur funktioniert das nicht, wie ich mir das vorstelle.<br />
<a href="http://abload.de/image.php?img=unbenanntfnou7.png" rel="nofollow">http://abload.de/image.php?img=unbenanntfnou7.png</a><br />
Wie macht man das korrekt?</p>
<p>3 - Zum Einlesen eines Byte habe ich ein char genommen, nur frage ich mich, ob das korrekt ist, oder was man da besser nimmt?</p>
<p>4 - Wo und wie müsste ich eventuelle Kommentare setzen, damit ein geneigter Helfer schneller den Code überblicken kann? Bei zB Zeile 32 'Bytes der Datei in vector einlesen' stelle ich mir überflüssig vor?</p>
<p>Es würden zu dem Code noch weitere kleine Fragen kommen, würde aber gerne erst die oberen Punkte abhaken.</p>
</blockquote>
<p>Ich bin ein relativ großes Stück weiter gekommen. Die formatierte Ausgabe steht (auch wenn sie nur ein Übergang darstellt, später wird sie nicht mehr benötigt) und ich kann gut die Farbtabelle bearbeiten.</p>
<p>Zur Erinnerung nochmal der entsprechende Wiki-Artikel, den ich als Grundlage genommen habe.</p>
<p><a href="https://de.wikipedia.org/wiki/Windows_Bitmap#Dateiformat_.28Version_3.29" rel="nofollow">https://de.wikipedia.org/wiki/Windows_Bitmap#Dateiformat_.28Version_3.29</a></p>
<p>Bei den Bilddaten aber stoße ich auf ein Verständnisproblem. Es geht um <code>biHeight</code></p>
<blockquote>
<p>Die Bilddaten werden Zeile für Zeile gespeichert. Wenn biHeight positiv ist, beginnen die Bilddaten mit der letzten und enden mit der ersten Bildzeile, ansonsten ist es umgekehrt.</p>
</blockquote>
<p>Ich weiß nicht, wie ich in den eingelesenen Werten einen negativen Wert erkennen und darstellen kann?</p>
<p>Einlesen tue ich sie so:</p>
<pre><code>std::vector &lt;char&gt; picmap;
    //std::vector &lt;uint8_t&gt; bytes_vec; //spätere Verwendung
    char s_char;
    uint8_t byte; //wird später als &lt;byte = picmap.at(offset);&gt; verwendet
    std::size_t offset = 0;

    std::string file_ = &quot;test&quot;;
    std::string file_name = file_ + &quot;.bmp&quot;;
    std::ifstream file (file_name.c_str(), std::ios::binary);
    if (!file)
    {
        std::cout &lt;&lt; &quot;fehlende Datei!&quot; &lt;&lt; '\n';
        return 0;
    }
    while (file.get(s_char)) picmap.push_back(s_char);
    std::cout &lt;&lt; &quot;_File: &quot; &lt;&lt; file_name &lt;&lt; '\n';
</code></pre>
<p>Bisher verstehe ich das so, das dort irgendwo ein seltsamer Wert sein muss, weil ich den Umweg über ein <code>signed char</code> nehmen muss. Ansonsten gibts in der Nähe des Wertes, der negativ sein könnte einen Fehler. Durch den späteren Cast zu <code>uint8_t</code> gibt es im Ausdruck dann aber keine Unregelmäßigkeiten.</p>
<p>Wie mache ich das also mit einem eventuell negativen Wert? Ich hoffe, der gesamte Beitrag ist trotzdem einigermaßen verständlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/337838/fragen-zu-windows-bitmap-einlesen-2</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 01:04:33 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/337838.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 03 May 2016 16:26:50 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Tue, 03 May 2016 16:26:50 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe ein ähnliches Thema vor Monaten eröffnet, eine Riesenpause gemacht und mich die Sache nun wieder abgenommen. Zum besseren Verständnis zeige ich den damaligen Eingangsbeitrag.<br />
<a href="https://www.c-plusplus.net/forum/335804">https://www.c-plusplus.net/forum/335804</a><br />
Der alte Thread uferte etwas zu einer Grundsatzdiskussion aus, deshalb dieser neue.</p>
<blockquote>
<p>Hallo,</p>
<p>ich möchte damit anfangen, kleine einfache Bilder zu verarbeiten. Als Format habe ich mir Windows Bitmap ausgewählt.</p>
<p>Um da besser durchzusteigen, will ich die Bytes der Datei erst mal nur ausgeben. Beschränke mich zum Anfang aber nur auf den Kopf und die Eigenschaften. Denn dort fangen schon genug Fragen an.</p>
<p>Als Grundlage habe ich den entsprechenden wiki-Artikel genommen.</p>
<p><a href="https://de.wikipedia.org/" rel="nofollow">https://de.wikipedia.org/</a> ....... teiformat_.28Version_3.29</p>
<pre><code>struct Head
{
    static const int Size = 4;
    std::array &lt;std::string, Size&gt; bName {{ &quot;bfType&quot;, &quot;bfSize&quot;, &quot;bfReserved&quot;, &quot;bfOffbits&quot; }};
    std::array &lt;int, Size&gt; bName_size {{ 2,4,4,4, }};
}head;
 
struct Info
{
    static const int Size = 11;
    std::array &lt;std::string, Size&gt; bName {{ &quot;biSize&quot;, &quot;biWidth&quot;, &quot;biHeight&quot;, &quot;biPlanes&quot;, &quot;biBitCount&quot;, &quot;biCompression&quot;, &quot;biSizeImage&quot;, &quot;biXPelsPerMeter&quot;, &quot;biYPelsPerMeter&quot;, &quot;biClrUsed&quot;, &quot;biClrImportant&quot; }};
    std::array &lt;int, Size&gt; bName_size {{ 4,4,4,2,2, 4,4,4,4,4,4 }};
}info;
 
struct dummy //nur ein dummy-struct für spätere Inhalte
{
    std::vector &lt;char&gt; dValue;
};
 
 
 
int main()
{
 
 
    std::vector &lt;char&gt; picmap;
    char byte;
    size_t offset = 0;
 
    std::string file_name = &quot;WOLKEN.bmp&quot;;
    std::ifstream file (file_name.c_str(), std::ios::binary|std::ios::in);
    while (file.get(byte)) picmap.push_back(byte);
 
 
    std::cout &lt;&lt; &quot;_Head_&quot; &lt;&lt; '\n';
    for (int i=0; i&lt;head.Size; i++)
    {
        std::cout &lt;&lt; '#' &lt;&lt; std::dec &lt;&lt; offset &lt;&lt; &quot;  &quot; &lt;&lt; head.bName.at(i) &lt;&lt; std::setw(11);
        for (int j=0; j&lt;head.bName_size.at(i); j++)
        {
            std::cout &lt;&lt; std::hex &lt;&lt; int(picmap.at(offset)) &lt;&lt; ' ';
            offset ++;
        }
        std::cout &lt;&lt; '\n';
    }
 
    std::cout &lt;&lt; '\n' &lt;&lt; &quot;_Info_&quot; &lt;&lt; '\n';
    for (int i=0; i&lt;info.Size; i++)
    {
        std::cout &lt;&lt; '#' &lt;&lt; std::dec &lt;&lt; offset &lt;&lt; &quot;  &quot; &lt;&lt; info.bName.at(i) &lt;&lt; std::setw(11);
        for (int j=0; j&lt;info.bName_size.at(i); j++)
        {
            std::cout &lt;&lt; std::hex &lt;&lt; int(picmap.at(offset)) &lt;&lt; ' ';
            offset ++;
        }
        std::cout &lt;&lt; '\n';
    }
 
 
}
</code></pre>
<p>Nun meine Fragen:</p>
<p>1 - ist es möglich die structs zu etwas größeren zusammenzufassen? Habe etwas über struct in einem struct nachgeschlagen, wollte aber wissen, ob es etwas besseres gibt.</p>
<p>2 - Ich wollte setw() für einen übersichtlichen Ausdruck nehmen, nur funktioniert das nicht, wie ich mir das vorstelle.<br />
<a href="http://abload.de/image.php?img=unbenanntfnou7.png" rel="nofollow">http://abload.de/image.php?img=unbenanntfnou7.png</a><br />
Wie macht man das korrekt?</p>
<p>3 - Zum Einlesen eines Byte habe ich ein char genommen, nur frage ich mich, ob das korrekt ist, oder was man da besser nimmt?</p>
<p>4 - Wo und wie müsste ich eventuelle Kommentare setzen, damit ein geneigter Helfer schneller den Code überblicken kann? Bei zB Zeile 32 'Bytes der Datei in vector einlesen' stelle ich mir überflüssig vor?</p>
<p>Es würden zu dem Code noch weitere kleine Fragen kommen, würde aber gerne erst die oberen Punkte abhaken.</p>
</blockquote>
<p>Ich bin ein relativ großes Stück weiter gekommen. Die formatierte Ausgabe steht (auch wenn sie nur ein Übergang darstellt, später wird sie nicht mehr benötigt) und ich kann gut die Farbtabelle bearbeiten.</p>
<p>Zur Erinnerung nochmal der entsprechende Wiki-Artikel, den ich als Grundlage genommen habe.</p>
<p><a href="https://de.wikipedia.org/wiki/Windows_Bitmap#Dateiformat_.28Version_3.29" rel="nofollow">https://de.wikipedia.org/wiki/Windows_Bitmap#Dateiformat_.28Version_3.29</a></p>
<p>Bei den Bilddaten aber stoße ich auf ein Verständnisproblem. Es geht um <code>biHeight</code></p>
<blockquote>
<p>Die Bilddaten werden Zeile für Zeile gespeichert. Wenn biHeight positiv ist, beginnen die Bilddaten mit der letzten und enden mit der ersten Bildzeile, ansonsten ist es umgekehrt.</p>
</blockquote>
<p>Ich weiß nicht, wie ich in den eingelesenen Werten einen negativen Wert erkennen und darstellen kann?</p>
<p>Einlesen tue ich sie so:</p>
<pre><code>std::vector &lt;char&gt; picmap;
    //std::vector &lt;uint8_t&gt; bytes_vec; //spätere Verwendung
    char s_char;
    uint8_t byte; //wird später als &lt;byte = picmap.at(offset);&gt; verwendet
    std::size_t offset = 0;

    std::string file_ = &quot;test&quot;;
    std::string file_name = file_ + &quot;.bmp&quot;;
    std::ifstream file (file_name.c_str(), std::ios::binary);
    if (!file)
    {
        std::cout &lt;&lt; &quot;fehlende Datei!&quot; &lt;&lt; '\n';
        return 0;
    }
    while (file.get(s_char)) picmap.push_back(s_char);
    std::cout &lt;&lt; &quot;_File: &quot; &lt;&lt; file_name &lt;&lt; '\n';
</code></pre>
<p>Bisher verstehe ich das so, das dort irgendwo ein seltsamer Wert sein muss, weil ich den Umweg über ein <code>signed char</code> nehmen muss. Ansonsten gibts in der Nähe des Wertes, der negativ sein könnte einen Fehler. Durch den späteren Cast zu <code>uint8_t</code> gibt es im Ausdruck dann aber keine Unregelmäßigkeiten.</p>
<p>Wie mache ich das also mit einem eventuell negativen Wert? Ich hoffe, der gesamte Beitrag ist trotzdem einigermaßen verständlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494819</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494819</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Tue, 03 May 2016 16:26:50 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Tue, 03 May 2016 17:48:13 GMT]]></title><description><![CDATA[<p>Na, wenn ich den Wiki-Artikel beim schnellen Überfliegen richtig verstanden habe, steht biHeight bei Offset 22 einer bmp-Datei.<br />
Also positionierst Du Dich dort, liest einen int32_t ein, und prüfst, ob er positiv oder negativ ist?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494823</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494823</guid><dc:creator><![CDATA[Belli]]></dc:creator><pubDate>Tue, 03 May 2016 17:48:13 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Tue, 03 May 2016 18:02:33 GMT]]></title><description><![CDATA[<p>Naja, dies ist mir eben nicht so recht verständlich <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Das biHeight negativ sein könnte, scheint auch nicht mehr üblich zu sein. Ich habe momentan nur ein recht altes File, wo dies vorkommt und dort steht bei #22 <code>60 01 00 00</code> = 352, die korrekte Bildhöhe. Ich weiß nur aus früheren Versuchen, das dort in der Nähe noch ein <code>ff</code> aufgetaucht ist, was ich als negatives Vorzeichen gewertet habe.</p>
<p>Dies steht aber momentan nur so sauber da, weil die Werte schon zu uint8_t gecastet sind.</p>
<p>Ich befürchte, wenn ich die Werte wie im Artikel und wie Du es andeutest, also in diesem Fall als <code>int32_t</code> einlesen will, den Code recht umfangreich umschreiben muss. Ich wollte ja wegen der Ausgabe zum Verständnis wirklich nur die einzelnen Bytes in hexadezimaler Form (und die Umrechung in dezimaler Form) darstellen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494827</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494827</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Tue, 03 May 2016 18:02:33 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Tue, 03 May 2016 19:21:55 GMT]]></title><description><![CDATA[<p>*Quatsch*</p>
<p>- sorry, ich mache lieber morgen oder so weiter -</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494833</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494833</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Tue, 03 May 2016 19:21:55 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 00:43:45 GMT]]></title><description><![CDATA[<p>Also...<br />
Es gibt eine einfache Variante (die fast überall verwendet wird), und eine &quot;korrekte&quot; (die kaum jemand verwendet).</p>
<p>Die einfache verlässt sich darauf dass die Maschine two's complement verwendet (und die ganz einfache zusätzlich darauf dass sie little-endian verwendet).<br />
Dabei schnappst du dir die 4 Byte aus deinen vector und kopierst sie per <code>memcpy</code> in einen <code>int</code> .<br />
Wenn du Endianness Berücksichtigen willst, musst du statt <code>memcpy</code> eine eigene Funktion verwenden die auf little-endian einfach <code>memcpy</code> aufruft und auf big-endian Systemen &quot;rückwärts&quot; kopiert. Und halt Byteweise kopieren, also per <code>char*</code> bzw. <code>unsigned char*</code> .<br />
Und schon hast du deinen <code>signed int</code> .</p>
<p>Die &quot;korrekte&quot; Variante wäre dir aus den 4 Bytes per</p>
<pre><code class="language-cpp">vector&lt;unsigned char&gt; data;

...

uint32_t val = data[pos + 0]
   + (static_cast&lt;uint32_t&gt;(data[pos + 1]) &lt;&lt; 8)
   + (static_cast&lt;uint32_t&gt;(data[pos + 2]) &lt;&lt; 16)
   + (static_cast&lt;uint32_t&gt;(data[pos + 3]) &lt;&lt; 24);
</code></pre>
<p>erstmal ne unsigned Zahl zu basteln. Das sollte auf jeder Plattform so funktionieren, egal was für representation von Zahlen sie verwendet, egal wir breit die Datentypen sind etc.</p>
<p>Dann kanns du gucken ob die Bitmaske eine negative 32 Bit 2s complement Zahl darstellt indem du Bit 31 prüfst.<br />
Also z.B. <code>if ((val &gt;&gt; 31) &amp; 1)</code><br />
Wenn die Bitmaske eine negative Zahl darstellt, dann kannst du die dazupassende positive Zahl bekommen, indem du alle Bits invertierst und danach eins draufaddierst.<br />
Die so erhaltene Zahl kannst du dann in einen <code>int32_t</code> verwandeln, und dann wieder negativ machen. So hast du die negative 2s complement Zahl in das native Format deiner Plattform konvertiert ohne dich dabei auf plattformabhängige Dinge zu verlassen.</p>
<p>Bleibt lediglich noch ein Problem, und zwar wenn du 2s complement Hardware hast, und die negative Zahl die kleinste mögliche negative Zahl ist. Also z.B. -128 bei 8 Bit. Die passt als positive Variante nämlich nicht in einen gleich breiten signed Integer (max. bei 8 Bit wären da ja +127).</p>
<p>Das kannst du lösen indem du das &quot;eins draufaddieren&quot; verschiebst bis du die Zahl in den signed Integer gepackt und dort wieder negativ gemacht hast. Danach musst du natürlich eins subtrahieren statt addieren, da du ja das Vorzeichen wieder geändert hast.</p>
<p>Macht dann in Summe:</p>
<pre><code class="language-cpp">vector&lt;unsigned char&gt; data;

...

uint32_t uval = data[pos + 0]
   + (static_cast&lt;uint32_t&gt;(data[pos + 1]) &lt;&lt; 8)
   + (static_cast&lt;uint32_t&gt;(data[pos + 2]) &lt;&lt; 16)
   + (static_cast&lt;uint32_t&gt;(data[pos + 3]) &lt;&lt; 24);

int32_t sval;
if ((uval &gt;&gt; 31) &amp; 1)
    sval = -static_cast&lt;int32_t&gt;(~uval) - 1;
else
    sval = uval;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2494844</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494844</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 04 May 2016 00:43:45 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 09:37:48 GMT]]></title><description><![CDATA[<p>lemon03 schrieb:</p>
<blockquote>
<p>Naja, dies ist mir eben nicht so recht verständlich <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Das biHeight negativ sein könnte, scheint auch nicht mehr üblich zu sein.</p>
<p>...</p>
<p>Ich wollte ja wegen der Ausgabe zum Verständnis wirklich nur die einzelnen Bytes in hexadezimaler Form (und die Umrechung in dezimaler Form) darstellen.</p>
</blockquote>
<p>Du kannst doch ganz unabhängig von jeglicher anderer Verarbeitung diesen einen Wert einlesen und prüfen, zB. zu Programmbeginn. Da sein Offset ja feststeht, ist das doch sehr einfach.</p>
<p>Danach positionierst Du Dich wieder auf den Dateibeginn und lässt Dein Programm laufen, wie bisher.</p>
<p>Zumindest weißt Du dann, ob biHeight negativ ist, oder nicht. Wenn es nicht mehr negativ sein kann, weil &quot;scheint auch nicht mehr üblich zu sein&quot;, dann hast Du doch gar kein Problem.</p>
<p>Was die Endianness angeht, würde ich mich zunächst mal nicht darum kümmern, sondern unterstellen, dass die korrekt ist. Ich schätze, wenn es anders wäre, könnte ein Bilddarstellungsprogramm auch nix mit der Datei anfangen - das ist aber nur Spekulation.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494871</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494871</guid><dc:creator><![CDATA[Belli]]></dc:creator><pubDate>Wed, 04 May 2016 09:37:48 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 13:38:17 GMT]]></title><description><![CDATA[<p>Belli schrieb:</p>
<blockquote>
<p>Was die Endianness angeht, würde ich mich zunächst mal nicht darum kümmern, sondern unterstellen, dass die korrekt ist. Ich schätze, wenn es anders wäre, könnte ein Bilddarstellungsprogramm auch nix mit der Datei anfangen - das ist aber nur Spekulation.</p>
</blockquote>
<p>Quatsch.<br />
Klar geht das. Wieso sollte man BMP auf big-endian Systemen nicht verwenden können?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494884</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494884</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 04 May 2016 13:38:17 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 18:09:54 GMT]]></title><description><![CDATA[<p>So hab ich das nicht gemeint.<br />
Wenn ich eine bmp-Datei auf einem Big-Endian - System habe, und die auf ein Little-Endian - System kopiere, dann könnte ich mir vorstellen, dass die Programme auf dem Little-Endian - System einige Dinge falsch interpretieren.</p>
<p>Wenn ich die Datei nur auf Systemen mit gleicher Endianess (zB nur auf Windows, nur auf Linux, usw.) verwende, brauche ich mich nicht darum zu kümmern, was sie für eine Endianess hat.</p>
<p>Das ist doch nur interessant, wenn ich damit rechnen muss, dass sie von einem anderen System kommt, als das, auf welchem mein Programm läuft.</p>
<p>Und da stelle ich mir halt die Frage, ob Bilddarstellungsprogramme dann nicht vor genau den gleichen Problemen stehen ...</p>
<p>Edit:<br />
Schließlich kann ich einem Integerwert nicht ansehen, ob er Bigendian oder Littleendian codiert ist ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494927</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494927</guid><dc:creator><![CDATA[Belli]]></dc:creator><pubDate>Wed, 04 May 2016 18:09:54 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 18:24:48 GMT]]></title><description><![CDATA[<p>Quatsch.</p>
<p>Das Format definiert, ob die Daten LE oder BE gespeichert werden! Wenn die Formatdefinition mit der der Maschine, die das Bild liest, übereinstimmt, muss nichts getan werden. Stimmt das nicht überein, muss konvertiert werden.</p>
<p>BMP ist immer LE kodiert. Das heißt, wenn dein Programm nur auf LE-Maschinen läuft, musst du dir keine Gedanken um Endianess machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494934</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494934</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Wed, 04 May 2016 18:24:48 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 18:26:27 GMT]]></title><description><![CDATA[<p>Beim Bitmap-Format ist laut Specs alles Kleinenderisch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494935</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494935</guid><dc:creator><![CDATA[Techel]]></dc:creator><pubDate>Wed, 04 May 2016 18:26:27 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 18:45:29 GMT]]></title><description><![CDATA[<p>Wurde ja schon geschrieben, aber trotzdem nochmal...</p>
<p>Belli schrieb:</p>
<blockquote>
<p>Edit:<br />
Schließlich kann ich einem Integerwert nicht ansehen, ob er Bigendian oder Littleendian codiert ist ...</p>
</blockquote>
<p>Dem Integer nicht, nein. Du hast aber nen Kontext, und zwar weisst du dass der Integer aus nem .BMP File kommt. Und .BMP ist eben immer 2s complement little endian. Egal auf welcher Hardware. Wenn die Hardware was anderes verwendet, dann muss sie beim Lesen bzw. Schreiben von BMP Files eben &quot;umrechnen&quot;.</p>
<p>Damit eben genau das nicht passiert was du schreibst, nämlich dass man ein BMP File von System X auf System Y nicht aufmachen kann wenn X und Y sich nicht über 1s/2s complement bzw. Endianness einig sind. Was ja total kacke wäre. Weswegen es nicht so ist. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494938</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494938</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 04 May 2016 18:45:29 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 20:30:02 GMT]]></title><description><![CDATA[<p>Na umso besser.<br />
Dann würde ich mich der Einfachheit halber (zumindest im ersten Wurf) um die Endianess nicht kümmern - ich unterstelle einfach mal, dass das Programm für einen x86(kompatiblen) geschrieben wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494953</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494953</guid><dc:creator><![CDATA[Belli]]></dc:creator><pubDate>Wed, 04 May 2016 20:30:02 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 20:32:44 GMT]]></title><description><![CDATA[<p>Belli schrieb:</p>
<blockquote>
<p>Na umso besser.<br />
Dann würde ich mich der Einfachheit halber (zumindest im ersten Wurf) um die Endianess nicht kümmern - ich unterstelle einfach mal, dass das Programm für einen x86(kompatiblen) geschrieben wird.</p>
</blockquote>
<p>Sooooo exotisch ist BigEndian nun auch wieder nicht. Eigentlich fast so ziemlich alles, was einen nennenswerten Marktanteil außer dem x86 hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494954</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494954</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 04 May 2016 20:32:44 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 04 May 2016 20:56:51 GMT]]></title><description><![CDATA[<p>ARM kann beides.<br />
Und da x86 halt so stark ist, fahren Android und Windows den ARM auch mit little endian. (iOS vermutlich auch, hab's nicht nachrecherchiert.)</p>
<p>Aber ja, es gibt sie noch die grossen Endianer <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2494960</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2494960</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 04 May 2016 20:56:51 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Thu, 12 May 2016 16:52:26 GMT]]></title><description><![CDATA[<p>Danke für die ganzen Beiträge <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Muss der Threadersteller erst wieder alle durcharbeiten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2495637</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2495637</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Thu, 12 May 2016 16:52:26 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 16:53:48 GMT]]></title><description><![CDATA[<p>Puh, also wieder ne große Pause ...</p>
<p>Danke nochmals für die Beiträge und den Beispielcode von hustbaer (den ich einfach ganz frech kopiert habe ;)). Da im Artikel steht</p>
<blockquote>
<p>BMP verwendet die Little-Endian-Konvention.</p>
</blockquote>
<p>dachte ich mir, darum muss ich mich nicht kümmern.</p>
<p>Jetzt habe ich aber das &quot;Problem&quot;, das es gar keine negativen Werte gibt, auch bei dem Bild, wo ich vorher von ausgegangen bin. Vielleicht habe ich aber beim Schreiben des Code auch gepfuscht? Vielleicht habe ich auch was falsch verstanden?</p>
<p>Oder kann mir jemand ein Beispiel für einen Beispielvector in der Form des <code>bmp_data</code> -vector mit negativen Werten geben, um dies zu überprüfen?</p>
<pre><code>struct Head //Kopf
{
    static const auto Size = 4;
    std::array &lt;std::pair &lt;std::string, int&gt;, Size&gt; bType
    {
        {
            { &quot;bfType&quot;, 1 }, //uint16_t
            { &quot;bfSize&quot;, 2 }, //uint32_t
            { &quot;bfReserved&quot;, 2 }, //uint32_t
            { &quot;bfOffbits&quot;, 2 } //uint32_t
        }
    };
    std::vector &lt;int&gt; data;

} head;

struct Info //Eigenschaften
{
    static const auto Size = 11;
    std::array &lt;std::pair &lt;std::string, int&gt;, Size&gt; bType
    {
        {
            { &quot;biSize&quot;, 2 }, //uint32_t
            { &quot;biWidth&quot;, 3 }, //int32_t
            { &quot;biHeight&quot;, 3 }, //int32_t
            { &quot;biPlanes&quot;, 1 }, //uint16_t
            { &quot;biBitCount&quot;, 1 }, //uint16_t
            { &quot;biCompression&quot;, 2 }, //uint32_t
            { &quot;biSizeImage&quot;, 2 }, //uint32_t
            { &quot;biXPelsPerMeter&quot;, 3 }, //int32_t
            { &quot;biYPelsPerMeter&quot;, 3 }, //int32_t
            { &quot;biClrUsed&quot;, 2 }, //uint32_t
            { &quot;biClrImportant&quot;, 2 } //uint32_t
        }
    };
    std::vector &lt;int&gt; data;

} info;

/*
struct ColTable //Farbtabelle
{
    bool is_ = true; //existiert Farbtabelle
    std::vector &lt;std::tuple &lt;uint8_t, uint8_t, uint8_t, uint8_t&gt;&gt; tblEntry;

} colTable;
*/

void read_bmpData (std::string file_, std::vector &lt;unsigned char&gt; &amp;bmp_data)
{
    std::string file_name = file_ + &quot;.bmp&quot;;
    char s_char;
    std::ifstream file (file_name.c_str(), std::ios::binary);
    if (!file)
    {
        std::string err_str = &quot;!Fehler bei &quot; + file_name;
        //throw err_str;
        std::cout &lt;&lt; err_str; //wird noch behandelt      
    }
    while (file.get(s_char)) bmp_data.push_back(s_char);
    std::cout &lt;&lt; &quot;_File: &quot; &lt;&lt; file_name &lt;&lt; '\n' &lt;&lt; '\n';
}

uint16_t make_uint16 (std::vector &lt;unsigned char&gt; bmp_data, std::size_t pos)
{
    uint16_t u_val = bmp_data.at(pos + 0)
                    + (static_cast &lt;uint16_t&gt; (bmp_data.at(pos + 1)) &lt;&lt; 8);

    return u_val;
}

uint32_t make_uint32 (std::vector &lt;unsigned char&gt; bmp_data, std::size_t pos)
{
    uint32_t u_val = bmp_data.at(pos + 0)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 1)) &lt;&lt; 8)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 2)) &lt;&lt; 16)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 3)) &lt;&lt; 24);

    return u_val;
}

int32_t make_int32 (std::vector &lt;unsigned char&gt; bmp_data, std::size_t pos)
{
    uint32_t u_val = bmp_data.at(pos + 0)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 1)) &lt;&lt; 8)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 2)) &lt;&lt; 16)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 3)) &lt;&lt; 24);

    int32_t s_val;
    if ((u_val &gt;&gt; 31) &amp; 1)
    {
        s_val = - static_cast &lt;int32_t&gt; (~u_val) - 1;
    }
    else
    {
        s_val = u_val;
    }

    return s_val;
}

int main()
{

    //std::string file_ = &quot;test_me&quot;;
    std::string file_ = &quot;WOLKEN&quot;;
    //std::string file_ = &quot;046&quot;;
    //std::string file_ = &quot;Cubis&quot;;

    std::vector &lt;unsigned char&gt; bmp_data;
    read_bmpData (file_, bmp_data);

    std::size_t offset = 0;
    uint16_t data_u16;
    uint32_t data_u32;
    int32_t data_32;

    for (auto i=0; i&lt;head.Size; i++)
    {
        switch (head.bType.at(i).second)
        {
        case 1:
            data_u16 = make_uint16 (bmp_data, offset);
            head.data.push_back(data_u16);
            offset += 2;
            break;
        case 2:
            data_u32 = make_uint32 (bmp_data, offset);
            head.data.push_back(data_u32);
            offset += 4;
            break;
        case 3:
            data_32 = make_int32 (bmp_data, offset);
            head.data.push_back(data_32);
            offset += 4;
            break;
        }
    }

    for (auto i=0; i&lt;info.Size; i++)
    {
        switch (info.bType.at(i).second)
        {
        case 1:
            data_u16 = make_uint16 (bmp_data, offset);
            info.data.push_back(data_u16);
            offset += 2;
            break;
        case 2:
            data_u32 = make_uint32 (bmp_data, offset);
            info.data.push_back(data_u32);
            offset += 4;
            break;
        case 3:
            data_32 = make_int32 (bmp_data, offset);
            info.data.push_back(data_32);
            offset += 4;
            break;
        }
    }

    for (std::size_t i=0; i&lt;head.Size; i++)
        std::cout &lt;&lt; head.bType.at(i).first &lt;&lt; &quot;:  &quot; &lt;&lt; head.data.at(i) &lt;&lt; '\n';
    std::cout &lt;&lt; '\n';
    for (std::size_t i=0; i&lt;info.Size; i++)
        std::cout &lt;&lt; info.bType.at(i).first &lt;&lt; &quot;:  &quot; &lt;&lt; info.data.at(i) &lt;&lt; '\n';

}
</code></pre>
<p>edit: einige Korrekturen im Code</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500488</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500488</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Wed, 29 Jun 2016 16:53:48 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 15:45:50 GMT]]></title><description><![CDATA[<p>lemon03 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">...

    int32_t s_val;
    if ((u_val &gt;&gt; 31) &amp; 1)
    {
        s_val = -u_val;           // &lt;--------------------
    }
    else
    {
        s_val = u_val;
    }
...
</code></pre>
</blockquote>
<p>Hast du in die markierte Zeile mal nen Breakpoint gemacht?<br />
Und: Wieso hast du den Code in genau dieser Zeile geändert? Das hat schon nen Grund dass ich das so geschrieben habe wie ich es eben geschrieben habe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500501</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500501</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 29 Jun 2016 15:45:50 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 16:19:55 GMT]]></title><description><![CDATA[<p>Einen Breakpoint nicht (ich kann leider noch nicht in CodeBlocks den Debugger benutzen, weil ich mich noch nicht ganz mit <code>ERROR: You need to specify a debugger program in the debuggers's settings.</code> auseinander gesetzt habe), aber ich habe eine cout-Ausgabe dort eingeführt, ob diese Wahl überhaupt getroffen wurde. Sie wurde nie aufgerufen.</p>
<p>Die Zeilen habe ich geändert, weil ich davon ausgegangen bin, das die dortige Abfrage <code>if ((u_val &gt;&gt; 31) &amp; 1)</code> nur zur Entscheidung negativ oder positiv dient. Die weitere Verarbeitung wäre dann nur für eventuell andere Systeme. Dachte ich jedenfalls.</p>
<p>Ich werd das mal korrigieren.</p>
<p>EDIT: Aber auch umgeschrieben, scheint es keine negativen Werte zu geben</p>
<pre><code>uint32_t u_val = bmp_data.at(pos + 0)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 1)) &lt;&lt; 8)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 2)) &lt;&lt; 16)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 3)) &lt;&lt; 24);

    int32_t s_val;
    if ((u_val &gt;&gt; 31) &amp; 1)
    {
        s_val = - static_cast &lt;int32_t&gt; (~u_val) - 1;
    }
    else
    {
        s_val = u_val;
    }

    return s_val;
</code></pre>
<p>Aber vielleicht ist das ja korrekt? Ich bräuchte zum Testen ein Beispiel, wo ganz bestimmt negative Werte enthalten sind?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500506</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500506</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Wed, 29 Jun 2016 16:19:55 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 16:22:23 GMT]]></title><description><![CDATA[<p>EDIT: Korrektur ist im oberen Beitrag.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500507</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500507</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Wed, 29 Jun 2016 16:22:23 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 17:15:14 GMT]]></title><description><![CDATA[<p>OK wenn das cout nie anschlägt dann wird es wohl keine negativen Werte gegeben haben in deinen Bitmaps.</p>
<p>lemon03 schrieb:</p>
<blockquote>
<p>Aber vielleicht ist das ja korrekt? Ich bräuchte zum Testen ein Beispiel, wo ganz bestimmt negative Werte enthalten sind?</p>
</blockquote>
<p>Ja korrekt ist es schon. Es gibt halt top-down und bottom-up BMPs. Standard ist bottom-up und bei denen ist die Höhe positiv.<br />
D.h. du musst dir irgendwoher top-down BMPs zum Testen besorgen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500521</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500521</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 29 Jun 2016 17:15:14 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 17:22:09 GMT]]></title><description><![CDATA[<p>Jo danke dann <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Und gute Idee, mal schauen ob man nach top-down BMPs goglen kannn, bzw was findet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500522</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500522</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Wed, 29 Jun 2016 17:22:09 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 17:57:44 GMT]]></title><description><![CDATA[<p>Super, hatte mehrere top-down Beispiele gefunden und bei allen wurde der korrekte Wert negativ angezeigt. Danke nochmals.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500529</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500529</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Wed, 29 Jun 2016 17:57:44 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 22:27:53 GMT]]></title><description><![CDATA[<p>Na super <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Nochwas...<br />
Ich würde folgende Änderungen vorschlagen:</p>
<pre><code class="language-cpp">int32_t make_int32 (std::vector &lt;unsigned char&gt; bmp_data, std::size_t pos)
{
    uint32_t u_val = bmp_data.at(pos + 0)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 1)) &lt;&lt; 8)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 2)) &lt;&lt; 16)
                    + (static_cast &lt;uint32_t&gt; (bmp_data.at(pos + 3)) &lt;&lt; 24);

    int32_t s_val;
    if ((u_val &gt;&gt; 31) &amp; 1)
    {
        s_val = - static_cast &lt;int32_t&gt; (~u_val) - 1;
    }
    else
    {
        s_val = u_val;
    }

    return s_val;
}

// =&gt;

int32_t better_make_int32 (std::vector &lt;unsigned char&gt; const&amp; /* 1 */ bmp_data, std::size_t pos)
{
    uint32_t const /* 2 */ u_val = /* 3 */ make_uint32(bmp_data, pos);

    if ((u_val &gt;&gt; 31) &amp; 1)
    {
        return - static_cast &lt;int32_t&gt; (~u_val) - 1; /* 4 */
    }
    else
    {
        return u_val;                                /* 4 */
    }
}
</code></pre>
<p>1: Du solltest nicht den ganzen std::vector kopieren. Das ist sogar im günstigsten Fall (wenig Daten) schon viel langsamer als nötig (dynamische Speicheranforderung!). Und wenn mal viel Daten drinnen wird's richtig langsam.</p>
<p>2: Lokale Variablen <code>const</code> machen wenn man sie (einfach, ohne grosse Umwege) <code>const</code> machen kann. Damit man gleich sieht dass der Wert der Variable sich nach der Initialisierung nie mehr ändert.</p>
<p>3: Code-Duplizierung vermeiden.</p>
<p>4: Mutable-State vermeiden, uninitialisierte Variablen vermeiden.<br />
Uninitialisierte Variablen vermeiden allerdings nur, wenn man ihnen gleich bei der Initialisierung einen sinnvollen Wert geben kann. Wenn wirklich nur die Wahl besteht zwischen &quot;uninitialisiert&quot; oder &quot;mit Dummy-Wert initialisiert&quot;, dann eher uninitialisiert. Meist kann man aber gleich mit dem passenden Wert initialisieren.</p>
<p>Einige dieser Dinge (z.B. (1)) betreffen auch andere Funktionen, dort natürlich ebenso nachziehen.</p>
<p>Und wie bei allen Richtlinien gibt es natürlich Ausnahmen. Viel Aufwand zu betreiben um eine dieser Regeln zu befolgen ist nicht immer sinnvoll.</p>
<p>----</p>
<p>Und ich würde vorschlagen die Leerzeichen vor öffnenden Klammern und nach schliessenden Klammern weg zu lassen. Ausnahme: zwischen Keywords und runde Klammer kommt ein Leerzeichen<br />
Also z.B.</p>
<pre><code class="language-cpp">int x = MeineFunktion(param); // nach MeineFunktion nicht
for (int i = 0; i &lt; x; i++)   // nach for schon
{
    if (static_cast&lt;int32_t&gt;(i * i) &lt; x)  // nach if auch, nach static_cast aber nicht
</code></pre>
<p>usw.</p>
<p>Das, also wo bei Klammern Leerzeichen gesetzt werden, ist nämlich eine der wenigen Regeln wo sich die meisten Programmierer einig sind. Zumindest ist das mein Eindruck anhand des Codes den ich so sehe.</p>
<p>EDIT: Copy/Paste/Edit Fehler korrigiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500546</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500546</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 29 Jun 2016 22:27:53 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 22:26:04 GMT]]></title><description><![CDATA[<p>Und wenn wir schon dabei sind, gleich nochmal weiter:</p>
<pre><code class="language-cpp">int32_t int32_from_uint32(uint32_t u_val)
{
    if ((u_val &gt;&gt; 31) &amp; 1)
        return -static_cast&lt;int32_t&gt;(~u_val) - 1;
    else
        return u_val;
}

int32_t make_int32(std::vector &lt;unsigned char&gt; const&amp; bmp_data, std::size_t pos)
{
    return int32_from_uint32(make_uint32(bmp_data, pos));
}
</code></pre>
<p>EDIT: Copy/Paste/Edit Fehler korrigiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500547</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500547</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 29 Jun 2016 22:26:04 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 21:17:58 GMT]]></title><description><![CDATA[<p>Gleichheitszeichen zwischen <code>return</code> und der Variablen finde ich wiederum merkwürdig - mein Compiler auch...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500552</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500552</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Wed, 29 Jun 2016 21:17:58 GMT</pubDate></item><item><title><![CDATA[Reply to Fragen zu Windows Bitmap einlesen #2 on Wed, 29 Jun 2016 21:26:49 GMT]]></title><description><![CDATA[<p>war bestimmt nur ein Tippfehler ...</p>
<p>Ok, danke für die Hinweise. Wenn ich richtig verstanden habe, müssten die drei Funktionen dann so aussehen?:</p>
<pre><code>uint16_t make_uint16(std::vector &lt;unsigned char&gt; const &amp;bmp_data, std::size_t pos)
{
    uint16_t const u_val = bmp_data.at(pos + 0)
                    + (static_cast&lt;uint16_t&gt;(bmp_data.at(pos + 1)) &lt;&lt; 8);

    return u_val;
}

uint32_t make_uint32(std::vector &lt;unsigned char&gt; const &amp;bmp_data, std::size_t pos)
{
    uint32_t const u_val = bmp_data.at(pos + 0)
                    + (static_cast&lt;uint32_t&gt;(bmp_data.at(pos + 1)) &lt;&lt; 8)
                    + (static_cast&lt;uint32_t&gt;(bmp_data.at(pos + 2)) &lt;&lt; 16)
                    + (static_cast&lt;uint32_t&gt;(bmp_data.at(pos + 3)) &lt;&lt; 24);

    return u_val;
}

int32_t make_int32(std::vector &lt;unsigned char&gt; const &amp;bmp_data, std::size_t pos)
{
    uint32_t const u_val = make_uint32 (bmp_data, pos);

    if ((u_val &gt;&gt; 31) &amp; 1)
    {
        return -static_cast&lt;int32_t&gt;(~u_val) - 1;
    }
    else
    {
        return u_val;
    }
}
</code></pre>
<p>Nur das doppelt ausschreiben in Deinem letzten Beitrag habe ich nicht ganz verstanden?</p>
<p>---</p>
<p>Ich hoffe, das wird jetzt nicht zuviel, aber ich hätte noch ein anderes Anliegen. Und zwar bin ich mit meiner switch-Lösung nicht ganz zufrieden. Ich würde lieber einen Funktionszeiger nehmen, bekomme das aber nicht hin.</p>
<p>Vorgestellt habe ich mir, das hier der second-Wert das Argument für den Zeiger sein soll. Welcher Typ das sein muss, ist mir unklar.</p>
<pre><code>struct Head //Kopf
{
    static const auto Size = 4;
    std::array &lt;std::pair &lt;std::string, int&gt;, Size&gt; bType
    {
        {
            { &quot;bfType&quot;, 1 }, //uint16_t
            { &quot;bfSize&quot;, 2 }, //uint32_t
            { &quot;bfReserved&quot;, 2 },
            { &quot;bfOffbits&quot;, 2 }
        }
    };
    std::array &lt;int, Size&gt; data;

} head;

//int (*make_data)(std::vector &lt;unsigned char&gt;, std::size_t);
</code></pre>
<p>Unklar ist mir auch, wie eine Funktion mit diesem Argument dann aufgerufen wird. Ich hatte bisher nur einmal mit Funktionszeigern zu tun, mir fehlt die Übung und ich kann den ersten Einsatz nicht für diesen Fall nachvollziehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2500555</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2500555</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Wed, 29 Jun 2016 21:26:49 GMT</pubDate></item></channel></rss>