From e1b851c4886ab3976f0591be5b740f2a3a8cb7d1 Mon Sep 17 00:00:00 2001 From: NRK Date: Sun, 27 Aug 2023 23:20:39 +0600 Subject: [PATCH] remove legacy multi-frame loaders this removes the legacy gif and webp loaders. moving forward multi-frame/animated images will be loaded by imlib2 itself. Closes: https://codeberg.org/nsxiv/nsxiv/issues/397 --- .github/workflows/build.yml | 4 +- Makefile | 10 +- README.md | 11 +- config.mk | 5 - etc/woodpecker/analysis.yml | 2 +- etc/woodpecker/build.yml | 4 +- image.c | 298 +----------------------------------- options.c | 7 - 8 files changed, 9 insertions(+), 332 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97a7c65..6b6af3f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,11 +43,11 @@ jobs: run: | brew update # see: https://github.com/actions/setup-python/issues/577 - brew install imlib2 libx11 libxft libexif giflib webp || true + brew install imlib2 libx11 libxft libexif || true - name: build run: | # libinotify-kqueue isn't available on homebrew make clean && make -s OPT_DEP_DEFAULT=1 HAVE_INOTIFY=0 # force uninstallation with --ignore-dependencies - brew uninstall --ignore-dependencies libxft libexif giflib webp + brew uninstall --ignore-dependencies libxft libexif make clean && make -s OPT_DEP_DEFAULT=0 diff --git a/Makefile b/Makefile index 3527741..b7ee37b 100644 --- a/Makefile +++ b/Makefile @@ -8,20 +8,14 @@ lib_fonts_0 = lib_fonts_1 = -lXft -lfontconfig lib_exif_0 = lib_exif_1 = -lexif -lib_gif_0 = -lib_gif_1 = -lgif -lib_webp_0 = -lib_webp_1 = -lwebpdemux -lwebp nsxiv_cppflags = -D_XOPEN_SOURCE=700 \ - -DHAVE_LIBGIF=$(HAVE_LIBGIF) -DHAVE_LIBEXIF=$(HAVE_LIBEXIF) \ - -DHAVE_LIBWEBP=$(HAVE_LIBWEBP) -DHAVE_LIBFONTS=$(HAVE_LIBFONTS) \ + -DHAVE_LIBEXIF=$(HAVE_LIBEXIF) -DHAVE_LIBFONTS=$(HAVE_LIBFONTS) \ -DHAVE_INOTIFY=$(HAVE_INOTIFY) $(inc_fonts_$(HAVE_LIBFONTS)) \ $(CPPFLAGS) nsxiv_ldlibs = -lImlib2 -lX11 \ - $(lib_exif_$(HAVE_LIBEXIF)) $(lib_gif_$(HAVE_LIBGIF)) \ - $(lib_webp_$(HAVE_LIBWEBP)) $(lib_fonts_$(HAVE_LIBFONTS)) \ + $(lib_exif_$(HAVE_LIBEXIF)) $(lib_fonts_$(HAVE_LIBFONTS)) \ $(LDLIBS) objs = autoreload.o commands.o image.o main.o options.o \ diff --git a/README.md b/README.md index 3a3b2d1..9a9c1d4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Features -------- * Basic image operations like zooming, panning, rotating -* Basic support for animated/multi-frame images +* Basic support for animated/multi-frame images (**requires Imlib2 v1.8.0 or above**) * Thumbnail mode: grid of selectable previews of all images * Ability to cache thumbnails for fast re-loading * Automatically refreshing modified images @@ -76,15 +76,6 @@ The following dependencies are optional: * `libexif`: Used for auto-orientation and exif thumbnails. Disable via `HAVE_LIBEXIF=0`. -The following dependencies are only used if your imlib2 version is lower than -v1.8.0. If your imlib2 version is v1.8.0 (or above) then the following -dependencies are unused and won't be built (even if you enable it explicitly). - - * `giflib`: Used for animated gif playback. Disabled via `HAVE_LIBGIF=0`. - * `libwebp`: Used for animated webp playback. - (***NOTE***: animated webp also requires Imlib2 v1.7.5 or above) - Disabled via `HAVE_LIBWEBP=0`. - Please make sure to install the corresponding development packages in case that you want to build nsxiv on a distribution with separate runtime and development packages (e.g. \*-dev on Debian). diff --git a/config.mk b/config.mk index fb28086..b1faec6 100644 --- a/config.mk +++ b/config.mk @@ -16,11 +16,6 @@ HAVE_INOTIFY = $(OPT_DEP_DEFAULT) HAVE_LIBFONTS = $(OPT_DEP_DEFAULT) HAVE_LIBEXIF = $(OPT_DEP_DEFAULT) -# unused if imlib2 version is 1.8.0 or higher. -# these options will be removed eventually. -HAVE_LIBGIF = $(OPT_DEP_DEFAULT) -HAVE_LIBWEBP = $(OPT_DEP_DEFAULT) - # CFLAGS, any additional compiler flags goes here CFLAGS = -Wall -pedantic -O2 -DNDEBUG # Uncomment for a debug build using gcc/clang diff --git a/etc/woodpecker/analysis.yml b/etc/woodpecker/analysis.yml index 9ebcc4f..b08dc36 100644 --- a/etc/woodpecker/analysis.yml +++ b/etc/woodpecker/analysis.yml @@ -6,6 +6,6 @@ pipeline: commands: | apk add --no-cache build-base cppcheck clang-extra-tools git \ imlib2-dev xorgproto \ - libxft-dev libexif-dev giflib-dev libwebp-dev >/dev/null + libxft-dev libexif-dev >/dev/null make config.h version.h ./etc/woodpecker/analysis.sh diff --git a/etc/woodpecker/build.yml b/etc/woodpecker/build.yml index 7c79a90..1f447a3 100644 --- a/etc/woodpecker/build.yml +++ b/etc/woodpecker/build.yml @@ -9,7 +9,7 @@ pipeline: commands: | apk add --no-cache \ imlib2 imlib2-dev xorgproto \ - libxft libxft-dev libexif libexif-dev giflib giflib-dev libwebp libwebp-dev \ + libxft libxft-dev libexif libexif-dev \ gcc clang llvm llvm-dev build-base wget ca-certificates bc >/dev/null wget "https://github.com/TinyCC/tinycc/archive/$TCC_SHA.tar.gz" >/dev/null tar xzf "$TCC_SHA.tar.gz" >/dev/null @@ -26,5 +26,5 @@ pipeline: # full-build with gcc and clang # build "1" "full" # ensure minimal-build works without opt deps installed - apk del libxft libxft-dev libexif libexif-dev giflib giflib-dev libwebp libwebp-dev >/dev/null + apk del libxft libxft-dev libexif libexif-dev >/dev/null build "0" "minimal" diff --git a/image.c b/image.c index 6020e93..2a01954 100644 --- a/image.c +++ b/image.c @@ -33,18 +33,6 @@ #include #endif -#if HAVE_LIBGIF && !HAVE_IMLIB2_MULTI_FRAME -#include -enum { DEF_GIF_DELAY = 75 }; -#endif - -#if HAVE_LIBWEBP && !HAVE_IMLIB2_MULTI_FRAME -#include -#include -#include -enum { DEF_WEBP_DELAY = 75 }; -#endif - #if HAVE_IMLIB2_MULTI_FRAME enum { DEF_ANIM_DELAY = 75 }; #endif @@ -144,7 +132,7 @@ void exif_auto_orientate(const fileinfo_t *file) } #endif -#if HAVE_LIBGIF || HAVE_LIBWEBP || HAVE_IMLIB2_MULTI_FRAME +#if HAVE_IMLIB2_MULTI_FRAME static void img_multiframe_context_set(img_t *img) { if (img->multi.cnt > 1) { @@ -157,283 +145,7 @@ static void img_multiframe_context_set(img_t *img) imlib_context_set_image(img->im); } -#endif -#if (HAVE_LIBGIF || HAVE_LIBWEBP) && !HAVE_IMLIB2_MULTI_FRAME -static void img_multiframe_deprecation_notice(void) -{ - static bool warned; - if (!warned) { - error(0, 0, "\n" - "################################################################\n" - "# DEPRECATION NOTICE #\n" - "################################################################\n" - "# Internal multi-frame gif and webp loaders are deprecated and #\n" - "# will be removed soon. Please upgrade to Imlib2 v1.8.0 for #\n" - "# multi-frame/animated image support. #\n" - "################################################################"); - warned = true; - } -} -#endif - -#if HAVE_LIBGIF && !HAVE_IMLIB2_MULTI_FRAME -static bool img_load_gif(img_t *img, const fileinfo_t *file) -{ - GifFileType *gif; - GifRowType *rows = NULL; - GifRecordType rec; - ColorMapObject *cmap; - uint32_t bgpixel = 0, *data, *ptr; - uint32_t *prev_frame = NULL; - Imlib_Image im; - int i, j, bg, r, g, b; - int x, y, w, h, sw, sh; - int px, py, pw, ph; - int intoffset[] = { 0, 4, 2, 1 }; - int intjump[] = { 8, 8, 4, 2 }; - int transp = -1; - unsigned int disposal = 0, prev_disposal = 0; - unsigned int delay = 0; - bool err = false; - multi_img_t *m = &img->multi; - - img_multiframe_deprecation_notice(); - -#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5 - gif = DGifOpenFileName(file->path, NULL); -#else - gif = DGifOpenFileName(file->path); -#endif - if (gif == NULL) { - error(0, 0, "%s: Error opening gif image", file->name); - return false; - } - bg = gif->SBackGroundColor; - sw = gif->SWidth; - sh = gif->SHeight; - px = py = pw = ph = 0; - - m->length = m->cnt = m->sel = 0; - do { - if (DGifGetRecordType(gif, &rec) == GIF_ERROR) { - err = true; - break; - } - if (rec == EXTENSION_RECORD_TYPE) { - int ext_code; - GifByteType *ext = NULL; - - DGifGetExtension(gif, &ext_code, &ext); - while (ext) { - if (ext_code == GRAPHICS_EXT_FUNC_CODE) { - if (ext[1] & 1) - transp = (int)ext[4]; - else - transp = -1; - - delay = 10 * ((unsigned int)ext[3] << 8 | (unsigned int)ext[2]); - disposal = (unsigned int)ext[1] >> 2 & 0x7; - } - ext = NULL; - DGifGetExtensionNext(gif, &ext); - } - } else if (rec == IMAGE_DESC_RECORD_TYPE) { - if (DGifGetImageDesc(gif) == GIF_ERROR) { - err = true; - break; - } - x = gif->Image.Left; - y = gif->Image.Top; - w = gif->Image.Width; - h = gif->Image.Height; - - rows = emalloc(h * sizeof(*rows)); - for (i = 0; i < h; i++) - rows[i] = emalloc(w * sizeof(*rows[i])); - if (gif->Image.Interlace) { - for (i = 0; i < 4; i++) { - for (j = intoffset[i]; j < h; j += intjump[i]) - DGifGetLine(gif, rows[j], w); - } - } else { - for (i = 0; i < h; i++) - DGifGetLine(gif, rows[i], w); - } - - ptr = data = emalloc(sw * sh * sizeof(*data)); - cmap = gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap; - /* if bg > cmap->ColorCount, it is transparent black already */ - if (cmap && bg >= 0 && bg < cmap->ColorCount) { - r = cmap->Colors[bg].Red; - g = cmap->Colors[bg].Green; - b = cmap->Colors[bg].Blue; - bgpixel = 0x00ffffff & (r << 16 | g << 8 | b); - } - - for (i = 0; i < sh; i++) { - for (j = 0; j < sw; j++) { - if (i < y || i >= y + h || j < x || j >= x + w || - rows[i - y][j - x] == transp) - { - if (prev_frame != NULL && - (prev_disposal != 2 || i < py || i >= py + ph || - j < px || j >= px + pw)) - { - *ptr = prev_frame[i * sw + j]; - } else { - *ptr = bgpixel; - } - } else { - assert(cmap != NULL); - r = cmap->Colors[rows[i - y][j - x]].Red; - g = cmap->Colors[rows[i - y][j - x]].Green; - b = cmap->Colors[rows[i - y][j - x]].Blue; - *ptr = 0xffu << 24 | r << 16 | g << 8 | b; - } - ptr++; - } - } - - im = imlib_create_image_using_copied_data(sw, sh, data); - - for (i = 0; i < h; i++) - free(rows[i]); - free(rows); - free(data); - - if (im == NULL) { - err = true; - break; - } - - imlib_context_set_image(im); - imlib_image_set_format("gif"); - if (transp >= 0) - imlib_image_set_has_alpha(1); - - if (disposal != 3) - prev_frame = imlib_image_get_data_for_reading_only(); - prev_disposal = disposal; - px = x, py = y, pw = w, ph = h; - - assert(m->cnt <= m->cap); - if (m->cnt == m->cap) { - m->cap = m->cap == 0 ? 16 : (m->cap * 2); - m->frames = erealloc(m->frames, m->cap * sizeof(*m->frames)); - } - m->frames[m->cnt].im = im; - delay = m->framedelay > 0 ? m->framedelay : delay; - m->frames[m->cnt].delay = delay > 0 ? delay : DEF_GIF_DELAY; - m->length += m->frames[m->cnt].delay; - m->cnt++; - } - } while (rec != TERMINATE_RECORD_TYPE); - -#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5 && GIFLIB_MINOR >= 1 - DGifCloseFile(gif, NULL); -#else - DGifCloseFile(gif); -#endif - - if (err && (file->flags & FF_WARN)) - error(0, 0, "%s: Corrupted gif file", file->name); - - img_multiframe_context_set(img); - - return !err; -} -#endif /* HAVE_LIBGIF */ - -#if HAVE_LIBWEBP && !HAVE_IMLIB2_MULTI_FRAME -static bool img_load_webp(img_t *img, const fileinfo_t *file) -{ - FILE *webp_file; - WebPData data; - Imlib_Image im = NULL; - struct WebPAnimDecoderOptions opts; - WebPAnimDecoder *dec = NULL; - struct WebPAnimInfo info; - unsigned char *buf = NULL, *bytes = NULL; - int ts; - const WebPDemuxer *demux; - WebPIterator iter; - unsigned long flags; - unsigned int delay; - bool err = false; - multi_img_t *m = &img->multi; - - img_multiframe_deprecation_notice(); - - if ((webp_file = fopen(file->path, "rb")) == NULL) { - error(0, errno, "%s: Error opening webp image", file->name); - return false; - } - fseek(webp_file, 0L, SEEK_END); - data.size = ftell(webp_file); - rewind(webp_file); - bytes = emalloc(data.size); - if ((err = fread(bytes, 1, data.size, webp_file) != data.size)) { - error(0, 0, "%s: Error reading webp image", file->name); - goto fail; - } - data.bytes = bytes; - - /* Setup the WebP Animation Decoder */ - if ((err = !WebPAnimDecoderOptionsInit(&opts))) { - error(0, 0, "%s: WebP library version mismatch", file->name); - goto fail; - } - opts.color_mode = MODE_BGRA; - /* NOTE: Multi-threaded decoding may cause problems on some system */ - opts.use_threads = true; - dec = WebPAnimDecoderNew(&data, &opts); - if ((err = (dec == NULL) || !WebPAnimDecoderGetInfo(dec, &info))) { - error(0, 0, "%s: WebP parsing or memory error (file is corrupt?)", file->name); - goto fail; - } - demux = WebPAnimDecoderGetDemuxer(dec); - - /* Get global information for the image */ - flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); - img->w = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); - img->h = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); - - if (info.frame_count > m->cap) { - m->cap = info.frame_count; - m->frames = erealloc(m->frames, m->cap * sizeof(*m->frames)); - } - - /* Load and decode frames (also works on images with only 1 frame) */ - m->length = m->cnt = m->sel = 0; - while (WebPAnimDecoderGetNext(dec, &buf, &ts)) { - im = imlib_create_image_using_copied_data(info.canvas_width, info.canvas_height, - (uint32_t *)buf); - imlib_context_set_image(im); - imlib_image_set_format("webp"); - /* Get an iterator of this frame - used for frame info (duration, etc.) */ - WebPDemuxGetFrame(demux, m->cnt + 1, &iter); - imlib_image_set_has_alpha((flags & ALPHA_FLAG) == ALPHA_FLAG); - /* Store info for this frame */ - m->frames[m->cnt].im = im; - delay = iter.duration > 0 ? iter.duration : DEF_WEBP_DELAY; - m->frames[m->cnt].delay = delay; - m->length += m->frames[m->cnt].delay; - m->cnt++; - } - WebPDemuxReleaseIterator(&iter); - - img_multiframe_context_set(img); -fail: - if (dec != NULL) - WebPAnimDecoderDelete(dec); - free(bytes); - fclose(webp_file); - return !err; -} -#endif /* HAVE_LIBWEBP */ - -#if HAVE_IMLIB2_MULTI_FRAME static void img_area_clear(int x, int y, int w, int h) { assert(x >= 0 && y >= 0); @@ -596,14 +308,6 @@ bool img_load(img_t *img, const fileinfo_t *file) #endif if ((fmt = imlib_image_format()) != NULL) { /* NOLINT: fmt might be unused, not worth fixing */ -#if HAVE_LIBGIF && !HAVE_IMLIB2_MULTI_FRAME - if (STREQ(fmt, "gif")) - img_load_gif(img, file); -#endif -#if HAVE_LIBWEBP && !HAVE_IMLIB2_MULTI_FRAME - if (STREQ(fmt, "webp")) - img_load_webp(img, file); -#endif #if HAVE_LIBEXIF && defined(IMLIB2_VERSION) if (!STREQ(fmt, "jpeg") && !STREQ(fmt, "jpg")) exif_auto_orientate(file); diff --git a/options.c b/options.c index 2835967..4ae2ea5 100644 --- a/options.c +++ b/options.c @@ -62,13 +62,6 @@ static void print_version(void) #endif #if HAVE_IMLIB2_MULTI_FRAME "+multiframe " -#else - #if HAVE_LIBGIF - "+giflib " - #endif - #if HAVE_LIBWEBP - "+libwebp " - #endif #endif "\n", stdout); }