From f9158592e1478b2013afc7041d9ed041cf2d2f4a Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 13 Jan 2014 19:47:58 +1000 Subject: Update Irrlicht to 1.8.1. Include actual change markers this time. lol --- .../source/Irrlicht/CImageLoaderPSD.cpp | 375 +++++++++++++++++++++ 1 file changed, 375 insertions(+) create mode 100644 libraries/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp (limited to 'libraries/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp') diff --git a/libraries/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp b/libraries/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp new file mode 100644 index 0000000..3eb5c3b --- /dev/null +++ b/libraries/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp @@ -0,0 +1,375 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPSD.h" + +#ifdef _IRR_COMPILE_WITH_PSD_LOADER_ + +#include "IReadFile.h" +#include "os.h" +#include "CImage.h" +#include "irrString.h" + + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderPSD::CImageLoaderPSD() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderPSD"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPSD::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "psd" ); +} + + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPSD::isALoadableFileFormat(io::IReadFile* file) const +{ + if (!file) + return false; + + u8 type[3]; + file->read(&type, sizeof(u8)*3); + return (type[2]==2); // we currently only handle tgas of type 2. +} + + + +//! creates a surface from the file +IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) const +{ + u32* imageData = 0; + + PsdHeader header; + file->read(&header, sizeof(PsdHeader)); + +#ifndef __BIG_ENDIAN__ + header.version = os::Byteswap::byteswap(header.version); + header.channels = os::Byteswap::byteswap(header.channels); + header.height = os::Byteswap::byteswap(header.height); + header.width = os::Byteswap::byteswap(header.width); + header.depth = os::Byteswap::byteswap(header.depth); + header.mode = os::Byteswap::byteswap(header.mode); +#endif + + if (header.signature[0] != '8' || + header.signature[1] != 'B' || + header.signature[2] != 'P' || + header.signature[3] != 'S') + return 0; + + if (header.version != 1) + { + os::Printer::log("Unsupported PSD file version", file->getFileName(), ELL_ERROR); + return 0; + } + + if (header.mode != 3 || header.depth != 8) + { + os::Printer::log("Unsupported PSD color mode or depth.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip color mode data + + u32 l; + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to image resources.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip image resources + + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to layer and mask.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip layer & mask + + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to image data section.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // read image data + + u16 compressionType; + file->read(&compressionType, sizeof(u16)); +#ifndef __BIG_ENDIAN__ + compressionType = os::Byteswap::byteswap(compressionType); +#endif + + if (compressionType != 1 && compressionType != 0) + { + os::Printer::log("Unsupported psd compression mode.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // create image data block + + imageData = new u32[header.width * header.height]; + + bool res = false; + + if (compressionType == 0) + res = readRawImageData(file, header, imageData); // RAW image data + else + res = readRLEImageData(file, header, imageData); // RLE compressed data + + video::IImage* image = 0; + + if (res) + { + // create surface + image = new CImage(ECF_A8R8G8B8, + core::dimension2d(header.width, header.height), imageData); + } + + if (!image) + delete [] imageData; + imageData = 0; + + return image; +} + + +bool CImageLoaderPSD::readRawImageData(io::IReadFile* file, const PsdHeader& header, u32* imageData) const +{ + u8* tmpData = new u8[header.width * header.height]; + + for (s32 channel=0; channelread(tmpData, sizeof(c8) * header.width * header.height)) + { + os::Printer::log("Error reading color channel\n", file->getFileName(), ELL_ERROR); + break; + } + + s16 shift = getShiftFromChannel((c8)channel, header); + if (shift != -1) + { + u32 mask = 0xff << shift; + + for (u32 x=0; xread(&rleCount[y], sizeof(u16))) + { + delete [] tmpData; + delete [] rleCount; + os::Printer::log("Error reading rle rows\n", file->getFileName(), ELL_ERROR); + return false; + } + +#ifndef __BIG_ENDIAN__ + rleCount[y] = os::Byteswap::byteswap(rleCount[y]); +#endif + size += rleCount[y]; + } + + s8 *buf = new s8[size]; + if (!file->read(buf, size)) + { + delete [] rleCount; + delete [] buf; + delete [] tmpData; + os::Printer::log("Error reading rle rows\n", file->getFileName(), ELL_ERROR); + return false; + } + + u16 *rcount=rleCount; + + s8 rh; + u16 bytesRead; + u8 *dest; + s8 *pBuf = buf; + + // decompress packbit rle + + for (s32 channel=0; channel= 0) + { + ++rh; + + while (rh--) + { + *dest = *pBuf++; + ++bytesRead; + ++dest; + } + } + else + if (rh > -128) + { + rh = -rh +1; + + while (rh--) + { + *dest = *pBuf; + ++dest; + } + + ++pBuf; + ++bytesRead; + } + } + } + + s16 shift = getShiftFromChannel((c8)channel, header); + + if (shift != -1) + { + u32 mask = 0xff << shift; + + for (u32 x=0; x