leocad/qt/lc_qimage.cpp

197 lines
3.6 KiB
C++

#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);
}