C++: Konvertieren eines uint32 Array in ein void*?
Hi,
ich habe diese Frage in einem Kommentar bei einer anderen Frage stehen, aber da heute Abgabe ist stelle ich es hier noch einmal für alle.
Ich habe ein uint32 Array mit Byte Werten welche Farbwerte eines Bildes repräsentieren. Diese Farbwerte möchte ich in ein neues Bild schreiben mit Funktion TIFFWriteScanline() von der Bibliothek Libtiff. Folgender Code existiert:
//Globale Variable
auto image = new uint32[20976 * 20976];
//for schleife einer Funktion
for (uint32 row = 0; row < nheight; row++)
{
TIFFWriteScanline(tif,&image[row * nheight], row, 0);
}
Ich bekomme keine Fehlermeldung aber das Bild sieht nicht so aus wie es aussehen soll. Die Farbwerte im Bild stimmen nicht.
Kurz bevor ich in die For-Schleife gehe, scheinen die RGB-Werte in image noch zu stimmen. Die habe ich mir für eine Position ausgeben lassen und die Werte machen für diese Position Sinn. Die Vermutung ist, dass ich die Bytes nicht ordentlich in TIFFWriteScanline() übergebe.
TIFFWriteScanline() erwartet kein uint32 Array sondern ein void*. Deshalb habe ich das '&' vor image geschrieben. Kann es sein, dass das so nicht korrekt ist? Wie kann ich die uint32 Byte Werte korrekt in void* konvertieren?
Hat das Bild denn die richtigen Maße, also stimmen nur die Farben nicht, oder kommt noch mehr beisammen, wo es hakt?
Das Bild hat die richtigen Maße ja. Ich kann sogar den Fluss oder das Dorf an der richtigen Stelle grob erkennen. Aber ich habe so komische RGB Streifen im Bild.
2 Antworten
An sich sieht der Code soweit in Ordnung aus (ein bisschen unsauber, aber in Ordnung).
Erstmal: void* bedeutet an sich nur: "Vollkommen egal, wie es deklariert wurde, solange es ein Pointer ist geht das erstmal klar."
Bedeutet: Es ist vollkommen egal, ob dein Array vom Typ uint32 (nicht uint32_t?) oder color_value ist.
Z.B. geht auch das:
struct color_value{
uint8_t R, G, B, A;
};
auto image = new color_value[20976 * 20976];
Deinen bisherigen Breschreibungen nach, klingt es am ehesten danach, dass entweder die Farbwerte in der Reihenfolge RGBA erwartet aber in ABGR übergeben werden bzw. umgekehrt.
Stichwort: Endianess (https://de.wikipedia.org/wiki/Byte-Reihenfolge)
Wenn es ein void* ist, müsstest du nicht auch irgendwo eine Länge mitgeben? Du hast auch ein Element im Array übergeben, und nicht das ganze Array. Irgendwas passt da nicht.
Oh man, ich stecke aktuell zu wenig in C drin. Ich würde vermutlich ewig ausprobieren, mir die Adressen und die Inhalte ausgeben lassen, ob ich die richtigen Werte an die richtige Stelle schreiben. Die Frage ist aber natürlich beim Tutorial, was image eigentlich genau ist. Was für eine Art Array ist das? Wird das Bild zeilenweise abgespeichert?
Also beim Tutorial wird Image nur folgendermaßen initialisiert:
char *image=new char [width*height*sampleperpixel];
Bei mir ist image ein
auto image = new uint32[20976 * 20976];
weil ich Bytefolgen habe. So wie ich das verstehe muss ich meine Bytes irgendwie in ein char* hineinschreiben. Aber das scheint nicht so einfach zu sein.
Ich habe mich da grob an einem Tutorial orientiert: Dort steht
linebytes ist die Breite (20976) * 3.
Und buf ist:
Wenn ich aber versuche diese memcpy() Zeile einzufügen bekomme ich eine Zugriffsverletzung. Da das Bild ja durchaus auch ohne den buffer geschrieben wird, dachte ich ich könne es weglassen.