4 Bytes in Heap zu int

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Benutzeravatar
starcow
Establishment
Beiträge: 522
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

4 Bytes in Heap zu int

Beitrag von starcow »

Abend liebe ZFX'ler :-)

Ich stehe hier mit meinem C-Code (es soll reines C sein) grad etwas am Hang.
Ich habe ein .bmp file eingelesen (zuvor die Grösse der Datei ermittelt) und die Daten in einem "Block" auf dem Heap angelegt. Dabei ist der Block vom Typ unsigned char (also der Pointer mit der Anfangsadresse des Blockes hat folglich den Typ unsigned char* ).
Nun muss ich ja entsprechend der BMP Spezifikation auch einzelne Blöcke zusammenfassen (öfters zu uint32_t).
Irgendwie fehlt mir hier aber ein Ansatz.
Wie kann ich es denn bewerkstelligen, dass ich vier solcher unsigned char's in einen uint32_t packen kann (um dann den Wert einer uint32_t Variable auf dem Stack zuzuweisen)?
Ich habe jetzt Ausschnitte von Beispielen gesehen, die das mittels Bitshifting lösen. So 100% durchschaue ich es noch nicht. Macht man das so unter C oder gibts vielleicht eine Technik die etwas kürzer ist ohne dabei externe Bibliotheken einbinden zu müssen?

Gruss, starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von xq »

Code: Alles auswählen

// read a 4-byte buffer into a 32 bit unsigned integer, little endian.
// buffer must be at least 4 byte large!
uint32_t read_u32_le(uint8_t const * buffer) {
  uint32_t const result = ((uint32_t)buffer[0] << 0)
      | ((uint32_t)buffer[1] << 8)
      | ((uint32_t)buffer[2] << 16)
      | ((uint32_t)buffer[3] << 24);
  return result;
}
Liest den Integer im Little-Endian-Format ein.

Stell dir einfach vor, jemand zerlegt den uint32_t so, dass er statt 1 * 32 bit als 4 * 8 bit gespeichert wird. Jetzt kannst du das ganze natürlich von "vorne" oder von "hinten" zerlegen, also die bit-bereiche 31..24, 23..16, 15..8, 7..0 entweder von "hoch nach tief" (big endian), oder von "tief nach hoch" (little endian) abzuspeichern.

Wenn du Big Endian lesen möchtest, musst du entweder die shifts oder die indizes vertauschen.
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Krishty »

Ja, genau das. BMP hat die Eigenschaft, dass die 32-Bit-Zahlen im Header nicht natürlich ausgerichtet sind (zwei statt vier Bytes). Also definitiv durch unsigned char * lesen und das uint32_t zusammenbauen.

Der Vollständigkeit halber wäre hier noch die Variante mit memcpy() und anschließendem Vertauschen der Bytes genannt (__builtin_bswap32() oder _byteswap_ulong()). Damit gibt es leicht bessere Optimierungsmöglichkeiten, aber das müsste ich nochmal mit aktuellen Compilern prüfen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
starcow
Establishment
Beiträge: 522
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von starcow »

Ahhh, super! Ich danke euch! :-)

Noch eine Frage in dem Zusammenhang:
Ich hatte mir nach dem Einlesen der Datei (in den Heap) Zwecks Kontrolle erstmals einfach alle Werte mittels printf ausgeben lassen:

Code: Alles auswählen

... // Grösse der Datei "fileSize" mittels fseek() und ftell() ermittelt.
char* data = (char*)malloc(fileSize);
for(int i = 0; i < fileSize; ++i)
{
    data[i] = fgetc(file);
    printf("[%2.2u]  ", data[i]);
}
Was ich mir nicht ganz erklären kann:
Ehe ich von char* auf unsigned char* gewechselt hatte (Pointer "data"), hatte mir printf bei Werten grösser als 127 irgendwie 4 Bytes angezeigt.
Konkret: Wenn im File ein Byte den Wert 128 hatte (0x80) hatte er mir 4294967295 ausgegeben. Nur wieso? Es ist ja ein char-Pointer, den ich dereferenziere? Wieso also schaut er sich trotzdem 4 Bytes an?

LG, starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Schrompf
Moderator
Beiträge: 4831
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Schrompf »

Bei printf() (und Varargs im Allgemeinen, glaube ich) wird alles auf 32bit hochgecastet. Wenn da ein signed char kommt, bedeutet 0x80 eine -128 und wird beim Aufpusten auf 32bit zu 0xffffff80 (-128 als int32). Und weil Du aber %u printest, gibt er diese Zahl dann als unsigned aus. Und das sind die 4 Milliarden Irgendwas.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Krishty »

Prinzipiell genau das ☝️
Schrompf hat geschrieben: 08.11.2022, 20:30Bei printf() (und Varargs im Allgemeinen, glaube ich) wird alles auf 32bit hochgecastet.
Jein. Auf 32-Bit-x86 wird alles auf 32-Bit-Werte promotet, bis auf Gleitkommazahlen – die werden zu double promotet. Auf 64-Bit-x86 wird alles zu 64-Bit-Werten promotet. Das sind natürlich Implementierungsdetails, auf die man sich in Standard-konformem C nicht verlassen darf – daher der ganze Aufwand in Compilern, falsche Format Strings zu erkennen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
udok
Beiträge: 40
Registriert: 01.02.2022, 17:34

Re: 4 Bytes in Heap zu int

Beitrag von udok »

Auch auf 64 Bit x86 wird nur auf 32 Bit hochgecastet (promoted), da int nur 32 bit hat, printf("%p\n", -1) liefert 00000000FFFFFFFF.
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Krishty »

Stimmt! Der Standard schreibt nur „int or larger“ vor. Tatsächlich machen GCC/MSVC nur 32-Bit-Promotion sogar auf x86-64, und alle folgenden Zugriffe auf die Parameterliste sind entsprechend daneben. Danke für die Korrektur!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 574
Registriert: 05.07.2003, 11:17

Re: 4 Bytes in Heap zu int

Beitrag von Lord Delvin »

Ist jetzt bestimmt ein doofer Einwand aber: Gab's da nicht schon vor zwanzig Jahren freie Bibliotheken, die das halbwegs zuverlässig für einen gemacht haben?
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: 4 Bytes in Heap zu int

Beitrag von Alexander Kornrumpf »

Lord Delvin hat geschrieben: 10.11.2022, 18:19 Ist jetzt bestimmt ein doofer Einwand aber: Gab's da nicht schon vor zwanzig Jahren freie Bibliotheken, die das halbwegs zuverlässig für einen gemacht haben?
Ist "das" jetzt BMP einlesen, oder 4 bytes in einen int konvertieren?

Fun fact: In npm gäbe es ein Paket für letzteres.

Just kidding ...
... JavaScript weiß nicht was ein int ist.
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 574
Registriert: 05.07.2003, 11:17

Re: 4 Bytes in Heap zu int

Beitrag von Lord Delvin »

:D
Ersteres natürlich.
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Krishty »

Unter Windows ist das Laden von BMPs literally fundamentaler Teil des Betriebssystems.

Aber wer starcows Threads verfolgt, weiß ja, dass er diese Projekte zum Lernen und Verstehen macht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: 4 Bytes in Heap zu int

Beitrag von Alexander Kornrumpf »

Krishty hat geschrieben: 11.11.2022, 21:29 Unter Windows ist das Laden von BMPs literally fundamentaler Teil des Betriebssystems.

Aber wer starcows Threads verfolgt, weiß ja, dass er diese Projekte zum Lernen und Verstehen macht.
Mir fehlt bei sowas immer die Phantasie, aber ich finde es sowieso schwer vorstellbar, dass man 2022 noch irgendwas neues starten würde wo man Bitmap produktiv einsetzt, egal ob jetzt von Hand oder mit Unterstützung des OS.

Gefühlt ist Bitmap von meinem Rechner ca. zusammen mit Windows 98 verschwunden. Ich fürchte wir müssen aus "Lord Delvin"'s "vor zwanzig Jahren" eher "vor dreißig" machen.
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 574
Registriert: 05.07.2003, 11:17

Re: 4 Bytes in Heap zu int

Beitrag von Lord Delvin »

Mir ist schon klar, dass er das zum Lernen macht; würde aber eher was machen, das mehr Spaß oder Komplexität oder Anwendungsfälle hat. Das mit dem Spaß kann natürlich eine Fehleinschätzung sein.
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Benutzeravatar
starcow
Establishment
Beiträge: 522
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von starcow »

Schrompf hat geschrieben: 08.11.2022, 20:30 Bei printf() (und Varargs im Allgemeinen, glaube ich) wird alles auf 32bit hochgecastet. Wenn da ein signed char kommt, bedeutet 0x80 eine -128 und wird beim Aufpusten auf 32bit zu 0xffffff80 (-128 als int32). Und weil Du aber %u printest, gibt er diese Zahl dann als unsigned aus. Und das sind die 4 Milliarden Irgendwas.
Danke Schrompf, das erklärt es natürlich. :-)
Krishty hat geschrieben: 11.11.2022, 21:29 Unter Windows ist das Laden von BMPs literally fundamentaler Teil des Betriebssystems.

Aber wer starcows Threads verfolgt, weiß ja, dass er diese Projekte zum Lernen und Verstehen macht.
Ja Krishty, du liegst damit genau richtig. :->
Tatsächlich macht mir sowas auch wirklich Spass - solche Dinge mal selbst umzusetzen - selbst zu probieren.
Alexander Kornrumpf hat geschrieben: 11.11.2022, 23:43 Mir fehlt bei sowas immer die Phantasie, aber ich finde es sowieso schwer vorstellbar, dass man 2022 noch irgendwas neues starten würde wo man Bitmap produktiv einsetzt, egal ob jetzt von Hand oder mit Unterstützung des OS.
Gefühlt ist Bitmap von meinem Rechner ca. zusammen mit Windows 98 verschwunden. Ich fürchte wir müssen aus "Lord Delvin"'s "vor zwanzig Jahren" eher "vor dreißig" machen.
Lord Delvin hat geschrieben: 12.11.2022, 15:38 Mir ist schon klar, dass er das zum Lernen macht; würde aber eher was machen, das mehr Spaß oder Komplexität oder Anwendungsfälle hat. Das mit dem Spaß kann natürlich eine Fehleinschätzung sein.
Jetzt bin ich doch etwas verunsichert... Ein 24Bit BMP-File ist ja im wesentlichen nichts anders als ein pixelbasiertes, unkomprimiertes RGB Grafikformat. Sowas ist ja gewissermassen zeitlos, oder? Für die Ansteuerung des Monitors benötigt man ja ohnehin früher oder später genau diese Daten im Grafikspeicher.

Gibts denn vielleicht einen technischen Grund, das nicht so (selbst per Hand) zu machen? Oder was meint ihr damit?

@Lord Delvin
An was hattest du denn dabei gedacht?

LG, starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: 4 Bytes in Heap zu int

Beitrag von Alexander Kornrumpf »

starcow hat geschrieben: 12.11.2022, 16:51 Jetzt bin ich doch etwas verunsichert... Ein 24Bit BMP-File ist ja im wesentlichen nichts anders als ein pixelbasiertes, unkomprimiertes RGB Grafikformat. Sowas ist ja gewissermassen zeitlos, oder? Für die Ansteuerung des Monitors benötigt man ja ohnehin früher oder später genau diese Daten im Grafikspeicher.
Mir schien es du würdest von Platte lesen. Ein "Bitmap" (zweidimensionales Array) ist sicherlich zeitlos für viele Anwendungsfälle. Ein "BMP" (Dateiformat inklusive Header auf Platte) habe ich seit den frühen 00ern nicht mehr gesehen. Wobei es natürlich nichts heißen muss, was ich so im Alltag zu sehen bekomme.

Aus besseren Kameras kommt soviel ich weiß "raw" also Bitmap ohne den Header raus, nur mal so als Beispiel.
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: 4 Bytes in Heap zu int

Beitrag von Alexander Kornrumpf »

Lord Delvin hat geschrieben: 12.11.2022, 15:38 Mir ist schon klar, dass er das zum Lernen macht; würde aber eher was machen, das mehr Spaß oder Komplexität oder Anwendungsfälle hat. Das mit dem Spaß kann natürlich eine Fehleinschätzung sein.
Jetzt muss man natürlich fairerweise sagen dass man das mit der Endianness schon mindestens einmal im Leben erlebt haben sollte. Ich fürchte viele Programmierer haben das leider nicht.
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Krishty »

Alexander Kornrumpf hat geschrieben: 11.11.2022, 23:43Gefühlt ist Bitmap von meinem Rechner ca. zusammen mit Windows 98 verschwunden. Ich fürchte wir müssen aus "Lord Delvin"'s "vor zwanzig Jahren" eher "vor dreißig" machen.
Die Hälfte von Windows nutzt noch GDI, das die Desktop-Komposition der GPU füttert. Ich würde behaupten, dass die Anzahl verarbeiteter BMPs pro Sekunde auf einem aktuellen Windows noch mindestens vierstellig ist. Für BMP-Dateien auf der Festplatte statt auf dem lokalen Stack irgendwelcher Windows-Interna hast du aber natürlich recht.

P.S.: Copy-Paste von Bilddaten (Screenshots, Copy Image im Browser) ist auch noch BMP.

P.P.S.: Sorry, jetzt erst deinen Post oben gesehen! Ja, Windows’ GDI und Clipboard nutzen für das interne Zweidimensionales Array von Pixeln tatsächlich das BMP-Format, das wir alle von der Platte kennen. Abwechselnd mit oder ohne den äußersten Header. Das dürfte auch dazu beitragen, dass Windows grundsätzlich Little Endian voraussetzt (selbst auf ARM).

Danke für den Hinweis mit der Endianness. Stimme voll zu.

@starcow Falls du andere schöne Formate für „unkomprimiertes 2D-Array aus Pixeln“ sehen willst: ILBM (Amiga) ist wesentlich besser entworfen als BMP. Leider siehst du daran auch, dass nicht alles so zeitlos ist, wie man denkt: Statt direkt mit RGB arbeitet das meist noch mit Bit Planes, denn so funktionierten Pixel damals.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von xq »

Alexander Kornrumpf hat geschrieben: 12.11.2022, 18:35 Aus besseren Kameras kommt soviel ich weiß "raw" also Bitmap ohne den Header raus, nur mal so als Beispiel.
Wichtig! .raw ist … kein Dateiformat. Es ist eine Dateiendung. Wikipedia hat da ein paar mehr Infos dazu. tl;dr: Es gibt mind. ein RAW-Format pro Hersteller, eher mehr.

Laut GIMP sind Daten ohne Header eher als .bin oder .data zu finden.
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 574
Registriert: 05.07.2003, 11:17

Re: 4 Bytes in Heap zu int

Beitrag von Lord Delvin »

starcow hat geschrieben: 12.11.2022, 16:51 @Lord Delvin
An was hattest du denn dabei gedacht?
Was mit SDL oder SFML. 2D grid oder 2D iso. Irgendwas Richtung solo survival oder tower defense; turn-based oder realtime ist Geschmackssache denke ich. Du hast dann halt was in der Hand, was man irgendwie benutzen kann; hat mich früher motiviert obwohl ich nie was in der Hand hatte, das wirklich zu was zu gebrauchen war ;)
Das geht dann vermutlich aber mehr in die Richtung Softwarearchitektur, Codequalität, Algorithmen; jenachdem wie man's macht, wie sehr man sich hinterfragt und ob man jemanden hat, der das vielleicht mal anschaut. Ich meine mich dunkel zu erinnern, dass ich ganz am Anfang mal eine draw-Funktion mit so 15+- Parametern hatte. Mache ich heute nicht mehr so :D

Wenn dir das mit den BMP Spaß macht mach' das aber fertig; die OGSS-Implementierungen gehen tatsächlich auch in die Richtung. Da lernt man unfassbar viel. Allerdings glaube ich, dass man die ohne Anleitung nicht hinbekommt.

Wenn man lernen will muss man bei so Implementierungsübungen aufpassen, dass man den Punkt erwischt, an dem es nur noch Arbeit ist und man nichts mehr lernen wird. Das selbst zu erkennen ist aber sehr schwer.
Alexander Kornrumpf hat geschrieben: 12.11.2022, 18:37 Jetzt muss man natürlich fairerweise sagen dass man das mit der Endianness schon mindestens einmal im Leben erlebt haben sollte. Ich fürchte viele Programmierer haben das leider nicht.
Volle Zustimmung.
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von dot »

Krishty hat geschrieben: 07.11.2022, 23:44 Ja, genau das. BMP hat die Eigenschaft, dass die 32-Bit-Zahlen im Header nicht natürlich ausgerichtet sind (zwei statt vier Bytes). Also definitiv durch unsigned char * lesen und das uint32_t zusammenbauen.

Der Vollständigkeit halber wäre hier noch die Variante mit memcpy() und anschließendem Vertauschen der Bytes genannt (__builtin_bswap32() oder _byteswap_ulong()). Damit gibt es leicht bessere Optimierungsmöglichkeiten, aber das müsste ich nochmal mit aktuellen Compilern prüfen.
Spoiler Alert: Du wirst finden, dass alle Compiler außer MSVC seit Jahrzehnten schon schlau genug sind, die Bitshifterei in ein mov (+ bswap) zu übersetzen… Dieser MSVC Performancebug ist seit Jahren auf meiner Liste an Dingen, für die ich endlich mal einen Bugreport öffnen sollte…
starcow hat geschrieben: 12.11.2022, 16:51
Lord Delvin hat geschrieben: 12.11.2022, 15:38 Mir ist schon klar, dass er das zum Lernen macht; würde aber eher was machen, das mehr Spaß oder Komplexität oder Anwendungsfälle hat. Das mit dem Spaß kann natürlich eine Fehleinschätzung sein.
Jetzt bin ich doch etwas verunsichert... Ein 24Bit BMP-File ist ja im wesentlichen nichts anders als ein pixelbasiertes, unkomprimiertes RGB Grafikformat. Sowas ist ja gewissermassen zeitlos, oder? Für die Ansteuerung des Monitors benötigt man ja ohnehin früher oder später genau diese Daten im Grafikspeicher.

Gibts denn vielleicht einen technischen Grund, das nicht so (selbst per Hand) zu machen? Oder was meint ihr damit?
.bmp Files lesen und schreiben ist imo eine sehr gute Übung, empfehle ich regelmäßig. Einfach genug um es selbst zu machen aber nicht zu einfach, man kann einiges dabei lernen…
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Krishty »

dot hat geschrieben: 14.11.2022, 17:07Spoiler Alert: Du wirst finden, dass alle Compiler außer MSVC seit Jahrzehnten schon schlau genug sind, die Bitshifterei in ein mov (+ bswap) zu übersetzen… Dieser MSVC Performancebug ist seit Jahren auf meiner Liste an Dingen, für die ich endlich mal einen Bugreport öffnen sollte…
Ja, tu das bitte! As for me, ich bevorzuge tatsächlich die Intrinsics: Weil ich den Funktionsaufruf im Code trotz recht kryptischem Namen verständlicher finde als die Bitshifterei mit ihren Klammern :D

Was das Lernen angeht: Für meinen BMP-Loader war diese Test-Suite ganz nützlich. Falls man es auf 11 treiben will :D
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4831
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Schrompf »

VS hat bei mir zuverlässig das Rumshiften als EndianSwap erkannt und durch bswap ersetzt. Ist aber schon ne Weile her, dass ich das letzte Mal ins ASM geguckt habe
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von dot »

Schrompf hat geschrieben: 14.11.2022, 21:21 VS hat bei mir zuverlässig das Rumshiften als EndianSwap erkannt und durch bswap ersetzt. Ist aber schon ne Weile her, dass ich das letzte Mal ins ASM geguckt habe
Sicher dass das mit MSVC war und nicht, e.g., clang? Ich versuche seit Jahren, MSVC dazu zu bewegen, einigermaßen effizienten Code für portable Serialization/Deserialization zu generieren; bisher ohne Erfolg…
Benutzeravatar
Schrompf
Moderator
Beiträge: 4831
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Schrompf »

Ja, sicher, weil meine letzte Überprüfung jetzt locker 10 Jahre her ist. Damals gab's noch keinen Clang auf Windows.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
starcow
Establishment
Beiträge: 522
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von starcow »

Update:
Das Einlesen klappt dank eurer Hilfe soweit einwandfrei. Jedoch liefert mir fgetc() beim Lesen einer Datei beim Wert 26 (1A) EOF, statt den tatsächlichen Wert.
Das lässt sich zwar umgehen, wenn ich den Modus von fopen() auf "rb" setze, jedoch bin ich mir nicht sicher, ob sich das wirklich so gehört? Ehrlich gesagt hab ich auch bis jetzt noch nicht so recht verstanden, was denn der Unterschied zwischen "normalen" Lesen "r" und "binary lesen" "rb" ist. Aber vielleicht ist dies einer (?) der Unterschiede?

LG, starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Jonathan
Establishment
Beiträge: 2348
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Jonathan »

Soweit ich weiß, hast du beim Öffnen im Textmodus zusätzliche automatische Konvertierung von Dingen wie New-Line Characters, während dir der Binärmodus die Datei so liefert, wie sie ist.
Mir scheint der Text-Modus ein wenig ein Relikt der Vergangenheit zu sein. Wenn du z.B. eine Datei im Textmodus einliest und direkt danach wieder schreibst, kann der Inhalt danach anders sein, weil Zeichen automatisch konvertiert wurden. "Relikt der Vergangenheit" deshalb, weil, soweit ich weiß, zwar Dinge wie Newlines berücksichtigt werden, aber sowas wie Unicode wiederum nicht. Du musst also ggf. nach dem Lesen trotzdem noch von Hand Anpassungen vornehmen, in Fällen wo das wichtig ist würde ich also direkt alles binär Öffnen und dann gleich alles von Hand machen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 574
Registriert: 05.07.2003, 11:17

Re: 4 Bytes in Heap zu int

Beitrag von Lord Delvin »

starcow hat geschrieben: 19.11.2022, 21:19 Jedoch liefert mir fgetc()
Schau' dir mal mmap an. Wenn du nicht auf Posix arbeitest dann gibt's da bestimmt was vergleichbares. Würde immer die ganze Datei mappen und das OS den Rest erledigen lassen.
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von dot »

starcow hat geschrieben: 19.11.2022, 21:19 Update:
Das Einlesen klappt dank eurer Hilfe soweit einwandfrei. Jedoch liefert mir fgetc() beim Lesen einer Datei beim Wert 26 (1A) EOF, statt den tatsächlichen Wert.
Das lässt sich zwar umgehen, wenn ich den Modus von fopen() auf "rb" setze, jedoch bin ich mir nicht sicher, ob sich das wirklich so gehört? Ehrlich gesagt hab ich auch bis jetzt noch nicht so recht verstanden, was denn der Unterschied zwischen "normalen" Lesen "r" und "binary lesen" "rb" ist. Aber vielleicht ist dies einer (?) der Unterschiede?
.bmp Files sind keine Textdateien, du kannst die im Textmodus gar nicht korrekt lesen weil Textmodus macht Dinge wie \r\n in \n übersetzen, filtert also potentiell Bytes aus dem Stream raus.

Fun fact: Das war der Grund für den Bug, der immer noch der Bug ist, der mich mit großem Abstand am meisten Zeit gekostet hat. Hab damals das ganze Programm vermutlich dreimal from Scratch neu geschrieben, weil ich mir einfach nicht erklären konnte wieso beim Lesen des 3d Models erst alles richtig läuft aber dann ab einem zufälligen Punkt auf einmal plötzlich nur Müll daherkommt… bis ich eines Tages durch Zufall auf einer MSDN Seite gelandet bin, wo im Text indirekt etwas erwähnt wurde, dass bedeutet hätte, dass Textmodus der Default sein könnte. Die Idee dass sowas wie Textmodus der Default wäre, war für mein naives Selbst einfach dermaßen unvorstellbar… tbf, ich finde es immer noch einfach nur falsch…
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: 4 Bytes in Heap zu int

Beitrag von Krishty »

dot hat geschrieben: 15.11.2022, 12:18Sicher dass das mit MSVC war und nicht, e.g., clang? Ich versuche seit Jahren, MSVC dazu zu bewegen, einigermaßen effizienten Code für portable Serialization/Deserialization zu generieren; bisher ohne Erfolg…
Lustig: Heute veröffentlicht das Team einen Artikel, dass sie diese Optimierung vor Kurzem in Visual Studio 2022 implementiert haben.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten