282 lines
7.0 KiB
C++
282 lines
7.0 KiB
C++
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2023
|
|
*
|
|
* This program is a free software product. You can redistribute it and/or
|
|
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
|
* version 3 as published by the Free Software Foundation. In accordance with
|
|
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
|
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
|
* of any third-party rights.
|
|
*
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
|
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
|
* street, Riga, Latvia, EU, LV-1050.
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of the Program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU AGPL version 3.
|
|
*
|
|
* Pursuant to Section 7(b) of the License you must retain the original Product
|
|
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
|
* grant you any rights under trademark law for use of our trademarks.
|
|
*
|
|
* All the Product's GUI elements, including illustrations and icon sets, as
|
|
* well as technical writing content are licensed under the terms of the
|
|
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
|
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
*
|
|
*/
|
|
#ifndef PICFILE_H
|
|
#define PICFILE_H
|
|
|
|
#include "../../graphics/pro/Graphics.h"
|
|
|
|
enum PixelTrait
|
|
{
|
|
UndefinedPixelTrait = 0x000000,
|
|
CopyPixelTrait = 0x000001,
|
|
UpdatePixelTrait = 0x000002,
|
|
BlendPixelTrait = 0x000004
|
|
};
|
|
|
|
enum ClassType
|
|
{
|
|
UndefinedClass,
|
|
DirectClass,
|
|
PseudoClass
|
|
};
|
|
|
|
enum PixelChannel
|
|
{
|
|
UndefinedPixelChannel = 0,
|
|
RedPixelChannel = 0,
|
|
CyanPixelChannel = 0,
|
|
GrayPixelChannel = 0,
|
|
LPixelChannel = 0,
|
|
LabelPixelChannel = 0,
|
|
YPixelChannel = 0,
|
|
aPixelChannel = 1,
|
|
GreenPixelChannel = 1,
|
|
MagentaPixelChannel = 1,
|
|
CbPixelChannel = 1,
|
|
bPixelChannel = 2,
|
|
BluePixelChannel = 2,
|
|
YellowPixelChannel = 2,
|
|
CrPixelChannel = 2,
|
|
BlackPixelChannel = 3,
|
|
AlphaPixelChannel = 4,
|
|
IndexPixelChannel = 5,
|
|
ReadMaskPixelChannel = 6,
|
|
WriteMaskPixelChannel = 7,
|
|
MetaPixelChannel = 8, /* deprecated */
|
|
CompositeMaskPixelChannel = 9,
|
|
MetaPixelChannels = 10,
|
|
IntensityPixelChannel = 64, /* ???? */
|
|
CompositePixelChannel = 64, /* ???? */
|
|
SyncPixelChannel = 65 /* not a real channel */
|
|
};
|
|
|
|
struct PixelChannelMap
|
|
{
|
|
PixelChannel channel{UndefinedPixelChannel};
|
|
PixelTrait traits{UndefinedPixelTrait};
|
|
size_t offset{0};
|
|
};
|
|
|
|
struct PixelInfo
|
|
{
|
|
ClassType storage_class{DirectClass};
|
|
|
|
PixelTrait alpha_trait{UndefinedPixelTrait};
|
|
|
|
double red{0.0};
|
|
double green{0.0};
|
|
double blue{0.0};
|
|
double alpha{0.0};
|
|
double index{0.0};
|
|
};
|
|
|
|
struct Image
|
|
{
|
|
ClassType m_eStorageClass{DirectClass};
|
|
PixelTrait m_eAlphaTrait{UndefinedPixelTrait};
|
|
|
|
PixelInfo* m_pColormap{nullptr};
|
|
PixelChannelMap* m_pChannelMap{nullptr};
|
|
|
|
size_t m_nColors{0};
|
|
size_t m_nHeight{0};
|
|
size_t m_nWidth{0};
|
|
BYTE* m_pPixelData{nullptr};
|
|
|
|
Image()
|
|
{
|
|
m_pChannelMap = new PixelChannelMap[65];
|
|
for (size_t i=0; i <= 64; i++)
|
|
m_pChannelMap[i].channel=(PixelChannel) i;
|
|
|
|
m_pChannelMap[RedPixelChannel].offset = 0;
|
|
m_pChannelMap[GreenPixelChannel].offset = 1;
|
|
m_pChannelMap[BluePixelChannel].offset = 2;
|
|
m_pChannelMap[AlphaPixelChannel].offset = 3;
|
|
m_pChannelMap[IndexPixelChannel].offset = 5;
|
|
}
|
|
|
|
Image(const Image& other) : Image()
|
|
{
|
|
*this = other;
|
|
}
|
|
|
|
~Image()
|
|
{
|
|
if (m_pChannelMap)
|
|
delete[] m_pChannelMap;
|
|
|
|
if (m_pColormap)
|
|
delete[] m_pColormap;
|
|
|
|
if (m_pPixelData)
|
|
free(m_pPixelData);
|
|
}
|
|
|
|
Image& operator=(const Image& other)
|
|
{
|
|
if (this == &other)
|
|
return *this;
|
|
|
|
m_eStorageClass = other.m_eStorageClass;
|
|
m_eAlphaTrait = other.m_eAlphaTrait;
|
|
|
|
m_nColors = other.m_nColors;
|
|
m_nWidth = other.m_nWidth;
|
|
m_nHeight = other.m_nHeight;
|
|
|
|
if (other.m_pColormap)
|
|
{
|
|
m_pColormap = new PixelInfo[m_nColors + 1];
|
|
memcpy(m_pColormap, other.m_pColormap, (m_nColors + 1) * sizeof(PixelInfo));
|
|
}
|
|
|
|
memcpy(m_pChannelMap, other.m_pChannelMap, 65 * sizeof(PixelChannelMap));
|
|
return *this;
|
|
}
|
|
|
|
void Realloc(const size_t& w, const size_t& h, const bool& isCopy = true)
|
|
{
|
|
size_t oldSize = 4 * m_nWidth * m_nHeight;
|
|
size_t newSize = 4 * w * h;
|
|
|
|
m_nWidth = w;
|
|
m_nHeight = h;
|
|
|
|
if (0 == newSize)
|
|
{
|
|
if (m_pPixelData)
|
|
free(m_pPixelData);
|
|
m_pPixelData = nullptr;
|
|
return;
|
|
}
|
|
|
|
if (oldSize == newSize)
|
|
return;
|
|
|
|
BYTE* oldPixels = m_pPixelData;
|
|
if (oldSize > newSize || !m_pPixelData)
|
|
{
|
|
m_pPixelData = (BYTE*)malloc(newSize);
|
|
if (isCopy && oldPixels)
|
|
memcpy(m_pPixelData, oldPixels, newSize);
|
|
|
|
if (oldPixels)
|
|
free(oldPixels);
|
|
}
|
|
else
|
|
{
|
|
m_pPixelData = (BYTE*)realloc(oldPixels, newSize);
|
|
if (NULL == m_pPixelData)
|
|
{
|
|
m_pPixelData = (BYTE*)malloc(newSize);
|
|
if (isCopy && oldPixels)
|
|
memcpy(m_pPixelData, oldPixels, oldSize);
|
|
|
|
if (oldPixels)
|
|
free(oldPixels);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class CPictFile
|
|
{
|
|
public:
|
|
CPictFile();
|
|
~CPictFile();
|
|
|
|
bool Open(CBgraFrame* frame, const std::wstring& fileName, bool isRGB);
|
|
bool Open(CBgraFrame* frame, BYTE* buffer, const size_t& size, bool isRGB);
|
|
private:
|
|
bool Decode();
|
|
bool DecodeHeader();
|
|
bool DecodeData();
|
|
|
|
size_t GetFileSize() const;
|
|
|
|
size_t Read(const size_t& length, void* data);
|
|
const void* ReadBlobStream(const size_t& length, void* data, size_t* count);
|
|
unsigned short ReadShortValue();
|
|
signed short ReadSignedShortValue();
|
|
unsigned int ReadLongValue();
|
|
bool ReadRectangle(Aggplus::Rect* rect);
|
|
|
|
void SetImageAlpha(Image* img, const BYTE alpha);
|
|
BYTE* DecodeImage(const Image& img, size_t bytesPerLine, size_t bitsPerPixel, size_t* extent);
|
|
const BYTE* UnpackScanline(const BYTE* pixels, const size_t& bitsPerPixel, BYTE* scanline, size_t* bytesPerLine);
|
|
BYTE* GetPixels(const Image& image, const long long& x, const long long& y, const size_t& width, const size_t& height) const;
|
|
void CompositeImage(const Image& composite,const long long& xOffset, const long long& yOffset);
|
|
|
|
void ReadPolygon();
|
|
Aggplus::Rect ContractRect(const Aggplus::Rect& rect, bool isFrame);
|
|
void DrawPolygon(bool isFrame);
|
|
void DrawLine(const Aggplus::Point& p1, const Aggplus::Point& p2);
|
|
void DrawRect(bool isFrame);
|
|
void DrawRoundRect(bool isFrame);
|
|
void DrawOval(bool isFrame);
|
|
void DrawArc();
|
|
void ReadAndDrawText(int x, int y);
|
|
|
|
void InitializeRenderer();
|
|
|
|
private:
|
|
int m_nVersion{0};
|
|
|
|
FILE* m_pFile{nullptr};
|
|
Image m_oImgData{};
|
|
CBgraFrame m_oFrame{};
|
|
BYTE* m_pFrameData{nullptr};
|
|
|
|
size_t m_nPenHeight{0};
|
|
size_t m_nPenWidth{0};
|
|
|
|
int m_nFontStyle{0};
|
|
int m_nFontSize{0};
|
|
|
|
std::wstring m_wsFontName{};
|
|
|
|
Aggplus::Point m_oPenPoint{0, 0};
|
|
Aggplus::Point m_oTextPoint{0, 0};
|
|
|
|
Aggplus::Rect m_oLastRect{};
|
|
Aggplus::Rect m_oLastRoundRect{};
|
|
Aggplus::Rect m_oLastOval{};
|
|
Aggplus::Rect m_oLastArc{};
|
|
std::vector<Aggplus::Point> m_arLastPolygon{};
|
|
|
|
NSGraphics::IGraphicsRenderer* m_pRenderer{nullptr};
|
|
NSFonts::IFontManager* m_pFontManager{nullptr};
|
|
};
|
|
|
|
#endif // PICFILE_H
|