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
				
			
		
							
								
								
									
										16
									
								
								tools/eaglemode/plugins/avif/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tools/eaglemode/plugins/avif/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| { depot, pkgs, ... }: | ||||
| 
 | ||||
| let | ||||
|   em = depot.tools.eaglemode; | ||||
|   emSrc = pkgs.srcOnly pkgs.em; | ||||
| in | ||||
| (em.buildPlugin { | ||||
|   name = "avif"; | ||||
|   version = "canon"; | ||||
|   src = ./.; | ||||
|   target = "PlAvif"; | ||||
| }).overrideAttrs | ||||
|   ({ buildInputs ? [ ], nativeBuildInputs ? [ ], ... }: { | ||||
|     buildInputs = buildInputs ++ [ pkgs.libavif ]; | ||||
|     nativeBuildInputs = nativeBuildInputs ++ [ pkgs.pkg-config ]; | ||||
|   }) | ||||
|  | @ -0,0 +1,6 @@ | |||
| #%rec:emFpPlugin%# | ||||
| 
 | ||||
| FileTypes = { ".avif" } | ||||
| Priority = 1.0 | ||||
| Library = "PlAvif" | ||||
| Function = "PlAvifFpPluginFunc" | ||||
							
								
								
									
										64
									
								
								tools/eaglemode/plugins/avif/makers/PlAvif.maker.pm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								tools/eaglemode/plugins/avif/makers/PlAvif.maker.pm
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | |||
| package PlAvif; | ||||
| 
 | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| sub GetDependencies | ||||
| { | ||||
| 	return ('emCore'); | ||||
| } | ||||
| 
 | ||||
| sub IsEssential | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| sub GetFileHandlingrules | ||||
| { | ||||
| 	return (); | ||||
| } | ||||
| 
 | ||||
| sub GetExtraBuildOptions | ||||
| { | ||||
| 	return (); | ||||
| } | ||||
| 
 | ||||
| sub Build | ||||
| { | ||||
| 	shift; | ||||
| 	my %options=@_; | ||||
| 
 | ||||
| 	my @libAvifFlags=(); | ||||
| 	if ($options{'avif-inc-dir'} eq '' && $options{'avif-lib-dir'} eq '') { | ||||
| 		@libAvifFlags=split("\n",readpipe( | ||||
| 			"perl \"".$options{'utils'}."/PkgConfig.pl\" libavif" | ||||
| 		)); | ||||
| 	} | ||||
| 	if (!@libAvifFlags) { | ||||
| 		if ($options{'avif-inc-dir'} ne '') { | ||||
| 			push(@libAvifFlags, "--inc-search-dir", $options{'avif-inc-dir'}); | ||||
| 		} | ||||
| 		if ($options{'avif-lib-dir'} ne '') { | ||||
| 			push(@libAvifFlags, "--lib-search-dir", $options{'avif-lib-dir'}); | ||||
| 		} | ||||
| 		push(@libAvifFlags, "--link", "avif"); | ||||
| 	} | ||||
| 
 | ||||
| 	system( | ||||
| 		@{$options{'unicc_call'}}, | ||||
| 		"--math", | ||||
| 		"--rtti", | ||||
| 		"--exceptions", | ||||
| 		"--bin-dir"       , "bin", | ||||
| 		"--lib-dir"       , "lib", | ||||
| 		"--obj-dir"       , "obj", | ||||
| 		"--inc-search-dir", "include", | ||||
| 		@libAvifFlags, | ||||
| 		"--link"          , "emCore", | ||||
| 		"--type"          , "dynlib", | ||||
| 		"--name"          , "PlAvif", | ||||
| 		"src/PlAvif.cpp" | ||||
| 	)==0 or return 0; | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
							
								
								
									
										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