//---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 File format // Content of the LTDBPixel class from DateiSystem.h // Constructor 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) {} // Destructor LTDBPixel::~LTDBPixel() { if (davor) davor->release(); } // non-constant bool LTDBPixel::addBitZuFarbe( unsigned char bit) // Adds a bit to the color values { if (changeR && iR != miR) // The bit belongs to Red { R = (unsigned char)(R | ((bit & 0x1) << (7 - komp - iR))); ++iR; } else if (changeG && iG != miG) // The bit belongs to Green { G = (unsigned char)(G | ((bit & 0x1) << (7 - komp - iG))); ++iG; } else if (changeB && iB != miB) // The bit belongs to Blue { B = (unsigned char)(B | ((bit & 0x1) << (7 - komp - iB))); ++iB; } else if (changeA && iA != miA) // The bit belongs to Alpha { A = (unsigned char)(A | ((bit & 0x1) << (7 - komp - iA))); ++iA; } else // The bit belongs to the next pixel return false; return true; } char LTDBPixel::addByte( char byte, char begin) // returns end of pixel, -1 if not finished { if (begin >= 8 || begin < 0) return -1; for (int i = begin; i < 8; ++i) { switch (index) { case 0: // The first bit of a pixel stores whether the // compression changed change = (bool)((byte >> (7 - i)) & 0x1); if (!change) // If compression doesn't change, the values // from the previous pixel are inherited { if (!davor) // The file is corrupted (the first pixel cannot // inherit from the previous one) { #ifdef WIN32 MessageBox(NULL, "Error, the image file is corrupted", "Error", 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)); // Determine the length // of the pixel in bits. Each color has 8 bits by default, // compression can make it smaller } else maxIndex = (char)(maxIndex + 7); // Since the pixel doesn't inherit // values from the previous one, // it is 7 bits larger break; case 1: // The second bit of a pixel stores either the // compression type or already the color if (change) // The bit belongs to the 7 compression bits changeR = (bool)((byte >> (7 - i)) & 0x1); else { if (!addBitZuFarbe( (unsigned char)(byte >> (7 - i)))) // The bit belongs to // the color return (unsigned char)i; } break; case 2: // The third bit of a pixel stores either the // compression type or already the color if (change) // The bit belongs to the 7 compression bits changeG = (bool)((byte >> (7 - i)) & 0x1); else { if (!addBitZuFarbe( (unsigned char)(byte >> (7 - i)))) // The bit belongs to // the color return (unsigned char)i; } break; case 3: // The fourth bit of a pixel stores either the // compression type or already the color if (change) // The bit belongs to the 7 compression bits changeB = (bool)((byte >> (7 - i)) & 0x1); else { if (!addBitZuFarbe( (unsigned char)(byte >> (7 - i)))) // The bit belongs to // the color return (unsigned char)i; } break; case 4: // The fifth bit of a pixel stores either the // compression type or already the color if (change) // The bit belongs to the 7 compression bits changeA = (bool)((byte >> (7 - i)) & 0x1); else { if (!addBitZuFarbe( (unsigned char)(byte >> (7 - i)))) // The bit belongs to // the color return (unsigned char)i; } break; case 5: // The sixth bit of a pixel stores either the // compression type or already the color if (change) // The bit belongs to the 7 compression bits komp = (unsigned char)(komp | ((unsigned char)((byte >> (7 - i)) & 0x1) << 2)) & 7; else { if (!addBitZuFarbe( (unsigned char)(byte >> (7 - i)))) // The bit belongs to // the color return (unsigned char)i; } break; case 6: // The seventh bit of a pixel stores either the // compression type or already the color if (change) // The bit belongs to the 7 compression bits komp = (unsigned char)(komp | ((unsigned char)((byte >> (7 - i)) & 0x1) << 1)) & 7; else { if (!addBitZuFarbe( (unsigned char)(byte >> (7 - i)))) // The bit belongs to // the color return (unsigned char)i; } break; case 7: // The eighth bit of a pixel stores either the // compression type or already the color if (change) // The bit belongs to the 7 compression bits { komp = (unsigned char)(komp | ((byte >> (7 - i)) & 0x1)) & 7; // That was the last compression bit // Evaluate compression 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)); // Bit length of the pixel } else { if (!addBitZuFarbe( (unsigned char)(byte >> (7 - i)))) // The bit belongs to // the color return (unsigned char)i; } break; default: // The remaining bits all store the color values of the pixel if (!addBitZuFarbe(( unsigned char)(byte >> (7 - i)))) // The bit belongs to the color 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) // sets the color of the pixel { // Since this function is called, the class is now to be used for saving // Reset values in case the class was already used for loading or saving 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; // Set color values R = (unsigned char)(f >> 16); G = (unsigned char)(f >> 8); B = (unsigned char)f; A = (unsigned char)(f >> 24); } void LTDBPixel::komprimieren() // Compresses the pixel { maxIndex = 1; if (!davor) { // This is the first 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 { // The difference to the previous pixel is stored 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(); } // Check if something changes 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()) { // Something changes change = 1; maxIndex = (char)(maxIndex + 7); } else { // Nothing changes change = 0; } } } bool LTDBPixel::getNextFarbeBit( char& byte, int i) // Stores the next color bit 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) // The bit belongs to red { byte |= (char)(((RR >> (7 - komp - iR)) & 0x1) << (7 - i)); ++iR; } else if (changeG && iG != miG) // The bit belongs to green { byte |= (char)(((GG >> (7 - komp - iG)) & 0x1) << (7 - i)); ++iG; } else if (changeB && iB != miB) // The bit belongs to blue { byte |= (char)(((BB >> (7 - komp - iB)) & 0x1) << (7 - i)); ++iB; } else if (changeA && iA != miA) // The bit belongs to alpha { byte |= (char)(((AA >> (7 - komp - iA)) & 0x1) << (7 - i)); ++iA; } else // The pixel is already finished return false; return true; } char LTDBPixel::getNextByte( char& byte, int begin) // Returns the next bits, -1 if the pixel // is not finished { // begin specifies where to write in the byte variable // the function returns the end of the pixel in the byte variable // -1 means the pixel is not finished for (int i = begin; i < 8; ++i) { switch (index) { case 0: // The first bit of the pixel stores whether the // compression changes byte |= (char)(((int)change & 0x1) << (7 - i)); break; case 1: // The second bit of the pixel stores either the color // or the compression if (change) // Compression byte |= (char)(((int)changeR & 0x1) << (7 - i)); else // Color { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 2: // The third bit of the pixel stores either the color // or the compression if (change) // Compression byte |= (char)(((int)changeG & 0x1) << (7 - i)); else // Color { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 3: // The fourth bit of the pixel stores either the color // or the compression if (change) // Compression byte |= (char)(((int)changeB & 0x1) << (7 - i)); else // Color { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 4: // The fifth bit of the pixel stores either the color // or the compression if (change) // Compression byte |= (char)(((int)changeA & 0x1) << (7 - i)); else // Color { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 5: // The sixth bit of the pixel stores either the color // or the compression if (change) // Compression byte |= (char)(((komp >> 2) & 0x1) << (7 - i)); else // Color { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 6: // The seventh bit of the pixel stores either the color // or the compression if (change) // Compression byte |= (char)(((komp >> 1) & 0x1) << (7 - i)); else // Color { if (!getNextFarbeBit(byte, i)) return (char)i; } break; case 7: // The eighth bit of the pixel stores either the color // or the compression if (change) // Compression byte |= (char)((komp & 0x1) << (7 - i)); else // Color { if (!getNextFarbeBit(byte, i)) return (char)i; } break; default: // The remaining bits store the color of the pixel 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 // returns the pixel as color { 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 // returns red { return R; } unsigned char LTDBPixel::getG() const // returns green { return G; } unsigned char LTDBPixel::getB() const // returns blue { return B; } unsigned char LTDBPixel::getA() const // returns alpha { return A; } // Content of the LTDBDateiKopf class from Dateisystem.h // Constructor LTDBDateiKopf::LTDBDateiKopf() : ReferenceCounter(), bilder(new RCArray()), pos(new Array<__int64>()), bAnzahl(0) {} // Destructor LTDBDateiKopf::~LTDBDateiKopf() { bilder->release(); pos->release(); } // non-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); // image name and half file position bilder->add(kpf->getTitel()); // sets title Punkt gr = kpf->getSize(); kpf->release(); char p[5]; inF->read((char*)p, 5); // other half of the file position 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); // sets 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; } // Content of the LTDBKopf class from DateiSystem.h // Constructor LTDBKopf::LTDBKopf() : ReferenceCounter() {} // non-constant void LTDBKopf::laden(std::ifstream* f) // Loads data from a file { 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) // Fills the data { 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] == SpecialCharacters::SMALL_UE || titel[i - skipped] == SpecialCharacters::BIG_UE) titel[i - skipped] = 27; else if (titel[i - skipped] == SpecialCharacters::SMALL_OE || titel[i - skipped] == SpecialCharacters::BIG_OE) titel[i - skipped] = 28; else if (titel[i - skipped] == SpecialCharacters::SMALL_AE || titel[i - skipped] == SpecialCharacters::BIG_AE) titel[i - skipped] = 29; else if (titel[i - skipped] == SpecialCharacters::SZ) 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; // store 1st character break; case 1: a |= (__int64)(titel[i] & 31) << 50; // store 2nd character break; case 2: a |= (__int64)(titel[i] & 31) << 45; // store 3rd character break; case 3: a |= (__int64)(titel[i] & 31) << 40; // store 4th character break; case 4: a |= (__int64)(titel[i] & 31) << 35; // store 5th character break; case 5: a |= (__int64)(titel[i] & 31) << 30; // store 6th character break; case 6: a |= (__int64)(titel[i] & 31) << 25; // store 7th character break; case 7: a |= (__int64)(titel[i] & 31) << 20; // store 8th character break; case 8: a |= (__int64)(titel[i] & 31) << 15; // store 9th character break; case 9: a |= (__int64)(titel[i] & 31) << 10; // store 10th character break; case 10: a |= (__int64)(titel[i] & 31) << 5; // store 11th character break; case 11: a |= (__int64)(titel[i] & 31); // store 12th character break; case 12: b |= (__int32)(titel[i] & 31) << 27; // store 13th character break; case 13: b |= (__int32)(titel[i] & 31) << 22; // store 14th character break; case 14: b |= (__int32)(titel[i] & 31) << 17; // store 15th character 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 // Saves data to a file { if (f->is_open()) { int bits = 4 /*title length*/ + getTitelLength() * 5 /*title*/ + 24 /*image size*/; int bytes = bits / 8; // byte length of the file header 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 // returns the length of the image name { return (int)(a >> 60 & Bits(4)); // The title length is stored in the first // 4 bits of the file } Text* LTDBKopf::getTitel() const // returns the name of the image { 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; // get 1st character break; case 1: c[0] = (a >> 50) & 31; // get 2nd character break; case 2: c[0] = (a >> 45) & 31; // get 3rd character break; case 3: c[0] = (a >> 40) & 31; // get 4th character break; case 4: c[0] = (a >> 35) & 31; // get 5th character break; case 5: c[0] = (a >> 30) & 31; // get 6th character break; case 6: c[0] = (a >> 25) & 31; // get 7th character break; case 7: c[0] = (a >> 20) & 31; // get 8th character break; case 8: c[0] = (a >> 15) & 31; // get 9th character break; case 9: c[0] = (a >> 10) & 31; // get 10th character break; case 10: c[0] = (a >> 5) & 31; // get 11th character break; case 11: c[0] = a & 31; // get 12th character break; case 12: c[0] = (char)((b >> 27) & 31); // get 13th character break; case 13: c[0] = (char)((b >> 22) & 31); // get 14th character break; case 14: c[0] = (char)((b >> 17) & 31); // get 15th character break; } if (c[0] == 27) c[0] = SpecialCharacters::SMALL_UE; else if (c[0] == 28) c[0] = SpecialCharacters::SMALL_OE; else if (c[0] == 29) c[0] = SpecialCharacters::SMALL_AE; else if (c[0] == 30) c[0] = SpecialCharacters::SZ; else if (c[0] == 31) c[0] = '.'; else c[0] = (char)(c[0] + 96); ret->append(c); } return ret; } Punkt LTDBKopf::getSize() const // returns the size of the image { int BeginBit = 4 /*title length*/ + getTitelLength() * 5 /*title*/; 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 // returns the bits from begin to ende (excluding 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; } // Content of the LTDBBody class from Dateisystem.h // Constructor LTDBBody::LTDBBody() : ReferenceCounter(), gr(0, 0), b(new Bild()) {} LTDBBody::LTDBBody(LTDBKopf* k) // calls init : ReferenceCounter(), gr(0, 0), b(new Bild()) { init(k); } // Destructor LTDBBody::~LTDBBody() { b->release(); } // non-constant void LTDBBody::init(LTDBKopf k) // Initializes, required before loading { 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) // Initializes, required before loading { 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) // loads the image { b->neuBild(gr.x, gr.y, 0xFF000000); // create new image int* buff = b->getBuffer(); int breite = b->getBreite(); char byte = 0; int index = 0; LTDBPixel* davor = 0; // last loaded pixel LTDBPixel* dieser = new LTDBPixel(0); // pixel currently being loaded int begin = 0; // pixel start, end position in the byte variable #ifdef WIN32 if (zF) { zF->reset(); zF->setAktionAnzahl(gr.x * gr.y); } #endif while (index < gr.x * gr.y) // for each pixel { if (!dieser) // if it is not the first pixel dieser = new LTDBPixel(dynamic_cast(davor->getThis())); int ende = -1; while (ende < 0) // load pixel { if (begin == 0) inF->read(&byte, 1); ende = dieser->addByte(byte, (char)begin); // evaluate byte 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) // sets the image to be saved { this->b->release(); this->b = b; } // constant void LTDBBody::speichern( FBalken* zF, std::ofstream* outF) const // saves image { if (outF->is_open()) { LTDBPixel* letzter = 0; // Last saved pixel LTDBPixel* dieser = new LTDBPixel(0); // The pixel currently being saved int begin = 0, ende = 0; // pixel start, end position in the byte variable char byte = 0; // The next byte of the file 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) // for each pixel { if (!dieser) // if it is not the first pixel dieser = new LTDBPixel( dynamic_cast(letzter->getThis())); dieser->setFarbe(pBuff[i]); // set pixel color dieser->komprimieren(); // compress pixel ende = -1; while (ende < 0) // fill byte { ende = dieser->getNextByte(byte, begin); begin = 0; w = 0; if (ende == -1 || ende == 8) // save byte { outF->write(&byte, 1); w = 1; byte = 0; } } // pixel finished begin = ende; if (begin == 8) begin = 0; if (letzter) letzter->release(); letzter = dynamic_cast( dieser->getThis()); // dieser becomes letzter dieser = (LTDBPixel*)dieser->release(); #ifdef WIN32 if (zF) zF->aktionPlus(); #endif } if (letzter) letzter = (LTDBPixel*)letzter->release(); if (!w) { outF->write(&byte, 1); // save the last byte } outF->flush(); // flush file stream } } Bild* LTDBBody::getBild() const // returns the loaded image { return dynamic_cast(b->getThis()); } const Punkt& LTDBBody::getSize() const // returns the size of the image { return gr; } // Content of the LTDBDatei class from Dateisystem.h // Constructor LTDBDatei::LTDBDatei() : ReferenceCounter(), pfad(new Text()), datKpf(0) {} // Destructor LTDBDatei::~LTDBDatei() { if (pfad) pfad->release(); if (datKpf) datKpf->release(); } // non-constant void LTDBDatei::setDatei(Text* pfad) // Sets the path to the file { // Delete values of any previous file if (datKpf) datKpf = (LTDBDateiKopf*)datKpf->release(); // Set path this->pfad->setText(*pfad); pfad->release(); } void LTDBDatei::erstellen() // Creates the file { 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) // The class briefly reads all images and remembers // where in the file each one is located { // This function will take some time, but will make // the other functions faster afterwards 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() // Deletes the file { if (DateiExistiert(dynamic_cast(pfad->getThis()))) { DateiRemove(dynamic_cast(pfad->getThis())); if (datKpf) datKpf->release(); } } void LTDBDatei::remove(FBalken* f, Text* name) // Deletes an image from the file { if (DateiExistiert(dynamic_cast(pfad->getThis())) && name) { if (!datKpf) leseDaten(0); // read data // Check if file is not present if (!datKpf) { name->release(); return; } int index = datKpf->getBildIndex(dynamic_cast(name->getThis())); if (index == -1) // the image does not exist { name->release(); return; } // Determine temporary file path 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); // open old file 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); // open new file 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); // Copy bytes up to the file for (__int64 i = inF->tellg(); i < position; ++i) { inF->read(&byte, 1); outF->write(&byte, 1); } // skip image to be deleted 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(); // copy remaining bytes 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) // Loads an image from the file { 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) { // Error message Text* fehler = new Text("The image "); fehler->append(*name); fehler->append(" was not found in the file\n"); fehler->append(*pfad); fehler->append("!"); Logging::error() << fehler << "\n"; name->release(); return 0; } std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // Determine start of the file to load __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(*name)) { // Error message t->release(); kpf->release(); inF->close(); delete inF; Text* fehler = new Text("The file "); fehler->append(*pfad); fehler->append(" is not a valid LTDB file!"); #ifdef WIN32 WMessageBox(0, new Text("Error"), fehler, MB_ICONERROR); #endif name->release(); return 0; } t->release(); LTDBBody* kpr = new LTDBBody(dynamic_cast(kpf->getThis())); kpr->laden(f, inF); // load image 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) // Saves an image to the file { 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() << "An image with this name already exists!\n"; bild->release(); name->release(); kpf->release(); return -1; } // find temporary file path 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); // save image header LTDBBody* kpr = new LTDBBody(dynamic_cast(kpf->getThis())); kpr->setBild(dynamic_cast(bild->getThis())); kpr->speichern(f, outF); // save image 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() // Lists all images in the file { if (!datKpf) leseDaten(0); if (datKpf) return datKpf->zBildListe(); return 0; } // constant Text* LTDBDatei::getPfad() const // Returns the path to the file { return dynamic_cast(pfad->getThis()); } int LTDBDatei::getBildAnzahl() const { if (!datKpf) return 0; return datKpf->getbAnzahl(); } bool LTDBDatei::istOffen() const // Checks if the file is open { if (!pfad) return 0; return DateiExistiert(dynamic_cast(pfad->getThis())); } #ifdef WIN32 // LTDS File format // Content of the LTDSPixel class from DateiSystem.h // Constructor LTDSPixel::LTDSPixel(LTDSPixel* davor) : ReferenceCounter(), index(0), iA(0), miA(8), maxIndex(1), aender(0), aenderA(0), komp(0), alpha(0), davor(davor) {} // Destructor LTDSPixel::~LTDSPixel() { if (davor) davor->release(); } // non-constant // intended for loading bool LTDSPixel::addBitZuFarbe(unsigned char bit) { if (aenderA && iA != miA) // The bit belongs to alpha { alpha |= ((bit & Bits(1))) << (7 - komp - iA); ++iA; } else // The bit belongs to the next pixel return false; return true; } char LTDSPixel::addByte(char byte, char begin) // returns end of pixel, -1 if not finished { if (begin >= 8 || begin < 0) return -1; for (int i = begin; i < 8; ++i) { switch (index) { case 0: // The first bit of a pixel stores whether the // compression changed aender = ((byte >> (7 - i)) & Bits(1)) == 1; if (!aender) // If compression doesn't change, the values // from the previous pixel are inherited { if (!davor) // The file is corrupted (the first pixel cannot // inherit from the previous one) { MessageBox(NULL, "Error, the image file is corrupted", "Error", MB_ICONERROR); exit(0); } aenderA = davor->getAEnderA(); komp = davor->getKomp(); miA -= komp; if (!aenderA) alpha = davor->getA(); maxIndex += aenderA * (8 - komp); // Determine the length // of the pixel in bits. Each color has 8 bits by default, // compression can make it smaller } else maxIndex += 4; // Since the pixel doesn't inherit values from // the previous one, it is 4 bits larger break; case 1: // The second bit of a pixel stores either the // compression type or already the color if (aender) // The bit belongs to the 4 compression bits aenderA = ((byte >> (7 - i)) & Bits(1)) == 1; else { if (!addBitZuFarbe( byte >> (7 - i))) // The bit belongs to the color return i; } break; case 2: // The sixth bit of a pixel stores either the // compression type or already the color if (aender) // The bit belongs to the 4 compression bits komp |= (unsigned char)((byte >> (7 - i)) & Bits(1)) << 2; else { if (!addBitZuFarbe( byte >> (7 - i))) // The bit belongs to the color return i; } break; case 3: // The seventh bit of a pixel stores either the // compression type or already the color if (aender) // The bit belongs to the 4 compression bits komp |= (unsigned char)((byte >> (7 - i)) & Bits(1)) << 1; else { if (!addBitZuFarbe( byte >> (7 - i))) // The bit belongs to the color return i; } break; case 4: // The eighth bit of a pixel stores either the // compression type or already the color if (aender) // The bit belongs to the 4 compression bits { komp |= (unsigned char)((byte >> (7 - i)) & Bits(1)); // That was the last compression bit // Evaluate compression miA -= komp; if (!aenderA) alpha = davor->getA(); maxIndex += aenderA * (8 - komp); // bit length of the pixel } else { if (!addBitZuFarbe( byte >> (7 - i))) // The bit belongs to the color return i; } break; default: // The remaining bits all store the color values of the pixel if (!addBitZuFarbe(byte >> (7 - i))) // The bit belongs to the color return i; break; } ++index; if (index >= maxIndex) { if (davor) { if (aenderA) alpha = davor->getA() + alpha; davor = (LTDSPixel*)davor->release(); } return i + 1; } } return -1; } // intended for saving void LTDSPixel::setAlpha(unsigned char alpha) // sets the color of the pixel { this->alpha = alpha; } void LTDSPixel::Komp() // Compresses the pixel { maxIndex = 1; if (!davor) { // This is the first pixel aender = 1; aenderA = 1; maxIndex += 4; miA = getBits(alpha); } else { // The difference to the previous pixel is stored miA = getBits(alpha - davor->getA()); if (alpha != davor->getA()) aenderA = 1; else aenderA = 0; } // Check if something changes if (!miA && aenderA) ++miA; komp = 8 - miA; maxIndex += aenderA * miA; if (davor) { if (aenderA != davor->getAEnderA() || komp != davor->getKomp()) { // Something changes aender = 1; maxIndex += 4; } else { // Nothing changes aender = 0; } } } bool LTDSPixel::getNextFarbeBit(char& byte, int i) { unsigned char AA = alpha; if (davor) { AA -= davor->getA(); } if (aenderA && iA != miA) // The bit belongs to alpha { byte |= ((AA >> (7 - komp - iA)) & Bits(1)) << (7 - i); ++iA; } else // The pixel is already finished return false; return true; } char LTDSPixel::getNextByte( char& byte, int bbegin) // Returns the next bits, -1 if the pixel // is not finished { // bbegin specifies where to write in the byte variable // the function returns the end of the pixel in the byte variable // -1 means the pixel is not finished for (int i = bbegin; i < 8; ++i) { switch (index) { case 0: // The first bit of the pixel stores whether the // compression changes byte |= ((int)aender & Bits(1)) << (7 - i); break; case 1: // The second bit of the pixel stores either the color // or the compression if (aender) // Compression byte |= ((int)aenderA & Bits(1)) << (7 - i); else // Color { if (!getNextFarbeBit(byte, i)) return i; } break; case 2: // The second bit of the pixel stores either the color // or the compression if (aender) // Compression byte |= ((komp >> 2) & Bits(1)) << (7 - i); else // Color { if (!getNextFarbeBit(byte, i)) return i; } break; case 3: // The third bit of the pixel stores either the color // or the compression if (aender) // Compression byte |= ((komp >> 1) & Bits(1)) << (7 - i); else // Color { if (!getNextFarbeBit(byte, i)) return i; } break; case 4: // The fourth bit of the pixel stores either the color // or the compression if (aender) // Compression byte |= (komp & Bits(1)) << (7 - i); else // Color { if (!getNextFarbeBit(byte, i)) return i; } break; default: // The remaining bits store the color of the pixel 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 // has the compression changed { return komp; } bool LTDSPixel::getAEnderA() const // returns whether the alpha value changes { return aenderA; } unsigned char LTDSPixel::getA() const // returns alpha { return alpha; } // Content of the LTDSDateiKopf class from Dateisystem.h // Constructor LTDSDateiKopf::LTDSDateiKopf() : ReferenceCounter(), sganzahl(0), gr(0), pos(0) {} // Destructor LTDSDateiKopf::~LTDSDateiKopf() { delete[] gr; delete[] pos; } // non-constant void LTDSDateiKopf::laden(std::ifstream* inF) // Loads from 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) // Add font size { ++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) // Remove font size { 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 // Saves to 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::getSchriftGroesseList() const // returns a list of stored font sizes { return gr; } int* LTDSDateiKopf::getPositionList() const // returns a position list of stored font sizes { return pos; } int LTDSDateiKopf::getSchriftGroesseAnzahl() const // returns the number of stored font sizes { return sganzahl; } // Content of the LTDSSchriftKopf class from Dateisystem.h // Constructor LTDSSchriftKopf::LTDSSchriftKopf() : ReferenceCounter(), schriftSize(0), zeichen(0), pos(0), zeichenAnzahl(0) {} // Destructor LTDSSchriftKopf::~LTDSSchriftKopf() { delete[] pos; delete[] zeichen; } // non-constant void LTDSSchriftKopf::laden(std::ifstream* inF) // loads from 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::setSchriftgroesse( unsigned char gr) // set font size { schriftSize = gr; } void LTDSSchriftKopf::setZeichenAlphabet( Alphabet* alphabet) // sets the characters from 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) // Add character { ++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) // Remove character { 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 // saves to 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::getSchriftGroesse() const // returns the font size { return schriftSize; } unsigned char LTDSSchriftKopf::getZeichenAnzahl() const // returns the character count { return zeichenAnzahl; } int* LTDSSchriftKopf::getPositionen() const // returns the character positions { return pos; } unsigned char* LTDSSchriftKopf::getZeichen() const // returns the characters { return zeichen; } // Content of the LTDSBuchstabenKopf class from Dateisystem.h // Constructor LTDSBuchstabenKopf::LTDSBuchstabenKopf() : ReferenceCounter(), zeichen(0), size(0, 0) {} // non-constant void LTDSBuchstabenKopf::laden(std::ifstream* inF) // loads from 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& groesse) // initialization (for saving) { this->zeichen = zeichen; this->size = groesse; } void LTDSBuchstabenKopf::init(unsigned char zeichen, int br, int hoe) { this->zeichen = zeichen; size.x = br, size.y = hoe; } // constant void LTDSBuchstabenKopf::speichern( std::ofstream* outF) const // saves to 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 // returns the character { return zeichen; } int LTDSBuchstabenKopf::getBreite() const // returns the width { return size.x; } int LTDSBuchstabenKopf::getHoehe() const // returns the height { return size.y; } const Punkt& LTDSBuchstabenKopf::getGroesse() const // returns the size { return size; } // Content of the LTDSBuchstabenKoerper class from Dateisystem.h // Constructor LTDSBuchstabenKoerper::LTDSBuchstabenKoerper(LTDSBuchstabenKopf* kopf) : ReferenceCounter(), size(kopf->getGroesse()), zeichen(kopf->getZeichen()), buchstabe(new Buchstabe()) { buchstabe->NeuBuchstabe(size); kopf->release(); } // Destructor LTDSBuchstabenKoerper::~LTDSBuchstabenKoerper() { if (buchstabe) buchstabe->release(); } // non-constant void LTDSBuchstabenKoerper::setBuchstabe( Buchstabe* zeichen) // sets the character { if (buchstabe) buchstabe->release(); buchstabe = zeichen; } void LTDSBuchstabenKoerper::laden(std::ifstream* inF) // Loads from 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) // if it is not the first pixel jetzt = new LTDSPixel( dynamic_cast(vorher->getThis())); int ende = -1; while (ende < 0) // load pixel { if (beg == 0) inF->read(&byte, 1); ende = jetzt->addByte(byte, beg); // evaluate byte 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 LTDSBuchstabenKoerper::speichern( std::ofstream* outF) const // saves to outF { if (outF->good() && outF->is_open()) { LTDSPixel* vorher = 0; // Last saved pixel LTDSPixel* jetzt = new LTDSPixel(0); // The pixel currently being saved int begin = 0, ende = 0; // pixel start, end position in the byte variable char byte = 0; // The next byte of the file bool w = 0; unsigned char* alphaBuff = buchstabe->getBuff(); for (int i = 0; i < size.x * size.y; ++i) // for each pixel { if (!jetzt) // if it is not the first pixel jetzt = new LTDSPixel( dynamic_cast(vorher->getThis())); jetzt->setAlpha(alphaBuff[i]); // set pixel color jetzt->Komp(); // compress pixel ende = -1; while (ende < 0) // fill byte { ende = jetzt->getNextByte(byte, begin); begin = 0; w = 0; if (ende == -1 || ende == 8) // save byte { outF->write(&byte, 1); w = 1; byte = 0; } } // pixel finished begin = ende; if (begin == 8) begin = 0; if (vorher) vorher->release(); vorher = dynamic_cast( jetzt->getThis()); // jetzt becomes vorher jetzt = (LTDSPixel*)jetzt->release(); } if (vorher) vorher = (LTDSPixel*)vorher->release(); if (!w) { outF->write(&byte, 1); // save the last byte } outF->flush(); // flush file stream } } Buchstabe* LTDSBuchstabenKoerper::getBuchstabe() const // returns the character { return dynamic_cast(buchstabe->getThis()); } unsigned char LTDSBuchstabenKoerper::getZeichen() const // returns the character { return zeichen; } // Content of the LTDSDatei class from Dateisystem.h // Constructor LTDSDatei::LTDSDatei() : ReferenceCounter(), pfad(new Text()), dateiKopf(0) {} // Destructor LTDSDatei::~LTDSDatei() { if (dateiKopf) dateiKopf->release(); pfad->release(); } // non-constant void LTDSDatei::setPfad(Text* txt) // sets the path to the file { if (dateiKopf) dateiKopf = (LTDSDateiKopf*)dateiKopf->release(); pfad->setText(txt->getText()); txt->release(); } void LTDSDatei::leseDaten() // reads the file header { 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::addSchriftgroesse( Alphabet* alphabet) // adds a font size { if (!DateiExistiert(dynamic_cast( pfad->getThis()))) // check if the file exists return; if (!dateiKopf) // check if the file header has been read leseDaten(); int sgroesse = alphabet ->getSchriftSize(); // font size to be added unsigned char* sglist = dateiKopf->getSchriftGroesseList(); // list of already existing // font sizes unsigned char sganzahl = dateiKopf->getSchriftGroesseAnzahl(); // number of already // existing font sizes for (int i = 0; i < sganzahl; ++i) // check if the font size already exists { if (sglist[i] == sgroesse) { alphabet->release(); return; } } dateiKopf->addSG(sgroesse); // add font size to file header int* sgPosList = dateiKopf ->getPositionList(); // list of font size positions sglist = dateiKopf->getSchriftGroesseList(); // list of already // existing font sizes std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // old file pfad->append("0"); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); // new file dateiKopf->speichern(outF); // save file header to new file inF->seekg(1 + 5 * sganzahl, std::ios::beg); // position of the first font size in the old file for (int i = 0; i < sganzahl; ++i) // update character positions of all font sizes { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // font size header sgKpf_tmp->laden(inF); // load from old file int* zeichP_tmp = sgKpf_tmp ->getPositionen(); // character positions of the font size unsigned char zeichA_tmp = sgKpf_tmp ->getZeichenAnzahl(); // number of characters in the font size for (int i1 = 0; i1 < zeichA_tmp; ++i1) zeichP_tmp[i1] += 5; // update character positions sgKpf_tmp->speichern( outF); // save font size header to new file int beginByte = (int)inF->tellg(); // copy remaining bytes until the next // font size to new file 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) // copy operation { inF->read(&byte, 1); outF->write(&byte, 1); } sgKpf_tmp->release(); } inF->close(); // close old file sgPosList[sganzahl] = (int)outF->tellp(); outF->seekp(0, std::ios::beg); for (int i = 0; i < sganzahl; ++i) // update positions in file header sgPosList[i] += 5; dateiKopf->speichern(outF); // save updated file header outF->seekp(sgPosList[sganzahl], std::ios::beg); LTDSSchriftKopf* sgkopf = new LTDSSchriftKopf(); // header of the new font size sgkopf->setZeichenAlphabet(dynamic_cast( alphabet->getThis())); // initialize font size header sgkopf->speichern(outF); // save font size header int* BuchstabenPosList = sgkopf->getPositionen(); // positions of the different characters // in the file (still 0) int count = 0; for (int i = 0; i < 256; ++i) { Buchstabe* zeich = alphabet->getBuchstabe(i); if (zeich) { BuchstabenPosList[count] = (int)outF->tellp(); // set character position LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); // character header zeichKpf->init(i, zeich->getBreite(), zeich->getHeight()); zeichKpf->speichern(outF); // save character header LTDSBuchstabenKoerper* zeichKoerp = new LTDSBuchstabenKoerper(dynamic_cast( zeichKpf->getThis())); // character body zeichKpf->release(); zeichKoerp->setBuchstabe( dynamic_cast(zeich->getThis())); zeichKoerp->speichern(outF); // save character body zeich->release(); ++count; } } outF->seekp(sgPosList[sganzahl], std::ios::beg); sgkopf->speichern(outF); // save updated font size header outF->close(); Text* pfad2 = new Text(); pfad2->setText(pfad->getText()); pfad->remove(pfad->getLength() - 1, pfad->getLength()); DateiRemove(dynamic_cast(pfad->getThis())); // delete old file DateiUmbenennen(dynamic_cast(pfad2->getThis()), dynamic_cast( pfad->getThis())); // rename new file to old pfad2->release(); // free memory sgkopf->release(); delete inF; delete outF; alphabet->release(); } void LTDSDatei::addBuchstabe(int gr, Buchstabe* zeich, unsigned char zeichen) // Adds a character to a font size { if (!DateiExistiert( dynamic_cast(pfad->getThis()))) // check if file exists { zeich->release(); return; } if (!dateiKopf) // check if the file header was loaded leseDaten(); unsigned char* sgList = dateiKopf->getSchriftGroesseList(); // list of font sizes from // the file int* sgPosList = dateiKopf->getPositionList(); // list of font size // positions from file unsigned char sgAnzahl = dateiKopf->getSchriftGroesseAnzahl(); // number of font sizes // from the file int sgNum = -1; for (int i = 0; i < sgAnzahl; ++i) // find the position of the correct font size { if (sgList[i] == gr) { sgNum = i; break; } } std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // old file pfad->append("0"); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); // new file inF->seekg(1 + 5 * sgAnzahl, std::ios::beg); if (sgNum == -1) // The font size does not exist yet and will be created { dateiKopf->addSG(gr); // add font size to file header sgPosList = dateiKopf->getPositionList(); sgList = dateiKopf->getSchriftGroesseList(); dateiKopf->speichern(outF); // save file header inF->seekg(1 + 5 * sgAnzahl, std::ios::beg); // position of the first // font size in the old file for (int i = 0; i < sgAnzahl; ++i) // update character positions of all font sizes { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // font size header sgKpf_tmp->laden(inF); // load from old file int* zeichP_tmp = sgKpf_tmp ->getPositionen(); // character positions of the font size unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // number of characters in // the font size for (int i1 = 0; i1 < zeichA_tmp; ++i1) zeichP_tmp[i1] += 5; // update character positions sgKpf_tmp->speichern( outF); // save font size header to new file int beginByte = (int)inF->tellg(); // copy remaining bytes until the next // font size to new file 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) // copy operation { 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) // update positions in file header sgPosList[i] += 5; dateiKopf->speichern(outF); // save updated file header outF->seekp(sgPosList[sgAnzahl], std::ios::beg); LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); // initialize font size header sgKpf->setSchriftgroesse(gr); sgKpf->addZeichen(zeichen); sgKpf->getPositionen()[0] = (int)outF->tellp() + 7; sgKpf->speichern(outF); // save font size header sgKpf->release(); LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); // character header zeichKpf->init(zeichen, zeich->getSize()); zeichKpf->speichern(outF); // save character header LTDSBuchstabenKoerper* zeichKoerp = new LTDSBuchstabenKoerper(dynamic_cast( zeichKpf->getThis())); // character body zeichKpf->release(); zeichKoerp->setBuchstabe(dynamic_cast(zeich->getThis())); zeichKoerp->speichern(outF); // save character body zeichKoerp->release(); } else { dateiKopf->speichern(outF); // save file header int beginByte = 1 + 5 * sgAnzahl; // copy remaining bytes until the next // font size to new file int endByte = sgPosList[sgNum]; char byte; for (int i1 = beginByte; i1 < endByte; ++i1) // copy operation up to the specified size { inF->read(&byte, 1); outF->write(&byte, 1); } LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); // font size header 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 of the new character 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); // save font size header sgKpf->release(); for (int i = (int)inF->tellg() + indexPlus; i < zeichenPos; ++i) // copy operation up to the character start { inF->read(&byte, 1); outF->write(&byte, 1); } LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); // character header zeichKpf->init(zeichen, zeich->getSize()); zeichKpf->speichern(outF); // save character header LTDSBuchstabenKoerper* zeichKoerp = new LTDSBuchstabenKoerper(dynamic_cast( zeichKpf->getThis())); // character body zeichKpf->release(); zeichKoerp->setBuchstabe(dynamic_cast(zeich->getThis())); zeichKoerp->speichern(outF); // save character body zeichKoerp->release(); int nowPos = (int)outF->tellp(); indexPlus += nowPos - zeichenPos; for (int i = sgNum + 1; i < sgAnzahl; ++i) // update file header sgPosList[i] += indexPlus; outF->seekp(0, std::ios::beg); dateiKopf->speichern(outF); // save file header outF->seekp(nowPos, std::ios::beg); for (int i = sgNum + 1; i < sgAnzahl; ++i) // update remaining font sizes { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // font size header sgKpf_tmp->laden(inF); // load from old file int* zeichP_tmp = sgKpf_tmp ->getPositionen(); // character positions of the font size unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // number of characters in // the font size for (int i1 = 0; i1 < zeichA_tmp; ++i1) zeichP_tmp[i1] += indexPlus; // update character positions sgKpf_tmp->speichern( outF); // save font size header to new file int beginByte = (int)inF->tellg(); // copy remaining bytes until the next // font size to new file 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) // copy operation { 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())); // delete old file DateiUmbenennen(dynamic_cast(pfad2->getThis()), dynamic_cast(pfad->getThis())); // rename new file to old pfad2->release(); // free memory delete inF; delete outF; zeich->release(); } void LTDSDatei::loescheSchrifrGroesse( int gr) // Deletes a font size from the file { if (!DateiExistiert(dynamic_cast( pfad->getThis()))) // check if file exists return; if (!dateiKopf) // check if the file header was loaded leseDaten(); unsigned char* sgList = dateiKopf->getSchriftGroesseList(); // list of font sizes unsigned char sgAnzahl = dateiKopf->getSchriftGroesseAnzahl(); // number of font sizes int sgNum = -1; for (int i = 0; i < sgAnzahl; ++i) // search for font size to delete { if (sgList[i] == gr) { sgNum = i; break; } } if (sgNum == -1) // the font size is not present return; int* sgPosList = dateiKopf ->getPositionList(); // list of font size positions std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // old file pfad->append("0"); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); // new file outF->seekp(1 + 5 * (sgAnzahl - 1), std::ios::beg); inF->seekg(1 + 5 * sgAnzahl, std::ios::beg); for (int i = 0; i < sgNum; ++i) // update font sizes before the one // being deleted { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // font size header sgKpf_tmp->laden(inF); // load font size header int* zeichPosLTmp = sgKpf_tmp->getPositionen(); // character positions unsigned char zeichATmp = sgKpf_tmp->getZeichenAnzahl(); // character count for (int i1 = 0; i1 < zeichATmp; ++i1) // move character positions back by 5 bytes zeichPosLTmp[i1] -= 5; sgKpf_tmp->speichern(outF); // save to new file char byte = 0; for (int i1 = (int)inF->tellg(); i1 < sgPosList[i + 1]; ++i1) // copy the character body { 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) // font sizes after the one being deleted { LTDSSchriftKopf* sgKpf_tmp = new LTDSSchriftKopf(); // font size header sgKpf_tmp->laden(inF); // load font size header int* zeichPosLTmp = sgKpf_tmp->getPositionen(); // character positions unsigned char zeichATmp = sgKpf_tmp->getZeichenAnzahl(); // character count for (int i1 = 0; i1 < zeichATmp; ++i1) // update character positions zeichPosLTmp[i1] -= indexMinus; sgKpf_tmp->speichern(outF); // save to new file 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) // copy the character body { inF->read(&byte, 1); outF->write(&byte, 1); } } for (int i = 0; i < sgNum; ++i) // update file header 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); // save file header inF->close(); outF->close(); Text* pfad2 = new Text(pfad->getText()); pfad->remove(pfad->getLength() - 1, pfad->getLength()); DateiRemove(dynamic_cast(pfad->getThis())); // delete old file DateiUmbenennen(dynamic_cast(pfad2->getThis()), dynamic_cast(pfad->getThis())); // rename new file to old pfad2->release(); delete inF; delete outF; } void LTDSDatei::loescheBuchstabe( int gr, unsigned char zeichen) // Deletes a character from the file { if (!DateiExistiert(dynamic_cast( pfad->getThis()))) // check if the file exists return; if (!dateiKopf) // check if the file header was read leseDaten(); unsigned char* sgList = dateiKopf->getSchriftGroesseList(); // list of font sizes unsigned char sgAnzahl = dateiKopf->getSchriftGroesseAnzahl(); // number of font sizes int* sgPosList = dateiKopf ->getPositionList(); // list of font size positions int sgNum = -1; for (int i = 0; i < sgAnzahl; ++i) // search for font size { if (sgList[i] == gr) { sgNum = i; break; } } if (sgNum == -1) // font size not found return; std::ifstream* inF = new std::ifstream(pfad->getText(), std::ios::binary); // old file pfad->append("0"); std::ofstream* outF = new std::ofstream(pfad->getText(), std::ios::binary); // new file int indexMinus = 0; inF->seekg(1 + 5 * sgAnzahl, std::ios::beg); dateiKopf->speichern(outF); // save file header for (int i = 0; i < sgAnzahl; ++i) { LTDSSchriftKopf* sgKopf = new LTDSSchriftKopf(); // font header sgKopf->laden(inF); // load font header unsigned char sgZeichAnzahl = sgKopf->getZeichenAnzahl(); // character count unsigned char* sgZeichenList = sgKopf->getZeichen(); // character list int* sgZPosList = sgKopf->getPositionen(); // position list if (i == sgNum) // character is in this font size { int sgZNum = -1; for (int i1 = 0; i1 < sgZeichAnzahl; ++i1) // search for character { if (sgZeichenList[i1] == zeichen) { sgZNum = i1; break; } } if (sgZNum == -1) // character not found { sgKopf->release(); inF->close(); outF->close(); delete inF; delete outF; DateiRemove(dynamic_cast(pfad->getThis())); pfad->remove(pfad->getLength() - 1, pfad->getLength()); return; // abort } outF->seekp(2 + 5 * (sgZeichAnzahl - 1), std::ios::cur); indexMinus += 5; for (int i1 = 0; i1 < sgZNum; ++i1) // characters before the one being deleted { char byte = 0; for (int i2 = sgZPosList[i1]; i2 < sgZPosList[i1 + 1]; ++i2) // copy { inF->read(&byte, 1); outF->write(&byte, 1); } sgZPosList[i1] -= indexMinus; // update font size header } 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) // characters after the deleted character { 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) // copy { inF->read(&byte, 1); outF->write(&byte, 1); } sgZPosList[i1] -= indexMinus; // update font size header } sgKopf->removeZeichen(zeichen); } else { for (int i1 = 0; i1 < sgZeichAnzahl; ++i1) // update font size header sgZPosList[i] -= indexMinus; sgKopf->speichern(outF); // save font size header 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) // copy { inF->read(&byte, 1); outF->write(&byte, 1); } sgPosList[i] -= indexMinus; } outF->seekp(sgPosList[i], std::ios::beg); sgKopf->speichern(outF); // save font size header 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())); // delete old file DateiUmbenennen(dynamic_cast(pfad2->getThis()), dynamic_cast( pfad->getThis())); // rename new file to old pfad2->release(); // free memory delete inF; delete outF; } void LTDSDatei::loescheDatei() // Deletes the entire file { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return; if (!dateiKopf) leseDaten(); DateiRemove(dynamic_cast(pfad->getThis())); } void LTDSDatei::erstelleDatei() // creates the file { 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) // Saves the provided font { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) { schrift->release(); return; } loescheDatei(); 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); LTDSBuchstabenKoerper* zeichKoerp = new LTDSBuchstabenKoerper( dynamic_cast(zeichKpf->getThis())); zeichKoerp->setBuchstabe( dynamic_cast(zeichen->getThis())); zeichKoerp->speichern(outF); zeichKoerp->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() // returns the loaded font { 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->getSchriftGroesseAnzahl(); ++i) { LTDSSchriftKopf* sgKpf = new LTDSSchriftKopf(); sgKpf->laden(inF); Alphabet* alphabet = new Alphabet(); alphabet->setSchriftSize(sgKpf->getSchriftGroesse()); for (int i1 = 0; i1 < sgKpf->getZeichenAnzahl(); ++i1) { LTDSBuchstabenKopf* zeichKpf = new LTDSBuchstabenKopf(); zeichKpf->laden(inF); LTDSBuchstabenKoerper* zeichKoerp = new LTDSBuchstabenKoerper( dynamic_cast(zeichKpf->getThis())); zeichKoerp->laden(inF); alphabet->setBuchstabe( zeichKpf->getZeichen(), zeichKoerp->getBuchstabe()); zeichKoerp->release(); zeichKpf->release(); } ret->addAlphabet(dynamic_cast(alphabet->getThis())); alphabet->release(); sgKpf->release(); } inF->close(); delete inF; return ret; } Alphabet* LTDSDatei::ladeAlphabet( int schriftgroesse) // returns a loaded font with only the specified // font size { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; Alphabet* ret = 0; int sgNum = -1; for (int i = 0; i < dateiKopf->getSchriftGroesseAnzahl(); ++i) { if (dateiKopf->getSchriftGroesseList()[i] == schriftgroesse) { sgNum = i; break; } } if (sgNum == -1) return 0; ret = new Alphabet(); ret->NeuAlphabet(); ret->setSchriftSize(schriftgroesse); 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); LTDSBuchstabenKoerper* sgZKoerp = new LTDSBuchstabenKoerper( dynamic_cast(sgZKpf->getThis())); sgZKoerp->laden(inF); ret->setBuchstabe(sgZKpf->getZeichen(), sgZKoerp->getBuchstabe()); sgZKoerp->release(); sgZKpf->release(); } sgKpf->release(); inF->close(); delete inF; return ret; } Buchstabe* LTDSDatei::ladeBuchstabe(int schriftgroesse, unsigned char zeichen) // Loads a specific character { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; Buchstabe* ret = 0; int sgNum = -1; for (int i = 0; i < dateiKopf->getSchriftGroesseAnzahl(); ++i) { if (dateiKopf->getSchriftGroesseList()[i] == schriftgroesse) { 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); LTDSBuchstabenKoerper* sgZKoerp = new LTDSBuchstabenKoerper( dynamic_cast(sgZKpf->getThis())); sgZKoerp->laden(inF); ret = sgZKoerp->getBuchstabe(); sgZKoerp->release(); sgZKpf->release(); } sgKpf->release(); inF->close(); delete inF; if (ret) { ret->setSchriftSize(schriftgroesse); } return ret; } Text* LTDSDatei::getPfad() const // returns the file path { return dynamic_cast(pfad->getThis()); } int LTDSDatei::getAnzahlSchriftgroessen() const // returns the number of font sizes from the file { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; return dateiKopf->getSchriftGroesseAnzahl(); } unsigned char* LTDSDatei::getSchriftGroessen() const // returns an array of font sizes { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; return dateiKopf->getSchriftGroesseList(); } unsigned char LTDSDatei::getAnzahlBuchstaben( int sg) // returns the number of stored characters for a font size { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; int ret = 0; unsigned char* groessen = dateiKopf->getSchriftGroesseList(); unsigned char granzahl = dateiKopf->getSchriftGroesseAnzahl(); int grpos = -1; for (int i = 0; i < granzahl; ++i) { if (groessen[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) // returns an array of characters for a font size { if (!DateiExistiert(dynamic_cast(pfad->getThis()))) return 0; if (!dateiKopf) return 0; unsigned char* ret = 0; unsigned char* groessen = dateiKopf->getSchriftGroesseList(); unsigned char granzahl = dateiKopf->getSchriftGroesseAnzahl(); int grpos = -1; for (int i = 0; i < granzahl; ++i) { if (groessen[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 functions int Framework::Bits(int a) // returns 1-bits in the desired count { int ret = 0; for (int i = 0; i < a; ++i) { ret <<= 1; ++ret; } return ret; } int Framework::getBits(char c) // returns how many bits c requires { int ret = 0; for (int i = 0; (c & (char)Bits(i)) != c; ++i) ++ret; return ret; }