mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 10:59:17 +08:00
Co-authored-by: Alexander Trofimov <alexander.trofimov@onlyoffice.com> Co-committed-by: Alexander Trofimov <alexander.trofimov@onlyoffice.com>
287 lines
7.1 KiB
C++
287 lines
7.1 KiB
C++
/*
|
|
* Copyright (C) Ascensio System SIA, 2009-2026
|
|
*
|
|
* 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, together with the
|
|
* additional terms provided in the LICENSE file.
|
|
*
|
|
* 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: https://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* You can contact Ascensio System SIA by email at info@onlyoffice.com
|
|
* or by postal mail at 20A-6 Ernesta Birznieka-Upisha Street, Riga,
|
|
* LV-1050, Latvia, European Union.
|
|
*
|
|
* The interactive user interfaces in modified versions of the Program
|
|
* are required to display Appropriate Legal Notices in accordance with
|
|
* Section 5 of the GNU AGPL version 3.
|
|
*
|
|
* No trademark rights are granted under this License.
|
|
*
|
|
* All non-code elements of the Product, including illustrations,
|
|
* icon sets, and technical writing content, are licensed under the
|
|
* Creative Commons Attribution-ShareAlike 4.0 International License:
|
|
* https://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
*
|
|
* This license applies only to such non-code elements and does not
|
|
* modify or replace the licensing terms applicable to the Program's
|
|
* source code, which remains licensed under the GNU Affero General
|
|
* Public License v3.
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
#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 InitializeFonts();
|
|
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{1};
|
|
size_t m_nPenWidth{1};
|
|
|
|
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::IApplicationFonts* m_pAppFonts{nullptr};
|
|
NSFonts::IFontManager* m_pFontManager{nullptr};
|
|
};
|
|
|
|
#endif // PICFILE_H
|