/** * alloziert Bildspeicher für die gewünschte Größe. * * @author FloSoft */ void libsiedler2::baseArchivItem_Bitmap::tex_alloc(void) { tex_clear(); tex_width = tex_pow2(width); tex_height = tex_pow2(height); if(format == FORMAT_UNKNOWN) format = getTextureFormat(); unsigned char clear; switch(format) { case FORMAT_RGBA: tex_bpp = 4; clear = 0x00; break; case FORMAT_PALETTED: tex_bpp = 1; clear = TRANSPARENT_INDEX; break; default: tex_bpp = 0; clear = 0x7F; } tex_data.resize(tex_width * tex_height * tex_bpp, clear); }
/** * virtueller Destruktor von @p baseArchivItem_Bitmap. * * @author FloSoft */ libsiedler2::baseArchivItem_Bitmap::~baseArchivItem_Bitmap(void) { tex_clear(); delete palette; palette = NULL; }
/** * lädt die Bilddaten aus einer Datei. * * @param[in] file Dateihandle der Datei * @param[in] palette Grundpalette * * @return liefert Null bei Erfolg, ungleich Null bei Fehler * * @author FloSoft */ int libsiedler2::baseArchivItem_Bitmap_Shadow::load(FILE *file, const ArchivItem_Palette *palette) { unsigned char *data = NULL; if(file == NULL) return 1; if(palette == NULL) palette = this->palette; if(palette == NULL) return 2; tex_clear(); // Nullpunkt X einlesen if(libendian::le_read_s(&nx, file) != 0) return 2; // Nullpunkt Y einlesen if(libendian::le_read_s(&ny, file) != 0) return 3; // Unbekannte Daten überspringen fseek(file, 4, SEEK_CUR); // Breite einlesen if(libendian::le_read_us(&width, file) != 0) return 4; // Höhe einlesen if(libendian::le_read_us(&height, file) != 0) return 5; // Unbekannte Daten überspringen fseek(file, 2, SEEK_CUR); // Länge einlesen if(libendian::le_read_ui(&length, file) != 0) return 6; // Daten einlesen if(length != 0) { data = new unsigned char[length]; if(libendian::le_read_uc(data, length, file) != (int)length) return 7; } // Speicher anlegen tex_alloc(); unsigned char gray = palette->lookup(255,255,255); if(length != 0 && data) { unsigned char *image = &data[height*2]; unsigned int position = 0; // Einlesen for(unsigned short y = 0; y < height; ++y) { unsigned short x = 0; // Solange Zeile einlesen, bis x voll ist while(x < width) { // graue Pixel setzen unsigned char count = image[position++]; for(unsigned char i = 0; i < count; ++i, ++x) tex_setPixel(x, y, gray, palette); // transparente Pixel setzen count = image[position++]; for(unsigned char i = 0; i < count; ++i, ++x) tex_setPixel(x, y, TRANSPARENT_INDEX, palette); } // FF überspringen ++position; } // FF überspringen ++position; if(position != length-(height*2) ) return 8; delete[] data; } return 0; }
/** * lädt die Bilddaten aus einer Datei. * * @param[in] file Dateihandle der Datei * @param[in] palette Grundpalette * * @return liefert Null bei Erfolg, ungleich Null bei Fehler */ int libsiedler2::baseArchivItem_Bitmap_RLE::load(std::istream& file, const ArchivItem_Palette* palette) { if(!file) return 1; if(palette == NULL) palette = this->palette_; if(palette == NULL) return 2; tex_clear(); libendian::LittleEndianIStreamRef fs(file); // Nullpunkt X einlesen fs >> nx_; // Nullpunkt Y einlesen fs >> ny_; // Unbekannte Daten überspringen fs.ignore(4); // Breite einlesen fs >> width_; // Höhe einlesen fs >> height_; // Unbekannte Daten überspringen fs.ignore(2); // Länge einlesen unsigned length; fs >> length; std::vector<unsigned char> data(length); // Daten einlesen fs >> data; // Speicher anlegen tex_alloc(); if(length != 0) { size_t position = height_ * 2; // Einlesen for(unsigned short y = 0; y < height_; ++y) { unsigned short x = 0; // Solange Zeile einlesen, bis x voll ist while(x < width_) { // farbige Pixel setzen unsigned char count = data[position++]; for(unsigned char i = 0; i < count; ++i, ++x) tex_setPixel(x, y, data[position++], palette); // transparente Pixel setzen count = data[position++]; for(unsigned char i = 0; i < count; ++i, ++x) tex_setPixel(x, y, TRANSPARENT_INDEX, palette); } // FF überspringen ++position; } // FF überspringen ++position; if(position != length) return 8; } return 0; }