mirror of
https://github.com/dyne/frei0r.git
synced 2025-12-05 22:29:59 +01:00
Add glitch0r plugin (#7)
* Add glitch0r plugin * glitch0r: Fixups according to review
This commit is contained in:
committed by
Dan Dennedy
parent
1ce7383db8
commit
79239c58e5
1
.gitignore
vendored
1
.gitignore
vendored
@@ -23,6 +23,7 @@ tags
|
|||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
|
install_manifest.txt
|
||||||
*~
|
*~
|
||||||
Makefile.in
|
Makefile.in
|
||||||
Makefile
|
Makefile
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ plugin_LTLIBRARIES = \
|
|||||||
G.la \
|
G.la \
|
||||||
gamma.la \
|
gamma.la \
|
||||||
glow.la \
|
glow.la \
|
||||||
|
glitch0r.la \
|
||||||
grain_extract.la \
|
grain_extract.la \
|
||||||
grain_merge.la \
|
grain_merge.la \
|
||||||
hardlight.la \
|
hardlight.la \
|
||||||
@@ -222,6 +223,7 @@ flippo_la_SOURCES = filter/flippo/flippo.c
|
|||||||
G_la_SOURCES = filter/RGB/G.c
|
G_la_SOURCES = filter/RGB/G.c
|
||||||
gamma_la_SOURCES = filter/gamma/gamma.c
|
gamma_la_SOURCES = filter/gamma/gamma.c
|
||||||
glow_la_SOURCES = filter/glow/glow.c
|
glow_la_SOURCES = filter/glow/glow.c
|
||||||
|
glitch0r_la_SOURCES = filter/glitch0r/glitch0r.c
|
||||||
hqdn3d_la_SOURCES = filter/denoise/hqdn3d.c
|
hqdn3d_la_SOURCES = filter/denoise/hqdn3d.c
|
||||||
hueshift0r_la_SOURCES = filter/hueshift0r/hueshift0r.c filter/hueshift0r/matrix.h
|
hueshift0r_la_SOURCES = filter/hueshift0r/hueshift0r.c filter/hueshift0r/matrix.h
|
||||||
IIRblur_la_SOURCES = filter/blur/IIRblur.c filter/blur/fibe.h
|
IIRblur_la_SOURCES = filter/blur/IIRblur.c filter/blur/fibe.h
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ add_subdirectory (equaliz0r)
|
|||||||
add_subdirectory (flippo)
|
add_subdirectory (flippo)
|
||||||
add_subdirectory (gamma)
|
add_subdirectory (gamma)
|
||||||
add_subdirectory (glow)
|
add_subdirectory (glow)
|
||||||
|
add_subdirectory (glitch0r)
|
||||||
#add_subdirectory (host_param_test)
|
#add_subdirectory (host_param_test)
|
||||||
add_subdirectory (hueshift0r)
|
add_subdirectory (hueshift0r)
|
||||||
add_subdirectory (invert0r)
|
add_subdirectory (invert0r)
|
||||||
|
|||||||
12
src/filter/glitch0r/CMakeLists.txt
Normal file
12
src/filter/glitch0r/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
set (SOURCES glitch0r.c)
|
||||||
|
set (TARGET glitch0r)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
set_source_files_properties (glitch0r.c PROPERTIES LANGUAGE CXX)
|
||||||
|
set (SOURCES ${SOURCES} ${FREI0R_DEF})
|
||||||
|
endif (MSVC)
|
||||||
|
|
||||||
|
add_library (${TARGET} MODULE ${SOURCES})
|
||||||
|
set_target_properties (${TARGET} PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR})
|
||||||
355
src/filter/glitch0r/glitch0r.c
Normal file
355
src/filter/glitch0r/glitch0r.c
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
/* glitch0r.c
|
||||||
|
* Copyright (C) 2016 IDENT Software ~ http://identsoft.org
|
||||||
|
* Inspired by the test video on frei0r.dune.org
|
||||||
|
*
|
||||||
|
* 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 <time.h>
|
||||||
|
|
||||||
|
#include "frei0r.h"
|
||||||
|
|
||||||
|
/* cheap & fast randomizer (by Fukuchi Kentarou) */
|
||||||
|
static uint32_t randval;
|
||||||
|
inline static uint32_t fastrand() { return (randval=randval*1103515245+12345); };
|
||||||
|
static void fastsrand(uint32_t seed) { randval = seed; };
|
||||||
|
|
||||||
|
struct glitch0r_state // helps to save time when allocating in a loop
|
||||||
|
{
|
||||||
|
unsigned int currentBlock;
|
||||||
|
unsigned int currentPos;
|
||||||
|
unsigned int currentY;
|
||||||
|
unsigned int blkShift;
|
||||||
|
|
||||||
|
uint32_t distortionSeed1;
|
||||||
|
uint32_t distortionSeed2;
|
||||||
|
|
||||||
|
short int howToDistort1;
|
||||||
|
short int howToDistort2;
|
||||||
|
short int passThisLine;
|
||||||
|
} g0r_state;
|
||||||
|
|
||||||
|
typedef struct glitch0r_instance
|
||||||
|
{
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
|
||||||
|
unsigned int maxBlockSize;
|
||||||
|
unsigned int maxBlockShift;
|
||||||
|
|
||||||
|
short int colorGlitchIntensity;
|
||||||
|
short int doColorDistortion;
|
||||||
|
short int glitchChance;
|
||||||
|
} glitch0r_instance_t;
|
||||||
|
|
||||||
|
|
||||||
|
inline static unsigned int rnd (unsigned int min, unsigned int max)
|
||||||
|
{
|
||||||
|
return fastrand() % (max - min + 1) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void glitch0r_state_reset(glitch0r_instance_t *inst)
|
||||||
|
{
|
||||||
|
g0r_state.currentPos = 0;
|
||||||
|
g0r_state.currentBlock = rnd(1, inst->maxBlockSize);
|
||||||
|
g0r_state.blkShift = rnd(1, inst->maxBlockShift);
|
||||||
|
g0r_state.passThisLine = (inst->glitchChance < rnd(1, 101)) ? 1 : 0;
|
||||||
|
|
||||||
|
if (inst->doColorDistortion)
|
||||||
|
{
|
||||||
|
g0r_state.distortionSeed1 = rnd(0x00000000, 0xfffffffe);
|
||||||
|
g0r_state.distortionSeed2 = rnd(0x00000000, 0xfffffffe);
|
||||||
|
g0r_state.howToDistort1 = rnd (0, inst->colorGlitchIntensity);
|
||||||
|
g0r_state.howToDistort2 = rnd (0, inst->colorGlitchIntensity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void glitch0r_pixel_dist0rt (uint32_t *pixel,
|
||||||
|
uint32_t distortionSeed, short int howToDistort)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Save alpha
|
||||||
|
uint8_t *px = (uint8_t *)pixel;
|
||||||
|
uint8_t alpha = px[3];
|
||||||
|
|
||||||
|
// Choose from five levels of madness:
|
||||||
|
switch (howToDistort)
|
||||||
|
{
|
||||||
|
case 0 : return; // ok, let this pixel live (just shift)
|
||||||
|
|
||||||
|
case 1 : // lightest distortion: just invert
|
||||||
|
*(pixel) = ~*(pixel);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2 : // add some unneeded colors
|
||||||
|
*(pixel) = distortionSeed | *(pixel);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3 : // change some colors
|
||||||
|
*(pixel) = distortionSeed ^ *(pixel);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4 : // oh shi...
|
||||||
|
*(pixel) = distortionSeed & *(pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore alpha
|
||||||
|
px[3] = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
int f0r_init()
|
||||||
|
{
|
||||||
|
fastsrand((uint32_t)time(0));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f0r_deinit()
|
||||||
|
{ /* no initialization required */ }
|
||||||
|
|
||||||
|
void f0r_get_plugin_info(f0r_plugin_info_t* glitch0rInfo)
|
||||||
|
{
|
||||||
|
glitch0rInfo->name = "Glitch0r";
|
||||||
|
glitch0rInfo->author = "IDENT Software";
|
||||||
|
glitch0rInfo->plugin_type = F0R_PLUGIN_TYPE_FILTER;
|
||||||
|
glitch0rInfo->color_model = F0R_COLOR_MODEL_RGBA8888;
|
||||||
|
glitch0rInfo->frei0r_version = FREI0R_MAJOR_VERSION;
|
||||||
|
glitch0rInfo->major_version = 0;
|
||||||
|
glitch0rInfo->minor_version = 1;
|
||||||
|
glitch0rInfo->num_params = 4;
|
||||||
|
glitch0rInfo->explanation = "Adds glitches and block shifting";
|
||||||
|
}
|
||||||
|
|
||||||
|
void f0r_get_param_info(f0r_param_info_t* info, int param_index)
|
||||||
|
{
|
||||||
|
switch(param_index) {
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
info->name = "Glitch frequency";
|
||||||
|
info->type = F0R_PARAM_DOUBLE;
|
||||||
|
info->explanation = "How frequently the glitch should be applied";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
info->name = "Block height";
|
||||||
|
info->type = F0R_PARAM_DOUBLE;
|
||||||
|
info->explanation = "Height range of the block that will be shifted/glitched";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
info->name = "Shift intensity";
|
||||||
|
info->type = F0R_PARAM_DOUBLE;
|
||||||
|
info->explanation = "How much we should move blocks when glitching";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
info->name = "Color glitching intensity";
|
||||||
|
info->type = F0R_PARAM_DOUBLE;
|
||||||
|
info->explanation = "How intensive should be color distortion";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
|
||||||
|
{
|
||||||
|
glitch0r_instance_t* inst = (glitch0r_instance_t*)calloc(1, sizeof(*inst));
|
||||||
|
inst->width = width; inst->height = height;
|
||||||
|
inst->maxBlockSize = (unsigned int)(inst->height / 2);
|
||||||
|
inst->maxBlockShift = (unsigned int)(inst->width / 2);
|
||||||
|
inst->colorGlitchIntensity = 3;
|
||||||
|
inst->doColorDistortion = 1;
|
||||||
|
|
||||||
|
glitch0r_state_reset(inst);
|
||||||
|
|
||||||
|
return (f0r_instance_t)inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f0r_destruct(f0r_instance_t instance)
|
||||||
|
{
|
||||||
|
free(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f0r_set_param_value(f0r_instance_t instance,
|
||||||
|
f0r_param_t param, int param_index)
|
||||||
|
{
|
||||||
|
assert(instance);
|
||||||
|
glitch0r_instance_t * inst = (glitch0r_instance_t*)instance;
|
||||||
|
|
||||||
|
switch (param_index)
|
||||||
|
{
|
||||||
|
|
||||||
|
case 0 : // glitch frequency
|
||||||
|
{
|
||||||
|
double glitchChance = *((double*)param);
|
||||||
|
// convert frei0r range [0, 1] to range between 0 and 100
|
||||||
|
glitchChance = (100 * glitchChance);
|
||||||
|
inst->glitchChance = (short int)glitchChance;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1 : // block height
|
||||||
|
{
|
||||||
|
double mbHeight = *((double*)param);
|
||||||
|
// convert frei0r range [0, 1] to range between 1 and maximal height
|
||||||
|
mbHeight = (1 + (inst->height - 1) * mbHeight);
|
||||||
|
inst->maxBlockSize = (unsigned int)mbHeight;
|
||||||
|
|
||||||
|
// zero size is a bad idea
|
||||||
|
if (inst->maxBlockSize == 0)
|
||||||
|
inst->maxBlockSize = (unsigned int)(inst->height / 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2 : // shift intensity
|
||||||
|
{
|
||||||
|
double intensity = *((double*)param);
|
||||||
|
// convert frei0r range [0, 1] to range between 1 and maximal width
|
||||||
|
intensity = (1 + (inst->width - 1) * intensity);
|
||||||
|
inst->maxBlockShift = (unsigned int)intensity;
|
||||||
|
|
||||||
|
// zero shift is a bad idea
|
||||||
|
if (inst->maxBlockShift == 0)
|
||||||
|
inst->maxBlockShift = (unsigned int)(inst->width / 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3 : // color intensity
|
||||||
|
{
|
||||||
|
double intensity = *((double*)param);
|
||||||
|
// convert frei0r range [0, 1] to range between 0 and 5
|
||||||
|
intensity = (5 * intensity);
|
||||||
|
inst->colorGlitchIntensity = (short int)intensity;
|
||||||
|
|
||||||
|
if (inst->colorGlitchIntensity > 0)
|
||||||
|
{
|
||||||
|
inst->doColorDistortion = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inst->doColorDistortion = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f0r_get_param_value(f0r_instance_t instance,
|
||||||
|
f0r_param_t param, int param_index)
|
||||||
|
{
|
||||||
|
|
||||||
|
assert(instance);
|
||||||
|
glitch0r_instance_t * inst = (glitch0r_instance_t*)instance;
|
||||||
|
|
||||||
|
switch (param_index)
|
||||||
|
{
|
||||||
|
case 0 : // glitch frequency
|
||||||
|
{
|
||||||
|
// convert plugin's param to frei0r range
|
||||||
|
*((double*)param) = (inst->glitchChance) / 100;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1 : // block height
|
||||||
|
{
|
||||||
|
// convert plugin's param to frei0r range
|
||||||
|
*((double*)param) = (inst->maxBlockSize - 1.0) / (inst->height - 1.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2 : // block shift intensity
|
||||||
|
{
|
||||||
|
*((double*)param) = (inst->maxBlockShift - 1.0) / (inst->width - 1.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3 : // color glitch intensity
|
||||||
|
{
|
||||||
|
*((double*)param) = (inst->colorGlitchIntensity) / 5; // 5 levels of madness
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void f0r_update(f0r_instance_t instance, double time,
|
||||||
|
const uint32_t* inframe, uint32_t* outframe)
|
||||||
|
{
|
||||||
|
assert(instance);
|
||||||
|
glitch0r_instance_t* inst = (glitch0r_instance_t*)instance;
|
||||||
|
unsigned int x, y;
|
||||||
|
|
||||||
|
uint32_t* dst = outframe;
|
||||||
|
const uint32_t* src = inframe;
|
||||||
|
uint32_t *pixel;
|
||||||
|
|
||||||
|
g0r_state.currentBlock = rnd(1, inst->maxBlockSize);
|
||||||
|
|
||||||
|
for (y = 0; y < inst->height; y++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (g0r_state.currentPos > g0r_state.currentBlock)
|
||||||
|
{
|
||||||
|
glitch0r_state_reset(inst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g0r_state.currentPos++;
|
||||||
|
|
||||||
|
g0r_state.currentY = y*inst->width;
|
||||||
|
pixel = dst + g0r_state.currentY;
|
||||||
|
|
||||||
|
if (g0r_state.passThisLine)
|
||||||
|
{
|
||||||
|
memcpy((uint32_t *)(dst + g0r_state.currentY),
|
||||||
|
(uint32_t *)(src + g0r_state.currentY),
|
||||||
|
(inst->width) * sizeof(uint32_t));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = g0r_state.blkShift; x < (inst->width); x++)
|
||||||
|
{
|
||||||
|
*(pixel) = *(src + g0r_state.currentY + x);
|
||||||
|
|
||||||
|
if (inst->doColorDistortion)
|
||||||
|
glitch0r_pixel_dist0rt(pixel,
|
||||||
|
g0r_state.distortionSeed1, g0r_state.howToDistort1);
|
||||||
|
|
||||||
|
pixel++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = 0; x < g0r_state.blkShift; x++)
|
||||||
|
{
|
||||||
|
*(pixel) = *(src + g0r_state.currentY + x);
|
||||||
|
|
||||||
|
if (inst->doColorDistortion)
|
||||||
|
glitch0r_pixel_dist0rt(pixel,
|
||||||
|
g0r_state.distortionSeed2, g0r_state.howToDistort2);
|
||||||
|
|
||||||
|
pixel++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user