libragephoto: update .NET version to 0.6.1.6

- RagePhoto.cs: fix initialization oversight
- RagePhoto.cs: improve exceptions
- RagePhoto.cs: use ExactSpelling in DllImport
- RagePhotoException.cs: restructure exceptions
This commit is contained in:
Syping 2025-10-17 14:03:11 +02:00
parent a17643d578
commit 72f094958d
3 changed files with 70 additions and 55 deletions

View file

@ -10,85 +10,85 @@ namespace Syping.RagePhoto {
private readonly IntPtr _instance;
private const String _library = "libragephoto";
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern IntPtr ragephoto_open();
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_clear(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_close(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ragephoto_load(IntPtr instance, Byte[] data, UIntPtr size);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ragephoto_loadfile(IntPtr instance, [MarshalAs(UnmanagedType.LPUTF8Str)] String filename);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern Int32 ragephoto_error(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern IntPtr ragephoto_getphotodata(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern IntPtr ragephoto_getphotodesc(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern UInt32 ragephoto_getphotoformat(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern IntPtr ragephoto_getphotojpeg(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern IntPtr ragephoto_getphotojson(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern IntPtr ragephoto_getphotoheader(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern UInt64 ragephoto_getphotosign(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern UInt32 ragephoto_getphotosize(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern IntPtr ragephoto_getphototitle(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern UIntPtr ragephoto_getsavesize(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern UIntPtr ragephoto_getsavesizef(IntPtr instance, UInt32 photoFormat);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ragephoto_save(IntPtr instance, [Out] Byte[] data);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ragephoto_savef(IntPtr instance, [Out] Byte[] data, UInt32 photoFormat);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ragephoto_savefile(IntPtr instance, [MarshalAs(UnmanagedType.LPUTF8Str)] String filename);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ragephoto_savefilef(IntPtr instance, [MarshalAs(UnmanagedType.LPUTF8Str)] String filename, UInt32 photoFormat);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_setbufferdefault(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_setbufferoffsets(IntPtr instance);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ragephoto_setphotodatac(IntPtr instance, IntPtr data);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_setphotodesc(IntPtr instance, [MarshalAs(UnmanagedType.LPUTF8Str)] String description, UInt32 bufferSize);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_setphotoformat(IntPtr instance, UInt32 photoFormat);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ragephoto_setphotojpeg(IntPtr instance, Byte[] jpeg, UInt32 size, UInt32 bufferSize);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_setphotojson(IntPtr instance, [MarshalAs(UnmanagedType.LPUTF8Str)] String json, UInt32 bufferSize);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_setphotoheader2(IntPtr instance, [MarshalAs(UnmanagedType.LPUTF8Str)] String header, UInt32 headerSum, UInt32 headerSum2);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern void ragephoto_setphototitle(IntPtr instance, [MarshalAs(UnmanagedType.LPUTF8Str)] String title, UInt32 bufferSize);
[DllImport(_library, CallingConvention = CallingConvention.Cdecl)]
[DllImport(_library, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
private static extern IntPtr ragephoto_version();
public Photo() {
try {
_instance = ragephoto_open();
if (_instance == IntPtr.Zero)
throw new RagePhotoException(this, "Failed to initialize libragephoto");
throw new RagePhotoException("Failed to initialize libragephoto");
}
catch (Exception exception) {
throw new RagePhotoException(this, "Failed to initialize libragephoto", exception);
throw new RagePhotoException("Failed to initialize libragephoto", exception);
}
}
@ -96,13 +96,13 @@ namespace Syping.RagePhoto {
try {
_instance = ragephoto_open();
if (_instance == IntPtr.Zero)
throw new RagePhotoException(this, "Failed to initialize libragephoto");
throw new RagePhotoException("Failed to initialize libragephoto");
if (!ragephoto_setphotodatac(_instance, ragephoto_getphotodata(photo._instance)))
throw new RagePhotoException(this, String.Format("Failed to copy Photo: {0}", Error), Error);
}
catch (Exception exception) {
throw new RagePhotoException(this, "Failed to initialize libragephoto", exception);
throw new RagePhotoException("Failed to initialize libragephoto", exception);
}
if (!ragephoto_setphotodatac(_instance, ragephoto_getphotodata(photo._instance)))
throw new RagePhotoException(this, string.Format("Failed to copy Photo: {0}", Error));
}
~Photo() {
@ -127,12 +127,12 @@ namespace Syping.RagePhoto {
public void Load(Byte[] data) {
if (!ragephoto_load(_instance, data, (UIntPtr)data.LongLength))
throw new RagePhotoException(this, string.Format("Failed to load Photo: {0}", Error));
throw new RagePhotoException(this, String.Format("Failed to load Photo: {0}", Error), Error);
}
public void LoadFile(String path) {
if (!ragephoto_loadfile(_instance, path))
throw new RagePhotoException(this, string.Format("Failed to load Photo: {0}", Error));
throw new RagePhotoException(this, String.Format("Failed to load Photo: {0}", Error), Error);
}
public String Description {
@ -154,7 +154,7 @@ namespace Syping.RagePhoto {
UInt32 size = ragephoto_getphotosize(_instance);
if (size == 0)
return Array.Empty<Byte>();
byte[] buffer = new Byte[size];
Byte[] buffer = new Byte[size];
IntPtr ptr = ragephoto_getphotojpeg(_instance);
Marshal.Copy(ptr, buffer, 0, (Int32)size);
return buffer;
@ -199,25 +199,25 @@ namespace Syping.RagePhoto {
public Byte[] Save() {
Byte[] photo = new Byte[Environment.Is64BitProcess ? (UInt64)GetSaveSize() : (UInt32)GetSaveSize()];
if (!ragephoto_save(_instance, photo))
throw new RagePhotoException(this, string.Format("Failed to save Photo: {0}", Error));
throw new RagePhotoException(this, string.Format("Failed to save Photo: {0}", Error), Error);
return photo;
}
public Byte[] Save(PhotoFormat photoFormat) {
Byte[] photo = new Byte[Environment.Is64BitProcess ? (UInt64)GetSaveSize(photoFormat) : (UInt32)GetSaveSize(photoFormat)];
if (!ragephoto_savef(_instance, photo, (UInt32)photoFormat))
throw new RagePhotoException(this, string.Format("Failed to save Photo: {0}", Error));
throw new RagePhotoException(this, string.Format("Failed to save Photo: {0}", Error), Error);
return photo;
}
public void SaveFile(String path) {
if (!ragephoto_savefile(_instance, path))
throw new RagePhotoException(this, string.Format("Failed to save Photo: {0}", Error));
throw new RagePhotoException(this, string.Format("Failed to save Photo: {0}", Error), Error);
}
public void SaveFile(String path, PhotoFormat photoFormat) {
if (!ragephoto_savefilef(_instance, path, (UInt32)photoFormat))
throw new RagePhotoException(this, string.Format("Failed to save Photo: {0}", Error));
throw new RagePhotoException(this, string.Format("Failed to save Photo: {0}", Error), Error);
}
public void SetBufferDefault() {
@ -261,12 +261,12 @@ namespace Syping.RagePhoto {
break;
}
if (!ragephoto_setphotojpeg(_instance, jpeg, size, bufferSize))
throw new RagePhotoException(this, string.Format("Failed to set Jpeg: {0}", Error));
throw new RagePhotoException(this, String.Format("Failed to set Jpeg: {0}", Error), Error);
}
public void SetJpeg(Byte[] jpeg, UInt32 bufferSize) {
if (!ragephoto_setphotojpeg(_instance, jpeg, (UInt32)jpeg.Length, bufferSize))
throw new RagePhotoException(this, string.Format("Failed to set Jpeg: {0}", Error));
throw new RagePhotoException(this, String.Format("Failed to set Jpeg: {0}", Error), Error);
}
public void SetJson(String json) {
@ -291,20 +291,20 @@ namespace Syping.RagePhoto {
private static String PtrToStringAnsi(IntPtr ptr) {
if (ptr == IntPtr.Zero)
return string.Empty;
return String.Empty;
return Marshal.PtrToStringAnsi(ptr);
}
private static String PtrToStringUTF8(IntPtr ptr) {
if (ptr == IntPtr.Zero)
return string.Empty;
return String.Empty;
#if NETSTANDARD2_1_OR_GREATER
return Marshal.PtrToStringUTF8(ptr);
#else
Int32 length = 0;
while (Marshal.ReadByte(ptr, length) != 0)
length++;
byte[] buffer = new byte[length];
Byte[] buffer = new Byte[length];
Marshal.Copy(ptr, buffer, 0, length);
return Encoding.UTF8.GetString(buffer);
#endif

View file

@ -4,14 +4,28 @@ namespace Syping.RagePhoto {
public class RagePhotoException : Exception {
private readonly PhotoError _error;
private readonly Photo _photo;
public RagePhotoException(Photo photo, String message) : base(message) {
public RagePhotoException(String message) : base(message) {
_error = PhotoError.Uninitialised;
}
public RagePhotoException(String message, Exception innerException) : base(message, innerException) {
_error = PhotoError.Uninitialised;
}
public RagePhotoException(Photo photo, String message, PhotoError error) : base(message) {
_error = error;
_photo = photo;
}
public RagePhotoException(Photo photo, String message, Exception innerException) : base(message, innerException) {
_photo = photo;
public PhotoError Error {
get => _error;
}
public Photo Photo {
get => _photo;
}
}
}

View file

@ -4,14 +4,15 @@
<TargetFrameworks>netstandard2.1;net47</TargetFrameworks>
<AssemblyName>Syping.RagePhoto.Core</AssemblyName>
<RootNamespace>Syping.RagePhoto</RootNamespace>
<Version>0.6.1.5</Version>
<AssemblyVersion>0.6.1.5</AssemblyVersion>
<FileVersion>0.6.1.5</FileVersion>
<Version>0.6.1.6</Version>
<AssemblyVersion>0.6.1.6</AssemblyVersion>
<FileVersion>0.6.1.6</FileVersion>
<Authors>Syping</Authors>
<Copyright>Copyright © 2025 Syping</Copyright>
<Description>Open Source RAGE Photo Parser for GTA V and RDR 2</Description>
<PackageLicenseExpression>BSD-2-Clause</PackageLicenseExpression>
<RepositoryUrl>https://github.com/Syping/libragephoto</RepositoryUrl>
<Nullable>disable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net47'">