Verständnisfrage in C

Hallo zusammen,
ich steh gerade irgendwie total aufm Schlauch. Im Prinzip kommt der Code aus dem anderen Thread hier von mir, aber das tut nicht so viel zur Sache bzw. zur Frage. Ich habe folgenden Code:
Code:
int main(void) {
	FILE* infile;
	FILE* outfile;
	unsigned char red, green, blue;
	unsigned int pixel;
	unsigned int maxval;
	unsigned short width, height;
	size_t i;

	infile = fopen("D:/fb0", "r");
	outfile = fopen("D:/fb.ppm", "wb");
	width = 480;
	height = 854;
	maxval = 255;
	fprintf(outfile, "P3\n#created with rgb2ppm\n%d %d\n%d\n", width, height, maxval);
	for (i = 0; i < width * height; i += 1) {
		fread(&pixel, 4, 1, infile);
		red = (unsigned short)((pixel & 0xFF0000) >> 16);  // 5
		green = (unsigned short)((pixel & 0xFF00) >> 8); // 6
		blue = (unsigned short)((pixel & 0xFF));         // 5
		fprintf(outfile, "%d %d %d\n", red, green, blue);
	}
	return 0;
}

Was er meiner Meinung nach macht ist folgendes: Er öffnet die fb0 Datei und läuft dann Breite x Höhe oft die for Schleife durch, dabei liest er 4 Bytes in "pixel" ein und nimmt dann das zweite Byte, das dritte Byte und das vierte Byte für die jeweiligen Farben mit einem Bitshift, sodass die Werte für die jeweiligen Farben am Anfang stehen. D.h., dass das erste Byte immer verworfen wird.

Wenn ich den Code jetzt so ändere:
Code:
int main(void) {
	FILE* infile;
	FILE* outfile;
	unsigned char red, green, blue;
	unsigned int pixel;
	unsigned char qu;
	unsigned int maxval;
	unsigned short width, height;
	size_t i;

	infile = fopen("D:/fb0", "r");
	outfile = fopen("D:/fb.ppm", "wb");
	width = 480;
	height = 854;
	maxval = 255;
	fprintf(outfile, "P3\n#created with rgb2ppm\n%d %d\n%d\n", width, height, maxval);
	fread(&qu, 1, 1, infile);
	for (i = 0; i < width * height; i += 1) {
		fread(&pixel, 4, 1, infile);
		red = (unsigned short)((pixel & 0xFF000000) >> 24);  // 5
		green = (unsigned short)((pixel & 0xFF0000) >> 16); // 6
		blue = (unsigned short)((pixel & 0xFF00) >> 8);         // 5
		fprintf(outfile, "%d %d %d\n", red, green, blue);
	}
	return 0;
}

Dann müsste doch in "qu" das erste Byte landen und dann lese ich immer wieder 4 Bytes ein und nehme diesmal die ersten 3 Bytes anstatt die letzten 3 Bytes. Entsprechend muss ich den Bitshift verändern, aber wieso kommt am Ende definitiv was anderes raus? Die Farbwerte stimmen nämlich nicht mehr im entstandenen Bild.
 
Habs glaube ich so halb kapiert. Hat was mit Endianness zu tun oder? Die 4 Bytes in der Datei haben die Reiehenfolge 1,2,3,4, aber im int dann 4,3,2,1, also nehme ich in der for Schleife doch, dass dritte, zweite und erste Byte.
 
richtig ...

was du ließt ist vermutlich eine art bitmap mit alpha kanal ...

dementsprechend haben vermutlich je 4 byte den aufbau

ARGB

wenn du nun 4 byte in einen int ließt und über maskierung ausließt passiert dies:

ARGB

-X-- -> R
--X- -> G
---X -> B

warum man dafür uints bemüht und keine structs, erschließt sich mir zwar nicht, aber ...
 
Jetzt nochmal im Klartext :D. Ich wollte das ganze mal in Java bringen, wie gesagt einfach nur so aus Spaß.

Wenn ich die ersten Bytes lese, dann ist der Binärstring in Java so: 10111101 01001101 00110001 11111111
und in C so:
11111111 00110001 01001101 10111101

Also in Java ist es dann Big-Endian und in C speichert fread die Bytes in Little-Endian oder? Denn meines Wissens ist das Format RGBX, heißt also das 4te Byte steht für "nix". In deinem Beispiel hast du das erste Byte genommen.

EDIT: Irgendwas stimmt daran immer noch nicht. Wenn das Format RGBX ist und ich in C Little-Endian habe, dann müsste die Bytes in XBGR angeordnet sein, aber tatsächlich nutze ich die Bytes ja in XRGB Reihenfolge. Also hast du wohl doch recht? Verwirrend :D

Was meinst du denn inwiefern structs da helfen? Verstehe ich gerade nicht so. Dann würde ich doch einfach ein struct "rgb" nehmen und dort die uint's reinhauen oder worauf spielst du an?
 
Zuletzt bearbeitet:
Wie liegen denn die Bytes im "infile" vor? (und warum "fopen(infile,'r')" - also nicht im binären Modus?)
RGBA RGBA RGBA => das erste fread(..., 1, 1) sorgt dafür, dass nun
GBAR GBAR GBAR eingelesen wird.
Edit: und ja, Java nutzt BigEndian.
 
Wie liegen denn die Bytes im "infile" vor? (und warum "fopen(infile,'r')" - also nicht im binären Modus?)

Ganz ehrlich: Ist eine gute Frage. Der Code ist größtenteils kopiert worden, weil ich, wie man sicherlich schon gemerkt hat, mit dem Umgang von Binärdaten nur viel halb Ahnung habe.

Wie krieg ich denn raus, wie es in der Datei liegt?
 
Liegen genauso vor wie sie Java einliest. Müsste also B G R X sein, weil das C Programm X R G B erhält und das zweite Byte für rot benutzt, dass dritte für grün und das vierte für blau.

@GrafZahl
Was würdest du denn mit structs machen bzw. wie hilft das einem weiter?
 
Liegen genauso vor wie sie Java einliest. Müsste also B G R X sein, weil das C Programm X R G B erhält und das zweite Byte für rot benutzt, dass dritte für grün und das vierte für blau.
Also führt die Verschiebung (wofür auch immer diese gut sein soll ;) ) um 1 Byte dazu, dass fread nun RGXB => pixel (= little endian: BXGR) einliest.
Man bekommt also Blue aus dem anderen Pixel.
 
Zurück
Oben