Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package frei0r-plugins for openSUSE:Factory checked in at 2026-08-19 17:56:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/frei0r-plugins (Old) and /work/SRC/openSUSE:Factory/.frei0r-plugins.new.1258 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "frei0r-plugins" Wed Aug 19 17:56:21 2026 rev:25 rq:1371934 version:3.4.0 Changes: -------- --- /work/SRC/openSUSE:Factory/frei0r-plugins/frei0r-plugins.changes 2026-06-29 17:33:42.608923126 +0200 +++ /work/SRC/openSUSE:Factory/.frei0r-plugins.new.1258/frei0r-plugins.changes 2026-08-19 17:56:54.826967617 +0200 @@ -1,0 +2,13 @@ +Wed Aug 19 07:59:18 UTC 2026 - Bjørn Lie <[email protected]> + +- Update to version 3.4.0: + + feat: add Shake0scillate filter + +------------------------------------------------------------------- +Tue Aug 18 07:12:26 UTC 2026 - Bjørn Lie <[email protected]> + +- Update to version 3.3.2: + + fix(ntsc): remove now redundant parameter + + Add pixels0rt filter + +------------------------------------------------------------------- Old: ---- frei0r-plugins-3.2.3.tar.gz New: ---- frei0r-plugins-3.4.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ frei0r-plugins.spec ++++++ --- /var/tmp/diff_new_pack.41lSAF/_old 2026-08-19 17:56:55.946008073 +0200 +++ /var/tmp/diff_new_pack.41lSAF/_new 2026-08-19 17:56:55.947008110 +0200 @@ -17,7 +17,7 @@ Name: frei0r-plugins -Version: 3.2.3 +Version: 3.4.0 Release: 0 Summary: Collection of video sources and filters plugins # Upstream says 2.0+ but quite few of their plugins are GPL-3.0+ ++++++ frei0r-plugins-3.2.3.tar.gz -> frei0r-plugins-3.4.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/.github/workflows/test.yml new/frei0r-3.4.0/.github/workflows/test.yml --- old/frei0r-3.2.3/.github/workflows/test.yml 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/.github/workflows/test.yml 2026-08-18 13:34:08.000000000 +0200 @@ -82,7 +82,9 @@ if: "!contains(github.event.pull_request.labels.*.name, 'skip-test')" strategy: matrix: - compiler: [clang-14] + include: + - compiler: clang-14 + cxx_compiler: clang++-14 fail-fast: false runs-on: ubuntu-latest steps: @@ -90,10 +92,13 @@ with: fetch-depth: 0 - uses: hendrikmuhs/[email protected] - - name: Cache APT packages - uses: awalsh128/cache-apt-pkgs-action@latest - with: - packages: "${{ matrix.compiler }} cmake ninja-build libfreetype-dev libopencv-dev libcairo2-dev libgavl-dev" + - name: Install APT packages + run: | + sudo apt-get update -qy + sudo apt-get install --no-install-recommends -y \ + "${{ matrix.compiler }}" \ + cmake ninja-build libfreetype-dev libopencv-dev \ + libcairo2-dev libgavl-dev - name: Detect new plugins id: detect if: github.event_name == 'pull_request' @@ -108,7 +113,12 @@ - name: ${{ matrix.compiler }} initialize cmake build run: | mkdir -p build && cd build - cmake -G "Ninja" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .. + cmake -G "Ninja" \ + -DCMAKE_C_COMPILER="${{ matrix.compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ matrix.cxx_compiler }}" \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + .. - name: ${{ matrix.compiler }} run ninja build if: github.event_name != 'pull_request' || steps.detect.outputs.mode != 'targeted' run: | @@ -126,5 +136,5 @@ if: github.event_name == 'pull_request' && steps.detect.outputs.mode == 'targeted' run: | for plugin in ${{ steps.detect.outputs.plugin_paths }}; do - ./frei0r-run -d -p "../$plugin" + build/test/frei0r-run -d -p "$plugin" done diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/.gitignore new/frei0r-3.4.0/.gitignore --- old/frei0r-3.2.3/.gitignore 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/.gitignore 2026-08-18 13:34:08.000000000 +0200 @@ -40,8 +40,12 @@ /.vs/ CMakeSettings.json .vscode +<<<<<<< HEAD docs/node_modules/ docs/.vitepress/dist/ docs/.vitepress/cache/ docs/public/codedoc/ docs/doxygen-warnings.log +======= +CMakeCache.txt +>>>>>>> d0c88f7 (chore: Ignore CMakeCache) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/CMakeLists.txt new/frei0r-3.4.0/src/filter/CMakeLists.txt --- old/frei0r-3.2.3/src/filter/CMakeLists.txt 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/src/filter/CMakeLists.txt 2026-08-18 13:34:08.000000000 +0200 @@ -13,6 +13,7 @@ add_subdirectory (cairoimagegrid) add_subdirectory (cairogradient) add_subdirectory (mirr0r) + add_subdirectory (shake0scillate) endif (${Cairo_FOUND}) add_subdirectory (3dflippo) @@ -77,6 +78,7 @@ add_subdirectory (ntsc) add_subdirectory (perspective) add_subdirectory (pixeliz0r) +add_subdirectory (pixels0rt) add_subdirectory (pixs0r) add_subdirectory (posterize) add_subdirectory (premultiply) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/ntsc/crt_core.c new/frei0r-3.4.0/src/filter/ntsc/crt_core.c --- old/frei0r-3.2.3/src/filter/ntsc/crt_core.c 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/src/filter/ntsc/crt_core.c 2026-08-18 13:34:08.000000000 +0200 @@ -60,22 +60,6 @@ } } -extern int -crt_bpp4fmt(int format) -{ - switch (format) { - case CRT_PIX_FORMAT_RGB: - case CRT_PIX_FORMAT_BGR: - return 3; - case CRT_PIX_FORMAT_ARGB: - case CRT_PIX_FORMAT_RGBA: - case CRT_PIX_FORMAT_ABGR: - case CRT_PIX_FORMAT_BGRA: - return 4; - default: - return 0; - } -} /*****************************************************************************/ /********************************* FILTERS ***********************************/ @@ -239,32 +223,25 @@ /*****************************************************************************/ extern void -crt_resize(struct CRT *v, int w, int h, int f, unsigned char *out) +crt_resize(struct CRT *v, int w, int h, unsigned char *out) { v->outw = w; v->outh = h; - v->out_format = f; v->out = out; } extern void crt_reset(struct CRT *v) { - v->hue = 0; - v->saturation = 10; - v->brightness = 0; - v->contrast = 180; - v->black_point = 0; - v->white_point = 100; v->hsync = 0; v->vsync = 0; } extern void -crt_init(struct CRT *v, int w, int h, int f, unsigned char *out) +crt_init(struct CRT *v, int w, int h, unsigned char *out) { memset(v, 0, sizeof(struct CRT)); - crt_resize(v, w, h, f, out); + crt_resize(v, w, h, out); crt_reset(v); v->rn = 194; @@ -302,20 +279,14 @@ int *ccr; /* color carrier signal */ int huesn, huecs; int xnudge = -3, ynudge = 3; - int bright = v->brightness - (BLACK_LEVEL + v->black_point); - int bpp, pitch; + int bright = CRT_BRIGHTNESS - (BLACK_LEVEL + CRT_BLACK_PT); + int pitch = v->outw * CRT_BPP; #if CRT_DO_BLOOM int prev_e; /* filtered beam energy per scan line */ int max_e; /* approx maximum energy in a scan line */ #endif - bpp = crt_bpp4fmt(v->out_format); - if (bpp == 0) { - return; - } - pitch = v->outw * bpp; - - crt_sincos14(&huesn, &huecs, ((v->hue % 360) + 33) * 8192 / 180); + crt_sincos14(&huesn, &huecs, ((CRT_HUE % 360) + 33) * 8192 / 180); huesn >>= 11; /* make 4-bit */ huecs >>= 11; @@ -407,6 +378,7 @@ field = (field * (ratio / 2)); for (line = CRT_TOP; line < CRT_BOT; line++) { + int field_gap; unsigned pos, ln, scanR; int scanL, dx; int L, R; @@ -425,8 +397,8 @@ int line_w; #endif - beg = (line - CRT_TOP + 0) * (v->outh + v->v_fac) / CRT_LINES + field; - end = (line - CRT_TOP + 1) * (v->outh + v->v_fac) / CRT_LINES + field; + beg = (line - CRT_TOP + 0) * (v->outh + CRT_V_FAC) / CRT_LINES + field; + end = (line - CRT_TOP + 1) * (v->outh + CRT_V_FAC) / CRT_LINES + field; if (beg >= v->outh) { continue; } if (end > v->outh) { end = v->outh; } @@ -473,15 +445,15 @@ dci = ccr[(phasealign + 1) & 3] - ccr[(phasealign + 3) & 3]; dcq = ccr[(phasealign + 2) & 3] - ccr[(phasealign + 0) & 3]; - wave[0] = ((dci * huecs - dcq * huesn) >> 4) * v->saturation; - wave[1] = ((dcq * huecs + dci * huesn) >> 4) * v->saturation; + wave[0] = ((dci * huecs - dcq * huesn) >> 4) * CRT_SATURATION; + wave[1] = ((dcq * huecs + dci * huesn) >> 4) * CRT_SATURATION; wave[2] = -wave[0]; wave[3] = -wave[1]; #elif (CRT_CC_SAMPLES == 5) { int dciA, dciB; int dcqA, dcqB; - int ang = (v->hue % 360); + int ang = (CRT_HUE % 360); int off180 = CRT_CC_SAMPLES / 2; int off90 = CRT_CC_SAMPLES / 4; int peakA = phasealign + off90; @@ -500,10 +472,10 @@ for (i = 0; i < CRT_CC_SAMPLES; i++) { int sn, cs; crt_sincos14(&sn, &cs, ang * 8192 / 180); - waveI[i] = ((dci * cs + dcq * sn) >> 15) * v->saturation; + waveI[i] = ((dci * cs + dcq * sn) >> 15) * CRT_SATURATION; /* Q is offset by 90 */ crt_sincos14(&sn, &cs, (ang + 90) * 8192 / 180); - waveQ[i] = ((dci * cs + dcq * sn) >> 15) * v->saturation; + waveQ[i] = ((dci * cs + dcq * sn) >> 15) * CRT_SATURATION; ang += (360 / CRT_CC_SAMPLES); } } @@ -570,9 +542,9 @@ q = ((yiqA->q * L) >> 14) + ((yiqB->q * R) >> 14); /* YIQ to RGB */ - r = (((y + 3879 * i + 2556 * q) >> 12) * v->contrast) >> 8; - g = (((y - 1126 * i - 2605 * q) >> 12) * v->contrast) >> 8; - b = (((y - 4530 * i + 7021 * q) >> 12) * v->contrast) >> 8; + r = (((y + 3879 * i + 2556 * q) >> 12) * CRT_CONTRAST) >> 8; + g = (((y - 1126 * i - 2605 * q) >> 12) * CRT_CONTRAST) >> 8; + b = (((y - 4530 * i + 7021 * q) >> 12) * CRT_CONTRAST) >> 8; if (r < 0) r = 0; if (g < 0) g = 0; @@ -581,86 +553,32 @@ if (g > 255) g = 255; if (b > 255) b = 255; - if (v->blend) { +#if CRT_BLEND aa = (r << 16 | g << 8 | b); - - switch (v->out_format) { - case CRT_PIX_FORMAT_RGB: - case CRT_PIX_FORMAT_RGBA: - bb = cL[0] << 16 | cL[1] << 8 | cL[2]; - break; - case CRT_PIX_FORMAT_BGR: - case CRT_PIX_FORMAT_BGRA: - bb = cL[2] << 16 | cL[1] << 8 | cL[0]; - break; - case CRT_PIX_FORMAT_ARGB: - bb = cL[1] << 16 | cL[2] << 8 | cL[3]; - break; - case CRT_PIX_FORMAT_ABGR: - bb = cL[3] << 16 | cL[2] << 8 | cL[1]; - break; - default: - bb = 0; - break; - } - + bb = cL[0] << 16 | cL[1] << 8 | cL[2]; + /* blend with previous color there */ bb = (((aa & 0xfefeff) >> 1) + ((bb & 0xfefeff) >> 1)); - } else { +#else bb = (r << 16 | g << 8 | b); - } +#endif - switch (v->out_format) { - case CRT_PIX_FORMAT_RGB: - cL[0] = bb >> 16 & 0xff; - cL[1] = bb >> 8 & 0xff; - cL[2] = bb >> 0 & 0xff; - break; - - case CRT_PIX_FORMAT_RGBA: - cL[0] = bb >> 16 & 0xff; - cL[1] = bb >> 8 & 0xff; - cL[2] = bb >> 0 & 0xff; - cL[3] = 0xff; - break; - - case CRT_PIX_FORMAT_BGR: - cL[0] = bb >> 0 & 0xff; - cL[1] = bb >> 8 & 0xff; - cL[2] = bb >> 16 & 0xff; - break; - - case CRT_PIX_FORMAT_BGRA: - cL[0] = bb >> 0 & 0xff; - cL[1] = bb >> 8 & 0xff; - cL[2] = bb >> 16 & 0xff; - cL[3] = 0xff; - break; - - case CRT_PIX_FORMAT_ARGB: - cL[0] = 0xff; - cL[1] = bb >> 16 & 0xff; - cL[2] = bb >> 8 & 0xff; - cL[3] = bb >> 0 & 0xff; - break; - - case CRT_PIX_FORMAT_ABGR: - cL[0] = 0xff; - cL[1] = bb >> 0 & 0xff; - cL[2] = bb >> 8 & 0xff; - cL[3] = bb >> 16 & 0xff; - break; + cL[0] = bb >> 16 & 0xff; + cL[1] = bb >> 8 & 0xff; + cL[2] = bb >> 0 & 0xff; + cL[3] = 0xff; - default: - break; - } - - cL += bpp; + cL += CRT_BPP; } /* duplicate extra lines */ - for (s = beg + 1; s < (end - v->scanlines); s++) { + if (v->progressive) { + field_gap = field + v->scanlines; + } else { + field_gap = v->scanlines; + } + for (s = beg + 1; s < (end - field_gap); s++) { memcpy(v->out + s * pitch, v->out + (s - 1) * pitch, pitch); } } -} +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/ntsc/crt_core.h new/frei0r-3.4.0/src/filter/ntsc/crt_core.h --- old/frei0r-3.2.3/src/filter/ntsc/crt_core.h 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/src/filter/ntsc/crt_core.h 2026-08-18 13:34:08.000000000 +0200 @@ -59,31 +59,33 @@ #endif /* NOTE: this library does not use the alpha channel at all */ -#define CRT_PIX_FORMAT_RGB 0 /* 3 bytes per pixel [R,G,B,R,G,B,R,G,B...] */ -#define CRT_PIX_FORMAT_BGR 1 /* 3 bytes per pixel [B,G,R,B,G,R,B,G,R...] */ -#define CRT_PIX_FORMAT_ARGB 2 /* 4 bytes per pixel [A,R,G,B,A,R,G,B...] */ -#define CRT_PIX_FORMAT_RGBA 3 /* 4 bytes per pixel [R,G,B,A,R,G,B,A...] */ -#define CRT_PIX_FORMAT_ABGR 4 /* 4 bytes per pixel [A,B,G,R,A,B,G,R...] */ -#define CRT_PIX_FORMAT_BGRA 5 /* 4 bytes per pixel [B,G,R,A,B,G,R,A...] */ +#define CRT_BPP 4 /* 4 bytes per pixel [R,G,B,A,R,G,B,A...] */ /* do bloom emulation (side effect: makes screen have black borders) */ #define CRT_DO_BLOOM 0 /* does not work for NES */ #define CRT_DO_VSYNC 1 /* look for VSYNC */ #define CRT_DO_HSYNC 1 /* look for HSYNC */ +/* common monitor settings */ +#define CRT_HUE 0 +#define CRT_BRIGHTNESS 10 +#define CRT_CONTRAST 180 +#define CRT_SATURATION 10 +#define CRT_BLACK_PT 0 +#define CRT_WHITE_PT 100 + +#define CRT_BLEND 0 /* blend new field onto previous image */ +#define CRT_V_FAC 0 /* factor to stretch img vertically onto the output img */ + struct CRT { signed char analog[CRT_INPUT_SIZE]; signed char inp[CRT_INPUT_SIZE]; /* CRT input, can be noisy */ int outw, outh; /* output width/height */ - int out_format; /* output pixel format (one of the CRT_PIX_FORMATs) */ unsigned char *out; /* output image */ - int hue, brightness, contrast, saturation; /* common monitor settings */ - int black_point, white_point; /* user-adjustable */ int scanlines; /* leave gaps between lines if necessary */ - int blend; /* blend new field onto previous image */ - unsigned v_fac; /* factor to stretch img vertically onto the output img */ + int progressive; /* render both fields, interlaced, onto single image (requires calling crt_demodulate twice per frame)*/ /* internal data */ int ccf[CRT_CC_VPER][CRT_CC_SAMPLES]; /* faster color carrier convergence */ @@ -97,15 +99,14 @@ * f - format of the output image * out - pointer to output image data */ -extern void crt_init(struct CRT *v, int w, int h, int f, unsigned char *out); +extern void crt_init(struct CRT *v, int w, int h, unsigned char *out); /* Updates the output image parameters * w - width of the output image * h - height of the output image - * f - format of the output image * out - pointer to output image data */ -extern void crt_resize(struct CRT *v, int w, int h, int f, unsigned char *out); +extern void crt_resize(struct CRT *v, int w, int h, unsigned char *out); /* Resets the CRT settings back to their defaults */ extern void crt_reset(struct CRT *v); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/ntsc/crt_ntsc.c new/frei0r-3.4.0/src/filter/ntsc/crt_ntsc.c --- old/frei0r-3.2.3/src/filter/ntsc/crt_ntsc.c 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/src/filter/ntsc/crt_ntsc.c 2026-08-18 13:34:08.000000000 +0200 @@ -137,7 +137,6 @@ int ccburst[CRT_CC_SAMPLES]; /* color phase for burst */ int sn, cs, n, ph; int inv_phase = 0; - int bpp; if (!s->iirs_initialized) { init_iir(&iirY, L_FREQ, Y_FREQ); @@ -146,7 +145,7 @@ s->iirs_initialized = 1; } #if CRT_DO_BLOOM - if (s->raw) { +#if NTSC_RAW destw = s->w; desth = s->h; if (destw > ((AV_LEN * 55500) >> 16)) { @@ -155,12 +154,12 @@ if (desth > ((CRT_LINES * 63500) >> 16)) { desth = ((CRT_LINES * 63500) >> 16); } - } else { +#else destw = (AV_LEN * 55500) >> 16; desth = (CRT_LINES * 63500) >> 16; - } +#endif #else - if (s->raw) { +#if NTSC_RAW destw = s->w; desth = s->h; if (destw > AV_LEN) { @@ -169,11 +168,11 @@ if (desth > ((CRT_LINES * 64500) >> 16)) { desth = ((CRT_LINES * 64500) >> 16); } - } #endif - if (s->as_color) { +#endif +#if NTSC_AS_COLOR for (x = 0; x < CRT_CC_SAMPLES; x++) { - n = s->hue + x * (360 / CRT_CC_SAMPLES); + n = NTSC_HUE + x * (360 / CRT_CC_SAMPLES); crt_sincos14(&sn, &cs, (n + 33) * 8192 / 180); ccburst[x] = sn >> 10; crt_sincos14(&sn, &cs, n * 8192 / 180); @@ -181,18 +180,14 @@ crt_sincos14(&sn, &cs, (n - 90) * 8192 / 180); ccmodQ[x] = sn >> 10; } - } else { +#else memset(ccburst, 0, sizeof(ccburst)); memset(ccmodI, 0, sizeof(ccmodI)); memset(ccmodQ, 0, sizeof(ccmodQ)); - } +#endif - bpp = crt_bpp4fmt(s->format); - if (bpp == 0) { - return; /* just to be safe */ - } - xo = AV_BEG + s->xoffset + (AV_LEN - destw) / 2; - yo = CRT_TOP + s->yoffset + (CRT_LINES - desth) / 2; + xo = AV_BEG + NTSC_X_OFFSET + (AV_LEN - destw) / 2; + yo = CRT_TOP + NTSC_Y_OFFSET + (CRT_LINES - desth) / 2; s->field &= 1; s->frame &= 1; @@ -275,47 +270,24 @@ int ire; /* composite signal */ int xoff; - pix = s->data + ((((x * s->w) / destw) + sy) * bpp); - switch (s->format) { - case CRT_PIX_FORMAT_RGB: - case CRT_PIX_FORMAT_RGBA: - rA = pix[0]; - gA = pix[1]; - bA = pix[2]; - break; - case CRT_PIX_FORMAT_BGR: - case CRT_PIX_FORMAT_BGRA: - rA = pix[2]; - gA = pix[1]; - bA = pix[0]; - break; - case CRT_PIX_FORMAT_ARGB: - rA = pix[1]; - gA = pix[2]; - bA = pix[3]; - break; - case CRT_PIX_FORMAT_ABGR: - rA = pix[3]; - gA = pix[2]; - bA = pix[1]; - break; - default: - rA = gA = bA = 0; - break; - } + pix = s->data + ((((x * s->w) / destw) + sy) * CRT_BPP); + + rA = pix[0]; + gA = pix[1]; + bA = pix[2]; /* RGB to YIQ */ fy = (19595 * rA + 38470 * gA + 7471 * bA) >> 14; fi = (39059 * rA - 18022 * gA - 21103 * bA) >> 14; fq = (13894 * rA - 34275 * gA + 20382 * bA) >> 14; - ire = BLACK_LEVEL + v->black_point; + ire = BLACK_LEVEL + CRT_BLACK_PT; xoff = (x + xo) % CRT_CC_SAMPLES; /* bandlimit Y,I,Q */ fy = iirf(&iirY, fy); fi = iirf(&iirI, fi) * ph * ccmodI[xoff] >> 4; fq = iirf(&iirQ, fq) * ph * ccmodQ[xoff] >> 4; - ire += (fy + fi + fq) * (WHITE_LEVEL * v->white_point / 100) >> 10; + ire += (fy + fi + fq) * (WHITE_LEVEL * CRT_WHITE_PT / 100) >> 10; if (ire < 0) ire = 0; if (ire > 110) ire = 110; @@ -328,4 +300,4 @@ } } } -#endif +#endif \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/ntsc/crt_ntsc.h new/frei0r-3.4.0/src/filter/ntsc/crt_ntsc.h --- old/frei0r-3.2.3/src/filter/ntsc/crt_ntsc.h 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/src/filter/ntsc/crt_ntsc.h 2026-08-18 13:34:08.000000000 +0200 @@ -108,17 +108,17 @@ #define BLANK_LEVEL 0 #define SYNC_LEVEL -40 +#define NTSC_RAW 0 /* 0 = scale image to fit monitor, 1 = don't scale */ +#define NTSC_AS_COLOR 1 /* 0 = monochrome, 1 = full color */ +#define NTSC_HUE 0 /* 0-359 */ +#define NTSC_X_OFFSET 0 /* x offset in sample space. 0 is minimum value */ +#define NTSC_Y_OFFSET 0 /* y offset in # of lines. 0 is minimum value */ + struct NTSC_SETTINGS { const unsigned char *data; /* image data */ - int format; /* pix format (one of the CRT_PIX_FORMATs in crt_core.h) */ int w, h; /* width and height of image */ - int raw; /* 0 = scale image to fit monitor, 1 = don't scale */ - int as_color; /* 0 = monochrome, 1 = full color */ int field; /* 0 = even, 1 = odd */ int frame; /* 0 = even, 1 = odd */ - int hue; /* 0-359 */ - int xoffset; /* x offset in sample space. 0 is minimum value */ - int yoffset; /* y offset in # of lines. 0 is minimum value */ /* make sure your NTSC_SETTINGS struct is zeroed out before you do anything */ int iirs_initialized; /* internal state */ }; @@ -127,4 +127,4 @@ } #endif -#endif +#endif \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/ntsc/ntsc-effect.c new/frei0r-3.4.0/src/filter/ntsc/ntsc-effect.c --- old/frei0r-3.2.3/src/filter/ntsc/ntsc-effect.c 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/src/filter/ntsc/ntsc-effect.c 2026-08-18 13:34:08.000000000 +0200 @@ -21,7 +21,6 @@ int noise; int field; - int progressive; } ntsc_instance_t; @@ -81,25 +80,18 @@ inst->width = width; inst->height = height; - inst->ntsc.format = CRT_PIX_FORMAT_RGBA; inst->ntsc.w = width; inst->ntsc.h = height; - inst->ntsc.raw = 0; inst->ntsc.field = 0; inst->ntsc.frame = 0; - inst->ntsc.as_color = 1; - inst->ntsc.hue = 0; - inst->ntsc.xoffset = 0; - inst->ntsc.yoffset = 0; inst->ntsc.iirs_initialized = 0; inst->noise = 0; - inst->progressive = 0; inst->field = 0; - crt_init(&(inst->crt), width, height, CRT_PIX_FORMAT_RGBA, NULL); - inst->crt.blend = 0; + crt_init(&(inst->crt), width, height, NULL); inst->crt.scanlines = 0; + inst->crt.progressive = 0; @@ -122,7 +114,7 @@ inst->noise = *((double*)param) * 200; break; case 1: - inst->progressive = (*((double*)param) >= 0.5); + inst->crt.progressive = (*((double*)param) >= 0.5); break; case 2: inst->crt.scanlines = (*((double*)param) >= 0.5); @@ -139,7 +131,7 @@ *((double*)param) = (inst->noise / 200); break; case 1: - *((double*)param) = (inst->progressive ? 1.0 : 0.0); + *((double*)param) = (inst->crt.progressive ? 1.0 : 0.0); break; case 2: *((double*)param) = (inst->crt.scanlines ? 1.0 : 0.0); @@ -147,19 +139,17 @@ } } - void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) { ntsc_instance_t* inst = (ntsc_instance_t*)instance; // clear the output frame memset(outframe, 0, inst->width * inst->height * sizeof(uint32_t)); - inst->crt.blend = 0; // set everything up for the simulation inst->crt.out = (char*)outframe; inst->ntsc.data = (const char*)inframe; - + _render_field: inst->ntsc.field = inst->field & 1; @@ -175,13 +165,7 @@ inst->field ^= 1; // if we are in progressive mode, we render both fields onto the frame. // in interlaced mode, we will hit the opposite field on the next frame. - if(inst->field && inst->progressive) - { - // if we are not leaving scanlines blank, we will want to blend the frames in progressive mode - if(!inst->crt.scanlines) - { - inst->crt.blend = 1; - } + if (inst->field && inst->crt.progressive) { goto _render_field; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/pixels0rt/CMakeLists.txt new/frei0r-3.4.0/src/filter/pixels0rt/CMakeLists.txt --- old/frei0r-3.2.3/src/filter/pixels0rt/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/frei0r-3.4.0/src/filter/pixels0rt/CMakeLists.txt 2026-08-18 13:34:08.000000000 +0200 @@ -0,0 +1,11 @@ +set (SOURCES pixels0rt.c) +set (TARGET pixels0rt) + +if (MSVC) + set (SOURCES ${SOURCES} ${FREI0R_DEF}) +endif (MSVC) + +add_library (${TARGET} MODULE ${SOURCES}) +set_target_properties (${TARGET} PROPERTIES PREFIX "") + +install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/pixels0rt/pixels0rt.c new/frei0r-3.4.0/src/filter/pixels0rt/pixels0rt.c --- old/frei0r-3.2.3/src/filter/pixels0rt/pixels0rt.c 1970-01-01 01:00:00.000000000 +0100 +++ new/frei0r-3.4.0/src/filter/pixels0rt/pixels0rt.c 2026-08-18 13:34:08.000000000 +0200 @@ -0,0 +1,418 @@ +/* pixels0rt.c + * Copyright (C) 2026 Asterleen ~ https://asterleen.com + * Implements a pixel sorting effect + * + * This file is a Frei0r plugin. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <stdio.h> + +#include "frei0r.h" + +#define S0RT_PARAM_THRESHOLD 0 +#define S0RT_PARAM_DIRECTION 1 +#define S0RT_PARAM_REVERSED 2 +#define S0RT_PARAM_ALPHA_THR 3 + +typedef enum pixels0rt_direction +{ + S0RT_DIRECTION_VER_TOP, // vertical, from top to bottom + S0RT_DIRECTION_VER_BOTTOM, // vertical, from bottom to top + S0RT_DIRECTION_HOR_LEFT, // horizontal, from left to right + S0RT_DIRECTION_HOR_RIGHT, // horizontal, from right to left + + S0RT_DIRECTION_COUNT // total number of possible directions + +} pixels0rt_direction_t; + + +typedef struct pixels0rt_instance +{ + unsigned int width; + unsigned int height; + + uint8_t *grayscale_px; // the frame in grayscale, will be used for radix sort + + float threshold; + float alpha_threshold; + short int reversed; + pixels0rt_direction_t direction; + +} pixels0rt_instance_t; + +inline static uint8_t pixel_grayscale(uint32_t px) +{ + uint8_t *pxSplit = (uint8_t *)&px; + + return ((pxSplit[0] & 0xFF) + + (pxSplit[1] & 0xFF) + + (pxSplit[2] & 0xFF)) / 3; +} + +inline static short pixel_alpha_threshold(uint32_t px, float threshold) +{ + uint8_t *pxSplit = (uint8_t *)&px; + + return pxSplit[3] / 0xFF >= threshold; +} + +inline static double pixel_diff(uint32_t px1, uint32_t px2) +{ + uint8_t *px1_split = (uint8_t *)&px1; + uint8_t *px2_split = (uint8_t *)&px2; + + return ( + abs(px1_split[0] - px2_split[0]) + + abs(px1_split[1] - px2_split[1]) + + abs(px1_split[2] - px2_split[2]) + ) / 765.0; +} + +int f0r_init() +{ + return 1; +} + +void f0r_deinit() +{ /* no initialization required */ } + +void f0r_get_plugin_info(f0r_plugin_info_t* pixels0rtInfo) +{ + pixels0rtInfo->name = "pixels0rt"; + pixels0rtInfo->author = "Asterleen"; + pixels0rtInfo->plugin_type = F0R_PLUGIN_TYPE_FILTER; + pixels0rtInfo->color_model = F0R_COLOR_MODEL_RGBA8888; + pixels0rtInfo->frei0r_version = FREI0R_MAJOR_VERSION; + pixels0rtInfo->major_version = 1; + pixels0rtInfo->minor_version = 0; + pixels0rtInfo->num_params = 4; + pixels0rtInfo->explanation = "Pixel sorting effect"; +} + +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ + switch(param_index) { + case S0RT_PARAM_THRESHOLD: + { + info->name = "Threshold"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Relative size of the line that will be sorted"; + break; + } + + case S0RT_PARAM_DIRECTION: + { + info->name = "Direction"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Sorting direction"; + break; + } + + case S0RT_PARAM_REVERSED: + { + info->name = "Reversed"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Should be pixels sorted in reversed order"; + break; + } + + case S0RT_PARAM_ALPHA_THR: + { + info->name = "Transparency threshold"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "What transparency level should be bypassed by the filter. 0 processes all pixels, 1 ignores all transparent pixels"; + break; + } + } +} + +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ + pixels0rt_instance_t* inst = (pixels0rt_instance_t*)calloc(1, sizeof(*inst)); + inst->width = width; + inst->height = height; + inst->threshold = 0.3; + inst->alpha_threshold = 1.0; + inst->direction = S0RT_DIRECTION_VER_TOP; + inst->reversed = 0; + + inst->grayscale_px = malloc(width * height * sizeof(uint8_t)); + + return (f0r_instance_t)inst; +} + +void f0r_destruct(f0r_instance_t instance) +{ + pixels0rt_instance_t *inst = (pixels0rt_instance_t*)instance; + + free(inst->grayscale_px); + + free(instance); +} + +void f0r_set_param_value(f0r_instance_t instance, + f0r_param_t param, int param_index) +{ + assert(instance); + pixels0rt_instance_t *inst = (pixels0rt_instance_t*)instance; + + switch (param_index) + { + case S0RT_PARAM_THRESHOLD: + { + inst->threshold = *((double*)param); + break; + } + + case S0RT_PARAM_DIRECTION: + { + inst->direction = (pixels0rt_direction_t)(*((double*)param) * S0RT_DIRECTION_COUNT); + break; + } + + case S0RT_PARAM_REVERSED: + { + inst->reversed = *((double*)param) >= 0.5; + break; + } + + case S0RT_PARAM_ALPHA_THR: + { + inst->alpha_threshold = *((double*)param); + break; + } + } +} + +void f0r_get_param_value(f0r_instance_t instance, + f0r_param_t param, int param_index) +{ + + assert(instance); + pixels0rt_instance_t *inst = (pixels0rt_instance_t*)instance; + + switch (param_index) + { + case S0RT_PARAM_THRESHOLD: + { + *((double*)param) = inst->threshold; + break; + } + + case S0RT_PARAM_DIRECTION: + { + *((double*)param) = inst->direction / S0RT_DIRECTION_COUNT; + break; + } + + case S0RT_PARAM_REVERSED: + { + *((double*)param) = inst->reversed ? 1. : 0.; + break; + } + + case S0RT_PARAM_ALPHA_THR: + { + *((double*)param) = inst->alpha_threshold; + break; + } + } + +} + +inline static void s0rt_line_horizontal( + const uint32_t *src, + uint32_t *dst, + uint8_t *gray, + unsigned int line, + unsigned int start, + unsigned int end) +{ + unsigned int length = end - start; + unsigned int line_start = line + start; + + uint32_t histogram[256] = {0}; + + for (int i = 0; i < length; i++) + histogram[gray[line_start + i]]++; + + for (int i = 1; i < 256; i++) + histogram[i] += histogram[i - 1]; + + for (int i = length; i-- > 0;) + { + uint8_t key = gray[line_start + i]; + dst[line_start + (--histogram[key])] = src[line_start + i]; + } +} + +inline static void s0rt_line_vertical( + const uint32_t *src, + uint32_t *dst, + uint8_t *gray, + unsigned int width, + unsigned int column, + unsigned int start, + unsigned int end) +{ + unsigned int length = end - start; + + uint32_t histogram[256] = {0}; + + for (int i = 0; i < length; i++) + histogram[gray[(start + i) * width + column]]++; + + for (int i = 1; i < 256; i++) + histogram[i] += histogram[i - 1]; + + for (int i = length; i-- > 0;) + { + uint8_t key = gray[(start + i) * width + column]; + dst[(start + (--histogram[key])) * width + column] = src[(start + i) * width + column]; + } +} + + +void f0r_update(f0r_instance_t instance, double time, + const uint32_t* src, uint32_t* dst) +{ + assert(instance); + pixels0rt_instance_t* inst = (pixels0rt_instance_t*)instance; + + unsigned int size = inst->width * inst->height; + + double px_diff = 0.0; + unsigned int line_idx; + unsigned int next_pos = 0; + + if (inst->reversed) { + for (int i = 0; i < size; i++) + inst->grayscale_px[i] = 255 - pixel_grayscale(src[i]); + } else { + for (int i = 0; i < size; i++) + inst->grayscale_px[i] = pixel_grayscale(src[i]); + } + + switch (inst->direction) { + case S0RT_DIRECTION_VER_TOP: + { + for (int column = 0; column < inst->width; column++) { + next_pos = 0; + + for (int i = 0; i < inst->height; i++) { + if (pixel_alpha_threshold(src[i * inst->width + column], inst->alpha_threshold)) { + px_diff = pixel_diff(src[next_pos * inst->width + column], src[i * inst->width + column]); + + if (px_diff > inst->threshold || + (i < inst->height - 2 && !pixel_alpha_threshold(src[(i + 1) * inst->width + column], inst->alpha_threshold)) || + i == inst->height - 1) { + s0rt_line_vertical(src, dst, inst->grayscale_px, inst->width, column, next_pos, i); + next_pos = i; + } + } else { + dst[i * inst->width + column] = src[i * inst->width + column]; + next_pos = i; + } + } + } + + break; + } + + case S0RT_DIRECTION_VER_BOTTOM: + { + for (int column = 0; column < inst->width; column++) { + next_pos = inst->height - 1; + + for (int i = inst->height - 1; i >= 0; i--) { + + if (pixel_alpha_threshold(src[i * inst->width + column], inst->alpha_threshold)) { + px_diff = pixel_diff(src[next_pos * inst->width + column], src[i * inst->width + column]); + + if (px_diff > inst->threshold || + (i > 0 && !pixel_alpha_threshold(src[(i - 1) * inst->width + column], inst->alpha_threshold)) || + i == 0) { + s0rt_line_vertical(src, dst, inst->grayscale_px, inst->width, column, i, next_pos); + next_pos = i; + } + } else { + dst[i * inst->width + column] = src[i * inst->width + column]; + next_pos = i; + } + } + } + + break; + } + + + case S0RT_DIRECTION_HOR_LEFT: + { + for (int line = 0; line < inst->height; line++) { + next_pos = 0; + line_idx = line * inst->width; + + for (int i = 0; i < inst->width; i++) { + if (pixel_alpha_threshold(src[line_idx + i], inst->alpha_threshold)) { + px_diff = pixel_diff(src[line_idx + next_pos], src[line_idx + i]); + + if (px_diff > inst->threshold || + (i < inst->width - 2 && !pixel_alpha_threshold(src[line_idx + i + 1], inst->alpha_threshold)) || + i == inst->width - 1) { + s0rt_line_horizontal(src, dst, inst->grayscale_px, line_idx, next_pos, i); + next_pos = i; + } + } else { + dst[line_idx + i] = src[line_idx + i]; + next_pos = i; + } + } + } + + break; + } + + case S0RT_DIRECTION_HOR_RIGHT: + { + for (int line = 0; line < inst->height; line++) { + next_pos = inst->width - 1; + line_idx = line * inst->width; + + for (int i = inst->width - 1; i >= 0; i--) { + if (pixel_alpha_threshold(src[line_idx + i], inst->alpha_threshold)) { + px_diff = pixel_diff(src[line_idx + next_pos], src[line_idx + i]); + + if (px_diff > inst->threshold || + (i > 0 && !pixel_alpha_threshold(src[line_idx + i - 1], inst->alpha_threshold)) || + i == 0) { + s0rt_line_horizontal(src, dst, inst->grayscale_px, line_idx, i, next_pos); + next_pos = i; + } + } else { + dst[line_idx + i] = src[line_idx + i]; + next_pos = i; + } + } + } + + break; + } + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/shake0scillate/CMakeLists.txt new/frei0r-3.4.0/src/filter/shake0scillate/CMakeLists.txt --- old/frei0r-3.2.3/src/filter/shake0scillate/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/frei0r-3.4.0/src/filter/shake0scillate/CMakeLists.txt 2026-08-18 13:34:08.000000000 +0200 @@ -0,0 +1,15 @@ +set (SOURCES shake0scillate.cpp) +set (TARGET shake0scillate) + +include_directories(${Cairo_INCLUDE_DIR}) +set(LIBS ${LIBS} ${Cairo_LIBRARY}) + +if (MSVC) + set (SOURCES ${SOURCES} ${FREI0R_DEF}) +endif (MSVC) + +add_library (${TARGET} MODULE ${SOURCES}) + +set_target_properties (${TARGET} PROPERTIES PREFIX "") +target_link_libraries(shake0scillate ${LIBS}) +install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/src/filter/shake0scillate/shake0scillate.cpp new/frei0r-3.4.0/src/filter/shake0scillate/shake0scillate.cpp --- old/frei0r-3.2.3/src/filter/shake0scillate/shake0scillate.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/frei0r-3.4.0/src/filter/shake0scillate/shake0scillate.cpp 2026-08-18 13:34:08.000000000 +0200 @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2024 Johann JEG ([email protected]) + * + * This file is a Frei0r plugin. + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "frei0r.hpp" +#include <cairo.h> +#define _USE_MATH_DEFINES +#include <math.h> + +class Shake0scillate : public frei0r::filter { + +private: + + double movement_amount_x; + double movement_speed_x; + double movement_amount_y; + double movement_speed_y; + double rotation_amount; + double rotation_speed; + double scale; + double phase; + bool mirrored; + + const float MOVEMENT_AMOUNT_MULTIPLIER = 0.3f; + const float ROTATION_AMOUNT_MULTIPLIER = 0.2f; + const float SPEED_MULTIPLIER = 10.0f; + +public: + + Shake0scillate(unsigned int width, unsigned int height) { + register_param(this->movement_amount_x, "movement_amount_x", "Amount of the X movement."); + register_param(this->movement_speed_x, "movement_speed_x", "X Movement Speed."); + register_param(this->movement_amount_y, "movement_amount_y", "Amount of the Y movement."); + register_param(this->movement_speed_y, "movement_speed_y", "Y Movement Speed."); + register_param(this->rotation_amount, "rotation_amount", "Rotation amount."); + register_param(this->rotation_speed, "rotation_speed", "Rotation Speed."); + register_param(this->scale, "scale", "Scale level."); + register_param(this->phase, "phase", "The phase of the sin and cos functions of this effect."); + register_param(this->mirrored, "mirrored", "On/Off Image Mirror Extend"); + + this->movement_amount_x = 0.5; // Movement amount off is 0.5 + this->movement_speed_x = 0.2; + this->movement_amount_y = 0.5; // Movement amount off is 0.5 + this->movement_speed_y = 0.1; + this->rotation_amount = 0.5; // Rotation amount off is 0.5 + this->rotation_speed = 0.2; + this->scale = 0.5; // Original image size is 0.5 + this->phase = 0.0; + this->mirrored = true; + } + + ~Shake0scillate() { + + } + + void clearScreen(cairo_t* cr) { + cairo_save (cr); + cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + cairo_restore (cr); + } + + void oscillate(cairo_matrix_t* matrix, double time) { + float x = 0.0f; + float y = 0.0f; + + // Operations for the translation amount do not depend on the screen size + float movement_range_x = MOVEMENT_AMOUNT_MULTIPLIER * this->height; + float movement_range_y = MOVEMENT_AMOUNT_MULTIPLIER * this->width; + + // Translate X + if(this->movement_amount_x != 0.5){ + float movement_x = (this->movement_amount_x - 0.5f) * 2.0f; + float movement_speed_value_x = this->movement_speed_x * SPEED_MULTIPLIER * time; + x = movement_x * movement_range_x * std::sin(movement_speed_value_x + this->phase); + } + + // Translate Y + if(this->movement_amount_y != 0.5){ + float movement_y = (this->movement_amount_y - 0.5f) * 2.0f; + float movement_speed_value_y = this->movement_speed_y * SPEED_MULTIPLIER * time; + y = movement_y * movement_range_y * std::cos(movement_speed_value_y + this->phase); + } + + // Translate by adding the half screen coordinates to scale and rotate from center + float center_x = this->width / 2.0f; + float center_y = this->height / 2.0f; + cairo_matrix_translate(matrix, center_x + x, center_y + y); + + // Scale + if(this->scale != 0.5){ + float scale_factor = 1.5f - this->scale; + cairo_matrix_scale(matrix, scale_factor, scale_factor); + } + + // Rotation + if(this->rotation_amount != 0.5){ + float rotation_speed_value = (this->rotation_speed * SPEED_MULTIPLIER * time) + this->phase; + float rotation = ((this->rotation_amount - 0.5f) * ROTATION_AMOUNT_MULTIPLIER) * std::sin(rotation_speed_value) * M_PI; + cairo_matrix_rotate(matrix, rotation); + } + + // Restore translate coordinates + cairo_matrix_translate(matrix, -center_x, -center_y); + } + + virtual void update(double time, uint32_t* out, const uint32_t* in) { + int w = this->width; + int h = this->height; + + // Calculate the stride for the image surface based on width and format + int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w); + + // Create a Cairo surface for the destination image + cairo_surface_t* dest_image = cairo_image_surface_create_for_data((unsigned char*)out, + CAIRO_FORMAT_ARGB32, + w, + h, + stride); + + // Create a Cairo drawing context for the destination surface + cairo_t *cr = cairo_create(dest_image); + + // Clear the screen + clearScreen(cr); + + // Create a Cairo surface for the source image + cairo_surface_t *image = cairo_image_surface_create_for_data((unsigned char*)in, + CAIRO_FORMAT_ARGB32, + w, + h, + stride); + + // Create a pattern from the source image surface + cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image); + + if(this->mirrored){ + // Set the pattern extend mode to reflect (mirror) when the pattern is out of bounds + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REFLECT); + } else { + // Set the pattern extend mode to none (mirroring does not apply) + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE); + } + + // Initialize the transformation matrix + cairo_matrix_t matrix; + cairo_matrix_init_identity(&matrix); + + // Call the function that applies the movement + oscillate(&matrix, time); + + // Set the transformation matrix for the pattern + cairo_pattern_set_matrix(pattern, &matrix); + // Set the source pattern to be used for drawing + cairo_set_source(cr, pattern); + + // Draw a rectangle covering the entire image area + cairo_rectangle(cr, 0, 0, w, h); + // Fill the rectangle with the source pattern + cairo_fill(cr); + + // Clean up resources + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); + cairo_surface_destroy (dest_image); + cairo_destroy (cr); + } +}; + +frei0r::construct<Shake0scillate> plugin( + "Shake0scillate", + "Animate the input image with adjustable parameters such as amount, speed, rotation, scale and option to mirror the image if it goes outside the screen bounds.", + "Johann JEG", + 1, 0, + F0R_COLOR_MODEL_RGBA8888); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/frei0r-3.2.3/test/CMakeLists.txt new/frei0r-3.4.0/test/CMakeLists.txt --- old/frei0r-3.2.3/test/CMakeLists.txt 2026-06-27 11:37:42.000000000 +0200 +++ new/frei0r-3.4.0/test/CMakeLists.txt 2026-08-18 13:34:08.000000000 +0200 @@ -48,6 +48,8 @@ foreach(dir ${DIRS}) get_directory_property(targets DIRECTORY "${dir}" BUILDSYSTEM_TARGETS) foreach(target ${targets}) + # Targeted plugin builds must also produce the runner used to inspect them. + add_dependencies(${target} frei0r-run) add_test( NAME "${target}" COMMAND "${CMAKE_BINARY_DIR}/test/frei0r-run" ${TESTFLAGS} -p "$<TARGET_FILE:${target}>"
