|
|
@@ -2859,10 +2859,9 @@ class VHS extends Shader { |
|
|
|
params.add(new Param ("sine y length", INTVAL, 1, 100, new int[]{TRIANG, SINE})); |
|
|
|
params.add(new Param ("bass", INTVAL, -15, 15, new int[]{TRIANG, SINE})); |
|
|
|
params.add(new Param ("treble", INTVAL, -15, 15, new int[]{TRIANG, SINE})); |
|
|
|
|
|
|
|
|
|
|
|
params.add(new Param ("direction", INTVAL, 0, 3, new int[]{RANDOM})); |
|
|
|
directionParamIndex = 4; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void apply() { |
|
|
@@ -2870,8 +2869,8 @@ class VHS extends Shader { |
|
|
|
syl = (int)params.get(1).value; |
|
|
|
bass = (int)params.get(2).value; |
|
|
|
treble = (int)params.get(3).value; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int virtw = canvas.width; |
|
|
|
int virth = canvas.height; |
|
|
|
PImage timg = createImage(canvas.width, canvas.height, RGB); |
|
|
@@ -2987,9 +2986,298 @@ class VHS extends Shader { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
LZ7 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
class LZ7 extends Shader { |
|
|
|
// choose colorspace |
|
|
|
int colorspace = HSB; // HSB or RGB |
|
|
|
// set compressor attributes for each channel in chosen colorspace |
|
|
|
// first number is length of dictionary in LZ77 - values 100 - 4000 |
|
|
|
// second number is length of word (ahead buffer) in LZ77 - about 5% - 50% of dictionary size |
|
|
|
int[][] compressor_attributes = { {2000, 250}, // channel 1 (H or R) |
|
|
|
{50, 10}, // channel 2 (S or G) |
|
|
|
{100, 100} }; // channel 3 (B or B) |
|
|
|
// set number of glitches made for each channel |
|
|
|
// first number is actual number of random change in compressed channel |
|
|
|
// second number is amount of change (values from 0.01 to 4) |
|
|
|
float[][] number_of_glitches = { {5000, 2}, // channel 1 |
|
|
|
{500, 1}, // channel 2 |
|
|
|
{50, 0.1} }; // channel 3 |
|
|
|
|
|
|
|
// working buffer |
|
|
|
PGraphics buffer; |
|
|
|
|
|
|
|
// image |
|
|
|
PImage img; |
|
|
|
|
|
|
|
|
|
|
|
boolean do_blend = false; // blend image after process |
|
|
|
int blend_mode = OVERLAY; // blend type |
|
|
|
|
|
|
|
|
|
|
|
LZ77 comp1, comp2, comp3; |
|
|
|
byte[] cr, cb, cg; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//red channel dictionary size |
|
|
|
//red channel word size |
|
|
|
//red channel randomness |
|
|
|
//red channel amount of change |
|
|
|
|
|
|
|
|
|
|
|
LZ7() { |
|
|
|
name = "fxLZ77"; |
|
|
|
params.add(new Param("dictionary size (red/hue)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("word length (red/hue)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("randomness (red/hue)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("amount of change (red/hue)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("dictionary size (green/saturation)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("word length (green/saturation)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("randomness (green/saturation)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("amount of change (green/saturation)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("dictionary size (blue/brightness)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("word length (blue/brightness)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("randomness (blue/brightness)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("amount of change (blue/brightness)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); |
|
|
|
params.add(new Param("colorspace (rgb / hsb)", INTVAL, 0, 1, new int[]{RANDOM, SQUAR})); |
|
|
|
params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR})); |
|
|
|
params.add(new Param("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM})); |
|
|
|
params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM})); |
|
|
|
directionParamIndex = 15; |
|
|
|
|
|
|
|
rw = canvas.width; |
|
|
|
rh = canvas.height; |
|
|
|
|
|
|
|
buffer = createGraphics(rw, rh); |
|
|
|
buffer.beginDraw(); |
|
|
|
buffer.noStroke(); |
|
|
|
//buffer.smooth(8); |
|
|
|
buffer.background(0); |
|
|
|
buffer.endDraw(); |
|
|
|
img = createImage(canvas.width, canvas.height, RGB); |
|
|
|
|
|
|
|
cr = new byte[rw*rh]; |
|
|
|
cb = new byte[rw*rh]; |
|
|
|
cg = new byte[rw*rh]; |
|
|
|
} |
|
|
|
|
|
|
|
int rw, rh; |
|
|
|
void apply() { |
|
|
|
if (rw != canvas.width || rh != canvas.height) { |
|
|
|
rw = canvas.width; |
|
|
|
rh = canvas.height; |
|
|
|
cr = new byte[rw*rh]; |
|
|
|
cb = new byte[rw*rh]; |
|
|
|
cg = new byte[rw*rh]; |
|
|
|
buffer = createGraphics(rw, rh); |
|
|
|
img.resize(rw, rh); |
|
|
|
} |
|
|
|
img = canvas.get(); |
|
|
|
|
|
|
|
colorspace = (int)params.get(12).value == 0 ?RGB:HSB; |
|
|
|
do_blend = boolean((int)params.get(13).value); |
|
|
|
blend_mode = blends[(int)params.get(14).value]; |
|
|
|
|
|
|
|
|
|
|
|
//red |
|
|
|
compressor_attributes[0][0] = (int)params.get(0).value; |
|
|
|
compressor_attributes[0][1] = (int)(params.get(1).value*compressor_attributes[0][0]); |
|
|
|
number_of_glitches[0][0] = (int)params.get(2).value; |
|
|
|
number_of_glitches[0][1] = params.get(3).value; |
|
|
|
//green |
|
|
|
compressor_attributes[1][0] = (int)params.get(4).value; |
|
|
|
compressor_attributes[1][1] = (int)(params.get(5).value*compressor_attributes[1][0]); |
|
|
|
number_of_glitches[1][0] = (int)params.get(6).value; |
|
|
|
number_of_glitches[1][1] = params.get(7).value; |
|
|
|
//blue |
|
|
|
compressor_attributes[2][0] = (int)params.get(8).value; |
|
|
|
compressor_attributes[2][1] = (int)(params.get(9).value*compressor_attributes[2][0]); |
|
|
|
number_of_glitches[2][0] = (int)params.get(10).value; |
|
|
|
number_of_glitches[2][1] = params.get(11).value; |
|
|
|
|
|
|
|
comp1 = new LZ77( compressor_attributes[0][0], compressor_attributes[0][1] ); |
|
|
|
comp2 = new LZ77( compressor_attributes[1][0], compressor_attributes[1][1] ); |
|
|
|
comp3 = new LZ77( compressor_attributes[2][0], compressor_attributes[2][1] ); |
|
|
|
|
|
|
|
buffer.beginDraw(); |
|
|
|
|
|
|
|
print("Preparing... "); |
|
|
|
|
|
|
|
img.loadPixels(); |
|
|
|
int iter=0; |
|
|
|
for (int i=0; i<img.pixels.length; i++) { |
|
|
|
color c = img.pixels[i]; |
|
|
|
if (colorspace == HSB) { |
|
|
|
cr[iter]= (byte)hue(c); |
|
|
|
cg[iter]= (byte)saturation(c); |
|
|
|
cb[iter]= (byte)brightness(c); |
|
|
|
} else { |
|
|
|
cr[iter]= (byte)red(c); |
|
|
|
cg[iter]= (byte)green(c); |
|
|
|
cb[iter]= (byte)blue(c); |
|
|
|
} |
|
|
|
iter++; |
|
|
|
} |
|
|
|
println("done"); |
|
|
|
|
|
|
|
print("Glitching channel 1... "); |
|
|
|
comp1.doCompress(cr); |
|
|
|
comp1.glitch( (int)number_of_glitches[0][0], number_of_glitches[0][1] ); |
|
|
|
comp1.doDecompress(cr); |
|
|
|
println("done"); |
|
|
|
|
|
|
|
print("Glitching channel 2... "); |
|
|
|
comp2.doCompress(cg); |
|
|
|
comp2.glitch( (int)number_of_glitches[1][0], number_of_glitches[1][1] ); |
|
|
|
comp2.doDecompress(cg); |
|
|
|
println("done"); |
|
|
|
|
|
|
|
print("Glitching channel 3... "); |
|
|
|
comp3.doCompress(cb); |
|
|
|
comp3.glitch( (int)number_of_glitches[2][0], number_of_glitches[2][1] ); |
|
|
|
comp3.doDecompress(cb); |
|
|
|
println("done"); |
|
|
|
for (int i = 0; i < 3; i++) { |
|
|
|
println("Channel "+(i+1)+" = ("+compressor_attributes[i][0]+","+compressor_attributes[i][1]+")" |
|
|
|
+ ", glitches = ("+number_of_glitches[i][0]+","+number_of_glitches[i][1]+")"); |
|
|
|
} |
|
|
|
|
|
|
|
buffer.loadPixels(); |
|
|
|
if (colorspace == HSB) colorMode(HSB); |
|
|
|
else colorMode(RGB); |
|
|
|
iter=0; |
|
|
|
for (int i=0; i<buffer.pixels.length; i++) { |
|
|
|
float r = cr[iter]; |
|
|
|
r = r>=0?r:r+256; |
|
|
|
float g = cg[iter]; |
|
|
|
g = g>=0?g:g+256; |
|
|
|
float b = cb[iter]; |
|
|
|
b = b>=0?b:b+256; |
|
|
|
|
|
|
|
buffer.pixels[i] = color(r, g, b); |
|
|
|
iter++; |
|
|
|
} |
|
|
|
|
|
|
|
buffer.updatePixels(); |
|
|
|
if (do_blend) |
|
|
|
buffer.blend(img, 0, 0, img.width, img.height, 0, 0, buffer.width, buffer.height, blend_mode); |
|
|
|
buffer.endDraw(); |
|
|
|
|
|
|
|
canvas.beginDraw(); |
|
|
|
canvas.image(buffer, canvas.width/2, canvas.height/2); |
|
|
|
canvas.endDraw(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class Tuple { |
|
|
|
public int offset, len; |
|
|
|
byte chr; |
|
|
|
public Tuple(int o, int l, byte c) { |
|
|
|
offset = o; |
|
|
|
len = l; |
|
|
|
chr = c; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
class LZ77 { |
|
|
|
int windowWidth; |
|
|
|
int lookAheadWidht; |
|
|
|
|
|
|
|
public LZ77(int ww, int law) { |
|
|
|
windowWidth = ww; |
|
|
|
lookAheadWidht = law; |
|
|
|
} |
|
|
|
|
|
|
|
ArrayList<Tuple> clist = new ArrayList<Tuple>(); |
|
|
|
|
|
|
|
public void glitch(int no, float fac) { |
|
|
|
for (int i=0; i<no; i++) { |
|
|
|
Tuple r = clist.get( (int)random(clist.size())); |
|
|
|
int what = (int)random(3); |
|
|
|
switch(what) { |
|
|
|
case 0: |
|
|
|
r.chr = (byte)random(256); |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
r.offset = (int)random(2*windowWidth*fac); |
|
|
|
break; |
|
|
|
default: |
|
|
|
r.len = (int)random(2*lookAheadWidht*fac); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void doCompress(byte[] buff) { |
|
|
|
int currByte = 1; |
|
|
|
|
|
|
|
// first is always byte |
|
|
|
clist.add( new Tuple(0, 0, buff[0]) ); |
|
|
|
|
|
|
|
while (currByte < buff.length) { |
|
|
|
int bend = constrain(currByte-windowWidth, 0, buff.length); |
|
|
|
int boff = 0; |
|
|
|
int blen = 0; |
|
|
|
|
|
|
|
if (currByte<buff.length-1) |
|
|
|
for (int i = currByte-1; i>=bend; i--) { |
|
|
|
if (buff[currByte] == buff[i]) { |
|
|
|
|
|
|
|
int tboff = abs(i-currByte); |
|
|
|
int tblen = 1; |
|
|
|
int laEnd = constrain(currByte+lookAheadWidht, 0, buff.length-1); |
|
|
|
int mi = currByte+1; |
|
|
|
|
|
|
|
while (mi<laEnd && (i+mi-currByte)<currByte) { |
|
|
|
if (buff[mi] == buff[i+mi-currByte]) { |
|
|
|
mi++; |
|
|
|
tblen++; |
|
|
|
} else { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (tblen>blen) { |
|
|
|
blen = tblen; |
|
|
|
boff = tboff; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
currByte +=blen+1; |
|
|
|
// println("currchar = " + (currByte-1)+",blen = " + blen); |
|
|
|
clist.add( new Tuple(boff, blen, buff[currByte-1]) ); |
|
|
|
// println(boff + ", " + blen + ", " + buff[currByte-1]); |
|
|
|
} |
|
|
|
//println("clist " + clist.size()*2); |
|
|
|
} |
|
|
|
|
|
|
|
void doDecompress(byte[] buff) { |
|
|
|
int i = 0; |
|
|
|
for (Tuple t : clist) { |
|
|
|
if (i>=buff.length) break; |
|
|
|
if (t.offset == 0) { |
|
|
|
buff[i++] = t.chr; |
|
|
|
} else { |
|
|
|
int start = i-t.offset; |
|
|
|
int end = start + t.len; |
|
|
|
for (int c = start; c<end; c++) { |
|
|
|
int pos = constrain(c, 0, buff.length-1); |
|
|
|
buff[constrain(i++, 0, buff.length-1)] = buff[pos]; |
|
|
|
if (i>=buff.length) break; |
|
|
|
} |
|
|
|
if (i>=buff.length) break; |
|
|
|
buff[i++] = t.chr; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|