From 3e2dee5719d83bd771bab0c1b0c2f6eb38e0236d Mon Sep 17 00:00:00 2001 From: Prokhorov Kirill Date: Mon, 30 Jun 2025 16:13:03 +0300 Subject: [PATCH] Fix heif encode --- DesktopEditor/raster/BgraFrame.cpp | 42 +++++++++++++----------- DesktopEditor/raster/heif/heif.cpp | 52 +++++++++++++++--------------- DesktopEditor/raster/heif/heif.h | 2 +- 3 files changed, 50 insertions(+), 46 deletions(-) diff --git a/DesktopEditor/raster/BgraFrame.cpp b/DesktopEditor/raster/BgraFrame.cpp index d1aca52622..8395cd22f7 100644 --- a/DesktopEditor/raster/BgraFrame.cpp +++ b/DesktopEditor/raster/BgraFrame.cpp @@ -580,28 +580,32 @@ bool CBgraFrame::SaveFile(const std::wstring& strFileName, unsigned int nFileTyp return res; } - else #endif +#if CXIMAGE_SUPPORT_HEIF + if (CXIMAGE_FORMAT_HEIF == nFileType) { - NSFile::CFileBinary oFile; - if (!oFile.CreateFileW(strFileName)) - return false; - - CxImage img; - - if (!img.CreateFromArray(m_pData, m_lWidth, m_lHeight, lBitsPerPixel * 8, lStride, (m_lStride >= 0) ? true : false, !m_bIsRGBA)) - return false; - - if (m_pPalette) - { - img.SetPalette((RGBQUAD*)m_pPalette, m_lPaletteColors); - } - - if (!img.Encode(oFile.GetFileNative(), nFileType)) - return false; - - oFile.CloseFile(); + return NSHeif::CHeifFile::Save(m_pData, m_lWidth, m_lHeight, strFileName); } +#endif + + NSFile::CFileBinary oFile; + if (!oFile.CreateFileW(strFileName)) + return false; + + CxImage img; + + if (!img.CreateFromArray(m_pData, m_lWidth, m_lHeight, lBitsPerPixel * 8, lStride, (m_lStride >= 0) ? true : false, !m_bIsRGBA)) + return false; + + if (m_pPalette) + { + img.SetPalette((RGBQUAD*)m_pPalette, m_lPaletteColors); + } + + if (!img.Encode(oFile.GetFileNative(), nFileType)) + return false; + + oFile.CloseFile(); return true; } bool CBgraFrame::Encode(BYTE*& pBuffer, int& nSize, unsigned int nFileType) diff --git a/DesktopEditor/raster/heif/heif.cpp b/DesktopEditor/raster/heif/heif.cpp index 0c2283d4a3..92ffaef2e0 100644 --- a/DesktopEditor/raster/heif/heif.cpp +++ b/DesktopEditor/raster/heif/heif.cpp @@ -14,7 +14,7 @@ namespace NSHeif { bool CHeifFile::isHeif(BYTE* buffer, DWORD size) { NSFile::CFileBinary file; - std::wstring tmp_file = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"heiс"); + std::wstring tmp_file = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"heic"); if (!file.CreateFile(tmp_file)) return false; @@ -79,7 +79,7 @@ namespace NSHeif { bool CHeifFile::Open(CBgraFrame *frame, BYTE* buffer, DWORD size) { NSFile::CFileBinary file; - std::wstring tmp_file = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"heif"); + std::wstring tmp_file = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"heic"); if (!file.CreateFile(tmp_file)) return false; @@ -97,38 +97,29 @@ namespace NSHeif { return status; } - bool CHeifFile::Save(CBgraFrame *frame, const std::wstring& dstPath) - { - if (!frame) + bool CHeifFile::Save(const BYTE* source, int width, int height, const std::wstring& dstPath) + { + if (!source) return false; - heif_context* ctx = heif_context_alloc(); - defer(heif_context_free(ctx);); - - heif_encoder* encoder; - defer(heif_encoder_release(encoder);); - - if (IsError(heif_context_get_encoder_for_format(ctx, heif_compression_HEVC, &encoder))) - return false; - - if (IsError(heif_encoder_set_lossy_quality(encoder, 50))) - return false; - - heif_image* img; + heif_image* img = nullptr; defer(heif_image_release(img);); - int width = frame->get_Width(); - int height = frame->get_Height(); - if (IsError(heif_image_create(width, height, heif_colorspace_RGB, heif_chroma_interleaved_RGB, &img))) return false; - BYTE* data = heif_image_get_plane(img, heif_channel_interleaved, nullptr); - const BYTE* source = frame->get_Data(); + if (IsError(heif_image_add_plane(img, heif_channel_interleaved, width, height, 24))) + return false; - for (size_t i = 0; i get_Stride(); + const BYTE* row = source + i * stride; for (size_t j = 0; j < width; ++j) { data[(i * width + j) * 3 + 0] = row[j * 3 + 2]; @@ -137,7 +128,16 @@ namespace NSHeif { } } - if (!data) + heif_context* ctx = heif_context_alloc(); + defer(heif_context_free(ctx);); + + heif_encoder* encoder = nullptr; + defer(heif_encoder_release(encoder);); + + if (IsError(heif_context_get_encoder_for_format(ctx, heif_compression_HEVC, &encoder))) + return false; + + if (IsError(heif_encoder_set_lossy_quality(encoder, 80))) return false; if (IsError(heif_context_encode_image(ctx, img, encoder, nullptr, nullptr))) diff --git a/DesktopEditor/raster/heif/heif.h b/DesktopEditor/raster/heif/heif.h index 668617f8c0..a36598d235 100644 --- a/DesktopEditor/raster/heif/heif.h +++ b/DesktopEditor/raster/heif/heif.h @@ -24,7 +24,7 @@ namespace NSHeif { static bool Open(CBgraFrame* frame, const std::wstring& fileName); static bool Open(CBgraFrame* frame, BYTE* buffer, DWORD size); - static bool Save(CBgraFrame* frame, const std::wstring& dstPath); + static bool Save(const BYTE* source, int width, int height, const std::wstring& dstPath); private: static inline bool IsError(heif_error err);