summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2020-12-11 07:19:55 +0100
committerKim Woelders <kim@woelders.dk>2020-12-18 07:18:29 +0100
commitb2153681964d10f7c86f1cad57da968111300af5 (patch)
tree8ead126d616e9d24a41ee55f0f4c503dd3611f2a
parent418d19e0667c2b3fdca148dc05c693478b09c52e (diff)
downloadimlib2-b2153681964d10f7c86f1cad57da968111300af5.tar.gz
Add XBM loader
-rw-r--r--src/modules/loaders/Makefile.am6
-rw-r--r--src/modules/loaders/loader_xbm.c228
2 files changed, 234 insertions, 0 deletions
diff --git a/src/modules/loaders/Makefile.am b/src/modules/loaders/Makefile.am
index f498a74..ca8c084 100644
--- a/src/modules/loaders/Makefile.am
+++ b/src/modules/loaders/Makefile.am
@@ -45,6 +45,7 @@ pnm.la \
tga.la \
$(TIFF_L) \
$(WEBP_L) \
+xbm.la \
xpm.la \
$(ZLIB_L)
@@ -122,6 +123,11 @@ webp_la_LDFLAGS = -module -avoid-version
webp_la_LIBADD = @WEBP_LIBS@ $(top_builddir)/src/lib/libImlib2.la
webp_la_LIBTOOLFLAGS = --tag=disable-static
+xbm_la_SOURCES = loader_xbm.c
+xbm_la_LDFLAGS = -module -avoid-version
+xbm_la_LIBADD = $(top_builddir)/src/lib/libImlib2.la
+xbm_la_LIBTOOLFLAGS = --tag=disable-static
+
xpm_la_SOURCES = loader_xpm.c
xpm_la_LDFLAGS = -module -avoid-version
xpm_la_LIBADD = $(top_builddir)/src/lib/libImlib2.la
diff --git a/src/modules/loaders/loader_xbm.c b/src/modules/loaders/loader_xbm.c
new file mode 100644
index 0000000..e7c648a
--- /dev/null
+++ b/src/modules/loaders/loader_xbm.c
@@ -0,0 +1,228 @@
+/*
+ * XBM loader
+ */
+#include "loader_common.h"
+
+#define DEBUG 0
+#if DEBUG
+#define D(fmt...) fprintf(stdout, "XBM loader: " fmt)
+#else
+#define D(fmt...)
+#endif
+
+static const DATA32 _bitmap_colors[2] = { 0xffffffff, 0xff000000 };
+
+static DATA32
+_bitmap_color(int bit)
+{
+ return _bitmap_colors[!!bit];
+}
+
+static int
+_bitmap_dither(int x, int y, DATA32 pixel)
+{
+ static const DATA8 _dither_44[4][4] = {
+ /**INDENT-OFF**/
+ { 0, 32, 8, 40},
+ {48, 16, 56, 24},
+ {12, 44, 4, 36},
+ {60, 28, 52, 20},
+ /**INDENT-ON**/
+ };
+ int val, set;
+
+ if (PIXEL_A(pixel) < 0x80)
+ {
+ set = 0;
+ }
+ else
+ {
+ val = (PIXEL_R(pixel) + PIXEL_G(pixel) + PIXEL_B(pixel)) / 12;
+ set = val <= _dither_44[x & 0x3][y & 0x3];
+ }
+
+ return set;
+}
+
+int
+load2(ImlibImage * im, int load_data)
+{
+ int rc;
+ char buf[4096], tok1[1024], tok2[1024];
+ DATA32 *ptr, pixel;
+ int i, x, y, bit;
+ char *s;
+ int header, val, nlen;
+
+ rc = LOAD_FAIL;
+ ptr = NULL;
+ x = y = 0;
+
+ header = 1;
+ for (;;)
+ {
+ s = fgets(buf, sizeof(buf), im->fp);
+ D(">>>%s", buf);
+ if (!s)
+ break;
+
+ if (header)
+ {
+ /* Header */
+ tok1[0] = tok2[0] = '\0';
+ val = -1;
+ sscanf(buf, " %1023s %1023s %d", tok1, tok2, &val);
+ D("'%s': '%s': %d\n", tok1, tok2, val);
+ if (strcmp(tok1, "#define") == 0)
+ {
+ if (tok2[0] == '\0')
+ goto quit;
+
+ nlen = strlen(tok2);
+ if (nlen > 6 && strcmp(tok2 + nlen - 6, "_width") == 0)
+ {
+ D("'%s' = %d\n", tok2, val);
+ im->w = val;
+ }
+ else if (nlen > 7 && strcmp(tok2 + nlen - 7, "_height") == 0)
+ {
+ D("'%s' = %d\n", tok2, val);
+ im->h = val;
+ }
+ }
+ else if (strcmp(tok1, "static") == 0)
+ {
+ if (!IMAGE_DIMENSIONS_OK(im->w, im->h))
+ goto quit;
+
+ if (!load_data)
+ {
+ rc = LOAD_SUCCESS;
+ goto quit;
+ }
+
+ UNSET_FLAG(im->flags, F_HAS_ALPHA);
+
+ header = 0;
+
+ ptr = __imlib_AllocateData(im);
+ if (!ptr)
+ goto quit;
+ }
+ else
+ {
+ goto quit;
+ }
+ }
+ else
+ {
+ /* Data */
+ for (; *s != '\0';)
+ {
+ nlen = -1;
+ sscanf(s, "%i%n", &val, &nlen);
+ D("Data %02x (%d)\n", val, nlen);
+ if (nlen < 0)
+ break;
+ s += nlen;
+ if (*s == ',')
+ s++;
+
+ for (i = 0; i < 8 && x < im->w; i++, x++)
+ {
+ bit = (val & (1 << i)) != 0;
+ pixel = _bitmap_color(bit);
+ *ptr++ = pixel;
+ D("i, x, y: %2d %2d %2d: %08x\n", i, x, y, pixel);
+ }
+
+ if (x >= im->w)
+ {
+ if (im->lc && __imlib_LoadProgressRows(im, y, 1))
+ {
+ rc = LOAD_BREAK;
+ goto quit;
+ }
+
+ x = 0;
+ y += 1;
+ }
+ }
+ }
+ }
+
+ rc = LOAD_SUCCESS;
+
+ quit:
+ if (rc <= 0)
+ __imlib_FreeData(im);
+
+ return rc;
+}
+
+char
+save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
+{
+ FILE *f;
+ int rc;
+ const char *s, *name;
+ char *bname;
+ int i, k, x, y, bits, nval, val;
+ DATA32 *ptr;
+
+ f = fopen(im->real_file, "wb");
+ if (!f)
+ return LOAD_FAIL;
+
+ rc = LOAD_SUCCESS;
+
+ name = im->real_file;
+ if ((s = strrchr(name, '/')) != 0)
+ name = s + 1;
+
+ bname = strndup(name, strcspn(name, "."));
+
+ fprintf(f, "#define %s_width %d\n", bname, im->w);
+ fprintf(f, "#define %s_height %d\n", bname, im->h);
+ fprintf(f, "static unsigned char %s_bits[] = {\n", bname);
+
+ free(bname);
+
+ nval = ((im->w + 7) / 8) * im->h;
+ ptr = im->data;
+ x = k = 0;
+ for (y = 0; y < im->h;)
+ {
+ bits = 0;
+ for (i = 0; i < 8 && x < im->w; i++, x++)
+ {
+ val = _bitmap_dither(x, y, *ptr++);
+ if (val)
+ bits |= 1 << i;
+ }
+ if (x >= im->w)
+ {
+ x = 0;
+ y += 1;
+ }
+ k++;
+ D("x, y = %2d,%2d: %d/%d\n", x, y, k, nval);
+ fprintf(f, " 0x%02x%s%s", bits, k < nval ? "," : "",
+ (k == nval) || ((k % 12) == 0) ? "\n" : "");
+ }
+
+ fprintf(f, "};\n");
+
+ fclose(f);
+
+ return rc;
+}
+
+void
+formats(ImlibLoader * l)
+{
+ static const char *const list_formats[] = { "xbm" };
+
+ __imlib_LoaderSetFormats(l, list_formats,
+ sizeof(list_formats) / sizeof(char *));
+}