fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

14
node_modules/image-ssim/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,14 @@
node_modules
deploy/
gulp_tasks/
test/
temp/
.idea/
.editorconfig
.gitattributes
.gitignore
.travis.yml
tslint.json

21
node_modules/image-ssim/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Igor Bezkrovny
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

24
node_modules/image-ssim/README.md generated vendored Normal file
View File

@@ -0,0 +1,24 @@
# Image SSIM [![Build Status](https://travis-ci.org/darosh/image-ssim-js.svg)](https://travis-ci.org/darosh/image-ssim-js)
Image structural similarity (SSIM). In TypeScript/JavaScript. For browser/server.
- Original TypeScript implementation: https://github.com/igor-bezkrovny/image-quantization/blob/9f62764ac047c3e53accdf1d7e4e424b0ef2fb60/src/quality/ssim.ts
- Based on Java implementation: https://github.com/rhys-e/structural-similarity
- For more information see: http://en.wikipedia.org/wiki/Structural_similarity
## Demo
[test/browser_test.html](http://darosh.github.io/image-ssim-js/test/browser_test.html)
## Similar stuff
- http://www.cns.nyu.edu/lcv/ssim/
- http://www.researchgate.net/publication/270584309_Window_Size_Influence_on_SSIM_Fidelity
- http://users.eecs.northwestern.edu/~pappas/papers/brooks_tip08.pdf
- http://foulard.ece.cornell.edu/dmr58/dmr_icip2008.pdf
- https://gist.github.com/Bibimaw/8873663
- https://github.com/bytespider/ssim
## Documentation
[http://darosh.github.io/image-ssim-js/doc/](http://darosh.github.io/image-ssim-js/doc/)

147
node_modules/image-ssim/dist/image-ssim.js generated vendored Normal file
View File

@@ -0,0 +1,147 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ImageSSIM = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/**
* @preserve
* Copyright 2015 Igor Bezkrovny
* All rights reserved. (MIT Licensed)
*
* ssim.ts - part of Image Quantization Library
*/
/**
* - Original TypeScript implementation:
* https://github.com/igor-bezkrovny/image-quantization/blob/9f62764ac047c3e53accdf1d7e4e424b0ef2fb60/src/quality/ssim.ts
* - Based on Java implementation: https://github.com/rhys-e/structural-similarity
* - For more information see: http://en.wikipedia.org/wiki/Structural_similarity
*/
var ImageSSIM;
(function (ImageSSIM) {
'use strict';
/**
* Grey = 1, GreyAlpha = 2, RGB = 3, RGBAlpha = 4
*/
(function (Channels) {
Channels[Channels["Grey"] = 1] = "Grey";
Channels[Channels["GreyAlpha"] = 2] = "GreyAlpha";
Channels[Channels["RGB"] = 3] = "RGB";
Channels[Channels["RGBAlpha"] = 4] = "RGBAlpha";
})(ImageSSIM.Channels || (ImageSSIM.Channels = {}));
var Channels = ImageSSIM.Channels;
/**
* Entry point.
* @throws new Error('Images have different sizes!')
*/
function compare(image1, image2, windowSize, K1, K2, luminance, bitsPerComponent) {
if (windowSize === void 0) { windowSize = 8; }
if (K1 === void 0) { K1 = 0.01; }
if (K2 === void 0) { K2 = 0.03; }
if (luminance === void 0) { luminance = true; }
if (bitsPerComponent === void 0) { bitsPerComponent = 8; }
if (image1.width !== image2.width || image1.height !== image2.height) {
throw new Error('Images have different sizes!');
}
/* tslint:disable:no-bitwise */
var L = (1 << bitsPerComponent) - 1;
/* tslint:enable:no-bitwise */
var c1 = Math.pow((K1 * L), 2), c2 = Math.pow((K2 * L), 2), numWindows = 0, mssim = 0.0;
var mcs = 0.0;
function iteration(lumaValues1, lumaValues2, averageLumaValue1, averageLumaValue2) {
// calculate variance and covariance
var sigxy, sigsqx, sigsqy;
sigxy = sigsqx = sigsqy = 0.0;
for (var i = 0; i < lumaValues1.length; i++) {
sigsqx += Math.pow((lumaValues1[i] - averageLumaValue1), 2);
sigsqy += Math.pow((lumaValues2[i] - averageLumaValue2), 2);
sigxy += (lumaValues1[i] - averageLumaValue1) * (lumaValues2[i] - averageLumaValue2);
}
var numPixelsInWin = lumaValues1.length - 1;
sigsqx /= numPixelsInWin;
sigsqy /= numPixelsInWin;
sigxy /= numPixelsInWin;
// perform ssim calculation on window
var numerator = (2 * averageLumaValue1 * averageLumaValue2 + c1) * (2 * sigxy + c2);
var denominator = (Math.pow(averageLumaValue1, 2) + Math.pow(averageLumaValue2, 2) + c1) * (sigsqx + sigsqy + c2);
mssim += numerator / denominator;
mcs += (2 * sigxy + c2) / (sigsqx + sigsqy + c2);
numWindows++;
}
// calculate SSIM for each window
Internals._iterate(image1, image2, windowSize, luminance, iteration);
return { ssim: mssim / numWindows, mcs: mcs / numWindows };
}
ImageSSIM.compare = compare;
/**
* Internal functions.
*/
var Internals;
(function (Internals) {
function _iterate(image1, image2, windowSize, luminance, callback) {
var width = image1.width, height = image1.height;
for (var y = 0; y < height; y += windowSize) {
for (var x = 0; x < width; x += windowSize) {
// avoid out-of-width/height
var windowWidth = Math.min(windowSize, width - x), windowHeight = Math.min(windowSize, height - y);
var lumaValues1 = _lumaValuesForWindow(image1, x, y, windowWidth, windowHeight, luminance), lumaValues2 = _lumaValuesForWindow(image2, x, y, windowWidth, windowHeight, luminance), averageLuma1 = _averageLuma(lumaValues1), averageLuma2 = _averageLuma(lumaValues2);
callback(lumaValues1, lumaValues2, averageLuma1, averageLuma2);
}
}
}
Internals._iterate = _iterate;
function _lumaValuesForWindow(image, x, y, width, height, luminance) {
var array = image.data, lumaValues = new Float32Array(new ArrayBuffer(width * height * 4)), counter = 0;
var maxj = y + height;
for (var j = y; j < maxj; j++) {
var offset = j * image.width;
var i = (offset + x) * image.channels;
var maxi = (offset + x + width) * image.channels;
switch (image.channels) {
case 1 /* Grey */:
while (i < maxi) {
// (0.212655 + 0.715158 + 0.072187) === 1
lumaValues[counter++] = array[i++];
}
break;
case 2 /* GreyAlpha */:
while (i < maxi) {
lumaValues[counter++] = array[i++] * (array[i++] / 255);
}
break;
case 3 /* RGB */:
if (luminance) {
while (i < maxi) {
lumaValues[counter++] = (array[i++] * 0.212655 + array[i++] * 0.715158 + array[i++] * 0.072187);
}
}
else {
while (i < maxi) {
lumaValues[counter++] = (array[i++] + array[i++] + array[i++]);
}
}
break;
case 4 /* RGBAlpha */:
if (luminance) {
while (i < maxi) {
lumaValues[counter++] = (array[i++] * 0.212655 + array[i++] * 0.715158 + array[i++] * 0.072187) * (array[i++] / 255);
}
}
else {
while (i < maxi) {
lumaValues[counter++] = (array[i++] + array[i++] + array[i++]) * (array[i++] / 255);
}
}
break;
}
}
return lumaValues;
}
function _averageLuma(lumaValues) {
var sumLuma = 0.0;
for (var i = 0; i < lumaValues.length; i++) {
sumLuma += lumaValues[i];
}
return sumLuma / lumaValues.length;
}
})(Internals || (Internals = {}));
})(ImageSSIM || (ImageSSIM = {}));
module.exports = ImageSSIM;
},{}]},{},[1])(1)
});

2
node_modules/image-ssim/dist/image-ssim.min.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.ImageSSIM=e()}}(function(){return function e(r,n,t){function o(a,f){if(!n[a]){if(!r[a]){var u="function"==typeof require&&require;if(!f&&u)return u(a,!0);if(i)return i(a,!0);var h=new Error("Cannot find module '"+a+"'");throw h.code="MODULE_NOT_FOUND",h}var s=n[a]={exports:{}};r[a][0].call(s.exports,function(e){var n=r[a][1][e];return o(n?n:e)},s,s.exports,e,r,n,t)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a<t.length;a++)o(t[a]);return o}({1:[function(e,r,n){var t;!function(e){"use strict";function r(e,r,t,o,i,a,f){function u(e,r,n,t){var o,i,a;o=i=a=0;for(var f=0;f<e.length;f++)i+=Math.pow(e[f]-n,2),a+=Math.pow(r[f]-t,2),o+=(e[f]-n)*(r[f]-t);var u=e.length-1;i/=u,a/=u,o/=u;var h=(2*n*t+s)*(2*o+c),v=(Math.pow(n,2)+Math.pow(t,2)+s)*(i+a+c);d+=h/v,p+=(2*o+c)/(i+a+c),l++}if(void 0===t&&(t=8),void 0===o&&(o=.01),void 0===i&&(i=.03),void 0===a&&(a=!0),void 0===f&&(f=8),e.width!==r.width||e.height!==r.height)throw new Error("Images have different sizes!");var h=(1<<f)-1,s=Math.pow(o*h,2),c=Math.pow(i*h,2),l=0,d=0,p=0;return n._iterate(e,r,t,a,u),{ssim:d/l,mcs:p/l}}!function(e){e[e.Grey=1]="Grey",e[e.GreyAlpha=2]="GreyAlpha",e[e.RGB=3]="RGB",e[e.RGBAlpha=4]="RGBAlpha"}(e.Channels||(e.Channels={}));e.Channels;e.compare=r;var n;!function(e){function r(e,r,o,i,a){for(var f=e.width,u=e.height,h=0;u>h;h+=o)for(var s=0;f>s;s+=o){var c=Math.min(o,f-s),l=Math.min(o,u-h),d=n(e,s,h,c,l,i),p=n(r,s,h,c,l,i),v=t(d),w=t(p);a(d,p,v,w)}}function n(e,r,n,t,o,i){for(var a=e.data,f=new Float32Array(new ArrayBuffer(t*o*4)),u=0,h=n+o,s=n;h>s;s++){var c=s*e.width,l=(c+r)*e.channels,d=(c+r+t)*e.channels;switch(e.channels){case 1:for(;d>l;)f[u++]=a[l++];break;case 2:for(;d>l;)f[u++]=a[l++]*(a[l++]/255);break;case 3:if(i)for(;d>l;)f[u++]=.212655*a[l++]+.715158*a[l++]+.072187*a[l++];else for(;d>l;)f[u++]=a[l++]+a[l++]+a[l++];break;case 4:if(i)for(;d>l;)f[u++]=(.212655*a[l++]+.715158*a[l++]+.072187*a[l++])*(a[l++]/255);else for(;d>l;)f[u++]=(a[l++]+a[l++]+a[l++])*(a[l++]/255)}}return f}function t(e){for(var r=0,n=0;n<e.length;n++)r+=e[n];return r/e.length}e._iterate=r}(n||(n={}))}(t||(t={})),r.exports=t},{}]},{},[1])(1)});
//# sourceMappingURL=image-ssim.min.js.map

1
node_modules/image-ssim/dist/image-ssim.min.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

20
node_modules/image-ssim/gulpfile.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var sequence = require('run-sequence');
function getTask(task) {
return require('./gulp_tasks/' + task)(gulp, plugins);
}
gulp.task('tslint', getTask('tslint'));
gulp.task('ts', getTask('typescript'));
gulp.task('doc', getTask('typedoc'));
gulp.task('browserify', getTask('browserify'));
gulp.task('build', function (done) {
sequence('ts', 'browserify', done);
});
gulp.task('default', ['tslint', 'doc', 'build']);
gulp.task('deploy', ['default'], getTask('gh-pages'));

4
node_modules/image-ssim/image-ssim.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module 'image-ssim' {
import ImageSSIM = require('index');
export = ImageSSIM;
}

41
node_modules/image-ssim/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,41 @@
/**
* @preserve
* Copyright 2015 Igor Bezkrovny
* All rights reserved. (MIT Licensed)
*
* ssim.ts - part of Image Quantization Library
*/
/**
* - Original TypeScript implementation:
* https://github.com/igor-bezkrovny/image-quantization/blob/9f62764ac047c3e53accdf1d7e4e424b0ef2fb60/src/quality/ssim.ts
* - Based on Java implementation: https://github.com/rhys-e/structural-similarity
* - For more information see: http://en.wikipedia.org/wiki/Structural_similarity
*/
declare module ImageSSIM {
type Data = number[] | any[] | Uint8Array;
/**
* Grey = 1, GreyAlpha = 2, RGB = 3, RGBAlpha = 4
*/
enum Channels {
Grey = 1,
GreyAlpha = 2,
RGB = 3,
RGBAlpha = 4,
}
interface IImage {
data: Data;
width: number;
height: number;
channels: Channels;
}
interface IResult {
ssim: number;
mcs: number;
}
/**
* Entry point.
* @throws new Error('Images have different sizes!')
*/
function compare(image1: IImage, image2: IImage, windowSize?: number, K1?: number, K2?: number, luminance?: boolean, bitsPerComponent?: number): IResult;
}
export = ImageSSIM;

143
node_modules/image-ssim/index.js generated vendored Normal file
View File

@@ -0,0 +1,143 @@
/**
* @preserve
* Copyright 2015 Igor Bezkrovny
* All rights reserved. (MIT Licensed)
*
* ssim.ts - part of Image Quantization Library
*/
/**
* - Original TypeScript implementation:
* https://github.com/igor-bezkrovny/image-quantization/blob/9f62764ac047c3e53accdf1d7e4e424b0ef2fb60/src/quality/ssim.ts
* - Based on Java implementation: https://github.com/rhys-e/structural-similarity
* - For more information see: http://en.wikipedia.org/wiki/Structural_similarity
*/
var ImageSSIM;
(function (ImageSSIM) {
'use strict';
/**
* Grey = 1, GreyAlpha = 2, RGB = 3, RGBAlpha = 4
*/
(function (Channels) {
Channels[Channels["Grey"] = 1] = "Grey";
Channels[Channels["GreyAlpha"] = 2] = "GreyAlpha";
Channels[Channels["RGB"] = 3] = "RGB";
Channels[Channels["RGBAlpha"] = 4] = "RGBAlpha";
})(ImageSSIM.Channels || (ImageSSIM.Channels = {}));
var Channels = ImageSSIM.Channels;
/**
* Entry point.
* @throws new Error('Images have different sizes!')
*/
function compare(image1, image2, windowSize, K1, K2, luminance, bitsPerComponent) {
if (windowSize === void 0) { windowSize = 8; }
if (K1 === void 0) { K1 = 0.01; }
if (K2 === void 0) { K2 = 0.03; }
if (luminance === void 0) { luminance = true; }
if (bitsPerComponent === void 0) { bitsPerComponent = 8; }
if (image1.width !== image2.width || image1.height !== image2.height) {
throw new Error('Images have different sizes!');
}
/* tslint:disable:no-bitwise */
var L = (1 << bitsPerComponent) - 1;
/* tslint:enable:no-bitwise */
var c1 = Math.pow((K1 * L), 2), c2 = Math.pow((K2 * L), 2), numWindows = 0, mssim = 0.0;
var mcs = 0.0;
function iteration(lumaValues1, lumaValues2, averageLumaValue1, averageLumaValue2) {
// calculate variance and covariance
var sigxy, sigsqx, sigsqy;
sigxy = sigsqx = sigsqy = 0.0;
for (var i = 0; i < lumaValues1.length; i++) {
sigsqx += Math.pow((lumaValues1[i] - averageLumaValue1), 2);
sigsqy += Math.pow((lumaValues2[i] - averageLumaValue2), 2);
sigxy += (lumaValues1[i] - averageLumaValue1) * (lumaValues2[i] - averageLumaValue2);
}
var numPixelsInWin = lumaValues1.length - 1;
sigsqx /= numPixelsInWin;
sigsqy /= numPixelsInWin;
sigxy /= numPixelsInWin;
// perform ssim calculation on window
var numerator = (2 * averageLumaValue1 * averageLumaValue2 + c1) * (2 * sigxy + c2);
var denominator = (Math.pow(averageLumaValue1, 2) + Math.pow(averageLumaValue2, 2) + c1) * (sigsqx + sigsqy + c2);
mssim += numerator / denominator;
mcs += (2 * sigxy + c2) / (sigsqx + sigsqy + c2);
numWindows++;
}
// calculate SSIM for each window
Internals._iterate(image1, image2, windowSize, luminance, iteration);
return { ssim: mssim / numWindows, mcs: mcs / numWindows };
}
ImageSSIM.compare = compare;
/**
* Internal functions.
*/
var Internals;
(function (Internals) {
function _iterate(image1, image2, windowSize, luminance, callback) {
var width = image1.width, height = image1.height;
for (var y = 0; y < height; y += windowSize) {
for (var x = 0; x < width; x += windowSize) {
// avoid out-of-width/height
var windowWidth = Math.min(windowSize, width - x), windowHeight = Math.min(windowSize, height - y);
var lumaValues1 = _lumaValuesForWindow(image1, x, y, windowWidth, windowHeight, luminance), lumaValues2 = _lumaValuesForWindow(image2, x, y, windowWidth, windowHeight, luminance), averageLuma1 = _averageLuma(lumaValues1), averageLuma2 = _averageLuma(lumaValues2);
callback(lumaValues1, lumaValues2, averageLuma1, averageLuma2);
}
}
}
Internals._iterate = _iterate;
function _lumaValuesForWindow(image, x, y, width, height, luminance) {
var array = image.data, lumaValues = new Float32Array(new ArrayBuffer(width * height * 4)), counter = 0;
var maxj = y + height;
for (var j = y; j < maxj; j++) {
var offset = j * image.width;
var i = (offset + x) * image.channels;
var maxi = (offset + x + width) * image.channels;
switch (image.channels) {
case 1 /* Grey */:
while (i < maxi) {
// (0.212655 + 0.715158 + 0.072187) === 1
lumaValues[counter++] = array[i++];
}
break;
case 2 /* GreyAlpha */:
while (i < maxi) {
lumaValues[counter++] = array[i++] * (array[i++] / 255);
}
break;
case 3 /* RGB */:
if (luminance) {
while (i < maxi) {
lumaValues[counter++] = (array[i++] * 0.212655 + array[i++] * 0.715158 + array[i++] * 0.072187);
}
}
else {
while (i < maxi) {
lumaValues[counter++] = (array[i++] + array[i++] + array[i++]);
}
}
break;
case 4 /* RGBAlpha */:
if (luminance) {
while (i < maxi) {
lumaValues[counter++] = (array[i++] * 0.212655 + array[i++] * 0.715158 + array[i++] * 0.072187) * (array[i++] / 255);
}
}
else {
while (i < maxi) {
lumaValues[counter++] = (array[i++] + array[i++] + array[i++]) * (array[i++] / 255);
}
}
break;
}
}
return lumaValues;
}
function _averageLuma(lumaValues) {
var sumLuma = 0.0;
for (var i = 0; i < lumaValues.length; i++) {
sumLuma += lumaValues[i];
}
return sumLuma / lumaValues.length;
}
})(Internals || (Internals = {}));
})(ImageSSIM || (ImageSSIM = {}));
module.exports = ImageSSIM;

211
node_modules/image-ssim/index.ts generated vendored Normal file
View File

@@ -0,0 +1,211 @@
/**
* @preserve
* Copyright 2015 Igor Bezkrovny
* All rights reserved. (MIT Licensed)
*
* ssim.ts - part of Image Quantization Library
*/
/**
* - Original TypeScript implementation:
* https://github.com/igor-bezkrovny/image-quantization/blob/9f62764ac047c3e53accdf1d7e4e424b0ef2fb60/src/quality/ssim.ts
* - Based on Java implementation: https://github.com/rhys-e/structural-similarity
* - For more information see: http://en.wikipedia.org/wiki/Structural_similarity
*/
module ImageSSIM {
'use strict';
export type Data = number[]|any[]|Uint8Array;
/**
* Grey = 1, GreyAlpha = 2, RGB = 3, RGBAlpha = 4
*/
export enum Channels {
Grey = 1,
GreyAlpha = 2,
RGB = 3,
RGBAlpha = 4
}
export interface IImage {
data:Data;
width:number;
height:number;
channels:Channels;
}
export interface IResult {
ssim:number;
mcs:number;
}
/**
* Entry point.
* @throws new Error('Images have different sizes!')
*/
export function compare(image1:IImage,
image2:IImage,
windowSize:number = 8,
K1:number = 0.01,
K2:number = 0.03,
luminance:boolean = true,
bitsPerComponent:number = 8):IResult {
if (image1.width !== image2.width ||
image1.height !== image2.height) {
throw new Error('Images have different sizes!');
}
/* tslint:disable:no-bitwise */
var L:number = (1 << bitsPerComponent) - 1;
/* tslint:enable:no-bitwise */
var c1:number = Math.pow((K1 * L), 2),
c2:number = Math.pow((K2 * L), 2),
numWindows:number = 0,
mssim:number = 0.0;
var mcs:number = 0.0;
function iteration(lumaValues1:number[],
lumaValues2:number[],
averageLumaValue1:number,
averageLumaValue2:number):void {
// calculate variance and covariance
var sigxy:number,
sigsqx:number,
sigsqy:number;
sigxy = sigsqx = sigsqy = 0.0;
for (var i:number = 0; i < lumaValues1.length; i++) {
sigsqx += Math.pow((lumaValues1[i] - averageLumaValue1), 2);
sigsqy += Math.pow((lumaValues2[i] - averageLumaValue2), 2);
sigxy += (lumaValues1[i] - averageLumaValue1) * (lumaValues2[i] - averageLumaValue2);
}
var numPixelsInWin:number = lumaValues1.length - 1;
sigsqx /= numPixelsInWin;
sigsqy /= numPixelsInWin;
sigxy /= numPixelsInWin;
// perform ssim calculation on window
var numerator:number = (2 * averageLumaValue1 * averageLumaValue2 + c1) * (2 * sigxy + c2);
var denominator:number = (Math.pow(averageLumaValue1, 2) +
Math.pow(averageLumaValue2, 2) + c1) * (sigsqx + sigsqy + c2);
mssim += numerator / denominator;
mcs += (2 * sigxy + c2) / (sigsqx + sigsqy + c2);
numWindows++;
}
// calculate SSIM for each window
Internals._iterate(image1, image2, windowSize, luminance, iteration);
return {ssim: mssim / numWindows, mcs: mcs / numWindows};
}
/**
* Internal functions.
*/
module Internals {
export function _iterate(image1:IImage,
image2:IImage,
windowSize:number,
luminance:boolean,
callback:(lumaValues1:number[],
lumaValues2:number[],
averageLumaValue1:number,
averageLumaValue2:number) => void):void {
var width:number = image1.width,
height:number = image1.height;
for (var y:number = 0; y < height; y += windowSize) {
for (var x:number = 0; x < width; x += windowSize) {
// avoid out-of-width/height
var windowWidth:number = Math.min(windowSize, width - x),
windowHeight:number = Math.min(windowSize, height - y);
var lumaValues1:number[] = _lumaValuesForWindow(image1, x, y, windowWidth, windowHeight, luminance),
lumaValues2:number[] = _lumaValuesForWindow(image2, x, y, windowWidth, windowHeight, luminance),
averageLuma1:number = _averageLuma(lumaValues1),
averageLuma2:number = _averageLuma(lumaValues2);
callback(lumaValues1, lumaValues2, averageLuma1, averageLuma2);
}
}
}
function _lumaValuesForWindow(image:IImage,
x:number,
y:number,
width:number,
height:number,
luminance:boolean):number[] {
var array:Data = image.data,
lumaValues:number[] = <any>new Float32Array(new ArrayBuffer(width * height * 4)),
counter:number = 0;
var maxj:number = y + height;
for (var j:number = y; j < maxj; j++) {
var offset:number = j * image.width;
var i:number = (offset + x) * image.channels;
var maxi:number = (offset + x + width) * image.channels;
switch (image.channels) {
case Channels.Grey:
while (i < maxi) {
// (0.212655 + 0.715158 + 0.072187) === 1
lumaValues[counter++] = array[i++];
}
break;
case Channels.GreyAlpha:
while (i < maxi) {
lumaValues[counter++] = array[i++] * (array[i++] / 255);
}
break;
case Channels.RGB:
if (luminance) {
while (i < maxi) {
lumaValues[counter++] = (array[i++] * 0.212655 + array[i++] * 0.715158 + array[i++] * 0.072187);
}
} else {
while (i < maxi) {
lumaValues[counter++] = (array[i++] + array[i++] + array[i++]);
}
}
break;
case Channels.RGBAlpha:
if (luminance) {
while (i < maxi) {
lumaValues[counter++] = (array[i++] * 0.212655 + array[i++] * 0.715158 + array[i++] * 0.072187) *
(array[i++] / 255);
}
} else {
while (i < maxi) {
lumaValues[counter++] = (array[i++] + array[i++] + array[i++]) *
(array[i++] / 255);
}
}
break;
}
}
return lumaValues;
}
function _averageLuma(lumaValues:number[]):number {
var sumLuma:number = 0.0;
for (var i:number = 0; i < lumaValues.length; i++) {
sumLuma += lumaValues[i];
}
return sumLuma / lumaValues.length;
}
}
}
export = ImageSSIM;

47
node_modules/image-ssim/package.json generated vendored Normal file
View File

@@ -0,0 +1,47 @@
{
"name": "image-ssim",
"description": "Image structural similarity (SSIM). In TypeScript/JavaScript. For browser/server.",
"version": "0.2.0",
"author": {
"name": "Jan Forst",
"email": "ensonador@gmail.com",
"url": "https://github.com/darosh"
},
"bugs": "https://github.com/darosh/image-ssim-js/issues",
"dependencies": {},
"devDependencies": {
"browserify": "^10.2.4",
"gulp": "^3.9.0",
"gulp-gh-pages": "^0.5.2",
"gulp-load-plugins": "^0.10.0",
"gulp-rename": "^1.2.2",
"gulp-sourcemaps": "^1.5.2",
"gulp-tslint": "^2.0.0",
"gulp-typedoc": "^1.1.0",
"gulp-typescript": "^2.7.8",
"gulp-uglify": "^1.2.0",
"gulp-util": "^3.0.6",
"merge2": "^0.3.6",
"mocha": "^2.2.5",
"pngjs": "^0.4.0",
"run-sequence": "^1.1.1",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0"
},
"homepage": "https://github.com/darosh/image-ssim-js/issues",
"keywords": [
"browser",
"compare",
"image",
"server",
"similarity",
"ssim",
"typescript"
],
"license": "MIT",
"main": "index.js",
"repository": "darosh/image-ssim-js",
"scripts": {
"test": "mocha"
}
}