//---Include--- #include "DateiSystem.h" #include #include "Bild.h" #include "Text.h" #ifdef WIN32 # include "Fenster.h" # include "Fortschritt.h" # include "Globals.h" # include "Schrift.h" #endif #include "Datei.h" #include "Logging.h" using namespace Framework; // LTDB Dateivormat // Inhalt der LTDBPixel Klasse aus Dateisystem.h // Konstruktor LTDBPixel::LTDBPixel(LTDBPixel* davor) : ReferenceCounter(), davor(davor), index(0), iR(0), iG(0), iB(0), iA(0), miR(8), miG(8), miB(8), miA(8), maxIndex(1), change(0), changeR(0), changeG(0), changeB(0), changeA(0), komp(0), R(0), G(0), B(0), A(0) {} // Destruktor LTDBPixel::~LTDBPixel() { if (davor) davor->release(); } // nicht constant bool LTDBPixel::addBitZuFarbe( unsigned char bit) // Fügt den Farbwerten ein Bit hinzu { if (changeR && iR != miR) // Das Bit gehört zu Rot { R = (unsigned char)(R | ((bit & 0x1) << (7 - komp - iR))); ++iR; } else if (changeG && iG != miG) // Das Bit gehört zu Grün { G = (unsigned char)(G | ((bit & 0x1) << (7 - komp - iG))); ++iG; } else if (changeB && iB != miB) // Das Bit gehört zu Blau { B = (unsigned char)(B | ((bit & 0x1) << (7 - komp - iB))); ++iB; } else if (changeA && iA != miA) // Das Bit gehört zu Alpha { A = (unsigned char)(A | ((bit & 0x1) << (7 - komp - iA))); ++iA; } else // Das Bit gehört zum nächsten Pixel return false; return true; } char LTDBPixel::addByte( char byte, char begin) // gibt ende des Pixels zurück, -1 wenn nicht zu ende { if (begin >= 8 || begin < 0) return -1; for (int i = begin; i < 8; ++i) { switch (index) { case 0: // Das erste Bit eines Pixels speichert, ob sich an der // Komprimierung etwas änderte change = (bool)((byte >> (7 - i)) & 0x1); if (!change) // Ändert sich nichts an der Komprimierung, so werden // die Werte vom vorherigen Pixel übernommen { if (!davor) // Die Datei ist beschädigt ( Der erste Pixel kann // nicht von dem davor Übernemen ) { #ifdef WIN32 MessageBox(NULL, "Fehler, die Bilddatei ist beschädigt", "Fehler", MB_ICONERROR); #endif exit(0); } changeR = davor->getChangeR(); changeG = davor->getChangeG(); changeB = davor->getChangeB(); changeA = davor->getChangeA(); komp = davor->getKomp() & 7; miR = (char)(miR - komp), miG = (char)(miG - komp), miB = (char)(miB - komp), miA = (char)(miA - komp); if (!changeR) R = davor->getR(); if (!changeG) G = davor->getG(); if (!changeB) B = davor->getB(); if (!changeA) A = davor->getA(); maxIndex = (char)(maxIndex + (changeR + changeG + changeB + changeA) * (8 - komp)); // Bestimmung der Länge // des Pixels in Bits. Jede Farbe hat von grund auf 8 Bits, // durch komprimierung kanns kleiner sein } else maxIndex = (char)(maxIndex + 7); // Da der Pixel nicht die Werte // des vorherigen übernimmt, // wird er um 7 Bits größer break; case 1: // Das zweite Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (change) // Das Bit gehört zu den 7 Komprimierungsbits changeR = (bool)((byte >> (7 - i)) & 0x1); else { if (!addBitZuFarbe(( unsigned char)(byte >> (7 - i)))) // Das Bit gehört zur Farbe return (unsigned char)i; } break; case 2: // Das dritte Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (change) // Das Bit gehört zu den 7 Komprimierungsbits changeG = (bool)((byte >> (7 - i)) & 0x1); else { if (!addBitZuFarbe(( unsigned char)(byte >> (7 - i)))) // Das Bit gehört zur Farbe return (unsigned char)i; } break; case 3: // Das vierte Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (change) // Das Bit gehört zu den 7 Komprimierungsbits changeB = (bool)((byte >> (7 - i)) & 0x1); else { if (!addBitZuFarbe(( unsigned char)(byte >> (7 - i)))) // Das Bit gehört zur Farbe return (unsigned char)i; } break; case 4: // Das fünfte Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (change) // Das Bit gehört zu den 7 Komprimierungsbits changeA = (bool)((byte >> (7 - i)) & 0x1); else { if (!addBitZuFarbe(( unsigned char)(byte >> (7 - i)))) // Das Bit gehört zur Farbe return (unsigned char)i; } break; case 5: // Das sechste Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (change) // Das Bit gehört zu den 7 Komprimierungsbits komp = (unsigned char)(komp | ((unsigned char)((byte >> (7 - i)) & 0x1) << 2)) & 7; else { if (!addBitZuFarbe(( unsigned char)(byte >> (7 - i)))) // Das Bit gehört zur Farbe return (unsigned char)i; } break; case 6: // Das siebte Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (change) // Das Bit gehört zu den 7 Komprimierungsbits komp = (unsigned char)(komp | ((unsigned char)((byte >> (7 - i)) & 0x1) << 1)) & 7; else { if (!addBitZuFarbe(( unsigned char)(byte >> (7 - i)))) // Das Bit gehört zur Farbe return (unsigned char)i; } break; case 7: // Das achte Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (change) // Das Bit gehört zu den 7 Komprimierungsbits { komp = (unsigned char)(komp | ((byte >> (7 - i)) & 0x1)) & 7; // Das war das letzte Komprimierungsbit // Komprimierung auswerten miR = (char)(miR - komp), miG = (char)(miG - komp), miB = (char)(miB - komp), miA = (char)(miA - komp); if (!changeR) R = davor->getR(); if (!changeG) G = davor->getG(); if (!changeB) B = davor->getB(); if (!changeA) A = davor->getA(); maxIndex = (char)(maxIndex + (changeR + changeG + changeB + changeA) * (8 - komp)); // Bitlänge des Pixels } else { if (!addBitZuFarbe(( unsigned char)(byte >> (7 - i)))) // Das Bit gehört zur Farbe return (unsigned char)i; } break; default: // Die restlichen Bits speichern alle die Farbwerte des Pixels if (!addBitZuFarbe( (unsigned char)(byte >> (7 - i)))) // Das Bit gehört zur Farbe return (unsigned char)i; break; } ++index; if (index >= maxIndex) { if (davor) { if (changeR) R = (unsigned char)(davor->getR() + R); if (changeG) G = (unsigned char)(davor->getG() + G); if (changeB) B = (unsigned char)(davor->getB() + B); if (changeA) A = (unsigned char)(davor->getA() + A); davor = (LTDBPixel*)davor->release(); } return (char)(i + 1); } } return -1; } void LTDBPixel::setFarbe(int f) // setzt die Farbe des Pixels { // Da diese Funktion aufgerufen wird, möchte man die Klasse nun zum speichern // verwenden // Werte zurücksetzen, fals mit der Klasse schon geladen oder gespeichert // wurde index = 0, maxIndex = 1; change = 0, changeR = 0, changeG = 0, changeB = 0, changeA = 0, komp = 0; iR = 0, iG = 0, iB = 0, iA = 0; miR = 8, miG = 8, miB = 8, miA = 8; // Farbwerte setzen R = (unsigned char)(f >> 16); G = (unsigned char)(f >> 8); B = (unsigned char)f; A = (unsigned char)(f >> 24); } void LTDBPixel::komprimieren() // Komprimiert den Pixel { maxIndex = 1; if (!davor) { // Das ist der erste Pixel change = 1; changeR = 1; changeG = 1; changeB = 1; changeA = 1; maxIndex = (char)(maxIndex + 7); miR = (char)getBits(R); miG = (char)getBits(G); miB = (char)getBits(B); miA = (char)getBits(A); } else { // Es wird die differenz zum vorrigen Pixel gespeichert miR = (char)getBits((char)(R - davor->getR())); miG = (char)getBits((char)(G - davor->getG())); miB = (char)getBits((char)(B - davor->getB())); miA = (char)getBits((char)(A - davor->getA())); changeR = R != davor->getR(); changeG = G != davor->getG(); changeB = B != davor->getB(); changeA = A != davor->getA(); } // Prüfen ob sich etwas ändert if (!miR && changeR) ++miR; if (!miG && changeG) ++miG; if (!miB && changeB) ++miB; if (!miA && changeA) ++miA; int k = (miR > miG ? miR : miG); k = (k > miB ? k : miB); k = (k > miA ? k : miA); miR = (char)k, miG = (char)k, miB = (char)k, miA = (char)k; komp = (unsigned char)(8 - k) & 7; maxIndex = (char)(maxIndex + (changeR + changeG + changeB + changeA) * k); if (davor) { if (changeR != davor->getChangeR() || changeG != davor->getChangeG() || changeB != davor->getChangeB() || changeA != davor->getChangeA() || komp != davor->getKomp()) { // Es ändert sich etwas change = 1; maxIndex = (char)(maxIndex + 7); } else { // Es ändert sich nichts change = 0; } } } bool LTDBPixel::getNextFarbeBit( char& byte, int i) // Speichert das nächste Farbbit in byte { unsigned char RR = R; unsigned char GG = G; unsigned char BB = B; unsigned char AA = A; if (davor) { RR = (unsigned char)(RR - davor->getR()); GG = (unsigned char)(GG - davor->getG()); BB = (unsigned char)(BB - davor->getB()); AA = (unsigned char)(AA - davor->getA()); } if (changeR && iR != miR) // Das Bit gehört zu Rot { byte |= (char)(((RR >> (7 - komp - iR)) & 0x1) << (7 - i)); ++iR; } else if (changeG && iG != miG) // Das Bit gehört zu Grün { byte |= (char)(((GG >> (7 - komp - iG)) & 0x1) << (7 - i)); ++iG; } else if (changeB && iB != miB) // Das Bit gehört zu Blau { byte |= (char)(((BB >> (7 - komp - iB)) & 0x1) << (7 - i)); ++iB; } else if (changeA && iA != miA) // Das Bit gehört zu Alpha { byte |= (char)(((AA >> (7 - komp - iA)) & 0x1) << (7 - i)); ++iA; } else // Der Pixel ist bereits zu ende return false; return true; } char LTDBPixel::getNextByte( char& byte, int begin) // Gibt die nächsten Bits Zurück, -1 wenn der Pixel // nicht zu ende ist { // bbegin gibt an wohin in die byte-variable geschrieben werden soll // die Funktion gibt das ende des Pixels in der byte-variable zurück // -1 heißt, dass der Pixel nicht zu ende ist for (int i = begin; i < 8; ++i) { switch (index) { case 0: // Das erste Bit des Pixels speichert, ob sich etwas an der // Komprimierung ändert byte |= (char)(((int)change & 0x1) << (7 - i)); break; case 1: // Das zweite Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (change) // Komprimierung byte |= (char)(((int)changeR & 0x1) << (7 - i)); else // Farbe { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 2: // Das dritte Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (change) // Komprimierung byte |= (char)(((int)changeG & 0x1) << (7 - i)); else // Farbe { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 3: // Das vierte Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (change) // Komprimierung byte |= (char)(((int)changeB & 0x1) << (7 - i)); else // Farbe { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 4: // Das fünfte Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (change) // Komprimierung byte |= (char)(((int)changeA & 0x1) << (7 - i)); else // Farbe { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 5: // Das sechste Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (change) // Komprimierung byte |= (char)(((komp >> 2) & 0x1) << (7 - i)); else // Farbe { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 6: // Das siebte Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (change) // Komprimierung byte |= (char)(((komp >> 1) & 0x1) << (7 - i)); else // Farbe { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 7: // Das sechste Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (change) // Komprimierung byte |= (char)((komp & 0x1) << (7 - i)); else // Farbe { if (!getNextFarbeBit(byte, i)) return (char)i; } break; default: // Die restlichen Bits speichern die Farbe des Pixels if (!getNextFarbeBit(byte, i)) return (char)i; break; } ++index; if (index >= maxIndex) { if (davor) davor = (LTDBPixel*)davor->release(); return (char)(i + 1); } } return -1; } // constant int LTDBPixel::zuFarbe() const // gibt den Pixel als Farbe zurück { return (((int)R << 16) | ((int)G << 8) | (int)B | ((int)A << 24)); } bool LTDBPixel::getChangeR() const { return changeR; } bool LTDBPixel::getChangeG() const { return changeG; } bool LTDBPixel::getChangeB() const { return changeB; } bool LTDBPixel::getChangeA() const { return changeA; } unsigned char LTDBPixel::getKomp() const { return komp; } unsigned char LTDBPixel::getR() const // gibt Rot zurück { return R; } unsigned char LTDBPixel::getG() const // gibt Grün zurück { return G; } unsigned char LTDBPixel::getB() const // gibt Blau zurück { return B; } unsigned char LTDBPixel::getA() const // gibt Alpha zurück { return A; } // Inhalt der LTDBDateiKopf Klasse aus Dateisystem.h // konstructor LTDBDateiKopf::LTDBDateiKopf() : ReferenceCounter(), bilder(new RCArray()), pos(new Array<__int64>()), bAnzahl(0) {} // destructor LTDBDateiKopf::~LTDBDateiKopf() { bilder->release(); pos->release(); } // nicht constant void LTDBDateiKopf::removeBild(int i) { if (i >= bAnzahl) return; bilder->remove(i); pos->remove(i); --bAnzahl; } void LTDBDateiKopf::removeBild(Text* txt) { int i = -1; for (int ii = 0; ii < bAnzahl; ++ii) { Text* b = bilder->z(ii); if (b->istGleich(txt->getText())) { i = ii; break; } } txt->release(); if (i == -1) return; bilder->remove(i); pos->remove(i); --bAnzahl; } void LTDBDateiKopf::addBild(Text* txt) { bilder->add(txt, bAnzahl); pos->add(0, bAnzahl); ++bAnzahl; } void LTDBDateiKopf::setBildPos(int i, __int64 pos) { this->pos->set(pos, i); } void LTDBDateiKopf::setBildPos(Text* txt, __int64 pos) { int i = -1; for (int ii = 0; ii < bAnzahl; ++ii) { Text* b = bilder->z(ii); if (b->istGleich(txt->getText())) { i = ii; break; } } txt->release(); if (i == -1) return; this->pos->set(pos, i); } void LTDBDateiKopf::laden(FBalken* f, std::ifstream* inF) { if (inF->is_open() && inF->good()) { char b = 0; inF->read(&b, 1); bAnzahl = b << 8; inF->read(&b, 1); bAnzahl |= b & 0xFF; #ifdef WIN32 if (f) { f->reset(); f->setAktionAnzahl(bAnzahl); } #endif bilder->leeren(); pos->leeren(); for (int i = 0; i < bAnzahl; ++i) { LTDBKopf* kpf = new LTDBKopf(); kpf->laden(inF); // bildname und halbe datei position bilder->add(kpf->getTitel()); // setzt titel Punkt gr = kpf->getSize(); kpf->release(); char p[5]; inF->read((char*)p, 5); // andere hälfte der Dateiposition unsigned __int64 position = (((__int64)gr.x << 52) & 0xFFF0000000000000) | (((__int64)gr.y << 40) & 0xFFF0000000000) | (((__int64)p[0] << 32) & 0xFF00000000) | (((__int64)p[1] << 24) & 0xFF000000) | (((__int64)p[2] << 16) & 0xFF0000) | (((__int64)p[3] << 8) & 0xFF00) | ((__int64)p[4] & 0xFF); pos->add(position, i); // setzt position #ifdef WIN32 if (f) f->aktionPlus(); #endif } } } // constant void LTDBDateiKopf::speichern(std::ofstream* outF) const { if (outF->is_open() && outF->good()) { char b = (char)(bAnzahl >> 8); outF->write(&b, 1); b = (char)bAnzahl; outF->write(&b, 1); for (int i = 0; i < bAnzahl; ++i) { LTDBKopf* kpf = new LTDBKopf(); __int64 position = pos->get(i); kpf->Init(bilder->get(i), Punkt((int)(position >> 52), (int)(position >> 40))); kpf->speichern(outF); kpf->release(); char p[] = {(char)(position >> 32), (char)(position >> 24), (char)(position >> 16), (char)(position >> 8), (char)(position)}; outF->write((char*)p, 5); } } } Text* LTDBDateiKopf::getBild(int i) const { return bilder->get(i); } Text* LTDBDateiKopf::zBild(int i) const { return bilder->z(i); } __int64 LTDBDateiKopf::getBildPosition(Text* txt) const { int i = -1; for (int ii = 0; ii < bAnzahl; ++ii) { Text* b = bilder->z(ii); if (b->istGleich(txt->getText())) { i = ii; break; } } txt->release(); if (i == -1) return -1; return pos->get(i); } __int64 LTDBDateiKopf::getBildPosition(int index) const { return pos->get(index); } int LTDBDateiKopf::getBildIndex(Text* txt) const { int i = -1; for (int ii = 0; ii < bAnzahl; ++ii) { Text* b = bilder->z(ii); if (b->istGleich(txt->getText())) { i = ii; break; } } txt->release(); return i; } int LTDBDateiKopf::getbAnzahl() const { return bAnzahl; } RCArray* LTDBDateiKopf::zBildListe() const { return bilder; } // Inhalt der LTDBKopf Klasse aus DateiSystem.h // Konstruktor LTDBKopf::LTDBKopf() : ReferenceCounter() {} // nicht constant void LTDBKopf::laden(std::ifstream* f) // Lät die Daten aus einer Datei { if (f->is_open()) { a = 0; b = 0; c = 0; char aa = 0; f->read(&aa, 1); int tl = (aa >> 4) & Bits(4); int BitAnzahl = 4 + tl * 5 + 24; f->seekg(-1, std::ios::cur); int Bytes = BitAnzahl / 8; if (((float)BitAnzahl / 8.0f) != (float)Bytes) ++Bytes; char byte = 0; for (int i = 0; i < Bytes; ++i) { f->read(&byte, 1); setBits(i * 8, i * 8 + 8, byte); } } } int LTDBKopf::Init(Text* t, const Punkt& g) // Befüllt die Daten { a = 0; b = 0; c = 0; int tl = t->getLength(); if (tl > 15) tl = 15; char* titel = new char[tl]; int skipped = 0; for (int i = 0; i < tl; ++i) { titel[i - skipped] = t->getText()[i]; if (titel[i - skipped] > 96 && titel[i - skipped] < 123) titel[i - skipped] = (char)(titel[i - skipped] - 96); else if (titel[i - skipped] > 64 && titel[i - skipped] < 91) titel[i - skipped] = (char)(titel[i - skipped] - 64); else if (titel[i - skipped] == 'ü' || titel[i - skipped] == 'Ü') titel[i - skipped] = 27; else if (titel[i - skipped] == 'ö' || titel[i - skipped] == 'Ö') titel[i - skipped] = 28; else if (titel[i - skipped] == 'ä' || titel[i - skipped] == 'Ä') titel[i - skipped] = 29; else if (titel[i - skipped] == 'ß') titel[i - skipped] = 30; else if (titel[i - skipped] == '.') titel[i - skipped] = 31; else ++skipped; } a = (__int64)((tl - skipped) & Bits(4)) << 60; int BeginBit = 4; for (int i = 0; i < tl - skipped; ++i) { BeginBit += 5; switch (i) { case 0: a |= (__int64)(titel[i] & 31) << 55; // ersten Buchstaben speichern break; case 1: a |= (__int64)(titel[i] & 31) << 50; // zweiten Buchstaben speichern break; case 2: a |= (__int64)(titel[i] & 31) << 45; // dritten Buchstaben speichern break; case 3: a |= (__int64)(titel[i] & 31) << 40; // vierten Buchstaben speichern break; case 4: a |= (__int64)(titel[i] & 31) << 35; // fünften Buchstaben speichern break; case 5: a |= (__int64)(titel[i] & 31) << 30; // sechsten Buchstaben speichern break; case 6: a |= (__int64)(titel[i] & 31) << 25; // siebten Buchstaben speichern break; case 7: a |= (__int64)(titel[i] & 31) << 20; // achten Buchstaben speichern break; case 8: a |= (__int64)(titel[i] & 31) << 15; // neunten Buchstaben speichern break; case 9: a |= (__int64)(titel[i] & 31) << 10; // zenten Buchstaben speichern break; case 10: a |= (__int64)(titel[i] & 31) << 5; // elften Buchstaben speichern break; case 11: a |= (__int64)(titel[i] & 31); // zwölften Buchstaben speichern break; case 12: b |= (__int32)(titel[i] & 31) << 27; // dreizenten Buchstaben speichern break; case 13: b |= (__int32)(titel[i] & 31) << 22; // vierzenten Buchstaben speichern break; case 14: b |= (__int32)(titel[i] & 31) << 17; // fünfzenten Buchstaben speichern break; } } __int16 grx = (short)(g.x & Bits(12)); __int16 gry = (short)(g.y & Bits(12)); int EndBit = BeginBit + 24; setBits(BeginBit, EndBit - 12, grx); setBits(BeginBit + 12, EndBit, gry); t->release(); delete[] titel; return skipped; } void LTDBKopf::setBits(int BeginBit, int EndBit, __int16 bits) { if (EndBit - BeginBit > 16) EndBit = BeginBit + 16; if (BeginBit < 64) { if (EndBit < 64) { a |= ((__int64)bits & Bits(EndBit - BeginBit)) << ((64 - BeginBit) - (EndBit - BeginBit)); } else { a |= (((__int64)bits >> (EndBit - 64)) & Bits(64 - BeginBit)); b |= ((__int32)bits & Bits(EndBit - 64)) << (32 - (EndBit - 64)); } } else { if (BeginBit < 96) { if (EndBit < 96) { b |= ((__int32)bits & Bits(EndBit - BeginBit)) << ((96 - BeginBit) - (EndBit - BeginBit)); } else { b |= (((__int32)bits >> (EndBit - 96)) & Bits(96 - BeginBit)); c = (char)(c | (((__int8)bits & Bits(EndBit - 96)) << (8 - (EndBit - 96)))); } } else { c = (char)(c | (((__int8)bits & Bits(EndBit - BeginBit)) << (8 - (EndBit - BeginBit)))); } } } // constant void LTDBKopf::speichern( std::ofstream* f) const // Speichert die Daten in eine Datei { if (f->is_open()) { int bits = 4 /*Titellänge*/ + getTitelLength() * 5 /*Titel*/ + 24 /*Bildgröße*/; int bytes = bits / 8; // Bytelänge des Dateikopfes if (((float)bits / 8.0f) != (float)bytes) ++bytes; char c = 0; for (int i = 0; i < bytes; ++i) { c = (char)getBits(i * 8, i * 8 + 8); f->write(&c, 1); } } } int LTDBKopf::getTitelLength() const // gibt die länge des Bildnamens zurück { return (int)(a >> 60 & Bits(4)); // Die Länge des Titels wird in den ersten // 4 Bits der Tatei gespeichert } Text* LTDBKopf::getTitel() const // gibt den Namen des Bildes zurück { Text* ret = new Text(""); char c[2]; c[1] = '\0'; int l = getTitelLength(); for (int i = 0; i < l; ++i) { c[0] = 0; switch (i) { case 0: c[0] = (a >> 55) & 31; // ersten Buchstaben holen break; case 1: c[0] = (a >> 50) & 31; // zweiten Buchstaben holen break; case 2: c[0] = (a >> 45) & 31; // dritten Buchstaben holen break; case 3: c[0] = (a >> 40) & 31; // vierten Buchstaben holen break; case 4: c[0] = (a >> 35) & 31; // fünften Buchstaben holen break; case 5: c[0] = (a >> 30) & 31; // sechsten Buchstaben holen break; case 6: c[0] = (a >> 25) & 31; // siebten Buchstaben holen break; case 7: c[0] = (a >> 20) & 31; // achten Buchstaben holen break; case 8: c[0] = (a >> 15) & 31; // neunten Buchstaben holen break; case 9: c[0] = (a >> 10) & 31; // zenten Buchstaben holen break; case 10: c[0] = (a >> 5) & 31; // elften Buchstaben holen break; case 11: c[0] = a & 31; // zwölften Buchstaben holen break; case 12: c[0] = (char)((b >> 27) & 31); // dreizenten Buchstaben holen break; case 13: c[0] = (char)((b >> 22) & 31); // vierzenten Buchstaben holen break; case 14: c[0] = (char)((b >> 17) & 31); // fünfzenten Buchstaben holen break; } if (c[0] == 27) c[0] = 'ü'; else if (c[0] == 28) c[0] = 'ö'; else if (c[0] == 29) c[0] = 'ä'; else if (c[0] == 30) c[0] = 'ß'; else if (c[0] == 31) c[0] = '.'; else c[0] = (char)(c[0] + 96); ret->append(c); } return ret; } Punkt LTDBKopf::getSize() const // gibt die Größe des Bildes zurück { int BeginBit = 4 /*Titellänge*/ + getTitelLength() * 5 /*Titel*/; int EndBit = BeginBit + 24; __int16 grx = getBits(BeginBit, EndBit - 12); __int16 gry = getBits(BeginBit + 12, EndBit); return Punkt((int)(grx & Bits(12)), (int)(gry & Bits(12))); } __int16 LTDBKopf::getBits(int begin, int ende) const // gibt die Bits von begin bis ende zurück( ohne ende ); { if (ende < begin) return 0; if (ende - begin > 16) ende = begin + 16; __int16 ret = 0; if (begin < 64) { if (ende < 64) { ret = (__int16)(a >> ((64 - begin) - (ende - begin)) & Bits(ende - begin)); } else { ret = (__int16)((a & Bits(64 - begin)) << (ende - 64)); ret = (__int16)(ret | ((b >> (32 - (ende - 64))) & Bits(ende - 64))); } } else { if (begin < 96) { if (ende < 96) { ret = (__int16)(b >> ((96 - begin) - (ende - begin)) & Bits(ende - begin)); } else { ret = (__int16)((b & Bits(96 - begin)) << (ende - 96)); ret = (__int16)(ret | ((c >> (8 - (ende - 96))) & Bits(ende - 96))); } } else { ret = (__int16)(c >> ((104 - begin) - (ende - begin)) & Bits(ende - begin)); } } return ret; } // Inhalt der LTDBKörper Klasse aus Dateisystem.h // Konstruktor LTDBBody::LTDBBody() : ReferenceCounter(), gr(0, 0), b(new Bild()) {} LTDBBody::LTDBBody(LTDBKopf* k) // ruft Init auf : ReferenceCounter(), gr(0, 0), b(new Bild()) { init(k); } // Destruktor LTDBBody::~LTDBBody() { b->release(); } // nicht constant void LTDBBody::init(LTDBKopf k) // Initialisiert, wird vor dem laden benötigt { gr = k.getSize(); int l = k.getTitelLength(); l = 4 + l * 5 + 24; dateiSize = (l / 8.0 == l) ? (l / 8) : (l / 8 + 1); } void LTDBBody::init(LTDBKopf* k) // Initialisiert, wird vor dem laden benötigt { gr = k->getSize(); int l = k->getTitelLength(); l = 4 + l * 5 + 24; dateiSize = (l / 8.0 == l) ? (l / 8) : (l / 8 + 1); k->release(); } void LTDBBody::laden(FBalken* zF, std::ifstream* inF) // läd das Bild { b->neuBild(gr.x, gr.y, 0xFF000000); // neues Bild erstellen int* buff = b->getBuffer(); int breite = b->getBreite(); char byte = 0; int index = 0; LTDBPixel* davor = 0; // zuletzt geladener Pixel LTDBPixel* dieser = new LTDBPixel(0); // momentan zu ladener Pixel int begin = 0; // Pixelbegin, endposition in der byte variable #ifdef WIN32 if (zF) { zF->reset(); zF->setAktionAnzahl(gr.x * gr.y); } #endif while (index < gr.x * gr.y) // für jeden Pixel { if (!dieser) // wenn es nicht der erste Pixel ist dieser = new LTDBPixel(dynamic_cast(davor->getThis())); int ende = -1; while (ende < 0) // Pixel laden { if (begin == 0) inF->read(&byte, 1); ende = dieser->addByte(byte, (char)begin); // byte auswerten begin = 0; } begin = ende; if (begin == 8) begin = 0; buff[(index % gr.x) + (index / gr.x) * breite] = dieser->zuFarbe(); if (davor) davor = (LTDBPixel*)davor->release(); davor = dynamic_cast(dieser->getThis()); dieser = (LTDBPixel*)dieser->release(); ++index; #ifdef WIN32 if (zF) zF->aktionPlus(); #endif } if (davor) davor = (LTDBPixel*)davor->release(); } void LTDBBody::setBild(Bild* b) // setzt das zu speichernde Bild { this->b->release(); this->b = b; } // constant void LTDBBody::speichern( FBalken* zF, std::ofstream* outF) const // speichert Bild { if (outF->is_open()) { LTDBPixel* letzter = 0; // Letzter gespeicherter Pixel LTDBPixel* dieser = new LTDBPixel(0); // Der momentan zu speichernde Pixel int begin = 0, ende = 0; // Pixelbeginn, endposition in der byte variable char byte = 0; // Der nächste byte der Datei bool w = 0; #ifdef WIN32 if (zF) { zF->reset(); zF->setAktionAnzahl(gr.x * gr.y); } #endif int* pBuff = b->getBuffer(); for (int i = 0; i < gr.x * gr.y; ++i) // für jeden Pixel { if (!dieser) // wenn es nicht der erste Pixel ist dieser = new LTDBPixel( dynamic_cast(letzter->getThis())); dieser->setFarbe(pBuff[i]); // Farbe des Pixels setzen dieser->komprimieren(); // Pixel komprimieren ende = -1; while (ende < 0) // byte befüllen { ende = dieser->getNextByte(byte, begin); begin = 0; w = 0; if (ende == -1 || ende == 8) // byte speichern { outF->write(&byte, 1); w = 1; byte = 0; } } // Pixel fertig begin = ende; if (begin == 8) begin = 0; if (letzter) letzter->release(); letzter = dynamic_cast( dieser->getThis()); // dieser wird zu letzter dieser = (LTDBPixel*)dieser->release(); #ifdef WIN32 if (zF) zF->aktionPlus(); #endif } if (letzter) letzter = (LTDBPixel*)letzter->release(); if (!w) { outF->write(&byte, 1); // Das letzte byte speichern } outF->flush(); // dateistream speichern } } Bild* LTDBBody::getBild() const // gibt das geladene Bild zurück { return dynamic_cast(b->getThis()); } const Punkt& LTDBBody::getSize() const // gibt die größe des Bildes zurück { return gr; } // Inhalt det LTDBDatei Klasse aus Dateisystem.h // Konstruktor LTDBDatei::LTDBDatei() : ReferenceCounter(), pfad(new Text()), datKpf(0) {} // Destruktor LTDBDatei::~LTDBDatei() { if (pfad) pfad->release(); if (datKpf) datKpf->release(); } // nicht constant void LTDBDatei::setDatei(Text* pfad) // Setzt den Pfad zur Datei { // Werte der eventuellen vorherigen Datei löschen if (datKpf) datKpf = (LTDBDateiKopf*)datKpf->release(); // Pfad setzen this->pfad->setText(dynamic_cast(pfad->getThis())); pfad->release(); } void LTDBDatei::erstellen() // Erstellt die Datei { DateiPfadErstellen(dynamic_cast(pfad->getThis())); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); int i = 0; outF->write((char*)&i, 2); delete outF; } void LTDBDatei::leseDaten( FBalken* f) // Die Klasse ließt alle Bilder kurz ein, und merkt sich, an // welcher stelle in der Datei was ist { // Diese Funktion wird ein wenig Zeit in Anspruch nemen, dafüraber danach die // anderen schneller machen if (DateiExistiert(dynamic_cast(pfad->getThis()))) { if (datKpf) datKpf->release(); datKpf = new LTDBDateiKopf(); std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); datKpf->laden(f, inF); delete inF; } } void LTDBDatei::remove() // Löscht die Datei { if (DateiExistiert(dynamic_cast(pfad->getThis()))) { DateiRemove(dynamic_cast(pfad->getThis())); if (datKpf) datKpf->release(); } } void LTDBDatei::remove(FBalken* f, Text* name) // Löscht ein Bild aus der Datei { if (DateiExistiert(dynamic_cast(pfad->getThis())) && name) { if (!datKpf) leseDaten(0); // Daten einlesen // Prüfen, ob Datei nicht vorhanden if (!datKpf) { name->release(); return; } int index = datKpf->getBildIndex(dynamic_cast(name->getThis())); if (index == -1) // das bild existiert nicht { name->release(); return; } // Zwischenspeicherpfad ermitteln Text* pf_tmp = new Text(pfad->getText()); char c = '0'; pf_tmp->append("0"); for (int i = 0; DateiExistiert(dynamic_cast(pf_tmp->getThis())); ++i) { c = (char)('0' + (i % 10)); if ((i % 10) == 0) pf_tmp->append("$"); pf_tmp->ersetzen( pf_tmp->anzahlVon((char)('0' - ((i - 1) % 10))) - 1, (char)('0' - ((i - 1) % 10)), c); } std::ifstream* inF = new std::ifstream( pfad->getText(), std::ios::binary); // Alte Datei öffnen inF->seekg(0, std::ios::end); __int64 datlen = inF->tellg(); inF->seekg(0, std::ios::beg); std::ofstream* outF = new std::ofstream( pf_tmp->getText(), std::ios::binary); // Neue Datei öffnen if (inF->is_open() && outF->is_open()) { __int64 position = datKpf->getBildPosition(index); datKpf->removeBild(index); datKpf->speichern(outF); LTDBDateiKopf* kpf_tmp = new LTDBDateiKopf(); kpf_tmp->laden(0, inF); kpf_tmp->release(); char byte = 0; __int64 pos_minus = inF->tellg() - outF->tellp(); for (int i = 0; i < index; ++i) datKpf->setBildPos(i, datKpf->getBildPosition(i) - pos_minus); // Bytes bis zur Datei kopieren for (__int64 i = inF->tellg(); i < position; ++i) { inF->read(&byte, 1); outF->write(&byte, 1); } // zu löschendes Bild überspringen LTDBKopf* delkpf = new LTDBKopf(); delkpf->laden(inF); LTDBBody* delkpr = new LTDBBody(dynamic_cast(delkpf->getThis())); delkpr->laden(f, inF); delkpf = (LTDBKopf*)delkpf->release(); delkpr = (LTDBBody*)delkpr->release(); // restliche bytes kopieren pos_minus = inF->tellg() - outF->tellp(); for (__int64 i = (__int64)inF->tellg(); i < datlen; ++i) { inF->read(&byte, 1); outF->write(&byte, 1); } for (int i = index; i < datKpf->getbAnzahl(); ++i) datKpf->setBildPos(i, datKpf->getBildPosition(i) - pos_minus); outF->seekp(0, std::ios::beg); datKpf->speichern(outF); inF->close(); outF->close(); DateiRemove(dynamic_cast(pfad->getThis())); DateiUmbenennen(dynamic_cast(pf_tmp->getThis()), dynamic_cast(pfad->getThis())); } delete inF; delete outF; pf_tmp = (Text*)pf_tmp->release(); } if (name) name = (Text*)name->release(); } Bild* LTDBDatei::laden(FBalken* f, Text* name) // Läd ein Bild aus der Datei { if (name) { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) { name->release(); return 0; } if (!datKpf) leseDaten(0); LTDBKopf* k_tmp = new LTDBKopf(); k_tmp->Init(dynamic_cast(name->getThis()), Punkt(0, 0)); int index = datKpf->getBildIndex(k_tmp->getTitel()); k_tmp->release(); if (index == -1) { // Fehlermeldung Text* fehler = new Text("Das Bild "); fehler->append(name); fehler->append(" wurde nicht in der Datei\n"); fehler->append(dynamic_cast(pfad->getThis())); fehler->append(" gefunden!"); Logging::error() << fehler << "\n"; return 0; } std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // Begin der zu ladenden Datei ermitteln __int64 position = datKpf->getBildPosition(index); inF->seekg(position, std::ios::beg); LTDBKopf* kpf = new LTDBKopf(); kpf->laden(inF); Text* t = kpf->getTitel(); if (!t->istGleich(dynamic_cast(name->getThis()))) { // Fehlermeldung t->release(); kpf->release(); inF->close(); delete inF; Text* fehler = new Text("Die Datei "); fehler->append(pfad); fehler->append(" ist ist keine gültige LTDB Datei!"); #ifdef WIN32 WMessageBox(0, new Text("Fehler"), fehler, MB_ICONERROR); #endif name->release(); return 0; } t->release(); LTDBBody* kpr = new LTDBBody(dynamic_cast(kpf->getThis())); kpr->laden(f, inF); // Bild laden Bild* ret = kpr->getBild(); kpr->release(); kpf->release(); inF->close(); delete inF; name->release(); return ret; } return 0; } int LTDBDatei::speichern( FBalken* f, Bild* bild, Text* name) // Speichert ein Bild in die Datei { int warn = -1; if (name && bild) { if (DateiExistiert(dynamic_cast(pfad->getThis()))) { if (!datKpf) leseDaten(0); int index = datKpf->getBildIndex(dynamic_cast(name->getThis())); if (index == -1) { warn = 0; LTDBKopf* kpf = new LTDBKopf(); warn = kpf->Init( dynamic_cast(name->getThis()), bild->getSize()); if (datKpf->getBildIndex(kpf->getTitel()) != -1) { Logging::error() << "Es existiert bereits ein Bild mit diesem Namen!\n"; bild->release(); name->release(); kpf->release(); return -1; } // zwischendateipfad suchen Text* pf_tmp = new Text(pfad->getText()); char c = '0'; pf_tmp->append("0"); for (int i = 0; DateiExistiert(dynamic_cast(pf_tmp->getThis())); ++i) { c = (char)('0' + (i % 10)); if ((i % 10) == 0) pf_tmp->append("$"); pf_tmp->ersetzen( pf_tmp->anzahlVon((char)('0' - ((i - 1) % 10))) - 1, (char)('0' - ((i - 1) % 10)), c); } std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); inF->seekg(0, std::ios::end); __int64 datLen = inF->tellg(); inF->seekg(0, std::ios::beg); std::ofstream* outF = new std::ofstream(pf_tmp->getText(), std::ios::binary); datKpf->addBild(kpf->getTitel()); index = datKpf->getBildIndex(kpf->getTitel()); datKpf->speichern(outF); LTDBDateiKopf* kpf_tmp = new LTDBDateiKopf(); kpf_tmp->laden(0, inF); kpf_tmp->release(); __int64 pos_plus = outF->tellp() - inF->tellg(); for (int i = 0; i < index; ++i) datKpf->setBildPos( i, datKpf->getBildPosition(i) + pos_plus); datKpf->setBildPos(index, datLen + pos_plus); outF->seekp(0, std::ios::beg); datKpf->speichern(outF); char byte = 0; for (__int64 i = inF->tellg(); i < datLen; ++i) { inF->read(&byte, 1); outF->write(&byte, 1); } kpf->speichern(outF); // Bild Kopf speichern LTDBBody* kpr = new LTDBBody(dynamic_cast(kpf->getThis())); kpr->setBild(dynamic_cast(bild->getThis())); kpr->speichern(f, outF); // Bild speichern kpf->release(); kpr->release(); inF->close(); outF->close(); delete inF; delete outF; DateiRemove(dynamic_cast(pfad->getThis())); DateiUmbenennen( (Text*)pf_tmp, dynamic_cast(pfad->getThis())); } } } if (name) name->release(); if (bild) bild->release(); return warn; } RCArray* LTDBDatei::zBildListe() // Listet alle Bilder in der datei auf { if (!datKpf) leseDaten(0); if (datKpf) return datKpf->zBildListe(); return 0; } // constant Text* LTDBDatei::getPfad() const // Gibt den Pfad zur Datei zurück { return dynamic_cast(pfad->getThis()); } int LTDBDatei::getBildAnzahl() const { if (!datKpf) return 0; return datKpf->getbAnzahl(); } bool LTDBDatei::istOffen() const // Prüft, ob die Datei geöffnet ist { if (!pfad) return 0; return DateiExistiert(dynamic_cast(pfad->getThis())); } #ifdef WIN32 // LTDS Dateivormat // Inhalt der LTDSPixel Klasse aus DateiSystem.h // Konstruktor LTDSPixel::LTDSPixel(LTDSPixel* davor) : ReferenceCounter(), index(0), iA(0), miA(8), maxIndex(1), änder(0), änderA(0), komp(0), alpha(0), davor(davor) {} // Destruktor LTDSPixel::~LTDSPixel() { if (davor) davor->release(); } // nicht constant // zum Laden gedacht bool LTDSPixel::addBitZuFarbe(unsigned char bit) { if (änderA && iA != miA) // Das Bit gehört zu Alpha { alpha |= ((bit & Bits(1))) << (7 - komp - iA); ++iA; } else // Das Bit gehört zum nächsten Pixel return false; return true; } char LTDSPixel::addByte( char byte, char begin) // gibt ende des Pixels zurück, -1 wenn nicht zu ende { if (begin >= 8 || begin < 0) return -1; for (int i = begin; i < 8; ++i) { switch (index) { case 0: // Das erste Bit eines Pixels speichert, ob sich an der // Komprimierung etwas änderte änder = ((byte >> (7 - i)) & Bits(1)) == 1; if (!änder) // Ändert sich nichts an der Komprimierung, so werden // die Werte vom vorherigen Pixel übernommen { if (!davor) // Die Datei ist beschädigt ( Der erste Pixel kann // nicht von dem davor Übernemen ) { MessageBox(NULL, "Fehler, die Bilddatei ist beschädigt", "Fehler", MB_ICONERROR); exit(0); } änderA = davor->getÄnderA(); komp = davor->getKomp(); miA -= komp; if (!änderA) alpha = davor->getA(); maxIndex += änderA * (8 - komp); // Bestimmung der Länge // des Pixels in Bits. Jede Farbe hat von grund auf 8 Bits, // durch komprimierung kanns kleiner sein } else maxIndex += 4; // Da der Pixel nicht die Werte des vorherigen // übernimmt, wird er um 4 Bits größer break; case 1: // Das zweite Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (änder) // Das Bit gehört zu den 4 Komprimierungsbits änderA = ((byte >> (7 - i)) & Bits(1)) == 1; else { if (!addBitZuFarbe(byte >> (7 - i))) // Das Bit gehört zur Farbe return i; } break; case 2: // Das sechste Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (änder) // Das Bit gehört zu den 4 Komprimierungsbits komp |= (unsigned char)((byte >> (7 - i)) & Bits(1)) << 2; else { if (!addBitZuFarbe(byte >> (7 - i))) // Das Bit gehört zur Farbe return i; } break; case 3: // Das siebte Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (änder) // Das Bit gehört zu den 4 Komprimierungsbits komp |= (unsigned char)((byte >> (7 - i)) & Bits(1)) << 1; else { if (!addBitZuFarbe(byte >> (7 - i))) // Das Bit gehört zur Farbe return i; } break; case 4: // Das achte Bit eines Pixels speichert entweder die // Komprimierungsart, oder schon die Farbe if (änder) // Das Bit gehört zu den 4 Komprimierungsbits { komp |= (unsigned char)((byte >> (7 - i)) & Bits(1)); // Das war das letzte Komprimierungsbit // Komprimierung auswerten miA -= komp; if (!änderA) alpha = davor->getA(); maxIndex += änderA * (8 - komp); // Bitlänge des Pixels } else { if (!addBitZuFarbe(byte >> (7 - i))) // Das Bit gehört zur Farbe return i; } break; default: // Die restlichen Bits speichern alle die Farbwerte des Pixels if (!addBitZuFarbe(byte >> (7 - i))) // Das Bit gehört zur Farbe return i; break; } ++index; if (index >= maxIndex) { if (davor) { if (änderA) alpha = davor->getA() + alpha; davor = (LTDSPixel*)davor->release(); } return i + 1; } } return -1; } // zum speichern gedacht void LTDSPixel::setAlpha(unsigned char alpha) // setzt die Farbe des Pixels { this->alpha = alpha; } void LTDSPixel::Komp() // Komprimiert den Pixel { maxIndex = 1; if (!davor) { // Das ist der erste Pixel änder = 1; änderA = 1; maxIndex += 4; miA = getBits(alpha); } else { // Es wird die differenz zum vorrigen Pixel gespeichert miA = getBits(alpha - davor->getA()); if (alpha != davor->getA()) änderA = 1; else änderA = 0; } // Prüfen ob sich etwas ändert if (!miA && änderA) ++miA; komp = 8 - miA; maxIndex += änderA * miA; if (davor) { if (änderA != davor->getÄnderA() || komp != davor->getKomp()) { // Es ändert sich etwas änder = 1; maxIndex += 4; } else { // Es ändert sich nichts änder = 0; } } } bool LTDSPixel::getNextFarbeBit(char& byte, int i) { unsigned char AA = alpha; if (davor) { AA -= davor->getA(); } if (änderA && iA != miA) // Das Bit gehört zu Alpha { byte |= ((AA >> (7 - komp - iA)) & Bits(1)) << (7 - i); ++iA; } else // Der Pixel ist bereits zu ende return false; return true; } char LTDSPixel::getNextByte( char& byte, int bbegin) // Gibt die nächsten Bits Zurück, -1 wenn der Pixel // nicht zu ende ist { // bbegin gibt an wohin in die byte-variable geschrieben werden soll // die Funktion gibt das ende des Pixels in der byte-variable zurück // -1 heißt, dass der Pixel nicht zu ende ist for (int i = bbegin; i < 8; ++i) { switch (index) { case 0: // Das erste Bit des Pixels speichert, ob sich etwas an der // Komprimierung ändert byte |= ((int)änder & Bits(1)) << (7 - i); break; case 1: // Das zweite Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (änder) // Komprimierung byte |= ((int)änderA & Bits(1)) << (7 - i); else // Farbe { if (!getNextFarbeBit(byte, i)) return i; } break; case 2: // Das zweite Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (änder) // Komprimierung byte |= ((komp >> 2) & Bits(1)) << (7 - i); else // Farbe { if (!getNextFarbeBit(byte, i)) return i; } break; case 3: // Das dritte Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (änder) // Komprimierung byte |= ((komp >> 1) & Bits(1)) << (7 - i); else // Farbe { if (!getNextFarbeBit(byte, i)) return i; } break; case 4: // Das vierte Bit des Pixels speichert entweder schon die Farbe // oder die Komprimierung if (änder) // Komprimierung byte |= (komp & Bits(1)) << (7 - i); else // Farbe { if (!getNextFarbeBit(byte, i)) return i; } break; default: // Die restlichen Bits speichern die Farbe des Pixels if (!getNextFarbeBit(byte, i)) return i; break; } ++index; if (index >= maxIndex) { if (davor) davor = (LTDSPixel*)davor->release(); return i + 1; } } return -1; } // constant unsigned char LTDSPixel::getKomp() const // hat sich die Komprimierung geändert { return komp; } bool LTDSPixel::getÄnderA() const // gibt zurück, ob sich der alphawert ändert { return änderA; } unsigned char LTDSPixel::getA() const // gibt Alpha zurück { return alpha; } // Inhalt der LTDSDateiKopf Klasse aus Dateisystem.h // Konstruktor LTDSDateiKopf::LTDSDateiKopf() : ReferenceCounter(), sganzahl(0), gr(0), pos(0) {} // Destruktor LTDSDateiKopf::~LTDSDateiKopf() { delete[] gr; delete[] pos; } // nicht constant void LTDSDateiKopf::laden(std::ifstream* inF) // Lät aus inF { if (inF->good() && inF->is_open()) { inF->read((char*)&sganzahl, 1); delete[] gr; delete[] pos; gr = new unsigned char[sganzahl + 1]; pos = new int[sganzahl + 1]; gr[sganzahl] = 0; pos[sganzahl] = 0; for (int i = 0; i < sganzahl; ++i) { inF->read((char*)&gr[i], 1); inF->read((char*)&pos[i], 4); } } } void LTDSDateiKopf::addSG(char sg) // Schriftgröße hinzufügen { ++sganzahl; unsigned char* gr_tmp = gr; int* pos_tmp = pos; gr = new unsigned char[sganzahl + 1]; pos = new int[sganzahl + 1]; gr[sganzahl] = 0; pos[sganzahl] = 0; if (sganzahl - 1 > 0) { memcpy(gr, gr_tmp, 1 * (sganzahl - 1)); memcpy(pos, pos_tmp, 4 * (sganzahl - 1)); } delete[] gr_tmp; delete[] pos_tmp; pos[sganzahl - 1] = 0; gr[sganzahl - 1] = sg; } void LTDSDateiKopf::removeSG(char sg) // Schriftgröße entfernen { bool hatsg = 0; int sgpos = 0; for (int i = 0; i < sganzahl; ++i) { hatsg = gr[i] == sg; sgpos = i; if (hatsg) break; } if (hatsg) { --sganzahl; unsigned char* gr_tmp = gr; int* pos_tmp = pos; gr = new unsigned char[sganzahl + 1]; pos = new int[sganzahl + 1]; gr[sganzahl] = 0; pos[sganzahl] = 0; for (int i = 0; i < sgpos; ++i) { gr[i] = gr_tmp[i]; pos[i] = pos_tmp[i]; } for (int i = sgpos + 1; i < sganzahl; ++i) { gr[i - 1] = gr_tmp[i]; pos[i - 1] = pos_tmp[i]; } delete[] gr_tmp; delete[] pos_tmp; } } // constant void LTDSDateiKopf::speichern(std::ofstream* outF) const // Speichert nach outF { if (outF->is_open() && outF->good()) { outF->write((char*)&sganzahl, 1); for (int i = 0; i < sganzahl; ++i) { outF->write((char*)&gr[i], 1); outF->write((char*)&pos[i], 4); } } } unsigned char* LTDSDateiKopf::getSchriftGrößeList() const // gibt eine Liste mit gespeicherten Schriftgrößen zurück { return gr; } int* LTDSDateiKopf::getPositionList() const // gibt eine Positionsliste der gespeicherten Schriftgrößen zurück { return pos; } int LTDSDateiKopf::getSchriftGrößeAnzahl() const // gibt die Anzahl der gespeicherten Schriftgrößen zurück { return sganzahl; } // Inhalt der LTDSSchriftKopf Klasse aus Dateisystem.h // Konstruktor LTDSSchriftKopf::LTDSSchriftKopf() : ReferenceCounter(), schriftSize(0), zeichen(0), pos(0), zeichenAnzahl(0) {} // Destruktor LTDSSchriftKopf::~LTDSSchriftKopf() { delete[] pos; delete[] zeichen; } // nicht constant void LTDSSchriftKopf::laden(std::ifstream* inF) // läht von inF { if (inF->good() && inF->is_open()) { inF->read((char*)&schriftSize, 1); inF->read((char*)&zeichenAnzahl, 1); delete[] pos; delete[] zeichen; zeichen = new unsigned char[zeichenAnzahl]; pos = new int[zeichenAnzahl + 1]; for (int i = 0; i < zeichenAnzahl; ++i) { inF->read((char*)&zeichen[i], 1); inF->read((char*)&pos[i], 4); } pos[zeichenAnzahl] = 0; } } void LTDSSchriftKopf::setSchriftgröße(unsigned char gr) // setze schriftgröße { schriftSize = gr; } void LTDSSchriftKopf::setZeichenAlphabet( Alphabet* alphabet) // setzt die Zeichen von alphabet { int count = 0; for (int i = 0; i < 256; ++i) { Buchstabe* zeich = alphabet->zBuchstabe(i); if (zeich) ++count; } delete[] zeichen; delete[] pos; zeichen = new unsigned char[count]; pos = new int[count + 1]; pos[count] = 0; zeichenAnzahl = count; count = 0; for (int i = 0; i < 256; ++i) { Buchstabe* zeich = alphabet->getBuchstabe(i); if (zeich) { zeichen[count] = i; pos[count] = 0; ++count; zeich->release(); } } schriftSize = alphabet->getSchriftSize(); alphabet->release(); } void LTDSSchriftKopf::addZeichen(unsigned char zeichen) // Zeichen hinzufügen { ++zeichenAnzahl; unsigned char* zeichen_tmp = this->zeichen; int* pos_tmp = pos; this->zeichen = new unsigned char[zeichenAnzahl]; pos = new int[zeichenAnzahl + 1]; if (zeichenAnzahl - 1 > 0) { memcpy(this->zeichen, zeichen_tmp, 1 * (zeichenAnzahl - 1)); memcpy(pos, pos_tmp, 4 * (zeichenAnzahl - 1)); } delete[] zeichen_tmp; delete[] pos_tmp; this->zeichen[zeichenAnzahl - 1] = zeichen; pos[zeichenAnzahl - 1] = 0; pos[zeichenAnzahl] = 0; } void LTDSSchriftKopf::removeZeichen(unsigned char zeich) // Zeichen entfernen { bool hatZ = 0; int zPos = 0; for (int i = 0; i < zeichenAnzahl; ++i) { hatZ = zeichen[i] == zeich; zPos = i; if (hatZ) break; } if (hatZ) { --zeichenAnzahl; unsigned char* zeichen_tmp = zeichen; int* pos_tmp = pos; zeichen = new unsigned char[zeichenAnzahl]; pos = new int[zeichenAnzahl + 1]; for (int i = 0; i < zPos; ++i) { zeichen[i] = zeichen_tmp[i]; pos[i] = pos_tmp[i]; } for (int i = zPos + 1; i <= zeichenAnzahl; ++i) { zeichen[i - 1] = zeichen_tmp[i]; pos[i - 1] = pos_tmp[i]; } pos[zeichenAnzahl] = 0; delete[] zeichen_tmp; delete[] pos_tmp; } } // constant void LTDSSchriftKopf::speichern( std::ofstream* outF) const // speichert nach outF { if (outF->good() && outF->is_open()) { outF->write((char*)&schriftSize, 1); outF->write((char*)&zeichenAnzahl, 1); for (int i = 0; i < zeichenAnzahl; ++i) { outF->write((char*)&zeichen[i], 1); outF->write((char*)&pos[i], 4); } } } unsigned char LTDSSchriftKopf::getSchriftGröße() const // gibt die Schriftgröße zurück { return schriftSize; } unsigned char LTDSSchriftKopf::getZeichenAnzahl() const // gibt die Zeichenanzahl zurück { return zeichenAnzahl; } int* LTDSSchriftKopf::getPositionen() const // gibt die Zeichenpositionen zurück { return pos; } unsigned char* LTDSSchriftKopf::getZeichen() const // gibt die zeichen zurück { return zeichen; } // Inhalt der LTDSBuchstabenKopf Klasse aus Dateisystem.h // Konstruktor LTDSBuchstabenKopf::LTDSBuchstabenKopf() : ReferenceCounter(), zeichen(0), size(0, 0) {} // nicht constant void LTDSBuchstabenKopf::laden(std::ifstream* inF) // lät aus inF { if (inF->good() && inF->is_open()) { inF->read((char*)&zeichen, 1); inF->read((char*)&size.x, 1); inF->read((char*)&size.y, 1); } } void LTDSBuchstabenKopf::init(unsigned char zeichen, const Punkt& größe) // initialisierung( für speichern ) { this->zeichen = zeichen; this->size = größe; } void LTDSBuchstabenKopf::init(unsigned char zeichen, int br, int hö) { this->zeichen = zeichen; size.x = br, size.y = hö; } // constant void LTDSBuchstabenKopf::speichern( std::ofstream* outF) const // speichertn nach outF { if (outF->good() && outF->is_open()) { outF->write((char*)&zeichen, 1); outF->write((char*)&size.x, 1); outF->write((char*)&size.y, 1); } } unsigned char LTDSBuchstabenKopf::getZeichen() const // gibt das Zeichen zurück { return zeichen; } int LTDSBuchstabenKopf::getBreite() const // gibt die Breite zurück { return size.x; } int LTDSBuchstabenKopf::getHöhe() const // gibt die höhe zurück { return size.y; } const Punkt& LTDSBuchstabenKopf::getGröße() const // gibt die Größe zurück { return size; } // Inhalt der LTDSBuchstabenKörper Klasse aus Dateisystem.h // Konstruktor LTDSBuchstabenKörper::LTDSBuchstabenKörper(LTDSBuchstabenKopf* kopf) : ReferenceCounter(), size(kopf->getGröße()), zeichen(kopf->getZeichen()), buchstabe(new Buchstabe()) { buchstabe->NeuBuchstabe(size); kopf->release(); } // Destruktor LTDSBuchstabenKörper::~LTDSBuchstabenKörper() { if (buchstabe) buchstabe->release(); } // nicht constant void LTDSBuchstabenKörper::setBuchstabe( Buchstabe* zeichen) // setzt den Buchstaben { if (buchstabe) buchstabe->release(); buchstabe = zeichen; } void LTDSBuchstabenKörper::laden(std::ifstream* inF) // Läht aus inF { if (inF->good() && inF->is_open()) { LTDSPixel* vorher = 0; LTDSPixel* jetzt = new LTDSPixel(vorher); char byte = 0; int beg = 0; int ende = -1; for (int i = 0; i < size.x * size.y; ++i) { if (!jetzt) // wenn es nicht der erste Pixel ist jetzt = new LTDSPixel( dynamic_cast(vorher->getThis())); int ende = -1; while (ende < 0) // Pixel laden { if (beg == 0) inF->read(&byte, 1); ende = jetzt->addByte(byte, beg); // byte auswerten beg = 0; } beg = ende; if (beg == 8) beg = 0; if (buchstabe) buchstabe->setPixel(i, jetzt->getA()); if (vorher) vorher = (LTDSPixel*)vorher->release(); vorher = dynamic_cast(jetzt->getThis()); jetzt = (LTDSPixel*)jetzt->release(); } if (vorher) vorher->release(); if (jetzt) jetzt->release(); } } // constant void LTDSBuchstabenKörper::speichern( std::ofstream* outF) const // speichert nach outF { if (outF->good() && outF->is_open()) { LTDSPixel* vorher = 0; // Letzter gespeicherter Pixel LTDSPixel* jetzt = new LTDSPixel(0); // Der momentan zu speichernde Pixel int begin = 0, ende = 0; // Pixelbeginn, endposition in der byte variable char byte = 0; // Der nächste byte der Datei bool w = 0; unsigned char* alphaBuff = buchstabe->getBuff(); for (int i = 0; i < size.x * size.y; ++i) // für jeden Pixel { if (!jetzt) // wenn es nicht der erste Pixel ist jetzt = new LTDSPixel( dynamic_cast(vorher->getThis())); jetzt->setAlpha(alphaBuff[i]); // Farbe des Pixels setzen jetzt->Komp(); // Pixel komprimieren ende = -1; while (ende < 0) // byte befüllen { ende = jetzt->getNextByte(byte, begin); begin = 0; w = 0; if (ende == -1 || ende == 8) // byte speichern { outF->write(&byte, 1); w = 1; byte = 0; } } // Pixel fertig begin = ende; if (begin == 8) begin = 0; if (vorher) vorher->release(); vorher = dynamic_cast( jetzt->getThis()); // dieser wird zu letzter jetzt = (LTDSPixel*)jetzt->release(); } if (vorher) vorher = (LTDSPixel*)vorher->release(); if (!w) { outF->write(&byte, 1); // Das letzte byte speichern } outF->flush(); // dateistream speichern } } Buchstabe* LTDSBuchstabenKörper::getBuchstabe() const // gibt den Buchstaben zurück { return dynamic_cast(buchstabe->getThis()); } unsigned char LTDSBuchstabenKörper::getZeichen() const // gibt das Zeichen zurück { return zeichen; } // Inhalt der LTDSDatei Klasse aus DAteisystem.h // Konstruktor LTDSDatei::LTDSDatei() : ReferenceCounter(), pfad(new Text()), dateiKopf(0) {} // Destruktor LTDSDatei::~LTDSDatei() { if (dateiKopf) dateiKopf->release(); pfad->release(); } // nicht constant void LTDSDatei::setPfad(Text* txt) // setzt den Pfad zur Datei { if (dateiKopf) dateiKopf = (LTDSDateiKopf*)dateiKopf->release(); pfad->setText(txt->getText()); txt->release(); } void LTDSDatei::leseDaten() // ließt den Dateikopf { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return; if (dateiKopf) dateiKopf->release(); dateiKopf = new LTDSDateiKopf(); std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); dateiKopf->laden(inF); inF->close(); delete inF; } void LTDSDatei::addSchriftgröße( Alphabet* alphabet) // fügt eine Schriftgröße hinzu { if (!DateiExistiert(dynamic_cast( pfad->getThis()))) // prüfen, ob die Datei existiert return; if (!dateiKopf) // prüfen, ob der Dateikopf schon gelesen wurde leseDaten(); int sgröße = alphabet ->getSchriftSize(); // Schriftgröße die hinzugefügt werden soll unsigned char* sglist = dateiKopf->getSchriftGrößeList(); // Liste von bereits vorhandenen // Schriftgrößen unsigned char sganzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der bereits vorhandenen // Schriftgrößen for (int i = 0; i < sganzahl; ++i) // prüfen, ob die Schriftgröße bereits existiert { if (sglist[i] == sgröße) { alphabet->release(); return; } } dateiKopf->addSG(sgröße); // Schriftgröße dem Dateikopf hinzufügen int* sgPosList = dateiKopf ->getPositionList(); // Liste mit positionen der Schriftgrößen sglist = dateiKopf->getSchriftGrößeList(); // Liste von bereits vorhandenen // Schriftgrößen std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // alte Datei pfad->append("0"); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); // neue Datei dateiKopf->speichern(outF); // Dateikopf in neue datei speichern inF->seekg(1 + 5 * sganzahl, std::ios::beg); // Position der ersten Schriftgröße in der alten Datei for (int i = 0; i < sganzahl; ++i) // Buchstabenpositionen aller Schriftgrößen aktualisieren { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf sgKpf_tmp->laden(inF); // aus alter Datei laden int* zeichP_tmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen der Schriftgröße unsigned char zeichA_tmp = sgKpf_tmp ->getZeichenAnzahl(); // Anzahl von Zeichen der Schriftgröße for (int i1 = 0; i1 < zeichA_tmp; ++i1) zeichP_tmp[i1] += 5; // Buchstabenpositionen aktualisieren sgKpf_tmp->speichern(outF); // Schriftgröße Kopf in neue Datei speichern int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten // Schriftgröße in neue Datei kopieren int endByte = sgPosList[i + 1]; if (!endByte) { inF->seekg(0, std::ios::end); endByte = (int)inF->tellg(); inF->seekg(beginByte, std::ios::beg); } char byte; for (int i1 = beginByte; i1 < endByte; ++i1) // Kopiervorgang { inF->read(&byte, 1); outF->write(&byte, 1); } sgKpf_tmp->release(); } inF->close(); // Alte datei schließen sgPosList[sganzahl] = (int)outF->tellp(); outF->seekp(0, std::ios::beg); for (int i = 0; i < sganzahl; ++i) // Positionen im Dateikopf aktualisieren sgPosList[i] += 5; dateiKopf->speichern(outF); // aktualisierter Dateikopf speichern outF->seekp(sgPosList[sganzahl], std::ios::beg); LTDSSchriftKopf* sgkopf = new LTDSSchriftKopf(); // Kopf der neuen Schriftgröße sgkopf->setZeichenAlphabet(dynamic_cast( alphabet->getThis())); // Kopf der Schriftgröße initialisieren sgkopf->speichern(outF); // Kopf der Schriftgröße speichern int* BuchstabenPosList = sgkopf->getPositionen(); // positionen der verschiedenen Zeichen in // der Datei( nuch 0 ) int count = 0; for (int i = 0; i < 256; ++i) { Buchstabe* zeich = alphabet->getBuchstabe(i); if (zeich) { BuchstabenPosList[count] = (int)outF->tellp(); // position des Zeichens setzen LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); // Zeichenkopf zeichKpf->init(i, zeich->getBreite(), zeich->getHeight()); zeichKpf->speichern(outF); // Zeichenkopf speichern LTDSBuchstabenKörper* zeichKörp = new LTDSBuchstabenKörper(dynamic_cast( zeichKpf->getThis())); // Zeichenkörper zeichKpf->release(); zeichKörp->setBuchstabe(dynamic_cast(zeich->getThis())); zeichKörp->speichern(outF); // Zeichenkörper speichern zeich->release(); ++count; } } outF->seekp(sgPosList[sganzahl], std::ios::beg); sgkopf->speichern(outF); // aktualisierter Schriftgrößen Kopf speichern outF->close(); Text* pfad2 = new Text(); pfad2->setText(pfad->getText()); pfad->remove(pfad->getLength() - 1, pfad->getLength()); DateiRemove(dynamic_cast(pfad->getThis())); // Alte datei Löschen DateiUmbenennen(dynamic_cast(pfad2->getThis()), dynamic_cast( pfad->getThis())); // neue Datei nach alte umbenennen pfad2->release(); // Speicher freigeben sgkopf->release(); delete inF; delete outF; alphabet->release(); } void LTDSDatei::addBuchstabe(int gr, Buchstabe* zeich, unsigned char zeichen) // Fügt einer Schriftgröße einen Buchstaben hinzu { if (!DateiExistiert( dynamic_cast(pfad->getThis()))) // prüfen ob Datei existiert { zeich->release(); return; } if (!dateiKopf) // prüfen, ob der DAteikopf geladen wurde leseDaten(); unsigned char* sgList = dateiKopf ->getSchriftGrößeList(); // Liste mit Schriftgrößen aus der Datei int* sgPosList = dateiKopf->getPositionList(); // Liste mit Schriftgrößen // positionen aus Datei unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl von Schriftgrößen aus // der Datei int sgNum = -1; for (int i = 0; i < sgAnzahl; ++i) // Position der richtigen Schriftgröße ermitteln { if (sgList[i] == gr) { sgNum = i; break; } } std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // Alte Datei pfad->append("0"); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); // Neue Datei inF->seekg(1 + 5 * sgAnzahl, std::ios::beg); if (sgNum == -1) // Die Schriftgröße existiert noch nicht und wird erstellt { dateiKopf->addSG(gr); // Schriftgröße dem Dateikopf hinzufügen sgPosList = dateiKopf->getPositionList(); sgList = dateiKopf->getSchriftGrößeList(); dateiKopf->speichern(outF); // Dateikopf speichern inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg); // Position der ersten // Schriftgröße in der alten Datei for (int i = 0; i < sgAnzahl; ++i) // Buchstabenpositionen aller Schriftgrößen aktualisieren { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf sgKpf_tmp->laden(inF); // aus alter Datei laden int* zeichP_tmp = sgKpf_tmp ->getPositionen(); // Zeichenpositionen der Schriftgröße unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // Anzahl von Zeichen der // Schriftgröße for (int i1 = 0; i1 < zeichA_tmp; ++i1) zeichP_tmp[i1] += 5; // Buchstabenpositionen aktualisieren sgKpf_tmp->speichern( outF); // Schriftgröße Kopf in neue Datei speichern int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten // Schriftgröße in neue Datei kopieren int endByte = sgPosList[i + 1]; if (i + 1 >= sgAnzahl) { inF->seekg(0, std::ios::end); endByte = (int)inF->tellg(); inF->seekg(beginByte, std::ios::beg); } char byte; for (int i1 = beginByte; i1 < endByte; ++i1) // Kopiervorgang { inF->read(&byte, 1); outF->write(&byte, 1); } sgKpf_tmp->release(); } sgPosList[sgAnzahl] = (int)outF->tellp(); outF->seekp(0, std::ios::beg); for (int i = 0; i < sgAnzahl; ++i) // Positionen im Dateikopf aktualisieren sgPosList[i] += 5; dateiKopf->speichern(outF); // aktualisierter Dateikopf speichern outF->seekp(sgPosList[sgAnzahl], std::ios::beg); LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); // Schriftgröße Kopf initialisiern sgKpf->setSchriftgröße(gr); sgKpf->addZeichen(zeichen); sgKpf->getPositionen()[0] = (int)outF->tellp() + 7; sgKpf->speichern(outF); // Schriftgröße Kopf speichern sgKpf->release(); LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); // Buchstabenkopf zeichKpf->init(zeichen, zeich->getSize()); zeichKpf->speichern(outF); // Buchstabenkopf speichern LTDSBuchstabenKörper* zeichKörp = new LTDSBuchstabenKörper(dynamic_cast( zeichKpf->getThis())); // Buchstabenkörper zeichKpf->release(); zeichKörp->setBuchstabe(dynamic_cast(zeich->getThis())); zeichKörp->speichern(outF); // Buchstabenkörper speichern zeichKörp->release(); } else { dateiKopf->speichern(outF); // Dateikopf speichern int beginByte = 1 + 5 * sgAnzahl; // Die restlichen bytes bis zur nächsten // Schriftgröße in neue Datei kopieren int endByte = sgPosList[sgNum]; char byte; for (int i1 = beginByte; i1 < endByte; ++i1) // Kopiervorgang bis zur angegebenen größe { inF->read(&byte, 1); outF->write(&byte, 1); } LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); // Schriftgröße Kopf sgKpf->laden(inF); for (int i = 0; i < sgKpf->getZeichenAnzahl(); ++i) sgKpf->getPositionen()[i] += 5; sgKpf->addZeichen(zeichen); int indexPlus = 5; int zeichenPos = sgPosList[sgNum + 1]; // position des neuen Zeichens if (sgNum + 1 >= sgAnzahl) { int tmp = (int)inF->tellg(); inF->seekg(0, std::ios::end); zeichenPos = (int)inF->tellg(); inF->seekg(tmp, std::ios::beg); } zeichenPos += indexPlus; sgKpf->getPositionen()[sgKpf->getZeichenAnzahl() - 1] = zeichenPos; sgKpf->speichern(outF); // Schriftgröße Kopf speichern sgKpf->release(); for (int i = (int)inF->tellg() + indexPlus; i < zeichenPos; ++i) // Kopiervorgang bis zum Zeichenbeginn { inF->read(&byte, 1); outF->write(&byte, 1); } LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); // Zeichenkopf zeichKpf->init(zeichen, zeich->getSize()); zeichKpf->speichern(outF); // Zeichenkopf speichern LTDSBuchstabenKörper* zeichKörp = new LTDSBuchstabenKörper(dynamic_cast( zeichKpf->getThis())); // Zeichenkörper zeichKpf->release(); zeichKörp->setBuchstabe(dynamic_cast(zeich->getThis())); zeichKörp->speichern(outF); // Zeichenkörper speichern zeichKörp->release(); int nowPos = (int)outF->tellp(); indexPlus += nowPos - zeichenPos; for (int i = sgNum + 1; i < sgAnzahl; ++i) // Dateikopf aktualisieren sgPosList[i] += indexPlus; outF->seekp(0, std::ios::beg); dateiKopf->speichern(outF); // Dateikopf speichern outF->seekp(nowPos, std::ios::beg); for (int i = sgNum + 1; i < sgAnzahl; ++i) // Restliche Schriftgrößen aktualisieren { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf sgKpf_tmp->laden(inF); // aus alter Datei laden int* zeichP_tmp = sgKpf_tmp ->getPositionen(); // Zeichenpositionen der Schriftgröße unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // Anzahl von Zeichen der // Schriftgröße for (int i1 = 0; i1 < zeichA_tmp; ++i1) zeichP_tmp[i1] += indexPlus; // Buchstabenpositionen aktualisieren sgKpf_tmp->speichern( outF); // Schriftgröße Kopf in neue Datei speichern int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten // Schriftgröße in neue Datei kopieren int endByte = sgPosList[i + 1]; if (i + 1 >= sgAnzahl) { inF->seekg(0, std::ios::end); endByte = (int)inF->tellg(); inF->seekg(beginByte, std::ios::beg); } char byte; for (int i1 = beginByte; i1 < endByte; ++i1) // Kopiervorgang { inF->read(&byte, 1); outF->write(&byte, 1); } sgKpf_tmp->release(); } } inF->close(); outF->close(); Text* pfad2 = new Text(pfad->getText()); pfad->remove(pfad->getLength() - 1, pfad->getLength()); DateiRemove(dynamic_cast(pfad->getThis())); // Alte Datei löschen DateiUmbenennen(dynamic_cast(pfad2->getThis()), dynamic_cast(pfad->getThis())); // Neue Datei in alte umbenennen pfad2->release(); // Speicher freigeben delete inF; delete outF; zeich->release(); } void LTDSDatei::löscheSchrifrGröße( int gr) // Löscht eine Schriftgröße aus der Datei { if (!DateiExistiert( dynamic_cast(pfad->getThis()))) // prüfen, ob Datei existiert return; if (!dateiKopf) // prüfen, ob der Dateikopf geladen wurde leseDaten(); unsigned char* sgList = dateiKopf->getSchriftGrößeList(); // Liste mit Schriftgrößen unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der Schriftgrößen int sgNum = -1; for (int i = 0; i < sgAnzahl; ++i) // zu löschende Schriftgröße suchen { if (sgList[i] == gr) { sgNum = i; break; } } if (sgNum == -1) // Die Schriftgröße ist nicht vorhanden return; int* sgPosList = dateiKopf ->getPositionList(); // Liste von Positionen der Schriftgrößen std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // alte Datei pfad->append("0"); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); // neue Datei outF->seekp(1 + 5 * (sgAnzahl - 1), std::ios::beg); inF->seekg(1 + 5 * sgAnzahl, std::ios::beg); for (int i = 0; i < sgNum; ++i) // Schriftgrößen vor der zu löschenden Schriftgröße aktualisieren { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf sgKpf_tmp->laden(inF); // Schriftgrößen Kopf laden int* zeichPosLTmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen unsigned char zeichATmp = sgKpf_tmp->getZeichenAnzahl(); // Zeichenanzahl for (int i1 = 0; i1 < zeichATmp; ++i1) // Position der Zeichen um 5 bytes zurücksetzen zeichPosLTmp[i1] -= 5; sgKpf_tmp->speichern(outF); // speichern in Neue Datei char byte = 0; for (int i1 = (int)inF->tellg(); i1 < sgPosList[i + 1]; ++i1) // Den Körper des Zeichens Kopieren { inF->read(&byte, 1); outF->write(&byte, 1); } sgKpf_tmp->release(); } int indexMinus = 5 + sgPosList[sgNum + 1] - (int)inF->tellg(); inF->seekg(sgPosList[sgNum + 1], std::ios::beg); for (int i = sgNum + 1; i < sgAnzahl; ++i) // Die Schriftgröße nach der zu löschenden Schriftgröße { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf sgKpf_tmp->laden(inF); // Schriftgrößen Kopf laden int* zeichPosLTmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen unsigned char zeichATmp = sgKpf_tmp->getZeichenAnzahl(); // Zeichenanzahl for (int i1 = 0; i1 < zeichATmp; ++i1) // Position der Zeichen aktualisieren zeichPosLTmp[i1] -= indexMinus; sgKpf_tmp->speichern(outF); // speichern in Neue Datei char byte = 0; int BeginByte = (int)inF->tellg(); int EndByte = sgPosList[i + 1]; if (!EndByte) { inF->seekg(0, std::ios::end); EndByte = (int)inF->tellg(); inF->seekg(BeginByte, std::ios::beg); } for (int i1 = BeginByte; i1 < EndByte; ++i1) // Den Körper des Zeichens Kopieren { inF->read(&byte, 1); outF->write(&byte, 1); } } for (int i = 0; i < sgNum; ++i) // Dateikopf aktualisieren sgPosList[i] -= 5; for (int i = sgNum + 1; i < sgAnzahl; ++i) sgPosList[i] -= indexMinus; dateiKopf->removeSG(gr); outF->seekp(0, std::ios::beg); dateiKopf->speichern(outF); // Dateikopf speichern inF->close(); outF->close(); Text* pfad2 = new Text(pfad->getText()); pfad->remove(pfad->getLength() - 1, pfad->getLength()); DateiRemove(dynamic_cast(pfad->getThis())); // alte Datei löschen DateiUmbenennen(dynamic_cast(pfad2->getThis()), dynamic_cast(pfad->getThis())); // neue Datei zu alter umbenennen pfad2->release(); delete inF; delete outF; } void LTDSDatei::löscheBuchstabe( int gr, unsigned char zeichen) // Löscht einen Buchstaben aus der Datei { if (!DateiExistiert(dynamic_cast( pfad->getThis()))) // prüfen, ob die Datei existiert return; if (!dateiKopf) // prüfen, ob der Dateikopf gelesen wurde leseDaten(); unsigned char* sgList = dateiKopf->getSchriftGrößeList(); // Liste mit Schriftgrößen unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der Schriftgrößen int* sgPosList = dateiKopf ->getPositionList(); // Liste mit Positionen der Schriftgrößen int sgNum = -1; for (int i = 0; i < sgAnzahl; ++i) // Schriftgröße suchen { if (sgList[i] == gr) { sgNum = i; break; } } if (sgNum == -1) // Schriftgröße nicht gefunden return; std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // alte Datei pfad->append("0"); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); // neue Datei int indexMinus = 0; inF->seekg(1 + 5 * sgAnzahl, std::ios::beg); dateiKopf->speichern(outF); // DateiKopf peichern for (int i = 0; i < sgAnzahl; ++i) { LTDSSchriftKopf* sgKopf = new LTDSSchriftKopf(); // Schriftkopf sgKopf->laden(inF); // Schriftkopf laden unsigned char sgZeichAnzahl = sgKopf->getZeichenAnzahl(); // Zeichenanzahl unsigned char* sgZeichenList = sgKopf->getZeichen(); // Zeichen Liste int* sgZPosList = sgKopf->getPositionen(); // Positions Liste if (i == sgNum) // Zeichen befindet sich in dieser Schriftgröße { int sgZNum = -1; for (int i1 = 0; i1 < sgZeichAnzahl; ++i1) // Zeichen suchen { if (sgZeichenList[i1] == zeichen) { sgZNum = i1; break; } } if (sgZNum == -1) // Zeichen nicht gefunden { sgKopf->release(); inF->close(); outF->close(); delete inF; delete outF; DateiRemove(dynamic_cast(pfad->getThis())); pfad->remove(pfad->getLength() - 1, pfad->getLength()); return; // abbruch } outF->seekp(2 + 5 * (sgZeichAnzahl - 1), std::ios::cur); indexMinus += 5; for (int i1 = 0; i1 < sgZNum; ++i1) // Zeichen vor dem zu löschenden Zeichen { char byte = 0; for (int i2 = sgZPosList[i1]; i2 < sgZPosList[i1 + 1]; ++i2) // Kopieren { inF->read(&byte, 1); outF->write(&byte, 1); } sgZPosList[i1] -= indexMinus; // Schriftgröße Kopf aktualisieren } if (!sgZPosList[sgZNum + 1]) { int endByte = sgPosList[i + 1]; if (!endByte) { int beginByte = (int)inF->tellg(); inF->seekg(0, std::ios::end); endByte = (int)inF->tellg(); inF->seekg(beginByte, std::ios::beg); } indexMinus += endByte - sgZPosList[sgZNum]; } else indexMinus += sgZPosList[sgZNum + 1] - sgZPosList[sgZNum]; if (sgZNum + 1 < sgZeichAnzahl) inF->seekg(sgZPosList[sgZNum + 1], std::ios::beg); for (int i1 = sgZNum + 1; i1 < sgZeichAnzahl; ++i1) // Zeichen nach dem gelöschten Zeichen { int beginByte = (int)inF->tellg(); int endByte = sgZPosList[i1 + 1]; if (!endByte) { inF->seekg(0, std::ios::end); endByte = (int)inF->tellg(); inF->seekg(beginByte, std::ios::beg); } char byte = 0; for (int i2 = beginByte; i2 < endByte; ++i2) // Kopieren { inF->read(&byte, 1); outF->write(&byte, 1); } sgZPosList[i1] -= indexMinus; // Schriftgröße Kopf aktualisieren } sgKopf->removeZeichen(zeichen); } else { for (int i1 = 0; i1 < sgZeichAnzahl; ++i1) // Schriftgröße Kopf aktualisieren sgZPosList[i] -= indexMinus; sgKopf->speichern(outF); // Schriftgröße Kopf speichern int beginByte = (int)inF->tellg(); int endByte = sgPosList[i + 1]; if (!endByte) { inF->seekg(0, std::ios::end); endByte = (int)inF->tellg(); inF->seekg(beginByte, std::ios::beg); } char byte; for (int i1 = beginByte; i1 < endByte; ++i1) // Kopieren { inF->read(&byte, 1); outF->write(&byte, 1); } sgPosList[i] -= indexMinus; } outF->seekp(sgPosList[i], std::ios::beg); sgKopf->speichern(outF); // Schriftgröße Kopf speichern outF->seekp(sgPosList[i + 1], std::ios::beg); sgKopf->release(); } inF->close(); outF->close(); Text* pfad2 = new Text(pfad->getText()); pfad->remove(pfad->getLength() - 1, pfad->getLength()); DateiRemove(dynamic_cast(pfad->getThis())); // alte Datei löschen DateiUmbenennen(dynamic_cast(pfad2->getThis()), dynamic_cast( pfad->getThis())); // neue Datei nach alte umbenennen pfad2->release(); // Speicher freigeben delete inF; delete outF; } void LTDSDatei::löscheDatei() // Löscht die gesamte Datei { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return; if (!dateiKopf) leseDaten(); DateiRemove(dynamic_cast(pfad->getThis())); } void LTDSDatei::erstelleDatei() // erstellt die Datei { DateiPfadErstellen(dynamic_cast(pfad->getThis())); if (dateiKopf) dateiKopf->release(); dateiKopf = new LTDSDateiKopf(); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); dateiKopf->speichern(outF); outF->close(); delete outF; } void LTDSDatei::speicherSchrift( Schrift* schrift) // Speichert die übergebene Schrift { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) { schrift->release(); return; } löscheDatei(); if (dateiKopf) dateiKopf->release(); dateiKopf = new LTDSDateiKopf(); for (int i = 0; i < 256; ++i) { Alphabet* alp = schrift->getAlphabet((unsigned char)i); if (alp) { dateiKopf->addSG((char)alp->getSchriftSize()); alp->release(); } } std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); dateiKopf->speichern(outF); for (int i = 0; i < 256; ++i) { Alphabet* alp = schrift->getAlphabet((unsigned char)i); if (alp) { dateiKopf->getPositionList()[i] = (int)outF->tellp(); LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); sgKpf->setZeichenAlphabet(dynamic_cast(alp->getThis())); sgKpf->speichern(outF); for (int i1 = 0; i1 < sgKpf->getZeichenAnzahl(); ++i1) { sgKpf->getPositionen()[i1] = (int)outF->tellp(); LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); Buchstabe* zeichen = alp->getBuchstabe(sgKpf->getZeichen()[i1]); zeichKpf->init(sgKpf->getZeichen()[i1], zeichen->getBreite(), zeichen->getHeight()); zeichKpf->speichern(outF); LTDSBuchstabenKörper* zeichKörp = new LTDSBuchstabenKörper( dynamic_cast(zeichKpf->getThis())); zeichKörp->setBuchstabe( dynamic_cast(zeichen->getThis())); zeichKörp->speichern(outF); zeichKörp->release(); zeichen->release(); zeichKpf->release(); } alp->release(); int p = (int)outF->tellp(); outF->seekp(dateiKopf->getPositionList()[i], std::ios::beg); sgKpf->speichern(outF); outF->seekp(p, std::ios::beg); sgKpf->release(); } } outF->seekp(0, std::ios::beg); dateiKopf->speichern(outF); outF->close(); delete outF; schrift->release(); } // constant Schrift* LTDSDatei::ladeSchrift() // gibt die geladene Schrift zurück { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; Schrift* ret = new Schrift(); std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); inF->seekg(dateiKopf->getPositionList()[0], std::ios::beg); for (int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); ++i) { LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); sgKpf->laden(inF); Alphabet* alphabet = new Alphabet(); alphabet->setSchriftSize(sgKpf->getSchriftGröße()); for (int i1 = 0; i1 < sgKpf->getZeichenAnzahl(); ++i1) { LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); zeichKpf->laden(inF); LTDSBuchstabenKörper* zeichKörp = new LTDSBuchstabenKörper( dynamic_cast(zeichKpf->getThis())); zeichKörp->laden(inF); alphabet->setBuchstabe( zeichKpf->getZeichen(), zeichKörp->getBuchstabe()); zeichKörp->release(); zeichKpf->release(); } ret->addAlphabet(dynamic_cast(alphabet->getThis())); alphabet->release(); sgKpf->release(); } inF->close(); delete inF; return ret; } Alphabet* LTDSDatei::ladeAlphabet( int schriftgröße) // gibt eine geladene Schrift nur mit der angegebenen // Schriftgröße zurück { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; Alphabet* ret = 0; int sgNum = -1; for (int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); ++i) { if (dateiKopf->getSchriftGrößeList()[i] == schriftgröße) { sgNum = i; break; } } if (sgNum == -1) return 0; ret = new Alphabet(); ret->NeuAlphabet(); ret->setSchriftSize(schriftgröße); std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); inF->seekg(dateiKopf->getPositionList()[sgNum], std::ios::beg); LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); sgKpf->laden(inF); for (int i = 0; i < sgKpf->getZeichenAnzahl(); ++i) { LTDSBuchstabenKopf* sgZKpf = new LTDSBuchstabenKopf(); sgZKpf->laden(inF); LTDSBuchstabenKörper* sgZKörp = new LTDSBuchstabenKörper( dynamic_cast(sgZKpf->getThis())); sgZKörp->laden(inF); ret->setBuchstabe(sgZKpf->getZeichen(), sgZKörp->getBuchstabe()); sgZKörp->release(); sgZKpf->release(); } sgKpf->release(); inF->close(); delete inF; return ret; } Buchstabe* LTDSDatei::ladeBuchstabe( int schriftgröße, unsigned char zeichen) // Läd einen bestimmten Buchstaben { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; Buchstabe* ret = 0; int sgNum = -1; for (int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); ++i) { if (dateiKopf->getSchriftGrößeList()[i] == schriftgröße) { sgNum = i; break; } } if (sgNum == -1) return 0; std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); inF->seekg(dateiKopf->getPositionList()[sgNum], std::ios::beg); LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); sgKpf->laden(inF); int sgZNum = -1; for (int i = 0; i < sgKpf->getZeichenAnzahl(); ++i) { if (sgKpf->getZeichen()[i] == zeichen) { sgZNum = i; break; } } if (sgZNum != -1) { inF->seekg(sgKpf->getPositionen()[sgZNum], std::ios::beg); LTDSBuchstabenKopf* sgZKpf = new LTDSBuchstabenKopf(); sgZKpf->laden(inF); LTDSBuchstabenKörper* sgZKörp = new LTDSBuchstabenKörper( dynamic_cast(sgZKpf->getThis())); sgZKörp->laden(inF); ret = sgZKörp->getBuchstabe(); sgZKörp->release(); sgZKpf->release(); } sgKpf->release(); inF->close(); delete inF; if (ret) { ret->setSchriftSize(schriftgröße); } return ret; } Text* LTDSDatei::getPfad() const // gibt den Dateipfad zurück { return dynamic_cast(pfad->getThis()); } int LTDSDatei::getAnzahlSchriftgrößen() const // gibt die Anzahl der Schriftgrößen aus der Datei zurück { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; return dateiKopf->getSchriftGrößeAnzahl(); } unsigned char* LTDSDatei::getSchriftGrößen() const // gibt einen Array von Schriftgrößen zurück { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; return dateiKopf->getSchriftGrößeList(); } unsigned char LTDSDatei::getAnzahlBuchstaben( int sg) // gibt die anzahl gespeicherter Buchstaben einer Schriftgröße // zurück { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; int ret = 0; unsigned char* größen = dateiKopf->getSchriftGrößeList(); unsigned char granzahl = dateiKopf->getSchriftGrößeAnzahl(); int grpos = -1; for (int i = 0; i < granzahl; ++i) { if (größen[i] == sg) { grpos = i; break; } } if (grpos != -1) { int* grposlist = dateiKopf->getPositionList(); LTDSSchriftKopf* sgkpf = new LTDSSchriftKopf(); std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); inF->seekg(grposlist[grpos], std::ios::beg); sgkpf->laden(inF); ret = sgkpf->getZeichenAnzahl(); sgkpf->release(); inF->close(); delete inF; } return ret; } unsigned char* LTDSDatei::getBuchstaben( int sg) // gibt einen Array von Buchstaben einer Schriftgröße zurück { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; unsigned char* ret = 0; unsigned char* größen = dateiKopf->getSchriftGrößeList(); unsigned char granzahl = dateiKopf->getSchriftGrößeAnzahl(); int grpos = -1; for (int i = 0; i < granzahl; ++i) { if (größen[i] == sg) { grpos = i; break; } } if (grpos != -1) { int* grposlist = dateiKopf->getPositionList(); LTDSSchriftKopf* sgkpf = new LTDSSchriftKopf(); std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); inF->seekg(grposlist[grpos], std::ios::beg); sgkpf->laden(inF); int anz = sgkpf->getZeichenAnzahl(); ret = new unsigned char[anz]; for (int i = 0; i < anz; ++i) ret[i] = sgkpf->getZeichen()[i]; sgkpf->release(); inF->close(); delete inF; } return ret; } #endif // Bit Funktionen int Framework::Bits(int a) // gibt 1-bits in gewinschter anzahl zurück { int ret = 0; for (int i = 0; i < a; ++i) { ret <<= 1; ++ret; } return ret; } int Framework::getBits(char c) // gibt zurück, wie viele Bits c benötigt { int ret = 0; for (int i = 0; (c & (char)Bits(i)) != c; ++i) ++ret; return ret; }