mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-14 01:43:39 +08:00
247 lines
5.9 KiB
C++
247 lines
5.9 KiB
C++
#pragma once
|
|
#include "stdafx.h"
|
|
#include "File.h"
|
|
#include ".\..\Common\GdiplusEx.h"
|
|
using namespace Gdiplus;
|
|
|
|
#include "libdjvu\GBitmap.h"
|
|
|
|
namespace NSImage
|
|
{
|
|
class CImage
|
|
{
|
|
private:
|
|
CGdiPlusInit m_oInit;
|
|
|
|
public:
|
|
CImage()
|
|
{
|
|
m_oInit.Init();
|
|
}
|
|
~CImage()
|
|
{
|
|
}
|
|
|
|
public:
|
|
void GetEncoderClsid(const CString& strFormat, CLSID* pClsid)
|
|
{
|
|
// variables
|
|
UINT nEncoders = 0;
|
|
UINT nSize = 0;
|
|
ImageCodecInfo* pImageCodecInfo = 0;
|
|
|
|
// retrieve encoders info
|
|
GetImageEncodersSize(&nEncoders, &nSize);
|
|
|
|
// check for valid encoders
|
|
if (!nSize)
|
|
throw 0;
|
|
|
|
// create encoders info structure of necessary size
|
|
pImageCodecInfo = (ImageCodecInfo*)(malloc(nSize));
|
|
|
|
// check for valid encoder
|
|
if (!pImageCodecInfo)
|
|
throw 0;
|
|
|
|
// retrieve all encoders
|
|
GetImageEncoders(nEncoders, nSize, pImageCodecInfo);
|
|
|
|
// locate necessary encoder
|
|
for (UINT nEncoder = 0; nEncoder < nEncoders; ++nEncoder)
|
|
{
|
|
// compare MIME strings
|
|
if (((CString)pImageCodecInfo[nEncoder].MimeType) == strFormat)
|
|
{
|
|
// save CLSID
|
|
*pClsid = pImageCodecInfo[nEncoder].Clsid;
|
|
|
|
// clear memory
|
|
free(pImageCodecInfo);
|
|
|
|
// all ok
|
|
return;
|
|
}
|
|
}
|
|
|
|
// clear memory
|
|
free(pImageCodecInfo);
|
|
|
|
// codec not found
|
|
throw 0;
|
|
}
|
|
|
|
void SaveImage8bit(BITMAPINFO* pInfo, GP<GBitmap>& pBitmap, CString strFile)
|
|
{
|
|
if (2 == pInfo->bmiHeader.biClrUsed)
|
|
{
|
|
pInfo->bmiHeader.biBitCount = 1;
|
|
return SaveImage1bit(pInfo, pBitmap, strFile);
|
|
}
|
|
|
|
CFile oFile;
|
|
oFile.CreateFile(strFile);
|
|
|
|
BITMAPFILEHEADER hdr;
|
|
hdr.bfType = 'MB';
|
|
hdr.bfReserved1 = 0;
|
|
hdr.bfReserved2 = 0;
|
|
|
|
DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * pInfo->bmiHeader.biClrUsed;
|
|
|
|
DWORD dwBitCount = pInfo->bmiHeader.biWidth * pInfo->bmiHeader.biBitCount;
|
|
DWORD dwDataSize = (((dwBitCount + 31) / 32) * 4) * pInfo->bmiHeader.biHeight;
|
|
|
|
hdr.bfOffBits = sizeof(BITMAPFILEHEADER) + dwHeaderSize;
|
|
hdr.bfSize = hdr.bfOffBits + dwDataSize;
|
|
|
|
oFile.WriteFile(&hdr, sizeof(hdr));
|
|
oFile.WriteFile(pInfo, dwHeaderSize);
|
|
oFile.WriteFile(pBitmap->operator[](0), dwDataSize);
|
|
|
|
oFile.CloseFile();
|
|
}
|
|
void SaveImage1bit(BITMAPINFO* pInfo, GP<GBitmap>& pBitmap, CString strFile)
|
|
{
|
|
/*pInfo->bmiHeader.biWidth = 64;
|
|
pInfo->bmiHeader.biHeight = 64;
|
|
|
|
LONG l = 64 * 64 / 8;
|
|
|
|
CFile oFile;
|
|
oFile.CreateFile(strFile);
|
|
|
|
BITMAPFILEHEADER hdr;
|
|
hdr.bfType = 'MB';
|
|
hdr.bfReserved1 = 0;
|
|
hdr.bfReserved2 = 0;
|
|
|
|
DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * pInfo->bmiHeader.biClrUsed;
|
|
hdr.bfOffBits = sizeof(BITMAPFILEHEADER) + dwHeaderSize;
|
|
hdr.bfSize = hdr.bfOffBits + l;
|
|
|
|
oFile.WriteFile(&hdr, sizeof(hdr));
|
|
oFile.WriteFile(pInfo, dwHeaderSize);
|
|
|
|
oFile.WriteReserved(l);
|
|
oFile.CloseFile();*/
|
|
|
|
CFile oFile;
|
|
oFile.CreateFile(strFile);
|
|
|
|
BITMAPFILEHEADER hdr;
|
|
hdr.bfType = 'MB';
|
|
hdr.bfReserved1 = 0;
|
|
hdr.bfReserved2 = 0;
|
|
|
|
DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * pInfo->bmiHeader.biClrUsed;
|
|
|
|
LONG lWidth = pInfo->bmiHeader.biWidth;
|
|
LONG lHeight = pInfo->bmiHeader.biHeight;
|
|
|
|
//pInfo->bmiHeader.biWidth = (pInfo->bmiHeader.biWidth >> 3) << 3;
|
|
|
|
DWORD dwBitCount = pInfo->bmiHeader.biWidth * pInfo->bmiHeader.biBitCount;
|
|
DWORD dwDataSize = (((dwBitCount + 31) / 32) * 4) * pInfo->bmiHeader.biHeight;
|
|
|
|
hdr.bfOffBits = sizeof(BITMAPFILEHEADER) + dwHeaderSize;
|
|
hdr.bfSize = hdr.bfOffBits + dwDataSize;
|
|
|
|
oFile.WriteFile(&hdr, sizeof(hdr));
|
|
oFile.WriteFile(pInfo, dwHeaderSize);
|
|
|
|
BYTE* p1Bit = new BYTE[dwDataSize];
|
|
|
|
_8BitTo1Bit(pBitmap, p1Bit, lWidth, lHeight, (((dwBitCount + 31) / 32) * 4));
|
|
oFile.WriteFile(p1Bit, dwDataSize);
|
|
RELEASEARRAYOBJECTS(p1Bit);
|
|
|
|
oFile.CloseFile();
|
|
}
|
|
void SaveImage24bit(GPixel* pBits, LONG lWidth, LONG lHeight, CString strFile)
|
|
{
|
|
LONG lPixels = lWidth * lHeight;
|
|
|
|
BYTE* pPixels = new BYTE[4 * lPixels];
|
|
BYTE* pPixMem = pPixels;
|
|
|
|
for (LONG j = lHeight - 1; j >= 0; --j)
|
|
{
|
|
GPixel* pLine = pBits + j * lWidth;
|
|
for (LONG i = 0; i < lWidth; ++i)
|
|
{
|
|
*pPixMem++ = pLine->b;
|
|
*pPixMem++ = pLine->g;
|
|
*pPixMem++ = pLine->r;
|
|
*pPixMem++ = 255; ++pLine;
|
|
}
|
|
}
|
|
|
|
Gdiplus::Bitmap oBitmap(lWidth, lHeight, 4 * lWidth, PixelFormat32bppRGB, pPixels);
|
|
|
|
CLSID oEncoder; GetEncoderClsid(_T("image/png"), &oEncoder);
|
|
EncoderParameters oSettings;
|
|
|
|
ULONG nQuality = 100;
|
|
oSettings.Count = 1;
|
|
oSettings.Parameter[0].Guid = EncoderQuality;
|
|
oSettings.Parameter[0].Type = EncoderParameterValueTypeLong;
|
|
oSettings.Parameter[0].NumberOfValues = 1;
|
|
oSettings.Parameter[0].Value = &nQuality;
|
|
|
|
BSTR bsFile = strFile.AllocSysString();
|
|
oBitmap.Save(bsFile, &oEncoder, NULL/*&oSettings*/);
|
|
SysFreeString(bsFile);
|
|
|
|
RELEASEARRAYOBJECTS(pPixels);
|
|
}
|
|
|
|
void _8BitTo1Bit(GP<GBitmap>& pBitmap, BYTE* p1Bit, LONG lWidth, LONG lHeight, LONG lStride)
|
|
{
|
|
for (LONG j = 0; j < lHeight; ++j)
|
|
{
|
|
BYTE* p8 = pBitmap->operator [](j);
|
|
|
|
BYTE* pMem = p1Bit + j * lStride;
|
|
int nBitIndex = 0;
|
|
|
|
for (LONG i = 0; i < lWidth; ++i, ++p8)
|
|
{
|
|
if (0 != *p8)
|
|
{
|
|
*pMem |= (1 << (7 - nBitIndex));
|
|
//SetBit(pMem, 7-nBitIndex, true);
|
|
}
|
|
else
|
|
{
|
|
//SetBit(pMem, 7-nBitIndex, false);
|
|
*pMem &= ~(1 << (7 - nBitIndex));
|
|
}
|
|
|
|
++nBitIndex;
|
|
if (8 == nBitIndex)
|
|
{
|
|
nBitIndex = 0;
|
|
++pMem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
inline void SetBit(BYTE* value, int pos, bool newVal)
|
|
{
|
|
// variables
|
|
int mask = (1 << pos);
|
|
BYTE val = *value;
|
|
|
|
// check for new value
|
|
if (newVal)
|
|
val |= mask;
|
|
else
|
|
val &= ~mask;
|
|
|
|
// update value
|
|
*value = val;
|
|
}
|
|
};
|
|
} |