This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository legacy-imlib2.
View the commit online.
commit bcf88d4431835f96a3c8850cbcbfff88fca99bf6
Author: Kim Woelders <[email protected]>
AuthorDate: Thu Jun 15 17:35:11 2023 +0200
QOI loader: Add progress calback, indent, cosmetics
---
src/modules/loaders/Makefile.am | 10 +-
src/modules/loaders/loader_qoi.c | 230 +++++++++++++++++++++------------------
2 files changed, 131 insertions(+), 109 deletions(-)
diff --git a/src/modules/loaders/Makefile.am b/src/modules/loaders/Makefile.am
index 41c4a93..151e89c 100644
--- a/src/modules/loaders/Makefile.am
+++ b/src/modules/loaders/Makefile.am
@@ -135,17 +135,17 @@ pnm_la_LDFLAGS = -module -avoid-version
pnm_la_LIBADD = $(top_builddir)/src/lib/libImlib2.la
pnm_la_LIBTOOLFLAGS = --tag=disable-static
-qoi_la_SOURCES = loader_qoi.c
-qoi_la_LDFLAGS = -module -avoid-version
-qoi_la_LIBADD = $(top_builddir)/src/lib/libImlib2.la
-qoi_la_LIBTOOLFLAGS = --tag=disable-static
-
ps_la_SOURCES = loader_ps.c
ps_la_CPPFLAGS = $(PS_CFLAGS) $(AM_CPPFLAGS)
ps_la_LDFLAGS = -module -avoid-version
ps_la_LIBADD = $(PS_LIBS) $(top_builddir)/src/lib/libImlib2.la
ps_la_LIBTOOLFLAGS = --tag=disable-static
+qoi_la_SOURCES = loader_qoi.c
+qoi_la_LDFLAGS = -module -avoid-version
+qoi_la_LIBADD = $(top_builddir)/src/lib/libImlib2.la
+qoi_la_LIBTOOLFLAGS = --tag=disable-static
+
svg_la_SOURCES = loader_svg.c
svg_la_CPPFLAGS = $(SVG_CFLAGS) $(AM_CPPFLAGS)
svg_la_LDFLAGS = -module -avoid-version
diff --git a/src/modules/loaders/loader_qoi.c b/src/modules/loaders/loader_qoi.c
index e749338..f371669 100644
--- a/src/modules/loaders/loader_qoi.c
+++ b/src/modules/loaders/loader_qoi.c
@@ -17,9 +17,7 @@
#if IMLIB2_DEBUG
#define QOIDEC_ASSERT(X) do { if (!(X)) D("%d: %s\n", __LINE__, #X); } while (0)
#elif defined(__GNUC__)
-#define QOIDEC_ASSERT(X) ((X) ? (void)0 : __builtin_unreachable())
-#else
-#define QOIDEC_ASSERT(X) ((void)0)
+#define QOIDEC_ASSERT(X)
#endif
static const char *const _formats[] = { "qoi" };
@@ -27,72 +25,80 @@ static const char *const _formats[] = { "qoi" };
// API
typedef struct {
- uint32_t w, h;
+ uint32_t w, h;
// this is where the decoded ARGB32 pixels will be put.
// to be allocated by the caller by at least `.data_size` bytes before calling qoi_dec().
- uint32_t *data;
- ptrdiff_t npixels, data_size;
- uint8_t channels, colorspace;
+ uint32_t *data;
+ ptrdiff_t npixels, data_size;
+ uint8_t channels, colorspace;
// private
- const uint8_t *p, *end;
+ const uint8_t *p, *end;
} QoiDecCtx;
typedef enum {
QOIDEC_OK,
QOIDEC_NOT_QOI, QOIDEC_CORRUPTED, QOIDEC_ZERO_DIM, QOIDEC_TOO_LARGE,
} QoiDecStatus;
-QOIDEC_API QoiDecStatus qoi_dec_init(QoiDecCtx *ctx, const void *buffer, ptrdiff_t size);
-QOIDEC_API QoiDecStatus qoi_dec(QoiDecCtx *ctx);
+QOIDEC_API QoiDecStatus qoi_dec_init(QoiDecCtx * ctx, const void *buffer,
+ ptrdiff_t size);
+QOIDEC_API QoiDecStatus qoi_dec(QoiDecCtx * ctx);
// implementation
-QOIDEC_API QoiDecStatus
-qoi_dec_init(QoiDecCtx *ctx, const void *buffer, ptrdiff_t size)
+QOIDEC_API QoiDecStatus
+qoi_dec_init(QoiDecCtx * ctx, const void *buffer, ptrdiff_t size)
{
QOIDEC_ASSERT(size >= 0);
- *ctx = (QoiDecCtx){0};
+
+ memset(ctx, 0, sizeof(QoiDecCtx));
ctx->p = buffer;
ctx->end = ctx->p + size;
if (size < 14 ||
- !((ctx->p[0] == 'q') & (ctx->p[1] == 'o') &
- (ctx->p[2] == 'i') & (ctx->p[3] == 'f')))
- {
- return QOIDEC_NOT_QOI;
- }
+ !((ctx->p[0] == 'q') && (ctx->p[1] == 'o') &&
+ (ctx->p[2] == 'i') && (ctx->p[3] == 'f')))
+ {
+ return QOIDEC_NOT_QOI;
+ }
ctx->p += 4;
- ctx->w = (uint32_t)ctx->p[0] << 24 | ctx->p[1] << 16 | ctx->p[2] << 8 | ctx->p[3];
+ ctx->w =
+ (uint32_t) ctx->p[0] << 24 | ctx->p[1] << 16 | ctx->p[2] << 8 | ctx->p[3];
ctx->p += 4;
- ctx->h = (uint32_t)ctx->p[0] << 24 | ctx->p[1] << 16 | ctx->p[2] << 8 | ctx->p[3];
+ ctx->h =
+ (uint32_t) ctx->p[0] << 24 | ctx->p[1] << 16 | ctx->p[2] << 8 | ctx->p[3];
ctx->p += 4;
- if (ctx->w == 0 || ctx->h == 0) {
- return QOIDEC_ZERO_DIM;
- }
- if ((PTRDIFF_MAX/4)/ctx->w < ctx->h) {
- return QOIDEC_TOO_LARGE;
- }
+ if (ctx->w == 0 || ctx->h == 0)
+ {
+ return QOIDEC_ZERO_DIM;
+ }
+ if ((PTRDIFF_MAX / 4) / ctx->w < ctx->h)
+ {
+ return QOIDEC_TOO_LARGE;
+ }
ctx->npixels = (ptrdiff_t)ctx->w * ctx->h;
ctx->data_size = ctx->npixels * 4;
- ctx->channels = *ctx->p++;
+ ctx->channels = *ctx->p++;
ctx->colorspace = *ctx->p++;
if (!(ctx->channels == 3 || ctx->channels == 4) ||
- ctx->colorspace & ~0x1u || ctx->end - ctx->p < 8 /* end marker */)
- {
- return QOIDEC_CORRUPTED;
- }
+ ctx->colorspace & ~0x1u || ctx->end - ctx->p < 8 /* end marker */ )
+ {
+ return QOIDEC_CORRUPTED;
+ }
return QOIDEC_OK;
}
-QOIDEC_API QoiDecStatus
-qoi_dec(QoiDecCtx *ctx)
+QOIDEC_API QoiDecStatus
+qoi_dec(QoiDecCtx * ctx)
{
- typedef struct { uint8_t b, g, r, a; } Clr;
- Clr t[64] = {0};
- Clr l = { .a = 0xFF };
+ typedef struct {
+ uint8_t b, g, r, a;
+ } Clr;
+ Clr t[64] = { 0 };
+ Clr l = {.a = 0xFF };
uint8_t lop = -1;
const uint8_t *p = ctx->p, *end = ctx->end;
@@ -102,75 +108,88 @@ qoi_dec(QoiDecCtx *ctx)
QOIDEC_ASSERT(ctx->p[-14] == 'q' && ctx->p[-13] == 'o');
QOIDEC_ASSERT(ctx->p[-12] == 'i' && ctx->p[-11] == 'f');
- if ((*p >> 6) == 0x3 && (*p & 0x3F) < 62) { // ref: https://github.com/phoboslab/qoi/issues/258
- t[(0xFF * 11) % 64] = l;
- }
- for (ptrdiff_t widx = 0; widx < ctx->npixels;) {
- uint32_t c;
- uint8_t tmp, op;
- int dg;
-
- QOIDEC_ASSERT(p <= end);
- if (end - p < 8) {
- return QOIDEC_CORRUPTED;
- }
- op = *p++;
- switch (op) {
- case 0xFF:
- l.r = *p++; l.g = *p++; l.b = *p++; l.a = *p++;
- break;
- case 0xFE:
- l.r = *p++; l.g = *p++; l.b = *p++;
- break;
- default:
- switch (op >> 6) {
- case 0x3:
- tmp = (op & 0x3F) + 1;
- if (ctx->npixels - widx < tmp) {
- return QOIDEC_CORRUPTED;
- }
- c = (uint32_t)l.a << 24 | l.r << 16 | l.g << 8 | l.b;
- for (int k = 0; k < tmp; ++k) {
- ctx->data[widx++] = c;
- }
- goto no_write;
- break;
- case 0x0:
- if (op == lop) {
- return QOIDEC_CORRUPTED; // seriously?
- }
- l = t[op & 0x3F];
- goto no_table;
- break;
- case 0x1:
- l.r += ((op >> 4) & 0x3) - 2;
- l.g += ((op >> 2) & 0x3) - 2;
- l.b += ((op >> 0) & 0x3) - 2;
- break;
- case 0x2:
- tmp = *p++;
- QOIDEC_ASSERT((tmp >> 8) == 0);
- dg = (op & 0x3F) - 32;
- l.r += dg + ((tmp >> 4) - 8);
- l.g += dg;
- l.b += dg + ((tmp & 0xF) - 8);
- break;
- }
- break;
- }
-
- t[(l.r*3 + l.g*5 + l.b*7 + l.a*11) % 64] = l;
-no_table:
- ctx->data[widx++] = (uint32_t)l.a << 24 | l.r << 16 | l.g << 8 | l.b;
-no_write:
- lop = op;
- }
+ if ((*p >> 6) == 0x3 && (*p & 0x3F) < 62)
+ { // ref: https://github.com/phoboslab/qoi/issues/258
+ t[(0xFF * 11) % 64] = l;
+ }
+ for (ptrdiff_t widx = 0; widx < ctx->npixels;)
+ {
+ uint32_t c;
+ uint8_t tmp, op;
+ int dg;
+
+ QOIDEC_ASSERT(p <= end);
+ if (end - p < 8)
+ {
+ return QOIDEC_CORRUPTED;
+ }
+ op = *p++;
+ switch (op)
+ {
+ case 0xFF:
+ l.r = *p++;
+ l.g = *p++;
+ l.b = *p++;
+ l.a = *p++;
+ break;
+ case 0xFE:
+ l.r = *p++;
+ l.g = *p++;
+ l.b = *p++;
+ break;
+ default:
+ switch (op >> 6)
+ {
+ case 0x3:
+ tmp = (op & 0x3F) + 1;
+ if (ctx->npixels - widx < tmp)
+ {
+ return QOIDEC_CORRUPTED;
+ }
+ c = (uint32_t) l.a << 24 | l.r << 16 | l.g << 8 | l.b;
+ for (int k = 0; k < tmp; ++k)
+ {
+ ctx->data[widx++] = c;
+ }
+ goto no_write;
+ break;
+ case 0x0:
+ if (op == lop)
+ {
+ return QOIDEC_CORRUPTED; // seriously?
+ }
+ l = t[op & 0x3F];
+ goto no_table;
+ break;
+ case 0x1:
+ l.r += ((op >> 4) & 0x3) - 2;
+ l.g += ((op >> 2) & 0x3) - 2;
+ l.b += ((op >> 0) & 0x3) - 2;
+ break;
+ case 0x2:
+ tmp = *p++;
+ QOIDEC_ASSERT((tmp >> 8) == 0);
+ dg = (op & 0x3F) - 32;
+ l.r += dg + ((tmp >> 4) - 8);
+ l.g += dg;
+ l.b += dg + ((tmp & 0xF) - 8);
+ break;
+ }
+ break;
+ }
+
+ t[(l.r * 3 + l.g * 5 + l.b * 7 + l.a * 11) % 64] = l;
+ no_table:
+ ctx->data[widx++] = (uint32_t) l.a << 24 | l.r << 16 | l.g << 8 | l.b;
+ no_write:
+ lop = op;
+ }
if (end - p < 8 ||
- !((p[0] == 0) & (p[1] == 0) & (p[2] == 0) & (p[3] == 0) &
- (p[4] == 0) & (p[5] == 0) & (p[6] == 0) & (p[7] == 1)))
- {
- return QOIDEC_CORRUPTED;
- }
+ !((p[0] == 0) & (p[1] == 0) & (p[2] == 0) & (p[3] == 0) &
+ (p[4] == 0) & (p[5] == 0) & (p[6] == 0) & (p[7] == 1)))
+ {
+ return QOIDEC_CORRUPTED;
+ }
return QOIDEC_OK;
}
@@ -197,6 +216,9 @@ _load(ImlibImage * im, int load_data)
if (qoi_dec(&qoi) != QOIDEC_OK)
return LOAD_BADIMAGE;
+ if (im->lc)
+ __imlib_LoadProgressRows(im, 0, im->h);
+
return LOAD_SUCCESS;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.