Add glitch0r plugin (#7)

* Add glitch0r plugin

* glitch0r: Fixups according to review
This commit is contained in:
Akito Iwakura
2016-12-05 04:42:54 +04:00
committed by Dan Dennedy
parent 1ce7383db8
commit 79239c58e5
5 changed files with 371 additions and 0 deletions

1
.gitignore vendored
View File

@@ -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

View File

@@ -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

View File

@@ -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)

View 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})

View 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++;
}
}
}