feat(tools/eaglemode/plugins/avif): AVIF image plugin
Animation not implemented. https: //en.wikipedia.org/wiki/AVIF Change-Id: I80f8c4132c4335b2e60ce7b70eb424457e50c73f Reviewed-on: https://cl.tvl.fyi/c/depot/+/12428 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
parent
e4714db2d5
commit
1c898f7ddc
5 changed files with 277 additions and 0 deletions
190
tools/eaglemode/plugins/avif/src/PlAvif.cpp
Normal file
190
tools/eaglemode/plugins/avif/src/PlAvif.cpp
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
#include <emCore/emFpPlugin.h>
|
||||
#include <emCore/emImageFile.h>
|
||||
|
||||
#include "avif/avif.h"
|
||||
|
||||
class PlAvifImageFileModel : public emImageFileModel
|
||||
{
|
||||
public:
|
||||
|
||||
static emRef<PlAvifImageFileModel> Acquire(
|
||||
emContext & context, const emString & name, bool common=true
|
||||
);
|
||||
|
||||
protected:
|
||||
PlAvifImageFileModel(emContext & context, const emString & name);
|
||||
virtual ~PlAvifImageFileModel();
|
||||
virtual void TryStartLoading();
|
||||
virtual bool TryContinueLoading();
|
||||
virtual void QuitLoading();
|
||||
virtual void TryStartSaving();
|
||||
virtual bool TryContinueSaving();
|
||||
virtual void QuitSaving();
|
||||
virtual emUInt64 CalcMemoryNeed();
|
||||
virtual double CalcFileProgress();
|
||||
|
||||
private:
|
||||
struct LoadingState;
|
||||
LoadingState * L = NULL;
|
||||
};
|
||||
|
||||
|
||||
struct PlAvifImageFileModel::LoadingState {
|
||||
avifRGBImage rgb;
|
||||
avifDecoder * decoder;
|
||||
};
|
||||
|
||||
|
||||
emRef<PlAvifImageFileModel> PlAvifImageFileModel::Acquire(
|
||||
emContext & context, const emString & name, bool common
|
||||
)
|
||||
{
|
||||
EM_IMPL_ACQUIRE(PlAvifImageFileModel, context, name, common)
|
||||
}
|
||||
|
||||
|
||||
PlAvifImageFileModel::PlAvifImageFileModel(
|
||||
emContext & context, const emString & name
|
||||
)
|
||||
: emImageFileModel(context, name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PlAvifImageFileModel::~PlAvifImageFileModel()
|
||||
{
|
||||
PlAvifImageFileModel::QuitLoading();
|
||||
PlAvifImageFileModel::QuitSaving();
|
||||
}
|
||||
|
||||
|
||||
void PlAvifImageFileModel::TryStartLoading()
|
||||
{
|
||||
avifResult result;
|
||||
|
||||
L = new LoadingState;
|
||||
memset(L, 0, sizeof(LoadingState));
|
||||
|
||||
L->decoder = avifDecoderCreate();
|
||||
if (L->decoder == NULL) {
|
||||
throw emException("failed to create AVIF decoder");
|
||||
}
|
||||
|
||||
result = avifDecoderSetIOFile(L->decoder, GetFilePath());
|
||||
if (result != AVIF_RESULT_OK) {
|
||||
throw emException("%s", avifResultToString(result));
|
||||
}
|
||||
|
||||
result = avifDecoderParse(L->decoder);
|
||||
if (result != AVIF_RESULT_OK) {
|
||||
throw emException("%s", avifResultToString(result));
|
||||
}
|
||||
|
||||
FileFormatInfo = emString::Format(
|
||||
"AVIF %s %ubpc",
|
||||
avifPixelFormatToString(L->decoder->image->yuvFormat),
|
||||
L->decoder->image->depth
|
||||
);
|
||||
|
||||
|
||||
Signal(ChangeSignal);
|
||||
}
|
||||
|
||||
|
||||
bool PlAvifImageFileModel::TryContinueLoading()
|
||||
{
|
||||
avifResult result;
|
||||
|
||||
if (!Image.GetHeight()) {
|
||||
Image.Setup(
|
||||
L->decoder->image->width,
|
||||
L->decoder->image->height,
|
||||
L->decoder->alphaPresent ? 4 : 3
|
||||
);
|
||||
}
|
||||
|
||||
result = avifDecoderNextImage(L->decoder);
|
||||
if (result != AVIF_RESULT_OK) {
|
||||
throw emException("%s", avifResultToString(result));
|
||||
}
|
||||
|
||||
avifRGBImageSetDefaults(&L->rgb, L->decoder->image);
|
||||
L->rgb.format = L->decoder->alphaPresent ?
|
||||
AVIF_RGB_FORMAT_RGBA : AVIF_RGB_FORMAT_RGB;
|
||||
L->rgb.pixels = Image.GetWritableMap();
|
||||
L->rgb.width = Image.GetWidth();
|
||||
L->rgb.height = Image.GetHeight();
|
||||
L->rgb.depth = 8;
|
||||
L->rgb.rowBytes = Image.GetWidth() * Image.GetChannelCount();
|
||||
|
||||
result = avifImageYUVToRGB(L->decoder->image, &L->rgb);
|
||||
if (result != AVIF_RESULT_OK) {
|
||||
throw emException("%s", avifResultToString(result));
|
||||
}
|
||||
|
||||
Signal(ChangeSignal);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PlAvifImageFileModel::QuitLoading()
|
||||
{
|
||||
if (L) {
|
||||
if (L->decoder) avifDecoderDestroy(L->decoder);
|
||||
delete L;
|
||||
L = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PlAvifImageFileModel::TryStartSaving()
|
||||
{
|
||||
throw emException("PlAvifImageFileModel: Saving not implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool PlAvifImageFileModel::TryContinueSaving()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PlAvifImageFileModel::QuitSaving()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
emUInt64 PlAvifImageFileModel::CalcMemoryNeed()
|
||||
{
|
||||
return
|
||||
(emUInt64)
|
||||
L->decoder->image->width *
|
||||
L->decoder->image->height *
|
||||
(L->decoder->alphaPresent ? 4 : 3);
|
||||
}
|
||||
|
||||
|
||||
double PlAvifImageFileModel::CalcFileProgress()
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
emPanel * PlAvifFpPluginFunc(
|
||||
emPanel::ParentArg parent, const emString & name,
|
||||
const emString & path, emFpPlugin * plugin,
|
||||
emString * errorBuf
|
||||
)
|
||||
{
|
||||
if (plugin->Properties.GetCount()) {
|
||||
*errorBuf="PlAvifFpPlugin: No properties allowed.";
|
||||
return NULL;
|
||||
}
|
||||
return new emImageFilePanel(
|
||||
parent, name,
|
||||
PlAvifImageFileModel::Acquire(
|
||||
parent.GetRootContext(), path
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue