mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-05 01:00:48 +00:00
165 lines
4.1 KiB
C++
165 lines
4.1 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
/* Based on code from eos https://github.com/DrMcCoy/xoreos/
|
|
* relicensed under GPLv2+ with permission from DrMcCoy and clone2727
|
|
*/
|
|
|
|
#include "common/util.h"
|
|
#include "common/stream.h"
|
|
#include "common/textconsole.h"
|
|
#include "common/error.h"
|
|
|
|
#include "engines/wintermute/graphics/tga.h"
|
|
|
|
namespace WinterMute {
|
|
|
|
TGA::TGA() {
|
|
|
|
}
|
|
|
|
TGA::~TGA() {
|
|
destroy();
|
|
}
|
|
|
|
void TGA::destroy() {
|
|
_surface.free();
|
|
}
|
|
|
|
bool TGA::loadStream(Common::SeekableReadStream &tga) {
|
|
byte imageType, pixelDepth;
|
|
bool success;
|
|
success = readHeader(tga, imageType, pixelDepth);
|
|
success = readData(tga, imageType, pixelDepth);
|
|
|
|
if (tga.err() || !success) {
|
|
warning("Failed reading TGA-file");
|
|
return false;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
bool TGA::readHeader(Common::SeekableReadStream &tga, byte &imageType, byte &pixelDepth) {
|
|
if (!tga.seek(0)) {
|
|
warning("Failed reading TGA-file");
|
|
return false;
|
|
}
|
|
|
|
// TGAs have an optional "id" string in the header
|
|
uint32 idLength = tga.readByte();
|
|
|
|
// Number of colors in the color map / palette
|
|
if (tga.readByte() != 0) {
|
|
warning("Unsupported feature: Color map");
|
|
return false;
|
|
}
|
|
|
|
// Image type. 2 == unmapped RGB, 3 == Grayscale
|
|
imageType = tga.readByte();
|
|
if ((imageType != 2) && (imageType != 3)) {
|
|
warning("Unsupported image type: %d", imageType);
|
|
return false;
|
|
}
|
|
|
|
// Color map specifications + X + Y
|
|
tga.skip(5 + 2 + 2);
|
|
|
|
// Image dimensions
|
|
_surface.w = tga.readUint16LE();
|
|
_surface.h = tga.readUint16LE();
|
|
|
|
// Bits per pixel
|
|
pixelDepth = tga.readByte();
|
|
_surface.format.bytesPerPixel = pixelDepth / 8;
|
|
|
|
if (imageType == 2) {
|
|
if (pixelDepth == 24) {
|
|
_hasAlpha = false;
|
|
_format = Graphics::PixelFormat(pixelDepth / 8, 8, 8, 8, 0, 16, 8, 0, 0);
|
|
} else if (pixelDepth == 16 || pixelDepth == 32) {
|
|
_hasAlpha = true;
|
|
_format = Graphics::PixelFormat(pixelDepth / 8, 8, 8, 8, 8, 24, 16, 8, 0);
|
|
} else {
|
|
warning("Unsupported pixel depth: %d, %d", imageType, pixelDepth);
|
|
return false;
|
|
}
|
|
} else if (imageType == 3) {
|
|
if (pixelDepth != 8) {
|
|
warning("Unsupported pixel depth: %d, %d", imageType, pixelDepth);
|
|
return false;
|
|
}
|
|
|
|
_hasAlpha = false;
|
|
_format = Graphics::PixelFormat(1, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
}
|
|
|
|
// Image descriptor
|
|
tga.skip(1);
|
|
|
|
// Skip the id string
|
|
tga.skip(idLength);
|
|
return true;
|
|
}
|
|
|
|
bool TGA::readData(Common::SeekableReadStream &tga, byte imageType, byte pixelDepth) {
|
|
if (imageType == 2) {
|
|
_surface.create(_surface.w, _surface.h, _format);
|
|
|
|
if (pixelDepth == 16) {
|
|
// Convert from 16bpp to 32bpp
|
|
// 16bpp TGA is ARGB1555
|
|
uint16 count = _surface.w * _surface.h;
|
|
byte *dst = (byte *)_surface.pixels;
|
|
|
|
while (count--) {
|
|
uint16 pixel = tga.readUint16LE();
|
|
|
|
*dst++ = (pixel & 0x1F) << 3;
|
|
*dst++ = (pixel & 0x3E0) >> 2;
|
|
*dst++ = (pixel & 0x7C00) >> 7;
|
|
*dst++ = (pixel & 0x8000) ? 0xFF : 0x00;
|
|
}
|
|
|
|
} else {
|
|
// Read it in raw
|
|
tga.read(_surface.pixels, _surface.pitch * _surface.w);
|
|
}
|
|
} else if (imageType == 3) {
|
|
_surface.create(_surface.w, _surface.h, _surface.format);
|
|
|
|
byte *data = (byte *)_surface.pixels;
|
|
uint32 count = _surface.w * _surface.h;
|
|
|
|
while (count-- > 0) {
|
|
byte g = tga.readByte();
|
|
|
|
memset(data, g, 3);
|
|
data[3] = 0xFF;
|
|
|
|
data += 4;
|
|
}
|
|
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // End of namespace Graphics
|