mirror of
https://github.com/dyne/frei0r.git
synced 2025-12-05 14:19:59 +01:00
fix: thread safety issues
- RGBNoise: move global vars (gaussian_lookup, TABLE_INITED, next_gaussian_index, last_in_range) - Glitch0r: move global g0r_state - Cartoon: fix PIXELAT macro to refer to instance address #188 (seems not all filters on that list are unsafe)
This commit is contained in:
@@ -46,7 +46,7 @@ typedef struct {
|
||||
uint32_t size;
|
||||
} ScreenGeometry;
|
||||
|
||||
#define PIXELAT(x1,y1,s) ((s)+(x1)+ yprecal[y1])// (y1)*(geo->w)))
|
||||
#define PIXELAT(x1,y1,s,inst) ((s)+(x1)+ inst->yprecal[y1])// (y1)*(geo->w)))
|
||||
#define GMERROR(cc1,cc2) ((((RED(cc1)-RED(cc2))*(RED(cc1)-RED(cc2))) + \
|
||||
((GREEN(cc1)-GREEN(cc2)) *(GREEN(cc1)-GREEN(cc2))) + \
|
||||
((BLUE(cc1)-BLUE(cc2))*(BLUE(cc1)-BLUE(cc2)))))
|
||||
@@ -155,26 +155,26 @@ long Cartoon::GetMaxContrast(int32_t *src,int x,int y) {
|
||||
long error,max=0;
|
||||
|
||||
/* Assumes PrePixelModify has been run */
|
||||
c1 = *PIXELAT(x-m_diffspace,y,src);
|
||||
c2 = *PIXELAT(x+m_diffspace,y,src);
|
||||
c1 = *PIXELAT(x-m_diffspace,y,src,this);
|
||||
c2 = *PIXELAT(x+m_diffspace,y,src,this);
|
||||
error = GMERROR(c1,c2);
|
||||
if (error>max) max = error;
|
||||
|
||||
c1 = *PIXELAT(x,y-m_diffspace,src);
|
||||
c2 = *PIXELAT(x,y+m_diffspace,src);
|
||||
|
||||
c1 = *PIXELAT(x,y-m_diffspace,src,this);
|
||||
c2 = *PIXELAT(x,y+m_diffspace,src,this);
|
||||
error = GMERROR(c1,c2);
|
||||
if (error>max) max = error;
|
||||
|
||||
c1 = *PIXELAT(x-m_diffspace,y-m_diffspace,src);
|
||||
c2 = *PIXELAT(x+m_diffspace,y+m_diffspace,src);
|
||||
|
||||
c1 = *PIXELAT(x-m_diffspace,y-m_diffspace,src,this);
|
||||
c2 = *PIXELAT(x+m_diffspace,y+m_diffspace,src,this);
|
||||
error = GMERROR(c1,c2);
|
||||
if (error>max) max = error;
|
||||
|
||||
c1 = *PIXELAT(x+m_diffspace,y-m_diffspace,src);
|
||||
c2 = *PIXELAT(x-m_diffspace,y+m_diffspace,src);
|
||||
|
||||
c1 = *PIXELAT(x+m_diffspace,y-m_diffspace,src,this);
|
||||
c2 = *PIXELAT(x-m_diffspace,y+m_diffspace,src,this);
|
||||
error = GMERROR(c1,c2);
|
||||
if (error>max) max = error;
|
||||
|
||||
|
||||
return(max);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ struct glitch0r_state // helps to save time when allocating in a loop
|
||||
short int howToDistort1;
|
||||
short int howToDistort2;
|
||||
short int passThisLine;
|
||||
} g0r_state;
|
||||
};
|
||||
|
||||
typedef struct glitch0r_instance
|
||||
{
|
||||
@@ -58,6 +58,8 @@ typedef struct glitch0r_instance
|
||||
short int colorGlitchIntensity;
|
||||
short int doColorDistortion;
|
||||
short int glitchChance;
|
||||
|
||||
struct glitch0r_state state; // Instance-specific state
|
||||
} glitch0r_instance_t;
|
||||
|
||||
|
||||
@@ -68,17 +70,17 @@ inline static unsigned int rnd (unsigned int min, unsigned int max)
|
||||
|
||||
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;
|
||||
inst->state.currentPos = 0;
|
||||
inst->state.currentBlock = rnd(1, inst->maxBlockSize);
|
||||
inst->state.blkShift = rnd(1, inst->maxBlockShift);
|
||||
inst->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);
|
||||
inst->state.distortionSeed1 = rnd(0x00000000, 0xfffffffe);
|
||||
inst->state.distortionSeed2 = rnd(0x00000000, 0xfffffffe);
|
||||
inst->state.howToDistort1 = rnd (0, inst->colorGlitchIntensity);
|
||||
inst->state.howToDistort2 = rnd (0, inst->colorGlitchIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,42 +313,42 @@ void f0r_update(f0r_instance_t instance, double time,
|
||||
for (y = 0; y < inst->height; y++)
|
||||
{
|
||||
|
||||
if (g0r_state.currentPos > g0r_state.currentBlock)
|
||||
if (inst->state.currentPos > inst->state.currentBlock)
|
||||
{
|
||||
glitch0r_state_reset(inst);
|
||||
}
|
||||
else
|
||||
g0r_state.currentPos++;
|
||||
inst->state.currentPos++;
|
||||
|
||||
g0r_state.currentY = y*inst->width;
|
||||
pixel = dst + g0r_state.currentY;
|
||||
inst->state.currentY = y*inst->width;
|
||||
pixel = dst + inst->state.currentY;
|
||||
|
||||
if (g0r_state.passThisLine)
|
||||
if (inst->state.passThisLine)
|
||||
{
|
||||
memcpy((uint32_t *)(dst + g0r_state.currentY),
|
||||
(uint32_t *)(src + g0r_state.currentY),
|
||||
memcpy((uint32_t *)(dst + inst->state.currentY),
|
||||
(uint32_t *)(src + inst->state.currentY),
|
||||
(inst->width) * sizeof(uint32_t));
|
||||
continue;
|
||||
}
|
||||
|
||||
for (x = g0r_state.blkShift; x < (inst->width); x++)
|
||||
for (x = inst->state.blkShift; x < (inst->width); x++)
|
||||
{
|
||||
*(pixel) = *(src + g0r_state.currentY + x);
|
||||
*(pixel) = *(src + inst->state.currentY + x);
|
||||
|
||||
if (inst->doColorDistortion)
|
||||
glitch0r_pixel_dist0rt(pixel,
|
||||
g0r_state.distortionSeed1, g0r_state.howToDistort1);
|
||||
inst->state.distortionSeed1, inst->state.howToDistort1);
|
||||
|
||||
pixel++;
|
||||
}
|
||||
|
||||
for (x = 0; x < g0r_state.blkShift; x++)
|
||||
for (x = 0; x < inst->state.blkShift; x++)
|
||||
{
|
||||
*(pixel) = *(src + g0r_state.currentY + x);
|
||||
*(pixel) = *(src + inst->state.currentY + x);
|
||||
|
||||
if (inst->doColorDistortion)
|
||||
glitch0r_pixel_dist0rt(pixel,
|
||||
g0r_state.distortionSeed2, g0r_state.howToDistort2);
|
||||
inst->state.distortionSeed2, inst->state.howToDistort2);
|
||||
|
||||
pixel++;
|
||||
}
|
||||
|
||||
@@ -29,17 +29,15 @@
|
||||
#include "frei0r.h"
|
||||
#include "frei0r/math.h"
|
||||
|
||||
static int MY_MAX_RAND = 32767;// I assume RAND_MAX to be at least this big.
|
||||
static double gaussian_lookup[32767];
|
||||
static int TABLE_INITED = 0;
|
||||
static int next_gaussian_index = 0;
|
||||
static int last_in_range = 32766;
|
||||
|
||||
typedef struct rgbnoise_instance
|
||||
{
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
double noise;
|
||||
double gaussian_lookup[32767];
|
||||
int table_inited;
|
||||
int next_gaussian_index;
|
||||
int last_in_range;
|
||||
} rgbnoise_instance_t;
|
||||
|
||||
|
||||
@@ -74,9 +72,12 @@ void f0r_get_param_info(f0r_param_info_t* info, int param_index)
|
||||
f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
|
||||
{
|
||||
rgbnoise_instance_t* inst = (rgbnoise_instance_t*)calloc(1, sizeof(*inst));
|
||||
inst->width = width;
|
||||
inst->width = width;
|
||||
inst->height = height;
|
||||
inst->noise = 0.2;
|
||||
inst->table_inited = 0;
|
||||
inst->next_gaussian_index = 0;
|
||||
inst->last_in_range = 32766;
|
||||
return (f0r_instance_t)inst;
|
||||
}
|
||||
|
||||
@@ -133,53 +134,44 @@ static inline double gauss()
|
||||
return x;
|
||||
}
|
||||
|
||||
static void create_new_lookup_range()
|
||||
static void create_new_lookup_range(rgbnoise_instance_t* inst)
|
||||
{
|
||||
int first, last, tmp;
|
||||
first = rand() % (MY_MAX_RAND - 1);
|
||||
last = rand() % (MY_MAX_RAND - 1);
|
||||
first = rand() % (32767 - 1);
|
||||
last = rand() % (32767 - 1);
|
||||
if (first > last)
|
||||
{
|
||||
tmp = last;
|
||||
last = first;
|
||||
first = tmp;
|
||||
}
|
||||
next_gaussian_index = first;
|
||||
last_in_range = last;
|
||||
inst->next_gaussian_index = first;
|
||||
inst->last_in_range = last;
|
||||
}
|
||||
|
||||
static inline double next_gauss()
|
||||
static inline double next_gauss(rgbnoise_instance_t* inst)
|
||||
{
|
||||
next_gaussian_index++;
|
||||
if (next_gaussian_index >= last_in_range)
|
||||
inst->next_gaussian_index++;
|
||||
if (inst->next_gaussian_index >= inst->last_in_range)
|
||||
{
|
||||
create_new_lookup_range();
|
||||
create_new_lookup_range(inst);
|
||||
}
|
||||
return gaussian_lookup[next_gaussian_index];
|
||||
return inst->gaussian_lookup[inst->next_gaussian_index];
|
||||
}
|
||||
|
||||
static inline int addNoise(int sample, double noise)
|
||||
static inline int addNoise(rgbnoise_instance_t* inst, int sample, double noise)
|
||||
{
|
||||
int byteNoise = 0;
|
||||
int noiseSample = 0;
|
||||
|
||||
byteNoise = (int) (noise * next_gauss());
|
||||
byteNoise = (int) (noise * next_gauss(inst));
|
||||
noiseSample = sample + byteNoise;
|
||||
noiseSample = CLAMP(noiseSample, 0, 255);
|
||||
return noiseSample;
|
||||
}
|
||||
}
|
||||
|
||||
int f0r_init()
|
||||
{
|
||||
if (TABLE_INITED == 0)
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < MY_MAX_RAND; i++)
|
||||
{
|
||||
gaussian_lookup[i] = gauss() * 127.0;
|
||||
}
|
||||
TABLE_INITED = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -189,6 +181,19 @@ void rgb_noise(f0r_instance_t instance, double time,
|
||||
rgbnoise_instance_t* inst = (rgbnoise_instance_t*)instance;
|
||||
unsigned int len = inst->width * inst->height;
|
||||
|
||||
// Initialize the gaussian lookup table if not already done
|
||||
if (inst->table_inited == 0)
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < 32767; i++)
|
||||
{
|
||||
inst->gaussian_lookup[i] = gauss() * 127.0;
|
||||
}
|
||||
inst->table_inited = 1;
|
||||
inst->next_gaussian_index = 0;
|
||||
inst->last_in_range = 32766;
|
||||
}
|
||||
|
||||
unsigned char* dst = (unsigned char*)outframe;
|
||||
const unsigned char* src = (unsigned char*)inframe;
|
||||
|
||||
@@ -197,11 +202,11 @@ void rgb_noise(f0r_instance_t instance, double time,
|
||||
while (len--)
|
||||
{
|
||||
sample = *src++;
|
||||
*dst++ = addNoise(sample, noise);
|
||||
*dst++ = addNoise(inst, sample, noise);
|
||||
sample = *src++;
|
||||
*dst++ = addNoise(sample, noise);
|
||||
*dst++ = addNoise(inst, sample, noise);
|
||||
sample = *src++;
|
||||
*dst++ = addNoise(sample, noise);
|
||||
*dst++ = addNoise(inst, sample, noise);
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user