2012-03-20 01:57:42 +01:00
|
|
|
#include "lc_global.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "image.h"
|
2015-01-31 21:19:03 +01:00
|
|
|
#include "lc_file.h"
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2017-12-02 21:22:04 +01:00
|
|
|
quint8* Bytes = (quint8*)Dest.mData;
|
2015-01-31 21:19:03 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-31 23:58:47 +02:00
|
|
|
Image::Image()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2017-04-14 02:26:40 +02:00
|
|
|
mData = nullptr;
|
2013-08-09 06:57:18 +02:00
|
|
|
mWidth = 0;
|
|
|
|
mHeight = 0;
|
2013-08-31 23:58:47 +02:00
|
|
|
mFormat = LC_PIXEL_FORMAT_INVALID;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2018-09-30 04:45:21 +02:00
|
|
|
Image::Image(Image&& Other)
|
|
|
|
{
|
|
|
|
mData = Other.mData;
|
|
|
|
mWidth = Other.mWidth;
|
|
|
|
mHeight = Other.mHeight;
|
|
|
|
mFormat = Other.mFormat;
|
|
|
|
|
|
|
|
Other.mData = nullptr;
|
|
|
|
Other.mWidth = 0;
|
|
|
|
Other.mHeight = 0;
|
|
|
|
Other.mFormat = LC_PIXEL_FORMAT_INVALID;
|
|
|
|
}
|
|
|
|
|
2013-08-31 23:58:47 +02:00
|
|
|
Image::~Image()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
FreeData();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-31 23:58:47 +02:00
|
|
|
int Image::GetBPP() const
|
|
|
|
{
|
|
|
|
switch (mFormat)
|
|
|
|
{
|
|
|
|
case LC_PIXEL_FORMAT_INVALID:
|
|
|
|
return 0;
|
|
|
|
case LC_PIXEL_FORMAT_A8:
|
|
|
|
return 1;
|
|
|
|
case LC_PIXEL_FORMAT_L8A8:
|
|
|
|
return 2;
|
|
|
|
case LC_PIXEL_FORMAT_R8G8B8:
|
|
|
|
return 3;
|
|
|
|
case LC_PIXEL_FORMAT_R8G8B8A8:
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Image::HasAlpha() const
|
|
|
|
{
|
|
|
|
switch (mFormat)
|
|
|
|
{
|
|
|
|
case LC_PIXEL_FORMAT_INVALID:
|
|
|
|
return false;
|
|
|
|
case LC_PIXEL_FORMAT_A8:
|
|
|
|
return true;
|
|
|
|
case LC_PIXEL_FORMAT_L8A8:
|
|
|
|
return true;
|
|
|
|
case LC_PIXEL_FORMAT_R8G8B8:
|
|
|
|
return false;
|
|
|
|
case LC_PIXEL_FORMAT_R8G8B8A8:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Image::FreeData()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
free(mData);
|
2017-04-14 02:26:40 +02:00
|
|
|
mData = nullptr;
|
2013-08-09 06:57:18 +02:00
|
|
|
mWidth = 0;
|
|
|
|
mHeight = 0;
|
2013-08-31 23:58:47 +02:00
|
|
|
mFormat = LC_PIXEL_FORMAT_INVALID;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-31 23:58:47 +02:00
|
|
|
void Image::Allocate(int Width, int Height, lcPixelFormat Format)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-31 23:58:47 +02:00
|
|
|
FreeData();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
mWidth = Width;
|
|
|
|
mHeight = Height;
|
2013-08-31 23:58:47 +02:00
|
|
|
mFormat = Format;
|
|
|
|
mData = (unsigned char*)malloc(mWidth * mHeight * GetBPP());
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-31 23:58:47 +02:00
|
|
|
void Image::ResizePow2()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-31 23:58:47 +02:00
|
|
|
int i, shifted_x, shifted_y;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
shifted_x = mWidth;
|
2013-08-31 23:58:47 +02:00
|
|
|
for (i = 0; ((i < 16) && (shifted_x != 0)); i++)
|
|
|
|
shifted_x = shifted_x >> 1;
|
|
|
|
shifted_x = (i != 0) ? 1 << (i-1) : 1;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
shifted_y = mHeight;
|
2013-08-31 23:58:47 +02:00
|
|
|
for (i = 0; ((i < 16) && (shifted_y != 0)); i++)
|
|
|
|
shifted_y = shifted_y >> 1;
|
|
|
|
shifted_y = (i != 0) ? 1 << (i-1) : 1;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
if ((shifted_x != mWidth) || (shifted_y != mHeight))
|
2013-08-31 23:58:47 +02:00
|
|
|
Resize (shifted_x, shifted_y);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-31 23:58:47 +02:00
|
|
|
void Image::Resize(int width, int height)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-31 23:58:47 +02:00
|
|
|
int i, j, k, components, stx, sty;
|
|
|
|
float accumx, accumy;
|
2017-04-14 02:26:40 +02:00
|
|
|
unsigned char* bits = nullptr;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-31 23:58:47 +02:00
|
|
|
components = GetBPP();
|
2017-02-13 03:05:20 +01:00
|
|
|
int BufferSize = width * height * components;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2017-02-13 03:05:20 +01:00
|
|
|
if (BufferSize)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2017-02-13 03:05:20 +01:00
|
|
|
bits = (unsigned char*)malloc(BufferSize);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2017-04-03 02:15:09 +02:00
|
|
|
if (bits)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2017-04-03 02:15:09 +02:00
|
|
|
for (j = 0; j < mHeight; j++)
|
2017-02-13 03:05:20 +01:00
|
|
|
{
|
2017-04-03 02:15:09 +02:00
|
|
|
accumy = (float)height*j / (float)mHeight;
|
|
|
|
sty = (int)floor(accumy);
|
|
|
|
|
|
|
|
for (i = 0; i < mWidth; i++)
|
|
|
|
{
|
|
|
|
accumx = (float)width*i / (float)mWidth;
|
|
|
|
stx = (int)floor(accumx);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2017-04-03 02:15:09 +02:00
|
|
|
for (k = 0; k < components; k++)
|
|
|
|
bits[(stx + sty*width)*components + k] = mData[(i + j * mWidth) * components + k];
|
|
|
|
}
|
2017-02-13 03:05:20 +01:00
|
|
|
}
|
2013-08-31 23:58:47 +02:00
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-10-12 01:26:23 +02:00
|
|
|
free(mData);
|
2013-08-09 06:57:18 +02:00
|
|
|
mData = bits;
|
|
|
|
mWidth = width;
|
|
|
|
mHeight = height;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2015-01-31 21:19:03 +01:00
|
|
|
|
|
|
|
bool Image::FileLoad(lcMemFile& File)
|
|
|
|
{
|
|
|
|
QImage Image;
|
|
|
|
|
|
|
|
unsigned char* Buffer = File.mBuffer + File.mPosition;
|
2016-02-17 00:11:52 +01:00
|
|
|
size_t BufferLength = File.mFileSize - File.mPosition;
|
2015-01-31 21:19:03 +01:00
|
|
|
|
2016-03-06 21:19:02 +01:00
|
|
|
if (!Image.loadFromData(Buffer, (int)BufferLength))
|
2015-01-31 21:19:03 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
CopyFromQImage(Image, *this);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-29 22:31:24 +02:00
|
|
|
bool Image::FileLoad(const QString& FileName)
|
2015-01-31 21:19:03 +01:00
|
|
|
{
|
|
|
|
QImage Image;
|
|
|
|
|
|
|
|
if (!Image.load(FileName))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
CopyFromQImage(Image, *this);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|