#include "lc_global.h" #include "image.h" #include "lc_file.h" #include "system.h" static void copyToQImage(const Image& src, QImage& dest, bool transparent) { bool alpha = src.HasAlpha(); dest = QImage(src.mWidth, src.mHeight, alpha ? QImage::Format_ARGB32 : QImage::Format_RGB32); lcuint8* bytes = (lcuint8*)src.mData; int bpp = src.GetBPP(); LC_ASSERT(src.mFormat == LC_PIXEL_FORMAT_R8G8B8 || src.mFormat == LC_PIXEL_FORMAT_R8G8B8A8); if (transparent && alpha) { for (int y = 0; y < src.mHeight; y++) { for (int x = 0; x < src.mWidth; x++) { dest.setPixel(x, y, qRgba(bytes[0], bytes[1], bytes[2], bytes[3])); bytes += bpp; } } } else { for (int y = 0; y < src.mHeight; y++) { for (int x = 0; x < src.mWidth; x++) { dest.setPixel(x, y, qRgb(bytes[0], bytes[1], bytes[2])); bytes += bpp; } } } } static void copyFromQImage(const QImage& src, Image& dest) { bool alpha = src.hasAlphaChannel(); dest.Allocate(src.width(), src.height(), alpha ? LC_PIXEL_FORMAT_R8G8B8A8 : LC_PIXEL_FORMAT_R8G8B8); lcuint8* bytes = (lcuint8*)dest.mData; for (int y = 0; y < dest.mHeight; y++) { for (int x = 0; x < dest.mWidth; x++) { QRgb pixel = src.pixel(x, y); *bytes++ = qRed(pixel); *bytes++ = qGreen(pixel); *bytes++ = qBlue(pixel); if (alpha) *bytes++ = qAlpha(pixel); } } } bool Image::FileLoad(lcMemFile& File) { QImage image; unsigned char* buffer = File.mBuffer + File.mPosition; int bufferLength = File.mFileSize - File.mPosition; if (!image.loadFromData(buffer, bufferLength)) return false; copyFromQImage(image, *this); return true; } bool Image::FileLoad(const char* FileName) { QImage image; if (!image.load(FileName)) return false; copyFromQImage(image, *this); return true; } bool Image::FileSave(lcMemFile& File, LC_IMAGE_FORMAT Format, bool Transparent) const { QImage image; copyToQImage(*this, image, Transparent); QByteArray byteArray; QBuffer buffer(&byteArray); buffer.open(QIODevice::WriteOnly); const char* formatString; switch (Format) { case LC_IMAGE_BMP: formatString = "BMP"; break; case LC_IMAGE_JPG: formatString = "JPG"; break; default: case LC_IMAGE_PNG: formatString = "PNG"; break; } if (!image.save(&buffer, formatString)) return false; File.WriteBuffer(byteArray.constData(), byteArray.size()); return true; } bool Image::FileSave(const char* FileName, LC_IMAGE_FORMAT Format, bool Transparent) const { QImage image; copyToQImage(*this, image, Transparent); const char* formatString; switch (Format) { case LC_IMAGE_BMP: formatString = "BMP"; break; case LC_IMAGE_JPG: formatString = "JPG"; break; default: case LC_IMAGE_PNG: formatString = "PNG"; break; } char name[LC_MAXPATH], ext[5], *p; bool needext = false; strcpy(name, FileName); p = name + strlen(name) - 1; while ((p > name) && (*p != '/') && (*p != '\\') && (*p != '.')) p--; if (*p != '.') needext = true; else { if (strlen (p) > 5) needext = true; else { strcpy(ext, p+1); strlwr(ext); if (strcmp(ext, "bmp") == 0) Format = LC_IMAGE_BMP; else if (strcmp(ext, "jpg") == 0) Format = LC_IMAGE_JPG; else if (strcmp(ext, "jpeg") == 0) Format = LC_IMAGE_JPG; else if (strcmp(ext, "png") == 0) Format = LC_IMAGE_PNG; else needext = true; } } if (needext) { switch (Format) { case LC_IMAGE_BMP: strcat (name, ".bmp"); break; case LC_IMAGE_JPG: strcat (name, ".jpg"); break; default: case LC_IMAGE_PNG: strcat (name, ".png"); break; } } return image.save(name, formatString); }