Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed QOI test, added QOI write #41

Merged
merged 2 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Framework/Images/Enums/ImageWriteFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Foster.Framework;

internal enum ImageWriteFormat
{
Png,
Qoi
}
24 changes: 23 additions & 1 deletion Framework/Images/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,28 @@ public void WritePng(string path)
/// Write the image to PNG
/// </summary>
public void WritePng(Stream stream)
{
Write(stream, ImageWriteFormat.Png);
}

/// <summary>
/// Writes the image to a PNG file
/// </summary>
public void WriteQoi(string path)
{
using var stream = File.Create(path);
WritePng(stream);
}

/// <summary>
/// Write the image to QOI
/// </summary>
public void WriteQoi(Stream stream)
{
Write(stream, ImageWriteFormat.Qoi);
}

private void Write(Stream stream, ImageWriteFormat format)
{
static unsafe void Write(IntPtr context, IntPtr data, int size)
{
Expand All @@ -169,7 +191,7 @@ static unsafe void Write(IntPtr context, IntPtr data, int size)
}

GCHandle handle = GCHandle.Alloc(stream);
Platform.FosterImageWrite(Write, GCHandle.ToIntPtr(handle), Width, Height, ptr);
Platform.FosterImageWrite(Write, GCHandle.ToIntPtr(handle), format, Width, Height, ptr);
handle.Free();
}

Expand Down
2 changes: 1 addition & 1 deletion Framework/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public static void FreeUTF8(IntPtr ptr)
[DllImport(DLL)]
public static extern void FosterImageFree(IntPtr data);
[DllImport(DLL)]
public static extern bool FosterImageWrite(FosterWriteFn func, IntPtr context, int w, int h, IntPtr data);
public static extern bool FosterImageWrite(FosterWriteFn func, IntPtr context, ImageWriteFormat format, int w, int h, IntPtr data);
[DllImport(DLL)]
public static extern IntPtr FosterFontInit(IntPtr data, int length);
[DllImport(DLL)]
Expand Down
8 changes: 7 additions & 1 deletion Platform/include/foster_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,12 @@ typedef enum FosterLogging
FOSTER_LOGGING_NONE
} FosterLogging;

typedef enum FosterImageWriteFormat
{
FOSTER_IMAGE_WRITE_FORMAT_PNG,
FOSTER_IMAGE_WRITE_FORMAT_QOI,
} FosterImageWriteFormat;

typedef void (FOSTER_CALL * FosterLogFn)(const char *msg);
typedef void (FOSTER_CALL * FosterExitRequestFn)();
typedef void (FOSTER_CALL * FosterOnTextFn)(const char* txt);
Expand Down Expand Up @@ -558,7 +564,7 @@ FOSTER_API unsigned char* FosterImageLoad(const unsigned char* memory, int lengt

FOSTER_API void FosterImageFree(unsigned char* data);

FOSTER_API bool FosterImageWrite(FosterWriteFn* func, void* context, int w, int h, const void* data);
FOSTER_API bool FosterImageWrite(FosterWriteFn* func, void* context, FosterImageWriteFormat format, int w, int h, const void* data);

FOSTER_API FosterFont* FosterFontInit(unsigned char* data, int length);

Expand Down
39 changes: 32 additions & 7 deletions Platform/src/foster_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

bool FosterImage_TestQOI(const unsigned char* data, int length);
unsigned char* FosterImage_LoadQOI(const unsigned char* data, int length, int* w, int * h);
bool FosterImage_WriteQOI(FosterWriteFn* func, void* context, int w, int h, const void* data);

unsigned char* FosterImageLoad(const unsigned char* data, int length, int* w, int* h)
{
Expand All @@ -37,20 +38,28 @@ void FosterImageFree(unsigned char* data)
stbi_image_free(data);
}

bool FosterImageWrite(FosterWriteFn* func, void* context, int w, int h, const void* data)
bool FosterImageWrite(FosterWriteFn* func, void* context, FosterImageWriteFormat format, int w, int h, const void* data)
{
// note: 'FosterWriteFn' and 'stbi_write_func' must be the same
return stbi_write_png_to_func((stbi_write_func*)func, context, w, h, 4, data, w * 4) != 0;
switch (format)
{
case FOSTER_IMAGE_WRITE_FORMAT_PNG:
return stbi_write_png_to_func((stbi_write_func*)func, context, w, h, 4, data, w * 4) != 0;
case FOSTER_IMAGE_WRITE_FORMAT_QOI:
return FosterImage_WriteQOI(func, context, w, h, data);
}
return false;
}

bool FosterImage_TestQOI(const unsigned char* data, int length)
{
if (length < 4)
if (length < QOI_HEADER_SIZE)
return false;

for (int i = 0; i < SDL_max(4, length); i ++)
if (data[i] != "qoif"[i])
return false;
int p = 0;
unsigned int magic = qoi_read_32(data, &p);
if (magic != QOI_MAGIC)
return false;

return true;
}
Expand All @@ -72,4 +81,20 @@ unsigned char* FosterImage_LoadQOI(const unsigned char* data, int length, int* w
*h = 0;
return NULL;
}
}
}

bool FosterImage_WriteQOI(FosterWriteFn* func, void* context, int w, int h, const void* data)
{
qoi_desc desc = { w, h, 4, 1 };
int length;
void* encoded = qoi_encode(data, &desc, &length);

if (encoded != NULL)
{
((stbi_write_func*)func)(context, encoded, length);
QOI_FREE(encoded);
return true;
}

return false;
}
Loading