FloatImg/Fonderie/glitches.c

192 lines
4.3 KiB
C

/*
* glitches.c
* ----------
*
* initially developped for the interpolator
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "../floatimg.h"
#include "glitches.h"
extern int verbosity;
/* -------------------------------------------------------------- */
int kill_a_random_line(FloatImg *pvictime, float fval, int bits)
{
int line, xpos, offset;
float ftmp;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pvictime, bits);
#endif
line = rand() % pvictime->height;
if (verbosity > 2) {
fprintf(stderr, "%s: try to kill line %d\n", __func__, line);
}
offset = pvictime->width * line;
for (xpos=0; xpos<pvictime->width; xpos++) {
if (bits & 1) { ftmp = pvictime->R[offset+xpos] * fval;
pvictime->R[offset+xpos] = sqrt(ftmp); }
else pvictime->R[offset+xpos] = 0.0;
if (bits & 2) { ftmp = pvictime->G[offset+xpos] * fval;
pvictime->G[offset+xpos] = sqrt(ftmp); }
else pvictime->G[offset+xpos] = 0.0;
if (bits & 4) { ftmp = pvictime->B[offset+xpos] * fval;
pvictime->B[offset+xpos] = sqrt(ftmp); }
else pvictime->B[offset+xpos] = 0.0;
}
return 0;
}
/* -------------------------------------------------------------- */
int kill_a_few_lines(FloatImg *who, float fval, int number)
{
int idx, foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %f %d )\n", __func__, who, fval, number);
#endif
/* Frag the pixels */
for (idx=0; idx<number; idx++) {
foo = kill_a_random_line(who, fval, rand() & 0x07);
if (foo) abort();
}
return foo;
}
/* -------------------------------------------------------------- */
int un_petit_flou_8x8(FloatImg *picture, int xpos, int ypos)
{
float sr, sg, sb;
int x, y, off;
/*
* please add boundary check ?
*/
sr = sg = sb = 0.0;
for (y=0; y<8; y++) {
off = xpos + (picture->width * (y+ypos));
for (x=0; x<8; x++) {
sr += picture->R[off];
sg += picture->G[off];
sb += picture->B[off];
off++;
}
}
sr /= 64.0; sg /= 64.0; sb /= 64.0;
for (y=0; y<8; y++) {
off = xpos + (picture->width * (y+ypos));
for (x=0; x<8; x++) {
picture->R[off] = sr;
picture->G[off] = sg;
picture->B[off] = sb;
off++;
}
}
return 0;
}
/* -------------------------------------------------------------- */
int random_blocks(FloatImg *picture, int percent)
{
int x, y;
if ( (picture->width%16) || (picture->height%16) )
{
fprintf(stderr, "%s: %d%d bad dims\n", __func__,
picture->width, picture->height);
}
for (y=0; y<picture->height; y+=16) {
for (x=0; x<picture->width; x+=16) {
if (percent < (rand()%100) ) {
un_petit_flou_8x8(picture, x, y);
un_petit_flou_8x8(picture, x+8, y);
un_petit_flou_8x8(picture, x, y+8);
un_petit_flou_8x8(picture, x+8, y+8);
}
}
}
return 0;
}
/* -------------------------------------------------------------- */
int un_moyen_flou_8x8(FloatImg *picture, int xpos, int ypos)
{
int i, j, x, y;
/*
* please add boundary check ?
*/
for (i=y=0; i<8; i++, y+=8) {
for (j=x=0; j<8; j++, x+=8 ) {
un_petit_flou_8x8(picture, x+xpos, y+ypos);
}
}
return 0;
}
/* -------------------------------------------------------------- */
int poke_a_random_pixel(FloatImg *picz, float fval, int kaboo)
{
return -1;
}
/* -------------------------------------------------------------- */
/*
* used by vertical_singlitch()
*/
static int x_delta(float dy, float phy)
{
float param, fv;
param = dy + phy;
fv = 9.999*sin(param) + 6.666*sin(param*3) + 3.333*sin(param*5);
return (int)fv;
}
/* -------------------------------------------------------------- */
/*
* please explain arguments
*/
int vertical_singlitch(FloatImg *picz, int xpos, float fval,
float omega, float phi)
{
int y, x, w, h;
float dy;
float fv;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d %f %f )\n", __func__, picz,
xpos, omega, phi);
#endif
h = picz->height; w = picz->width;
#define BB 4
for (y=BB; y<h-BB; y++) {
dy = (float)y * omega; /* normalize vertical position */
x = xpos + x_delta(dy, phi); /* add sinus deviation */
/* compute bounding box */
if ( (x>BB) && (x<w-BB) ) {
/* an make the glitch */
fimg_plot_rgb(picz, x, y, fval, fval, fval);
fv = fval / 3.0;
if (rand() & 8)
fimg_plot_rgb(picz, x-1, y, fv, fv, fv);
if (rand() & 8)
fimg_plot_rgb(picz, x+1, y, fv, fv, fv);
}
}
return 0;
}
/* -------------------------------------------------------------- */