Bitmapgröße verdoppeln

Also, die Aufgabe ist, dass man eine Bitmap durch Veränderung der binären-Datei verdoppelt. Das Programm sollte unter Linux in der Konsole laufen, ich habe jedoch aus Faulheit beim Fehlersuchen auf den BCB 2007 zurück gegriffen.
Code:
//Verdoppeln der Bildgroesse
bool CDoppelBitmap::Verdoppeln()
{       unsigned char temp_byte [3];
		int anzahl_byte=0;
		long alte_pos;
		long pos [2];
		int bearbeitete_elemente;

        //nach Farbtiefe unterscheiden
		switch(quelle->bit_pro_pixel)
		{	case 8: anzahl_byte=1; break;
			case 24: anzahl_byte=3; break;
			default: return false;
		}

        //Header und Farbdefinitionen kopieren
		*ziel=*quelle;

		fseek(quelle->datei,quelle->offset,SEEK_SET);
		fseek(ziel->datei,ziel->offset,SEEK_SET);

		//Bild verdoppeln (in x- und y-Richtung)
		for (int i=0; i<quelle->hoehe; ++i)
		{       alte_pos=ftell(ziel->datei);
				//In der Zeile die Pixel verdoppeln
				for (int j=0; j<quelle->breite; ++j)
				{   pos[0]=ftell(ziel->datei);
					bearbeitete_elemente=fread(temp_byte,sizeof(char),anzahl_byte,quelle->datei);
					bearbeitete_elemente=fwrite(temp_byte,sizeof(char),anzahl_byte,ziel->datei);
					bearbeitete_elemente=fwrite(temp_byte,sizeof(char),anzahl_byte,ziel->datei);
				}

				//Quell-Dateizeiger auf den Anfang der Zeile zurücksetzen
				fseek(quelle->datei,alte_pos,SEEK_SET);
				//Zeile ein zweites Mal schreiben
				for (int j=0; j<quelle->breite; ++j)
				{   pos[1]=ftell(ziel->datei);
					bearbeitete_elemente=fread(temp_byte,sizeof(char),anzahl_byte,quelle->datei);
					bearbeitete_elemente=fwrite(temp_byte,sizeof(char),anzahl_byte,ziel->datei);
					bearbeitete_elemente=fwrite(temp_byte,sizeof(char),anzahl_byte,ziel->datei);
				}
        }

        //Header anpassen
        ziel->breite*=2;
        ziel->hoehe*=2;
        ziel->datei_laenge+=ziel->datei_laenge-ziel->offset;
        ziel->groesse_pixeldaten*=4;

        return true;
}
Das Verhalten von diesem Stück Quellcode verblüfft mich aber leider ziemlich. Die Werte in dem pos-Array werden nämlich kleiner, was schließlich bedeuten würde, dass der Dateizeiger nach vorne geschoben wird.
Desweiteren wird einer der beiden fwrite-Befehle nicht wirklich ausgeführt, weil die Werte sich immer nur um 3 Byte ändern.
Unter Linux erhalte ich noch einen Segmantation fault, aber dass ist jetzt nicht so relevant, auch wenn es interessant ist, dass ich unter LInux einen Speicherzugriffsfehler bekomme, der unter Windows nicht auftaucht.

Vielen Dank für eure Hilfe,
benediktibk

Vollständig:
Code:
#ifndef BITMAP
#define BITMAP

class CBitmap
{	public:
		int datei_laenge;
		int reserviert;
		int offset;
		int header_groesse;
		int breite;
		int hoehe;
		short anzahl_bildebenen;
		short bit_pro_pixel;
		int kompression;
		int groesse_pixeldaten;
		int xdpm;
		int ydpm;
		int anzahl_farben_genutzt;
		int anzahl_farben_wichtig;

		FILE *datei;
	
		CBitmap(char verzeichnis [], char modus []);
		~CBitmap();		
                CBitmap(CBitmap const& rechte_seite);
};

class CDoppelBitmap
{       private:
                CBitmap *quelle;
                CBitmap *ziel;
                bool fehler;
        public:
                CDoppelBitmap(char ziel_verzeichnis [],char quell_verzeichnis []);
                ~CDoppelBitmap();
                bool Verdoppeln();
                bool get_fehler();
};

//Konstruktor von CBitmap
CBitmap::CBitmap(char verzeichnis [], char modus [])
{	datei=NULL;
        char temp_byte [2];

	//Oeffnen der Datei
	datei=fopen(verzeichnis,modus);

	//Fehler beim Oeffnen abfangen
	if (datei==NULL)
	        return;

	rewind(datei);
	
	//char Ueberspringen
	fread(temp_byte,sizeof(char),2,datei);

	//Einlesen des Headers
	fread(&datei_laenge,sizeof(int),1,datei);
 	fread(&reserviert,sizeof(int),1,datei);
 	fread(&offset,sizeof(int),1,datei);
 	fread(&header_groesse,sizeof(int),1,datei);
 	fread(&breite,sizeof(int),1,datei);
 	fread(&hoehe,sizeof(int),1,datei);
 	fread(&anzahl_bildebenen,sizeof(short),1,datei);
 	fread(&bit_pro_pixel,sizeof(short),1,datei);
 	fread(&kompression,sizeof(int),1,datei);
 	fread(&groesse_pixeldaten,sizeof(int),1,datei);
 	fread(&xdpm,sizeof(int),1,datei);
 	fread(&ydpm,sizeof(int),1,datei);
 	fread(&anzahl_farben_genutzt,sizeof(int),1,datei);
 	fread(&anzahl_farben_wichtig,sizeof(int),1,datei);

	rewind(datei);
}

//Destruktor von CBitmap
CBitmap::~CBitmap()
{   char temp_byte[]="BM";

	rewind(datei);
	
	//BM-String schreiben
	fwrite(temp_byte,sizeof(char),2,datei);

	//Schreiben des Headers
	fwrite(&datei_laenge,sizeof(int),1,datei);
	fwrite(&reserviert,sizeof(int),1,datei);
	fwrite(&offset,sizeof(int),1,datei);
	fwrite(&header_groesse,sizeof(int),1,datei);
	fwrite(&breite,sizeof(int),1,datei);
	fwrite(&hoehe,sizeof(int),1,datei);
	fwrite(&anzahl_bildebenen,sizeof(short),1,datei);
	fwrite(&bit_pro_pixel,sizeof(short),1,datei);
	fwrite(&kompression,sizeof(int),1,datei);
	fwrite(&groesse_pixeldaten,sizeof(int),1,datei);
	fwrite(&xdpm,sizeof(int),1,datei);
	fwrite(&ydpm,sizeof(int),1,datei);
	fwrite(&anzahl_farben_genutzt,sizeof(int),1,datei);
	fwrite(&anzahl_farben_wichtig,sizeof(int),1,datei);

	fflush(datei);
	fclose(datei);
}

//Kopierkonstruktor von CBitmap
CBitmap::CBitmap(CBitmap const& rechte_seite)
{       char temp_byte;

        //Header kopieren
        datei_laenge=rechte_seite.datei_laenge;
        reserviert=rechte_seite.reserviert;
        offset=rechte_seite.offset;
        header_groesse=rechte_seite.header_groesse;
        breite=rechte_seite.breite;
        hoehe=rechte_seite.hoehe;
        anzahl_bildebenen=rechte_seite.anzahl_bildebenen;
        bit_pro_pixel=rechte_seite.bit_pro_pixel;
        kompression=rechte_seite.kompression;
        groesse_pixeldaten=rechte_seite.groesse_pixeldaten;
        xdpm=rechte_seite.xdpm;
        ydpm=rechte_seite.ydpm;
        anzahl_farben_genutzt=rechte_seite.anzahl_farben_genutzt;
        anzahl_farben_wichtig=rechte_seite.anzahl_farben_wichtig;

        //Farbdefinitionen kopieren
        fseek(datei,13L*sizeof(int),SEEK_SET);
        fseek(rechte_seite.datei,13L*sizeof(int),SEEK_SET);
        while(ftell(rechte_seite.datei)<offset)
        {       fread(&temp_byte,sizeof(char),1,rechte_seite.datei);
                fwrite(&temp_byte,sizeof(char),1,datei);
        }
}

//Konstruktor von CDoppelBitmap
CDoppelBitmap::CDoppelBitmap(char ziel_verzeichnis [], char quell_verzeichnis [])
{       fehler=false;

        quelle=new CBitmap(quell_verzeichnis,"rb");
        ziel=new CBitmap(ziel_verzeichnis,"wb");

        //Fehler beim Oeffnen abfangen
        if (quelle->datei==NULL || ziel->datei==NULL)
        {       fehler=true;
                return;
        }
}

//Destruktor von CDoppelBitmap
CDoppelBitmap::~CDoppelBitmap()
{       delete quelle;
        delete ziel;
}

//get_fehler von CDoppelBitmap
bool CDoppelBitmap::get_fehler()
{       return fehler;
}

//Verdoppeln der Bildgroesse
bool CDoppelBitmap::Verdoppeln()
{       unsigned char temp_byte [3];
		int anzahl_byte=0;
		long alte_pos;
		long pos [2];
		int bearbeitete_elemente;

        //nach Farbtiefe unterscheiden
		switch(quelle->bit_pro_pixel)
		{	case 8: anzahl_byte=1; break;
			case 24: anzahl_byte=3; break;
			default: return false;
		}

        //Header und Farbdefinitionen kopieren
		*ziel=*quelle;

		fseek(quelle->datei,quelle->offset,SEEK_SET);
		fseek(ziel->datei,ziel->offset,SEEK_SET);

		//Bild verdoppeln (in x- und y-Richtung)
		for (int i=0; i<quelle->hoehe; ++i)
		{       alte_pos=ftell(ziel->datei);
				//In der Zeile die Pixel verdoppeln
				for (int j=0; j<quelle->breite; ++j)
				{   pos[0]=ftell(ziel->datei);
					bearbeitete_elemente=fread(temp_byte,sizeof(char),anzahl_byte,quelle->datei);
					bearbeitete_elemente=fwrite(temp_byte,sizeof(char),anzahl_byte,ziel->datei);
					bearbeitete_elemente=fwrite(temp_byte,sizeof(char),anzahl_byte,ziel->datei);
				}

				//Quell-Dateizeiger auf den Anfang der Zeile zurücksetzen
				fseek(quelle->datei,alte_pos,SEEK_SET);
				//Zeile ein zweites Mal schreiben
				for (int j=0; j<quelle->breite; ++j)
				{   pos[1]=ftell(ziel->datei);
					bearbeitete_elemente=fread(temp_byte,sizeof(char),anzahl_byte,quelle->datei);
					bearbeitete_elemente=fwrite(temp_byte,sizeof(char),anzahl_byte,ziel->datei);
					bearbeitete_elemente=fwrite(temp_byte,sizeof(char),anzahl_byte,ziel->datei);
				}
        }

        //Header anpassen
        ziel->breite*=2;
        ziel->hoehe*=2;
        ziel->datei_laenge+=ziel->datei_laenge-ziel->offset;
        ziel->groesse_pixeldaten*=4;

        return true;
}

#endif
Code:
#include <stdio.h>
#include <iostream.h>
//#include <conio.h>
#include "bitmap_klasse.h"

int main()
{       CDoppelBitmap *bitmap;

        bitmap=new CDoppelBitmap ("bildx4.bmp","bild.bmp");

        if (!bitmap->get_fehler())
                bitmap->Verdoppeln();
        else
                printf("Dateien konnten nicht geöffnet werden");
		//getch();

		delete bitmap;

        return 0;
}
 
Zurück
Oben