1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-16 21:05:12 +00:00
oot/tools/assets/n64texconv/lib/libimagequant/mempool.c
Tharo 3d61fb85ef
Add n64texconv and bin2c tools to convert extracted .png and .bin to C arrays during build (#2477)
* n64texconv and bin2c

* mv tools/n64texconv tools/assets/

* fix

* more light fixes

* Silence -Wshadow for libimagequant

* Add reference counting gc for palette objects in python bindings

* Fix missing alignment in n64texconv_*_to_c functions

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>

* Check palette size in n64texconv_image_from_png

* accept memoryview as well as bytes for binary data

* minimal doc on n64texconv_quantize_shared

* fix a buffer size passed to libimagequant

* assert pal count <= 256 on png write

* Disable palette size check for input pngs, ZAPD fails the check

* No OpenMP for clang

* When reading an indexed png into a CI format, requantize if there are too many colors for the target texel size

---------

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
2025-02-17 17:09:42 -05:00

70 lines
2.1 KiB
C

/*
** © 2009-2017 by Kornel Lesiński.
** © 1989, 1991 by Jef Poskanzer.
** © 1997, 2000, 2002 by Greg Roelofs; based on an idea by Stefan Schneider.
**
** See COPYRIGHT file for license.
*/
#include "libimagequant.h"
#include "mempool.h"
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#define ALIGN_MASK 15UL
#define MEMPOOL_RESERVED ((sizeof(struct mempool)+ALIGN_MASK) & ~ALIGN_MASK)
struct mempool {
unsigned int used, size;
void* (*malloc)(size_t);
void (*free)(void*);
struct mempool *next;
};
LIQ_PRIVATE void* mempool_create(mempoolptr *mptr, const unsigned int size, unsigned int max_size, void* (*malloc)(size_t), void (*free)(void*))
{
if (*mptr && ((*mptr)->used+size) <= (*mptr)->size) {
unsigned int prevused = (*mptr)->used;
(*mptr)->used += (size+15UL) & ~0xFUL;
return ((char*)(*mptr)) + prevused;
}
mempoolptr old = *mptr;
if (!max_size) max_size = (1<<17);
max_size = size+ALIGN_MASK > max_size ? size+ALIGN_MASK : max_size;
*mptr = malloc(MEMPOOL_RESERVED + max_size);
if (!*mptr) return NULL;
**mptr = (struct mempool){
.malloc = malloc,
.free = free,
.size = MEMPOOL_RESERVED + max_size,
.used = sizeof(struct mempool),
.next = old,
};
uintptr_t mptr_used_start = (uintptr_t)(*mptr) + (*mptr)->used;
(*mptr)->used += (ALIGN_MASK + 1 - (mptr_used_start & ALIGN_MASK)) & ALIGN_MASK; // reserve bytes required to make subsequent allocations aligned
assert(!(((uintptr_t)(*mptr) + (*mptr)->used) & ALIGN_MASK));
return mempool_alloc(mptr, size, size);
}
LIQ_PRIVATE void* mempool_alloc(mempoolptr *mptr, const unsigned int size, const unsigned int max_size)
{
if (((*mptr)->used+size) <= (*mptr)->size) {
unsigned int prevused = (*mptr)->used;
(*mptr)->used += (size + ALIGN_MASK) & ~ALIGN_MASK;
return ((char*)(*mptr)) + prevused;
}
return mempool_create(mptr, size, max_size, (*mptr)->malloc, (*mptr)->free);
}
LIQ_PRIVATE void mempool_destroy(mempoolptr m)
{
while (m) {
mempoolptr next = m->next;
m->free(m);
m = next;
}
}