From 5cabf38155fed90d38182369a2bd94fecb1dd0a8 Mon Sep 17 00:00:00 2001 From: FRIGN Date: Sat, 30 Jan 2016 22:44:42 +0100 Subject: [PATCH] Add a Farbfeld loader (http://tools.suckless.org/farbfeld) --- AUTHORS | 1 + imlib2.spec.in | 9 ++ src/modules/loaders/Makefile.am | 7 ++ src/modules/loaders/loader_ff.c | 162 ++++++++++++++++++++++++++++++++ 4 files changed, 179 insertions(+) create mode 100644 src/modules/loaders/loader_ff.c diff --git a/AUTHORS b/AUTHORS index d24bcd9..907ae55 100644 --- a/AUTHORS +++ b/AUTHORS @@ -30,3 +30,4 @@ Nick Blievers Mike Castle R.Ramkumar Dmitry Antipov +Laslo Hunhold diff --git a/imlib2.spec.in b/imlib2.spec.in index a7b0ebf..999ae4b 100644 --- a/imlib2.spec.in +++ b/imlib2.spec.in @@ -72,6 +72,12 @@ Group: System Environment/Libraries %description loader_bmp BMP image loader/saver for Imlib2 +%package loader_ff +Summary: Imlib2 Farbfeld loader +Group: System Environment/Libraries +%description loader_ff +Farbfeld image loader/saver for Imlib2 + %package loader_gif Summary: Imlib2 GIF loader Group: System Environment/Libraries @@ -187,6 +193,9 @@ test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT %files loader_bmp %attr(755,root,root) %{_libdir}/imlib2/loaders/bmp.so +%files loader_ff +%attr(755,root,root) %{_libdir}/imlib2/loaders/ff.so + %files loader_gif %attr(755,root,root) %{_libdir}/imlib2/loaders/gif.so diff --git a/src/modules/loaders/Makefile.am b/src/modules/loaders/Makefile.am index 0f3ff3f..40e2257 100644 --- a/src/modules/loaders/Makefile.am +++ b/src/modules/loaders/Makefile.am @@ -31,6 +31,7 @@ pkg_LTLIBRARIES = \ $(JPEG_L) \ $(PNG_L) \ $(TIFF_L) \ +$(FF_L) \ $(GIF_L) \ $(ZLIB_L) \ $(BZ2_L) \ @@ -38,6 +39,7 @@ $(ID3_L) \ pnm.la \ argb.la \ bmp.la \ +ff.la \ xpm.la \ tga.la \ lbm.la @@ -60,6 +62,11 @@ tiff_la_LDFLAGS = -module -avoid-version tiff_la_LIBADD = @TIFFLIBS@ $(top_builddir)/src/lib/libImlib2.la tiff_la_LIBTOOLFLAGS = --tag=disable-static +ff_la_SOURCES = loader_ff.c +ff_la_LDFLAGS = -module -avoid-version +ff_la_LIBADD = $(top_builddir)/src/lib/libImlib2.la +ff_la_LIBTOOLFLAGS = --tag=disable-static + gif_la_SOURCES = loader_gif.c gif_la_LDFLAGS = -module -avoid-version gif_la_LIBADD = @GIFLIBS@ $(top_builddir)/src/lib/libImlib2.la diff --git a/src/modules/loaders/loader_ff.c b/src/modules/loaders/loader_ff.c new file mode 100644 index 0000000..63f4c65 --- /dev/null +++ b/src/modules/loaders/loader_ff.c @@ -0,0 +1,162 @@ +/* Farbfeld (http://tools.suckless.org/farbfeld) */ +#include +#include + +#include "loader_common.h" + +#define LEN(x) (sizeof((x)) / sizeof(*(x))) + +char +load(ImlibImage *im, ImlibProgressFunction progress, + char progress_granularity, char immediate_load) +{ + FILE *f; + size_t rowlen, i, j; + uint32_t hdr[2 + 1 + 1], w, h; + uint16_t *row; + uint8_t *dat; + + /* open the file for reading */ + if (!(f = fopen(im->real_file, "rb"))) { + return 0; + } + + /* read and check the header */ + if (!im->data) { + if (fread(hdr, sizeof(uint32_t), LEN(hdr), f) != LEN(hdr) || + memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) { + fclose(f); + return 0; + } + im->w = ntohl(hdr[2]); + im->h = ntohl(hdr[3]); + if (!IMAGE_DIMENSIONS_OK(im->w, im->h)) { + fclose(f); + return 0; + } + + /* set format */ + if (!im->loader) { + if (!(im->format = strdup("ff"))) { + fclose(f); + return 0; + } + } + SET_FLAG(im->flags, F_HAS_ALPHA); + } + + /* load the data */ + if (im->loader || immediate_load || progress) { + w = im->w; + h = im->h; + rowlen = w * (sizeof("RGBA") - 1); + + free(im->data); + if (!(im->data = malloc(rowlen * h)) || + !(row = malloc(rowlen * sizeof(uint16_t)))) { + free(im->data); + im->data = NULL; + free(row); + fclose(f); + return 0; + } + + dat = (uint8_t *)im->data; + for (i = 0; i < h; i++, dat += rowlen) { + if (fread(row, sizeof(uint16_t), rowlen, f) != + rowlen) { + free(im->data); + im->data = NULL; + free(row); + fclose(f); + return 0; + } + for (j = 0; j < rowlen; j += 4) { + /* + * 16-Bit to 8-Bit (RGBA -> BGRA) + * 255 * 257 = 65535 = 2^16-1 = UINT16_MAX + */ + dat[j + 2] = ntohs(row[j + 0]) / 257; + dat[j + 1] = ntohs(row[j + 1]) / 257; + dat[j + 0] = ntohs(row[j + 2]) / 257; + dat[j + 3] = ntohs(row[j + 3]) / 257; + } + } + if (progress) { + progress(im, 100, 0, 0, im->w, im->h); + } + + free(row); + } + + fclose(f); + return 1; +} + +char +save(ImlibImage *im, ImlibProgressFunction progress, char progress_gran) +{ + FILE *f; + size_t rowlen, i, j; + uint32_t tmp32; + uint16_t *row; + uint8_t *dat; + + /* open the file for writing */ + if (!(f = fopen(im->real_file, "wb"))) { + return 0; + } + + /* write header */ + fputs("farbfeld", f); + tmp32 = htonl(im->w); + if (fwrite(&tmp32, sizeof(uint32_t), 1, f) != 1) { + fclose(f); + return 0; + } + tmp32 = htonl(im->h); + if (fwrite(&tmp32, sizeof(uint32_t), 1, f) != 1) { + fclose(f); + return 0; + } + + /* write data */ + rowlen = im->w * (sizeof("RGBA") - 1); + if (!(row = malloc(rowlen * sizeof(uint16_t)))) { + fclose(f); + return 0; + } + dat = (uint8_t *)im->data; + for (i = 0; i < (uint32_t)im->h; ++i, dat += rowlen) { + for (j = 0; j < rowlen; j += 4) { + /* + * 8-Bit to 16-Bit + * 255 * 257 = 65535 = 2^16-1 = UINT16_MAX + */ + row[j + 0] = htons(dat[j + 2] * 257); + row[j + 1] = htons(dat[j + 1] * 257); + row[j + 2] = htons(dat[j + 0] * 257); + row[j + 3] = htons(dat[j + 3] * 257); + } + if (fwrite(row, sizeof(uint16_t), rowlen, f) != rowlen) { + free(row); + fclose(f); + return 0; + } + } + if (progress) { + progress(im, 100, 0, 0, im->w, im->h); + } + + free(row); + fclose(f); + return 1; +} + +void +formats(ImlibLoader *l) +{ + l->num_formats = 1; + l->formats = malloc(sizeof(char *)); + *(l->formats) = strdup("ff"); +}