Skip to content

Commit

Permalink
Fixed QOI test, added QOI write
Browse files Browse the repository at this point in the history
  • Loading branch information
MrBrixican committed Nov 14, 2023
1 parent 2161c0d commit dc4e8fd
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 10 deletions.
10 changes: 10 additions & 0 deletions Framework/Images/Enums/ImageWriteFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
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;
}

0 comments on commit dc4e8fd

Please sign in to comment.