//! 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<u32>(header.width, header.height), imageData); } if (!image) delete [] imageData; imageData = 0; return image; }
//! creates a surface from the file IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) { delete [] imageData; imageData = 0; file->seek(0); file->read(&header, sizeof(PsdHeader)); header.version = convert2le(header.version); header.channels = convert2le(header.channels); header.height = convert2le(header.height); header.width = convert2le(header.width); header.depth = convert2le(header.depth); header.mode = convert2le(header.mode); if (header.signature[0] != '8' || header.signature[1] != 'B' || header.signature[2] != 'P' || header.signature[3] != 'S') return 0; if (header.version != 1) { LOGGER.log("Unsupported PSD file version", file->getFileName(), io::ELL_ERROR); return 0; } if (header.mode != 3 || header.depth != 8) { LOGGER.log("Unsupported PSD color mode or depth. ", file->getFileName(), io::ELL_ERROR); return 0; } // skip color mode data u32 l; file->read(&l, sizeof(s32)); l = convert2le(l); if (!file->seek(l, true)) { LOGGER.log("Error seeking file pos to image resources. ", file->getFileName(), io::ELL_ERROR); return 0; } // skip image resources file->read(&l, sizeof(s32)); l = convert2le(l); if (!file->seek(l, true)) { LOGGER.log("Error seeking file pos to layer and mask. ", file->getFileName(), io::ELL_ERROR); return 0; } // skip layer & mask file->read(&l, sizeof(s32)); l = convert2le(l); if (!file->seek(l, true)) { LOGGER.log("Error seeking file pos to image data section. ", file->getFileName(), io::ELL_ERROR); return 0; } // read image data u16 compressionType; file->read(&compressionType, sizeof(u16)); compressionType = convert2le(compressionType); if (compressionType != 1 && compressionType != 0) { LOGGER.log("Unsupported psd compression mode. ", file->getFileName(), io::ELL_ERROR); return 0; } // create image data block imageData = new u32[header.width * header.height]; bool res = false; if (compressionType == 0) res = readRawImageData(file); // RAW image data else res = readRLEImageData(file); // RLE compressed data IImage* image = 0; if (res) { // create surface image = new CImage(ECF_A8R8G8B8, core::dimension2d<s32>(header.width, header.height), imageData); } if (!image) delete [] imageData; imageData = 0; return image; }