Skip to content

Commit e8adecf

Browse files
committed
v.1.7.0 contd
1 parent 6f35ad1 commit e8adecf

File tree

8 files changed

+324
-111
lines changed

8 files changed

+324
-111
lines changed

build/filter.js

+161-55
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*
33
* FILTER.js
44
* @version: 1.7.0
5-
* @built on 2023-08-23 15:46:47
5+
* @built on 2023-08-24 10:01:13
66
* @dependencies: Asynchronous.js
77
*
88
* JavaScript Image Processing Library
@@ -12,7 +12,7 @@
1212
*
1313
* FILTER.js
1414
* @version: 1.7.0
15-
* @built on 2023-08-23 15:46:47
15+
* @built on 2023-08-24 10:01:13
1616
* @dependencies: Asynchronous.js
1717
*
1818
* JavaScript Image Processing Library
@@ -1557,14 +1557,11 @@ function hypot(a, b, c)
15571557
c = c || 0;
15581558
b = b || 0;
15591559
var m = Max(Abs(a), Abs(b), Abs(c));
1560-
if (m)
1561-
{
1562-
a /= m;
1563-
b /= m;
1564-
c /= m;
1565-
return m*Sqrt(a*a + b*b + c*c);
1566-
}
1567-
return 0;
1560+
if (0 === m) return 0;
1561+
a /= m;
1562+
b /= m;
1563+
c /= m;
1564+
return m*Sqrt(a*a + b*b + c*c);
15681565
}
15691566

15701567
function arrayset_shim(a, b, offset, b0, b1)
@@ -2260,7 +2257,28 @@ return {
22602257
].join('\n')
22612258
};
22622259
}
2263-
2260+
function image_glsl()
2261+
{
2262+
return {
2263+
'crop': [
2264+
'vec4 crop(vec2 pix, sampler2D img, vec2 wh, float x1, float y1, float x2, float y2) {',
2265+
' vec2 start = vec2(x1, y1); vec2 end = vec2(x2, y2);',
2266+
' return texture2D(img, start + pix*(end-start));',
2267+
'}'
2268+
].join('\n'),
2269+
'pad': [
2270+
'vec4 pad(vec2 pix, sampler2D img, vec2 wh, float pad_right, float pad_bot, float pad_left, float pad_top) {',
2271+
' if (pix.x < pad_left || pix.x > pad_left+wh.x || pix.y < pad_top || pix.y > pad_top+wh.y) return vec4(0.0);',
2272+
' return texture2D(img, (pix-vec2(pad_left,pad_top))/(wh+vec2(pad_right,pad_bot)));',
2273+
'}'
2274+
].join('\n'),
2275+
'interpolate': [
2276+
'vec4 interpolate(vec2 pix, sampler2D img, vec2 wh, vec2 nwh) {',
2277+
' return texture2D(img, wh*pix/nwh);',
2278+
'}'
2279+
].join('\n')
2280+
};
2281+
}
22642282
// speed-up convolution for special kernels like moving-average
22652283
function integral_convolution(mode, im, w, h, stride, matrix, matrix2, dimX, dimY, dimX2, dimY2, coeff1, coeff2, numRepeats)
22662284
{
@@ -3391,6 +3409,7 @@ StringUtil.function_body = function_body;
33913409
ImageUtil.crop = ArrayUtil.hasArrayset ? crop : crop_shim;
33923410
ImageUtil.pad = ArrayUtil.hasArrayset ? pad : pad_shim;
33933411
ImageUtil.interpolate = interpolate_bilinear;
3412+
ImageUtil.glsl = image_glsl;
33943413

33953414
FilterUtil.ct_eye = ct_eye;
33963415
FilterUtil.ct_multiply = ct_multiply;
@@ -3812,8 +3831,9 @@ GLSL.run = function(img, filter, glsls, im, w, h, metaData) {
38123831
pos, uv, src, dst, prev = [null, null],
38133832
buf0, buf1, buf = [null, null],
38143833
program, cache, im0, t,
3815-
canRun, isContextLost, cleanUp, lost,
3816-
first = -1, last = -1,
3834+
canRun, isContextLost,
3835+
cleanUp, lost, resize,
3836+
first = -1, last = -1, nw, nh,
38173837
fromshader = false, flipY = false;
38183838
if (!gl) return;
38193839
cleanUp = function() {
@@ -3842,6 +3862,38 @@ GLSL.run = function(img, filter, glsls, im, w, h, metaData) {
38423862
img.cache = {}; // need to recompile programs?
38433863
FILTER.log('GL context lost on #'+img.id);
38443864
};
3865+
resize = function(nw, nh) {
3866+
if (w === nw && h === nh) return;
3867+
w = nw;
3868+
h = nh;
3869+
FILTER.setGLDimensions(img, w, h);
3870+
deleteBuffer(gl, pos);
3871+
pos = createBuffer(gl, new FILTER.Array32F([
3872+
0, 0,
3873+
w, 0,
3874+
0, h,
3875+
0, h,
3876+
w, 0,
3877+
w, h
3878+
]));
3879+
gl.viewport(0, 0, w, h);
3880+
deleteFramebufferTexture(gl, buf0);
3881+
deleteFramebufferTexture(gl, buf1);
3882+
deleteFramebufferTexture(gl, buf[0]);
3883+
deleteFramebufferTexture(gl, buf[1]);
3884+
buf = [null, null];
3885+
if (last > first)
3886+
{
3887+
buf0 = createFramebufferTexture(gl, w, h);
3888+
buf1 = createFramebufferTexture(gl, w, h);
3889+
}
3890+
if (filter.hasMeta)
3891+
{
3892+
filter.meta = filter.meta || {};
3893+
filter.meta._IMG_WIDTH = w;
3894+
filter.meta._IMG_HEIGHT = h;
3895+
}
3896+
};
38453897
if (gl.isContextLost && gl.isContextLost()) return lost();
38463898
for (i=0; i<n; ++i)
38473899
{
@@ -3891,6 +3943,12 @@ GLSL.run = function(img, filter, glsls, im, w, h, metaData) {
38913943
if (fromshader) prev[0] = uploadTexture(gl, getPixels(gl, w, h), w, h);
38923944
else prev[0] = uploadTexture(gl, im, w, h);
38933945
}
3946+
if (null != glsl.width && null != glsl.height)
3947+
{
3948+
nw = 'function' === typeof glsl.width ? glsl.width(w, h) : glsl.width;
3949+
nh = 'function' === typeof glsl.height ? glsl.height(w, h) : glsl.height;
3950+
resize(nw, nh);
3951+
}
38943952
if (i === first)
38953953
{
38963954
if (!input) input = uploadTexture(gl, im, w, h, 0);
@@ -3923,40 +3981,9 @@ GLSL.run = function(img, filter, glsls, im, w, h, metaData) {
39233981
if (glsl._apply) im = glsl._apply(im0, w, h, metaData);
39243982
else if (glsl.instance._apply_wasm) im = glsl.instance._apply_wasm(im0, w, h, metaData);
39253983
else im = glsl.instance._apply(im0, w, h, metaData);
3926-
if (glsl.instance.hasMeta && (
3927-
(null != glsl.instance.meta._IMG_WIDTH && w !== glsl.instance.meta._IMG_WIDTH)
3928-
|| (null != glsl.instance.meta._IMG_HEIGHT && h !== glsl.instance.meta._IMG_HEIGHT)
3929-
))
3984+
if (glsl.instance.hasMeta && null != glsl.instance.meta._IMG_WIDTH && null != glsl.instance.meta._IMG_HEIGHT)
39303985
{
3931-
w = glsl.instance.meta._IMG_WIDTH;
3932-
h = glsl.instance.meta._IMG_HEIGHT;
3933-
FILTER.setGLDimensions(img, w, h);
3934-
deleteBuffer(gl, pos);
3935-
pos = createBuffer(gl, new FILTER.Array32F([
3936-
0, 0,
3937-
w, 0,
3938-
0, h,
3939-
0, h,
3940-
w, 0,
3941-
w, h
3942-
]));
3943-
gl.viewport(0, 0, w, h);
3944-
deleteFramebufferTexture(gl, buf0);
3945-
deleteFramebufferTexture(gl, buf1);
3946-
deleteFramebufferTexture(gl, buf[0]);
3947-
deleteFramebufferTexture(gl, buf[1]);
3948-
buf = [null, null];
3949-
if (last > first)
3950-
{
3951-
buf0 = createFramebufferTexture(gl, w, h);
3952-
buf1 = createFramebufferTexture(gl, w, h);
3953-
}
3954-
if (filter.hasMeta)
3955-
{
3956-
filter.meta = filter.meta || {};
3957-
filter.meta._IMG_WIDTH = w;
3958-
filter.meta._IMG_HEIGHT = h;
3959-
}
3986+
resize(glsl.instance.meta._IMG_WIDTH, glsl.instance.meta._IMG_HEIGHT);
39603987
}
39613988
fromshader = false;
39623989
}
@@ -7664,11 +7691,7 @@ function wasm()
76647691
!function(FILTER, undef) {
76657692
"use strict";
76667693

7667-
var stdMath = Math,
7668-
crop = FILTER.Util.Image.crop,
7669-
pad = FILTER.Util.Image.pad,
7670-
interpolate = FILTER.Util.Image.interpolate
7671-
;
7694+
var stdMath = Math, ImageUtil = FILTER.Util.Image, GLSL = FILTER.Util.GLSL;
76727695

76737696
// Dimension Filter, change image dimension
76747697
FILTER.Create({
@@ -7747,6 +7770,10 @@ FILTER.Create({
77477770
return this.set(null);
77487771
}
77497772

7773+
,getGLSL: function() {
7774+
return glsl(this);
7775+
}
7776+
77507777
,_apply_wasm: function(im, w, h, metaData) {
77517778
var self = this, ret;
77527779
self._runWASM = true;
@@ -7784,7 +7811,7 @@ FILTER.Create({
77847811
b = stdMath.round(b);
77857812
c = stdMath.round(c);
77867813
d = stdMath.round(d);
7787-
im = pad(im, w, h, c, d, a, b);
7814+
im = ImageUtil.pad(im, w, h, c, d, a, b);
77887815
self.meta = {_IMG_WIDTH:b + d + h, _IMG_HEIGHT:a + c + w};
77897816
self.hasMeta = true;
77907817
break;
@@ -7793,7 +7820,7 @@ FILTER.Create({
77937820
b = stdMath.round(b);
77947821
c = stdMath.round(c);
77957822
d = stdMath.round(d);
7796-
im = crop(im, w, h, a, b, a+c-1, b+d-1);
7823+
im = ImageUtil.crop(im, w, h, a, b, a+c-1, b+d-1);
77977824
self.meta = {_IMG_WIDTH:c, _IMG_HEIGHT:d};
77987825
self.hasMeta = true;
77997826
break;
@@ -7811,7 +7838,7 @@ FILTER.Create({
78117838
a = stdMath.round(a);
78127839
b = stdMath.round(b);
78137840
}
7814-
im = isWASM ? FILTER.Util.Image.wasm.interpolate(im, w, h, a, b) : interpolate(im, w, h, a, b);
7841+
im = isWASM ? (ImageUtil.wasm||ImageUtil)['interpolate'](im, w, h, a, b) : ImageUtil.interpolate(im, w, h, a, b);
78157842
self.meta = {_IMG_WIDTH:a, _IMG_HEIGHT:b};
78167843
self.hasMeta = true;
78177844
break;
@@ -7820,6 +7847,85 @@ FILTER.Create({
78207847
}
78217848
});
78227849

7850+
function glsl(filter)
7851+
{
7852+
/*if (!filter.mode)*/ return {instance: filter/*, shader: GLSL.DEFAULT*/};
7853+
/*
7854+
// in progress
7855+
var img_util = ImageUtil.glsl(), w, h;
7856+
return {instance: filter, shader: [
7857+
'varying vec2 pix;',
7858+
'uniform sampler2D img;',
7859+
'uniform vec2 wh;',
7860+
'uniform int mode;',
7861+
'uniform float a;',
7862+
'uniform float b;',
7863+
'uniform float c;',
7864+
'uniform float d;',
7865+
'vec4 set(vec2 pix, sampler2D img) {',
7866+
' return vec4(0.0);',
7867+
'}',
7868+
img_util['crop'],
7869+
img_util['pad'],
7870+
img_util['interpolate'],
7871+
'void main(void) {',
7872+
' if (1 == mode) gl_FragColor = set(pix, img);',
7873+
' else if (2 == mode) gl_FragColor = pad(pix, img, wh, c, d, a, b);',
7874+
' else if (3 == mode) gl_FragColor = crop(pix, img, wh, a, b, a+c-1, b+d-1);',
7875+
' else gl_FragColor = interpolate(pix, img, wh, vec2(a, b));',
7876+
'}'
7877+
].join('\n'),
7878+
vars: function(gl, w, h, program) {
7879+
var modeCode,
7880+
a = filter.a,
7881+
b = filter.b,
7882+
c = filter.c,
7883+
d = filter.d;
7884+
switch (filter.mode)
7885+
{
7886+
case 'set':
7887+
modeCode = 1;
7888+
if (c && d)
7889+
{
7890+
// scale given
7891+
a = c*w;
7892+
b = d*h;
7893+
}
7894+
break;
7895+
case 'pad':
7896+
modeCode = 2;
7897+
break;
7898+
case 'crop':
7899+
modeCode = 3;
7900+
break;
7901+
case 'scale':
7902+
default:
7903+
if (c && d)
7904+
{
7905+
// scale given
7906+
a = c*w;
7907+
b = d*h;
7908+
}
7909+
modeCode = 4;
7910+
break;
7911+
}
7912+
gl.uniform2fv(program.uniform.wh, new FILTER.Array32F([
7913+
w, h
7914+
]));
7915+
gl.uniform1i(program.uniform.mode, modeCode);
7916+
gl.uniform1f(program.uniform.a, a);
7917+
gl.uniform1f(program.uniform.b, b);
7918+
gl.uniform1f(program.uniform.c, c);
7919+
gl.uniform1f(program.uniform.d, d);
7920+
}, width: function(ww, hh) {
7921+
w = ww; h = hh;
7922+
return w;
7923+
}, height: function(ww, hh) {
7924+
return h;
7925+
}
7926+
};*/
7927+
}
7928+
78237929
}(FILTER);/**
78247930
*
78257931
* Table Lookup Filter
@@ -17213,7 +17319,7 @@ function haar_detect(feats, w, h, sel_x1, sel_y1, sel_x2, sel_y2,
1721317319

1721417320
bx=w-1; by=imSize-w;
1721517321
startx = sel_x1|0; starty = sel_y1|0;
17216-
maxScale = Min(/*selw*/w/sizex, /*selh*/h/sizey);
17322+
maxScale = Min(selw/*w*//sizex, selh/*h*//sizey);
1721717323
//minScale = Max(selw/w, selh/h);
1721817324
for (scale=baseScale/* *minScale*/; scale<=maxScale; scale*=scaleIncrement)
1721917325
{

build/filter.min.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ __1.7.0__
66
* CannyEdges better GLSL version
77
* Image.setDimensions scales appropriately with selection if active, else resizes whole image as before
88
* dimensions changing during GLSL correctly set filter meta
9+
* fix HaarDetector selection again
910
* some optimizations
1011
* update examples and tests
1112

readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
This is a library for processing images/video in pure JavaScript using HTML5 features like `Canvas`, **Web Workers, WebAssembly and WebGL** or alternatives in Node.js (eg `CanvasLite`, `node-canvas`, `node-gl`, node `processes`).
88

99

10-
**version 1.7.0** (370 kB minified)
10+
**version 1.7.0** (371 kB minified)
1111

1212

1313
### Contents

0 commit comments

Comments
 (0)