/**
 *  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;
}
Exemple #4
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;
}