leocad/common/image.cpp

193 lines
3.4 KiB
C++
Raw Normal View History

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