Bitmap::Bitmap(const char *fname, const char *data, int len) : Object() { _fname = fname; if (len < 8 || memcmp(data, "BM F\0\0\0", 8) != 0) { if (gDebugLevel == DEBUG_BITMAPS || gDebugLevel == DEBUG_ERROR || gDebugLevel == DEBUG_ALL) error("Invalid magic loading bitmap"); } strcpy(_filename, fname); int codec = READ_LE_UINT32(data + 8); // _paletteIncluded = READ_LE_UINT32(data + 12); _numImages = READ_LE_UINT32(data + 16); _x = READ_LE_UINT32(data + 20); _y = READ_LE_UINT32(data + 24); // _transparentColor = READ_LE_UINT32(data + 28); _format = READ_LE_UINT32(data + 32); // _numBits = READ_LE_UINT32(data + 36); // _blueBits = READ_LE_UINT32(data + 40); // _greenBits = READ_LE_UINT32(data + 44); // _redBits = READ_LE_UINT32(data + 48); // _blueShift = READ_LE_UINT32(data + 52); // _greenShift = READ_LE_UINT32(data + 56); // _redShift = READ_LE_UINT32(data + 60); _width = READ_LE_UINT32(data + 128); _height = READ_LE_UINT32(data + 132); _currImage = 1; _data = new char *[_numImages]; int pos = 0x88; for (int i = 0; i < _numImages; i++) { _data[i] = new char[2 * _width * _height]; if (codec == 0) { memcpy(_data[i], data + pos, 2 * _width * _height); pos += 2 * _width * _height + 8; } else if (codec == 3) { int compressed_len = READ_LE_UINT32(data + pos); decompress_codec3(data + pos + 4, _data[i]); pos += compressed_len + 12; } #ifdef SYSTEM_BIG_ENDIAN if (_format == 1) for (int j = 0; j < _width * _height; ++j) { ((uint16 *)_data[i])[j] = SWAP_BYTES_16(((uint16 *)_data[i])[j]); } #endif } g_driver->createBitmap(this); }
bool BitmapData::loadGrimBm(Common::SeekableReadStream *data) { uint32 tag2 = data->readUint32BE(); if (tag2 != (MKTAG('F','\0','\0','\0'))) return false; int codec = data->readUint32LE(); data->readUint32LE(); //_paletteIncluded _numImages = data->readUint32LE(); _x = data->readUint32LE(); _y = data->readUint32LE(); data->readUint32LE(); //_transparentColor _format = data->readUint32LE(); _bpp = data->readUint32LE(); // uint32 redBits = data->readUint32LE(); // uint32 greenBits = data->readUint32LE(); // uint32 blueBits = data->readUint32LE(); // uint32 redShift = data->readUint32LE(); // uint32 greenShift = data->readUint32LE(); // uint32 blueShift = data->readUint32LE(); // Hardcode the format, since the values saved in the files are garbage for some, like "ha_0_elvos.zbm". Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); data->seek(128, SEEK_SET); _width = data->readUint32LE(); _height = data->readUint32LE(); _colorFormat = BM_RGB565; _hasTransparency = false; _data = new Graphics::PixelBuffer[_numImages]; data->seek(0x80, SEEK_SET); for (int i = 0; i < _numImages; i++) { data->seek(8, SEEK_CUR); _data[i].create(pixelFormat, _width * _height, DisposeAfterUse::YES); if (codec == 0) { uint32 dsize = _bpp / 8 * _width * _height; data->read(_data[i].getRawBuffer(), dsize); } else if (codec == 3) { int compressed_len = data->readUint32LE(); char *compressed = new char[compressed_len]; data->read(compressed, compressed_len); bool success = decompress_codec3(compressed, (char *)_data[i].getRawBuffer(), _bpp / 8 * _width * _height); delete[] compressed; if (!success) warning(".. when loading image %s.\n", _fname.c_str()); } else Debug::error(Debug::Bitmaps, "Unknown image codec in BitmapData ctor!"); #ifdef SCUMM_BIG_ENDIAN if (_format == 1) { uint16 *d = (uint16 *)_data[i].getRawBuffer(); for (int j = 0; j < _width * _height; ++j) { d[j] = SWAP_BYTES_16(d[j]); } } #endif } // Initially, no GPU-side textures created. the createBitmap // function will allocate some if necessary (and successful) _numTex = 0; _texIds = nullptr; g_driver->createBitmap(this); return true; }