Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
elphel-web-393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
elphel-web-393
Commits
e233bb6d
Commit
e233bb6d
authored
Apr 04, 2017
by
Oleg Dzhimiev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reordering jp4 blocks in web worker
parent
4bdc75f5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
455 additions
and
380 deletions
+455
-380
Makefile
src/jp4-canvas/Makefile
+2
-1
elphel.js
src/jp4-canvas/elphel.js
+321
-327
jquery-jp4.js
src/jp4-canvas/jquery-jp4.js
+99
-52
webworker.js
src/jp4-canvas/webworker.js
+33
-0
No files found.
src/jp4-canvas/Makefile
View file @
e233bb6d
...
...
@@ -8,7 +8,8 @@ DOCS= jp4-canvas.html \
LIBS
=
elphel.js
\
exif.js
\
jquery-jp4.js
\
jcanvas.js
jcanvas.js
\
webworker.js
PHP_SCRIPTS
=
get-image.php
...
...
src/jp4-canvas/elphel.js
View file @
e233bb6d
/**
* @file elphel.js
* @brief functions for pixel manipulation
(canvas)
* @copyright Copyright (C) 201
6
Elphel Inc.
* @brief functions for pixel manipulation
and drawing on canvas
* @copyright Copyright (C) 201
7
Elphel Inc.
* @author Oleg Dzhimiev <oleg@elphel.com>
*
* @licstart The following is the entire license notice for the
...
...
@@ -26,41 +26,114 @@
*/
var
Elphel
=
{
// Drawing
Canvas
:{
/* Name: reorderJP4Blocks
* Description: clear from the function's name
*
* ctx - canvas 2D context
* format:
* 'jpeg' - skip reordering
* 'jp4' - jp4 reordeing
* 'jp46' - jp46 reordering
* mosaic - [["Gr","R"],["B","Gb"]] =
* odd lines: Gr,R,Gr,R
* even lines: B,Gb,B,Gb
* nwd - true/false - demosaicing: 'Nearest Neighbor' with 1/2 scale -
* put mosaic (different channels) for GrRBGb into one pixel for
* faster performance
*/
reorderJP4Blocks
:
function
(
ctx
,
format
=
"JP4"
,
mosaic
=
[[
"Gr"
,
"R"
],[
"B"
,
"Gb"
]],
nwd
=
false
)
{
/**
* Name: putImageData - the same but not the same
* Description: -
*/
putImageData
:
function
(
ctx
,
px
,
width
,
height
){
var
t0
=
Date
.
now
();
var
width
=
ctx
.
canvas
.
width
;
var
height
=
ctx
.
canvas
.
height
;
ctx
.
canvas
.
width
=
width
;
ctx
.
canvas
.
height
=
height
;
var
imgdata
=
new
ImageData
(
new
Uint8ClampedArray
(
px
),
width
,
height
);
ctx
.
putImageData
(
imgdata
,
0
,
0
);
console
.
log
(
"drawImageData(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
/*
// new: http://stackoverflow.com/questions/15908179/draw-image-from-pixel-array-on-canvas-with-putimagedata
// obsolete:
//var img = ctx.createImageData(ctx.canvas.width,ctx.canvas.height);
//var imgdata = img.data;
// byte-copy?!!
for(var i=0;i<(imgdata.length>>2);i++){
imgdata[4*i+0] = px[4*i+0];
imgdata[4*i+1] = px[4*i+1];
imgdata[4*i+2] = px[4*i+2];
imgdata[4*i+3] = px[4*i+3];
}
ctx.putImageData(img,0,0);
*/
var
inputImage
=
ctx
.
getImageData
(
0
,
0
,
width
,
height
);
var
iPixels
=
inputImage
.
data
;
},
/**
* Name: drawScaled
* Description: Plugin specific. Takes source canvas - draws a scaled
* version on destination canvas
*/
drawScaled
:
function
(
cnv_src
,
cnv_dst
,
width
){
var
t0
=
Date
.
now
();
var
ctx
=
cnv_src
[
0
].
getContext
(
'2d'
);
var
tw
=
ctx
.
canvas
.
width
;
var
th
=
ctx
.
canvas
.
height
;
var
tr
=
tw
/
th
;
var
sctx
=
cnv_dst
[
0
].
getContext
(
'2d'
);
var
w
=
Math
.
round
(
width
);
var
h
=
Math
.
round
(
w
/
tr
);
sctx
.
canvas
.
width
=
w
;
sctx
.
canvas
.
height
=
h
;
cscale
=
Math
.
round
(
w
/
tw
*
100
)
/
100
;
sctx
.
scale
(
cscale
,
cscale
);
sctx
.
drawImage
(
cnv_src
[
0
],
0
,
0
);
var
outputImage
=
ctx
.
createImageData
((
nwd
)?
width
/
2
:
width
,(
nwd
)?
height
/
2
:
height
);
var
oPixels
=
outputImage
.
data
;
console
.
log
(
"drawScaled(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
}
},
// Pixel manipulation
Pixels
:{
/**
* Name: reorderJP4Blocks
* Description: clear from the function's name
*
* @pixels - pixel array, read from origin canvas
* pixels is a long 1-D array with the following structure:
* pix[i+0] - red
* pix[i+1] - green
* pix[i+2] - blue
* pix[i+3] - alpha
* @width - origin canvas width
* @height - origin canvas height
* @format - value comes from exif.js function
* 'jpeg' - skip reordering
* 'jp4' - jp4 reordeing
* 'jp46' - jp46 reordering
* @mosaic - [["Gr","R"],["B","Gb"]] - value comes from application
* odd lines: Gr,R,Gr,R
* even lines: B,Gb,B,Gb
* @nwd - true/false - comes from application - demosaicing: 'Nearest Neighbor' with 1/2 scale -
* put mosaic (different channels) for GrRBGb into one pixel for
* faster performance
*/
reorderBlocksJPx
:
function
(
pixels
,
width
,
height
,
format
=
"JP4"
,
mosaic
=
[[
"Gr"
,
"R"
],[
"B"
,
"Gb"
]],
nwd
=
false
){
var
t0
=
Date
.
now
();
//
img.data
is a long 1-D array with the following structure:
//
pixels
is a long 1-D array with the following structure:
// pix[i+0] - red
// pix[i+1] - green
// pix[i+2] - blue
// pix[i+3] - alpha
var
oPixels
=
new
Uint8Array
((
nwd
)?
pixels
.
length
/
4
:
pixels
.
length
);
// buffer for reordering pixels
var
macroblock
=
new
Array
();
//16x16
for
(
var
y
=
0
;
y
<
16
;
y
++
)
macroblock
[
y
]
=
new
Array
();
...
...
@@ -84,7 +157,7 @@ var Elphel = {
//offset=(((yb<<4)+y)*width)+(nb<<3)+((xb>=(width>>5))?(((xb<<5)-width)+(width<<3)):(xb<<5));
offset
=
(((
yb
<<
4
)
+
y
)
*
width
)
+
(
nb
<<
3
)
+
(
xb
<<
5
)
+
((
xb
>=
(
width
>>
5
))?((
width
<<
3
)
-
width
):
0
);
for
(
x
=
0
;
x
<
8
;
x
++
)
{
macroblock
[(
y
<<
1
)
|
ybyr
][(
x
<<
1
)
|
xbyr
]
=
iP
ixels
[
4
*
(
offset
+
x
)];
macroblock
[(
y
<<
1
)
|
ybyr
][(
x
<<
1
)
|
xbyr
]
=
p
ixels
[
4
*
(
offset
+
x
)];
}
}
}
...
...
@@ -94,7 +167,7 @@ var Elphel = {
offset
=
((
yb
<<
4
)
+
y
)
*
width
+
(
xb
<<
4
);
for
(
x
=
0
;
x
<
16
;
x
++
)
{
//Red value only
macroblock
[((
y
<<
1
)
&
0xe
)
|
((
y
>>
3
)
&
0x1
)][((
x
<<
1
)
&
0xe
)
|
((
x
>>
3
)
&
0x1
)]
=
iP
ixels
[
4
*
(
offset
+
x
)];
macroblock
[((
y
<<
1
)
&
0xe
)
|
((
y
>>
3
)
&
0x1
)][((
x
<<
1
)
&
0xe
)
|
((
x
>>
3
)
&
0x1
)]
=
p
ixels
[
4
*
(
offset
+
x
)];
}
}
}
...
...
@@ -134,47 +207,42 @@ var Elphel = {
}
}
}
if
(
nwd
)
{
ctx
.
canvas
.
width
=
width
/
2
;
ctx
.
canvas
.
height
=
height
/
2
;
}
ctx
.
putImageData
(
outputImage
,
0
,
0
);
console
.
log
(
"reorderJP4Blocks(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
console
.
log
(
"reorderJP4Blocks: "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
return
oPixels
;
},
/**
* Name: demosaicNearestNeighbor with downscale
* Description: A separate function, just in case, same as in
* reorderJP4Blocks
*
* @pixels - pixel array, read from origin canvas
* pixels is a long 1-D array with the following structure:
* pix[i+0] - red
* pix[i+1] - green
* pix[i+2] - blue
* pix[i+3] - alpha
* @width - origin canvas width
* @height - origin canvas height
* @mosaic - [["Gr","R"],["B","Gb"]] - value comes from application
* odd lines: Gr,R,Gr,R
* even lines: B,Gb,B,Gb
*/
demosaicNearestNeighbor
:
function
(
pixels
,
width
,
height
,
mosaic
=
[[
"Gr"
,
"R"
],[
"B"
,
"Gb"
]]){
/* Name: demosaicNearestNeighbor
* Description: A separate function, just in case, same as in
* reorderJP4Blocks
*
* ctx - canvas 2D context
* mosaic - [["Gr","R"],["B","Gb"]] =
* odd lines: Gr,R,Gr,R
* even lines: B,Gb,B,Gb
*/
demosaicNearestNeighbor
:
function
(
ctx
,
mosaic
=
[[
"Gr"
,
"R"
],[
"B"
,
"Gb"
]]){
var
t0
=
Date
.
now
();
var
width
=
ctx
.
canvas
.
width
;
var
height
=
ctx
.
canvas
.
height
;
var
inputImage
=
ctx
.
getImageData
(
0
,
0
,
width
,
height
);
var
iPixels
=
inputImage
.
data
;
var
outputImage
=
ctx
.
createImageData
(
width
/
2
,
height
/
2
);
var
oPixels
=
outputImage
.
data
;
var
oPixels
=
new
Uint8Array
(
pixels
.
length
/
4
);
for
(
var
y
=
0
;
y
<
height
/
2
;
y
++
){
for
(
var
x
=
0
;
x
<
width
/
2
;
x
++
){
for
(
var
k
=
0
;
k
<
4
;
k
++
){
y0
=
(
k
>>
1
)
&
1
;
x0
=
k
&
1
;
if
(
mosaic
[
y0
&
1
][
x0
&
1
]
==
"R"
)
r
=
iP
ixels
[
4
*
(
width
*
(
2
*
y
+
y0
)
+
2
*
x
+
x0
)
+
0
];
else
if
(
mosaic
[
y0
&
1
][
x0
&
1
]
==
"Gr"
)
gr
=
iP
ixels
[
4
*
(
width
*
(
2
*
y
+
y0
)
+
2
*
x
+
x0
)
+
1
];
else
if
(
mosaic
[
y0
&
1
][
x0
&
1
]
==
"Gb"
)
gb
=
iP
ixels
[
4
*
(
width
*
(
2
*
y
+
y0
)
+
2
*
x
+
x0
)
+
1
];
else
if
(
mosaic
[
y0
&
1
][
x0
&
1
]
==
"B"
)
b
=
iP
ixels
[
4
*
(
width
*
(
2
*
y
+
y0
)
+
2
*
x
+
x0
)
+
2
];
if
(
mosaic
[
y0
&
1
][
x0
&
1
]
==
"R"
)
r
=
p
ixels
[
4
*
(
width
*
(
2
*
y
+
y0
)
+
2
*
x
+
x0
)
+
0
];
else
if
(
mosaic
[
y0
&
1
][
x0
&
1
]
==
"Gr"
)
gr
=
p
ixels
[
4
*
(
width
*
(
2
*
y
+
y0
)
+
2
*
x
+
x0
)
+
1
];
else
if
(
mosaic
[
y0
&
1
][
x0
&
1
]
==
"Gb"
)
gb
=
p
ixels
[
4
*
(
width
*
(
2
*
y
+
y0
)
+
2
*
x
+
x0
)
+
1
];
else
if
(
mosaic
[
y0
&
1
][
x0
&
1
]
==
"B"
)
b
=
p
ixels
[
4
*
(
width
*
(
2
*
y
+
y0
)
+
2
*
x
+
x0
)
+
2
];
}
g
=
(
gr
+
gb
)
>>
1
;
oPixels
[
4
*
(
width
/
2
*
y
+
x
)
+
0
]
=
r
;
...
...
@@ -183,36 +251,36 @@ var Elphel = {
oPixels
[
4
*
(
width
/
2
*
y
+
x
)
+
3
]
=
255
;
}
}
ctx
.
canvas
.
width
=
width
/
2
;
ctx
.
canvas
.
height
=
height
/
2
;
ctx
.
putImageData
(
outputImage
,
0
,
0
);
console
.
log
(
"demosaicNearestNeighbor(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
return
oPixels
;
},
/* Name: demosaicBilinear
* Description: a simple bilinear demosaicing
*
* ctx - canvas 2D context
* px - pixel array as in "ctx.getImageData(0,0,width,height)"
* or use pixelsToArray(ctx,true) to get linear array from canvas
* mosaic - [["Gr","R"],["B","Gb"]] =
* odd lines: Gr,R,Gr,R
* even lines: B,Gb,B,Gb
* precise - true/false:
* true - calculate values then apply gamma - provide linear pixel array
* px_linear (8bit) = px^gamma (32bit), gamma=2
* false - calculate values from gamma encoded pixels - 2-4x times faster
*/
demosaicBilinear
:
function
(
ctx
,
px
,
mosaic
=
[[
"Gr"
,
"R"
],[
"B"
,
"Gb"
]],
precise
=
false
){
/**
* Name: demosaicBilinear
* Description: a simple bilinear demosaicing
*
* @pixels - pixel array, read from origin canvas
* pixels is a long 1-D array with the following structure:
* pix[i+0] - red
* pix[i+1] - green
* pix[i+2] - blue
* pix[i+3] - alpha
* @width - origin canvas width
* @height - origin canvas height
* @mosaic - [["Gr","R"],["B","Gb"]] - value comes from application
* odd lines: Gr,R,Gr,R
* even lines: B,Gb,B,Gb
* @precise - true/false:
* true - calculate values then apply gamma - provide linear pixel array
* px_linear (8bit) = px^gamma (32bit), gamma=2
* false - calculate values from gamma encoded pixels - 2-4x times faster
*/
demosaicBilinear
:
function
(
pixels
,
width
,
height
,
mosaic
=
[[
"Gr"
,
"R"
],[
"B"
,
"Gb"
]],
precise
=
false
){
var
t0
=
Date
.
now
();
var
width
=
ctx
.
canvas
.
width
;
var
height
=
ctx
.
canvas
.
height
;
var
outputImage
=
ctx
.
getImageData
(
0
,
0
,
width
,
height
);
var
oPixels
=
outputImage
.
data
;
var
oPixels
=
new
Uint8Array
(
pixels
.
length
);
var
x_l
=
0
,
x_r
=
0
;
var
y_t
=
0
,
y_b
=
0
;
...
...
@@ -229,16 +297,16 @@ var Elphel = {
//Gr
if
(
mosaic
[
y
%
2
][
x
%
2
]
==
"Gr"
){
Pr_y0xl
=
p
x
[
4
*
(
width
*
(
y
+
0
)
+
(
x_l
))
+
0
];
Pr_y0xr
=
p
x
[
4
*
(
width
*
(
y
+
0
)
+
(
x_r
))
+
0
];
Pb_ybx0
=
p
x
[
4
*
(
width
*
(
y_b
)
+
(
x
+
0
))
+
2
];
Pb_ytx0
=
p
x
[
4
*
(
width
*
(
y_t
)
+
(
x
+
0
))
+
2
];
Pr_y0xl
=
p
ixels
[
4
*
(
width
*
(
y
+
0
)
+
(
x_l
))
+
0
];
Pr_y0xr
=
p
ixels
[
4
*
(
width
*
(
y
+
0
)
+
(
x_r
))
+
0
];
Pb_ybx0
=
p
ixels
[
4
*
(
width
*
(
y_b
)
+
(
x
+
0
))
+
2
];
Pb_ytx0
=
p
ixels
[
4
*
(
width
*
(
y_t
)
+
(
x
+
0
))
+
2
];
if
(
precise
){
//Pr = pixel_l2g(1/2*(pixel_g2l(Pr_y0xl)+pixel_g2l(Pr_y0xr)));
//Pb = pixel_l2g(1/2*(pixel_g2l(Pb_ybx0)+pixel_g2l(Pb_ytx0)));
Pr
=
this
.
l2g
(
1
/
2
*
(
Pr_y0xl
+
Pr_y0xr
));
Pb
=
this
.
l2g
(
1
/
2
*
(
Pb_ybx0
+
Pb_ytx0
));
Pr
=
this
.
Functions
.
l2g
(
1
/
2
*
(
Pr_y0xl
+
Pr_y0xr
));
Pb
=
this
.
Functions
.
l2g
(
1
/
2
*
(
Pb_ybx0
+
Pb_ytx0
));
}
else
{
Pr
=
1
/
2
*
(
Pr_y0xl
+
Pr_y0xr
);
Pb
=
1
/
2
*
(
Pb_ybx0
+
Pb_ytx0
);
...
...
@@ -250,19 +318,19 @@ var Elphel = {
//R
if
(
mosaic
[
y
%
2
][
x
%
2
]
==
"R"
){
Pg_ytx0
=
p
x
[
4
*
(
width
*
(
y_t
)
+
(
x
+
0
))
+
1
];
Pg_y0xl
=
p
x
[
4
*
(
width
*
(
y
+
0
)
+
(
x_l
))
+
1
];
Pg_y0xr
=
p
x
[
4
*
(
width
*
(
y
+
0
)
+
(
x_r
))
+
1
];
Pg_ybx0
=
p
x
[
4
*
(
width
*
(
y_b
)
+
(
x
+
0
))
+
1
];
Pg_ytx0
=
p
ixels
[
4
*
(
width
*
(
y_t
)
+
(
x
+
0
))
+
1
];
Pg_y0xl
=
p
ixels
[
4
*
(
width
*
(
y
+
0
)
+
(
x_l
))
+
1
];
Pg_y0xr
=
p
ixels
[
4
*
(
width
*
(
y
+
0
)
+
(
x_r
))
+
1
];
Pg_ybx0
=
p
ixels
[
4
*
(
width
*
(
y_b
)
+
(
x
+
0
))
+
1
];
Pb_ytxl
=
p
x
[
4
*
(
width
*
(
y_t
)
+
(
x_l
))
+
2
];
Pb_ytxr
=
p
x
[
4
*
(
width
*
(
y_t
)
+
(
x_r
))
+
2
];
Pb_ybxl
=
p
x
[
4
*
(
width
*
(
y_b
)
+
(
x_l
))
+
2
];
Pb_ybxr
=
p
x
[
4
*
(
width
*
(
y_b
)
+
(
x_r
))
+
2
];
Pb_ytxl
=
p
ixels
[
4
*
(
width
*
(
y_t
)
+
(
x_l
))
+
2
];
Pb_ytxr
=
p
ixels
[
4
*
(
width
*
(
y_t
)
+
(
x_r
))
+
2
];
Pb_ybxl
=
p
ixels
[
4
*
(
width
*
(
y_b
)
+
(
x_l
))
+
2
];
Pb_ybxr
=
p
ixels
[
4
*
(
width
*
(
y_b
)
+
(
x_r
))
+
2
];
if
(
precise
){
Pg
=
this
.
l2g
(
1
/
4
*
(
Pg_ytx0
+
Pg_y0xl
+
Pg_y0xr
+
Pg_ybx0
));
Pb
=
this
.
l2g
(
1
/
4
*
(
Pb_ytxl
+
Pb_ytxr
+
Pb_ybxl
+
Pb_ybxr
));
Pg
=
this
.
Functions
.
l2g
(
1
/
4
*
(
Pg_ytx0
+
Pg_y0xl
+
Pg_y0xr
+
Pg_ybx0
));
Pb
=
this
.
Functions
.
l2g
(
1
/
4
*
(
Pb_ytxl
+
Pb_ytxr
+
Pb_ybxl
+
Pb_ybxr
));
}
else
{
Pg
=
1
/
4
*
(
Pg_ytx0
+
Pg_y0xl
+
Pg_y0xr
+
Pg_ybx0
);
Pb
=
1
/
4
*
(
Pb_ytxl
+
Pb_ytxr
+
Pb_ybxl
+
Pb_ybxr
);
...
...
@@ -275,19 +343,19 @@ var Elphel = {
//B
if
(
mosaic
[
y
%
2
][
x
%
2
]
==
"B"
){
Pr_ytxl
=
p
x
[
4
*
(
width
*
(
y_t
)
+
(
x_l
))
+
0
];
Pr_ytxr
=
p
x
[
4
*
(
width
*
(
y_t
)
+
(
x_r
))
+
0
];
Pr_ybxl
=
p
x
[
4
*
(
width
*
(
y_b
)
+
(
x_l
))
+
0
];
Pr_ybxr
=
p
x
[
4
*
(
width
*
(
y_b
)
+
(
x_r
))
+
0
];
Pr_ytxl
=
p
ixels
[
4
*
(
width
*
(
y_t
)
+
(
x_l
))
+
0
];
Pr_ytxr
=
p
ixels
[
4
*
(
width
*
(
y_t
)
+
(
x_r
))
+
0
];
Pr_ybxl
=
p
ixels
[
4
*
(
width
*
(
y_b
)
+
(
x_l
))
+
0
];
Pr_ybxr
=
p
ixels
[
4
*
(
width
*
(
y_b
)
+
(
x_r
))
+
0
];
Pg_ytx0
=
p
x
[
4
*
(
width
*
(
y_t
)
+
(
x
+
0
))
+
1
];
Pg_y0xl
=
p
x
[
4
*
(
width
*
(
y
+
0
)
+
(
x_l
))
+
1
];
Pg_y0xr
=
p
x
[
4
*
(
width
*
(
y
+
0
)
+
(
x_r
))
+
1
];
Pg_ybx0
=
p
x
[
4
*
(
width
*
(
y_b
)
+
(
x
+
0
))
+
1
];
Pg_ytx0
=
p
ixels
[
4
*
(
width
*
(
y_t
)
+
(
x
+
0
))
+
1
];
Pg_y0xl
=
p
ixels
[
4
*
(
width
*
(
y
+
0
)
+
(
x_l
))
+
1
];
Pg_y0xr
=
p
ixels
[
4
*
(
width
*
(
y
+
0
)
+
(
x_r
))
+
1
];
Pg_ybx0
=
p
ixels
[
4
*
(
width
*
(
y_b
)
+
(
x
+
0
))
+
1
];
if
(
precise
){
Pr
=
this
.
l2g
(
1
/
4
*
(
Pr_ytxl
+
Pr_ytxr
+
Pr_ybxl
+
Pr_ybxr
));
Pg
=
this
.
l2g
(
1
/
4
*
(
Pg_ytx0
+
Pg_y0xl
+
Pg_y0xr
+
Pg_ybx0
));
Pr
=
this
.
Functions
.
l2g
(
1
/
4
*
(
Pr_ytxl
+
Pr_ytxr
+
Pr_ybxl
+
Pr_ybxr
));
Pg
=
this
.
Functions
.
l2g
(
1
/
4
*
(
Pg_ytx0
+
Pg_y0xl
+
Pg_y0xr
+
Pg_ybx0
));
}
else
{
Pr
=
1
/
4
*
(
Pr_ytxl
+
Pr_ytxr
+
Pr_ybxl
+
Pr_ybxr
);
Pg
=
1
/
4
*
(
Pg_ytx0
+
Pg_y0xl
+
Pg_y0xr
+
Pg_ybx0
);
...
...
@@ -299,14 +367,14 @@ var Elphel = {
//Gb
if
(
mosaic
[
y
%
2
][
x
%
2
]
==
"Gb"
){
Pr_ytx0
=
p
x
[
4
*
(
width
*
(
y_t
)
+
(
x
+
0
))
+
0
];
Pr_ybx0
=
p
x
[
4
*
(
width
*
(
y_b
)
+
(
x
+
0
))
+
0
];
Pb_y0xl
=
p
x
[
4
*
(
width
*
(
y
+
0
)
+
(
x_l
))
+
2
];
Pb_y0xr
=
p
x
[
4
*
(
width
*
(
y
+
0
)
+
(
x_r
))
+
2
];
Pr_ytx0
=
p
ixels
[
4
*
(
width
*
(
y_t
)
+
(
x
+
0
))
+
0
];
Pr_ybx0
=
p
ixels
[
4
*
(
width
*
(
y_b
)
+
(
x
+
0
))
+
0
];
Pb_y0xl
=
p
ixels
[
4
*
(
width
*
(
y
+
0
)
+
(
x_l
))
+
2
];
Pb_y0xr
=
p
ixels
[
4
*
(
width
*
(
y
+
0
)
+
(
x_r
))
+
2
];
if
(
precise
){
Pr
=
this
.
l2g
(
1
/
2
*
(
Pr_ytx0
+
Pr_ybx0
));
Pb
=
this
.
l2g
(
1
/
2
*
(
Pb_y0xl
+
Pb_y0xr
));
Pr
=
this
.
Functions
.
l2g
(
1
/
2
*
(
Pr_ytx0
+
Pr_ybx0
));
Pb
=
this
.
Functions
.
l2g
(
1
/
2
*
(
Pb_y0xl
+
Pb_y0xr
));
}
else
{
Pr
=
1
/
2
*
(
Pr_ytx0
+
Pr_ybx0
);
Pb
=
1
/
2
*
(
Pb_y0xl
+
Pb_y0xr
);
...
...
@@ -317,66 +385,73 @@ var Elphel = {
}
}
}
ctx
.
putImageData
(
outputImage
,
0
,
0
);
console
.
log
(
"demosaicBilinear(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
return
oPixels
;
},
/* Name: showSingleColorChannel
* Description: make a BW from selected channel
*
* ctx - canvas 2D context
* channel - "red","green","blue"
*/
showSingleColorChannel
:
function
(
ctx
,
channel
){
var
width
=
ctx
.
canvas
.
width
;
var
height
=
ctx
.
canvas
.
height
;
var
inputImage
=
ctx
.
getImageData
(
0
,
0
,
width
,
height
);
var
iPixels
=
inputImage
.
data
;
/**
* Name: showSingleColorChannel
* Description: make a BW from selected channel
*
* @pixels - pixel array, read from origin canvas
* pixels is a long 1-D array with the following structure:
* pix[i+0] - red
* pix[i+1] - green
* pix[i+2] - blue
* pix[i+3] - alpha
* @width - origin canvas width (not really needed)
* @height - origin canvas height (not really needed)
* @channel - string - "red","green","blue"
*/
showSingleColorChannel
:
function
(
pixels
,
width
,
height
,
channel
){
for
(
var
y
=
0
;
y
<
height
;
y
++
){
for
(
var
x
=
0
;
x
<
width
;
x
++
){
r
=
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
0
];
g
=
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
1
];
b
=
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
2
];
r
=
p
ixels
[
4
*
(
width
*
y
+
x
)
+
0
];
g
=
p
ixels
[
4
*
(
width
*
y
+
x
)
+
1
];
b
=
p
ixels
[
4
*
(
width
*
y
+
x
)
+
2
];
if
(
channel
==
"red"
){
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
0
]
=
r
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
1
]
=
r
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
2
]
=
r
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
0
]
=
r
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
1
]
=
r
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
2
]
=
r
;
}
else
if
(
channel
==
"green"
){
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
0
]
=
g
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
1
]
=
g
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
2
]
=
g
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
0
]
=
g
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
1
]
=
g
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
2
]
=
g
;
}
else
if
(
channel
==
"blue"
){
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
0
]
=
b
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
1
]
=
b
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
2
]
=
b
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
0
]
=
b
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
1
]
=
b
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
2
]
=
b
;
}
}
}
ctx
.
putImageData
(
inputImage
,
0
,
0
)
;
return
pixels
;
},
/* Name: applySaturation
* Description: get data from ctx saturate and redraw
*
* ctx - canvas 2D context
* s - value
*/
applySaturation
:
function
(
ctx
,
s
){
var
width
=
ctx
.
canvas
.
width
;
var
height
=
ctx
.
canvas
.
height
;
var
inputImage
=
ctx
.
getImageData
(
0
,
0
,
width
,
height
);
var
iPixels
=
inputImage
.
data
;
/**
* Name: applySaturation
* Description: get data from ctx saturate and redraw
*
* @pixels - pixel array, read from origin canvas
* pixels is a long 1-D array with the following structure:
* pix[i+0] - red
* pix[i+1] - green
* pix[i+2] - blue
* pix[i+3] - alpha
* @width - origin canvas width
* @height - origin canvas height
* @s - saturation coefficient
*/
applySaturation
:
function
(
pixels
,
width
,
height
,
s
){
var
r
,
g
,
b
;
var
Y
,
Cb
,
Cr
;
for
(
var
y
=
0
;
y
<
height
;
y
++
){
for
(
var
x
=
0
;
x
<
width
;
x
++
){
r
=
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
0
];
g
=
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
1
];
b
=
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
2
];
r
=
p
ixels
[
4
*
(
width
*
y
+
x
)
+
0
];
g
=
p
ixels
[
4
*
(
width
*
y
+
x
)
+
1
];
b
=
p
ixels
[
4
*
(
width
*
y
+
x
)
+
2
];
Y
=
0.299
*
r
+
0.5870
*
g
+
0.144
*
b
;
...
...
@@ -394,117 +469,21 @@ var Elphel = {
if
(
g
<
0
)
g
=
0
;
if
(
g
>
255
)
g
=
255
;
if
(
b
<
0
)
b
=
0
;
if
(
b
>
255
)
b
=
255
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
0
]
=
r
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
1
]
=
g
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
2
]
=
b
;
iP
ixels
[
4
*
(
width
*
y
+
x
)
+
3
]
=
255
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
0
]
=
r
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
1
]
=
g
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
2
]
=
b
;
p
ixels
[
4
*
(
width
*
y
+
x
)
+
3
]
=
255
;
}
}
ctx
.
putImageData
(
inputImage
,
0
,
0
);
},
/* Name: l2g
* Desctiptin: convert a value from linear to gamma encoded,
* close to square root
*/
l2g
:
function
(
pv
){
// assuming gamma=2
var
tmp
=
Math
.
sqrt
(
pv
);
if
(
tmp
>
255
)
tmp
=
255
;
return
tmp
;
},
/* Name: g2l
* Desctiptin: convert a value gamma encoded to linear,
* close to square
*/
g2l
:
function
(
pv
){
// assuming gamma = 2
var
tmp
=
pv
*
pv
;
return
tmp
;
},
/* Name: pixelsToArray
* Desctiptin: get pixel data from canvas context and copy to
* an array. The array will be Uint8ClampedArray
*/
pixelsToArray
:
function
(
ctx
){
t0
=
Date
.
now
();
var
px
=
[];
var
width
=
ctx
.
canvas
.
width
;
var
height
=
ctx
.
canvas
.
height
;
var
image
=
ctx
.
getImageData
(
0
,
0
,
width
,
height
);
var
pixels
=
image
.
data
;
px
=
pixels
.
slice
(
0
);
console
.
log
(
"pixelsToArray(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
return
px
;
},
/* Name: pixelsToArrayLinear
* Desctiptin: get pixel data from canvas context, convert to linear,
* then copy to an array.
*/
pixelsToArrayLinear
:
function
(
ctx
){
t0
=
Date
.
now
();
var
px
=
[];
var
width
=
ctx
.
canvas
.
width
;
var
height
=
ctx
.
canvas
.
height
;
var
image
=
ctx
.
getImageData
(
0
,
0
,
width
,
height
);
var
pixels
=
image
.
data
;
for
(
var
i
=
0
;
i
<
pixels
.
length
;
i
+=
4
){
px
[
i
+
0
]
=
this
.
g2l
(
pixels
[
i
+
0
]);
px
[
i
+
1
]
=
this
.
g2l
(
pixels
[
i
+
1
]);
px
[
i
+
2
]
=
this
.
g2l
(
pixels
[
i
+
2
]);
px
[
i
+
3
]
=
pixels
[
i
+
3
];
//alpha
}
console
.
log
(
"pixelsToArrayLinear(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
return
px
;
return
pixels
;
},
/* Name: drawScaled
* Description: Plugin specific. Takes source canvas - draws a scaled
* version on destination canvas
*/
drawScaled
:
function
(
cnv_src
,
cnv_dst
,
width
){
var
t0
=
Date
.
now
();
var
ctx
=
cnv_src
[
0
].
getContext
(
'2d'
);
var
tw
=
ctx
.
canvas
.
width
;
var
th
=
ctx
.
canvas
.
height
;
var
tr
=
tw
/
th
;
var
sctx
=
cnv_dst
[
0
].
getContext
(
'2d'
);
var
w
=
Math
.
round
(
width
);
var
h
=
Math
.
round
(
w
/
tr
);
sctx
.
canvas
.
width
=
w
;
sctx
.
canvas
.
height
=
h
;
cscale
=
Math
.
round
(
w
/
tw
*
100
)
/
100
;
sctx
.
scale
(
cscale
,
cscale
);
sctx
.
drawImage
(
cnv_src
[
0
],
0
,
0
);
console
.
log
(
"drawScaled(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
},
/* Name: diffColorChannels
* Description: color channel difference
*
*/
diffColorChannels
:
function
(
px
,
chn1
,
chn2
,
k
=
1
){
/**
* Name: diffColorChannels
* Description: color channel difference
*
*/
diffColorChannels
:
function
(
pixels
,
chn1
,
chn2
,
k
=
1
){
var
t0
=
Date
.
now
();
...
...
@@ -516,37 +495,38 @@ var Elphel = {
if
(
chn2
==
"green"
)
i2
=
1
;
if
(
chn2
==
"blue"
)
i2
=
2
;
for
(
var
i
=
0
;
i
<
(
p
x
.
length
>>
2
);
i
++
){
diff
=
k
*
p
x
[
4
*
i
+
i1
]
-
px
[
4
*
i
+
i2
];
p
x
[
4
*
i
+
0
]
=
diff
;
p
x
[
4
*
i
+
1
]
=
diff
;
p
x
[
4
*
i
+
2
]
=
diff
;
p
x
[
4
*
i
+
3
]
=
255
;
for
(
var
i
=
0
;
i
<
(
p
ixels
.
length
>>
2
);
i
++
){
diff
=
k
*
p
ixels
[
4
*
i
+
i1
]
-
pixels
[
4
*
i
+
i2
];
p
ixels
[
4
*
i
+
0
]
=
diff
;
p
ixels
[
4
*
i
+
1
]
=
diff
;
p
ixels
[
4
*
i
+
2
]
=
diff
;
p
ixels
[
4
*
i
+
3
]
=
255
;
}
console
.
log
(
"diffColorChannels(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
return
p
x
;
return
p
ixels
;
},
/* Name: ndvi
* Description: get ndvi
*/
ndvi
:
function
(
px
){
/**
* Name: ndvi_experimental
* Description: get ndvi
*/
ndvi_experimental
:
function
(
pixels
){
var
r
,
g
,
b
;
var
NIR
,
RED
,
NDVI
;
for
(
var
i
=
0
;
i
<
(
p
x
.
length
>>
2
);
i
++
){
r
=
p
x
[
4
*
i
+
0
];
g
=
p
x
[
4
*
i
+
1
];
b
=
p
x
[
4
*
i
+
2
];
for
(
var
i
=
0
;
i
<
(
p
ixels
.
length
>>
2
);
i
++
){
r
=
p
ixels
[
4
*
i
+
0
];
g
=
p
ixels
[
4
*
i
+
1
];
b
=
p
ixels
[
4
*
i
+
2
];
if
((
b
>
r
)
||
(
g
>
r
))
{
console
.
log
(
"Color error!"
);
NIR
=
0
;
RED
=
1
;
//if (b>r) p
x
[4*(width*y+x)+2]=255;
if
(
b
>
r
)
p
x
[
4
*
i
+
2
]
=
0
;
if
(
g
>
r
)
p
x
[
4
*
i
+
1
]
=
0
;
p
x
[
4
*
i
+
0
]
=
200
;
//if (b>r) p
ixels
[4*(width*y+x)+2]=255;
if
(
b
>
r
)
p
ixels
[
4
*
i
+
2
]
=
0
;
if
(
g
>
r
)
p
ixels
[
4
*
i
+
1
]
=
0
;
p
ixels
[
4
*
i
+
0
]
=
200
;
}
else
{
if
((
r
-
b
)
<
20
)
b
=
0
;
k
=
0.6
;
...
...
@@ -563,58 +543,72 @@ var Elphel = {
}
//console.log("RED="+RED+" NIR="+NIR);
p
x
[
4
*
i
+
0
]
=
r
;
p
x
[
4
*
i
+
1
]
=
g
;
p
x
[
4
*
i
+
2
]
=
b
;
p
ixels
[
4
*
i
+
0
]
=
r
;
p
ixels
[
4
*
i
+
1
]
=
g
;
p
ixels
[
4
*
i
+
2
]
=
b
;
}
}
return
p
x
;
return
p
ixels
;
},
/* Name: gammaEncode
* Description: -
*/
gammaEncode
:
function
(
px
){
for
(
var
i
=
0
;
i
<
(
px
.
length
>>
2
);
i
++
){
px
[
4
*
i
+
0
]
=
this
.
l2g
(
px
[
4
*
i
+
0
]);
px
[
4
*
i
+
1
]
=
this
.
l2g
(
px
[
4
*
i
+
1
]);
px
[
4
*
i
+
2
]
=
this
.
l2g
(
px
[
4
*
i
+
2
]);
/**
* Name: gammaEncode
* Description: -
*/
gammaEncode
:
function
(
pixels
){
for
(
var
i
=
0
;
i
<
(
pixels
.
length
>>
2
);
i
++
){
pixels
[
4
*
i
+
0
]
=
this
.
Functions
.
l2g
(
pixels
[
4
*
i
+
0
]);
pixels
[
4
*
i
+
1
]
=
this
.
Functions
.
l2g
(
pixels
[
4
*
i
+
1
]);
pixels
[
4
*
i
+
2
]
=
this
.
Functions
.
l2g
(
pixels
[
4
*
i
+
2
]);
}
return
p
x
;
return
p
ixels
;
},
/* Name: gammaDecode
* Description: -
*/
gammaDecode
:
function
(
px
){
for
(
var
i
=
0
;
i
<
(
px
.
length
>>
2
);
i
++
){
px
[
4
*
i
+
0
]
=
this
.
g2l
(
px
[
4
*
i
+
0
]);
px
[
4
*
i
+
1
]
=
this
.
g2l
(
px
[
4
*
i
+
1
]);
px
[
4
*
i
+
2
]
=
this
.
g2l
(
px
[
4
*
i
+
2
]);
}
return
px
;
},
/* Name: drawImageData
* Description: -
*/
drawImageData
:
function
(
ctx
,
px
){
var
t0
=
Date
.
now
();
var
img
=
ctx
.
createImageData
(
ctx
.
canvas
.
width
,
ctx
.
canvas
.
height
);
var
imgdata
=
img
.
data
;
for
(
var
i
=
0
;
i
<
(
imgdata
.
length
>>
2
);
i
++
){
imgdata
[
4
*
i
+
0
]
=
px
[
4
*
i
+
0
];
imgdata
[
4
*
i
+
1
]
=
px
[
4
*
i
+
1
];
imgdata
[
4
*
i
+
2
]
=
px
[
4
*
i
+
2
];
imgdata
[
4
*
i
+
3
]
=
px
[
4
*
i
+
3
];
/**
* Name: gammaDecode
* Description: -
*/
gammaDecode
:
function
(
pixels
){
for
(
var
i
=
0
;
i
<
(
pixels
.
length
>>
2
);
i
++
){
pixels
[
4
*
i
+
0
]
=
this
.
Functions
.
g2l
(
pixels
[
4
*
i
+
0
]);
pixels
[
4
*
i
+
1
]
=
this
.
Functions
.
g2l
(
pixels
[
4
*
i
+
1
]);
pixels
[
4
*
i
+
2
]
=
this
.
Functions
.
g2l
(
pixels
[
4
*
i
+
2
]);
}
ctx
.
putImageData
(
img
,
0
,
0
);
console
.
log
(
"drawImageData(): "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
return
pixels
;
}
},
// simple funcitons
Functions
:{
/**
* Name: l2g
* Desctiptin: convert a value from linear to gamma encoded,
* close to square root
*/
l2g
:
function
(
pv
){
// assuming gamma=2
var
tmp
=
Math
.
sqrt
(
pv
);
if
(
tmp
>
255
)
tmp
=
255
;
return
tmp
;
},
};
/*
* Name: g2l
* Desctiptin: convert a value gamma encoded to linear,
* close to square
*/
g2l
:
function
(
pv
){
// assuming gamma = 2
var
tmp
=
pv
*
pv
;
return
tmp
;
}
},
test
:
function
(){
console
.
log
(
"Test message from elphel.js: ok"
);
}
}
\ No newline at end of file
src/jp4-canvas/jquery-jp4.js
View file @
e233bb6d
...
...
@@ -59,71 +59,75 @@
var
PIXELS
=
[];
var
cnv_working
=
$
(
"<canvas>"
,{
id
:
"result"
}).
css
({
display
:
"none"
});
var
cnv_display
=
$
(
"<canvas>"
,{
id
:
"scaled"
});
var
cnv_working
=
$
(
"<canvas>"
,{
id
:
"working"
});
var
cnv_display
=
$
(
"<canvas>"
,{
id
:
"display"
});
elem
.
append
(
cnv_working
).
append
(
cnv_display
);
// hide working canvas
cnv_working
.
css
({
display
:
"none"
});
elem
.
append
(
cnv_working
);
elem
.
append
(
cnv_display
);
get_image
();
//end
function
get_image
(){
var
canvas
=
cnv_working
;
var
scaled_canvas
=
cnv_display
;
//reset format
IMAGE_FORMAT
=
"JPEG"
;
var
http
=
new
XMLHttpRequest
();
var
rq
=
""
;
if
(
settings
.
port
!=
""
){
rq
=
"get-image.php?port="
+
settings
.
port
+
"&rel=bimg&ts="
+
Date
.
now
();
settings
.
refresh
=
true
;
}
else
{
rq
=
settings
.
image
;
}
http
.
open
(
"GET"
,
rq
,
true
);
http
.
responseType
=
"blob"
;
http
.
onload
=
function
(
e
)
{
if
(
this
.
status
===
200
)
{
var
heavyImage
=
new
Image
();
heavyImage
.
onload
=
function
(){
EXIF
.
getData
(
this
,
function
()
{
//update canvas size
canvas
.
attr
(
"width"
,
this
.
width
);
canvas
.
attr
(
"height"
,
this
.
height
);
var
canvas
=
cnv_working
;
//reset format
IMAGE_FORMAT
=
"JPEG"
;
parseEXIFMakerNote
(
this
);
canvas
.
drawImage
({
x
:
0
,
y
:
0
,
source
:
heavyImage
,
load
:
redraw
,
//scale: 1,
fromCenter
:
false
});
});
};
heavyImage
.
src
=
URL
.
createObjectURL
(
http
.
response
);
}
var
http
=
new
XMLHttpRequest
();
var
rq
=
""
;
if
(
settings
.
port
!=
""
){
rq
=
"get-image.php?port="
+
settings
.
port
+
"&rel=bimg&ts="
+
Date
.
now
();
settings
.
refresh
=
true
;
}
else
{
rq
=
settings
.
image
;
}
http
.
open
(
"GET"
,
rq
,
true
);
http
.
responseType
=
"blob"
;
http
.
onload
=
function
(
e
)
{
if
(
this
.
status
===
200
)
{
var
heavyImage
=
new
Image
();
heavyImage
.
onload
=
function
(){
EXIF
.
getData
(
this
,
function
()
{
//update canvas size
canvas
.
attr
(
"width"
,
this
.
width
);
canvas
.
attr
(
"height"
,
this
.
height
);
parseEXIFMakerNote
(
this
);
canvas
.
drawImage
({
x
:
0
,
y
:
0
,
source
:
heavyImage
,
load
:
redraw
,
fromCenter
:
false
});
});
};
h
ttp
.
send
(
);
h
eavyImage
.
src
=
URL
.
createObjectURL
(
http
.
response
);
}
};
http
.
send
();
}
function
redraw
(){
$
(
this
).
draw
({
fn
:
function
(
ctx
){
var
t0
=
Date
.
now
();
if
((
IMAGE_FORMAT
==
"JP4"
)
||
(
IMAGE_FORMAT
==
"JP46"
)){
if
(
settings
.
fast
){
quickestPreview
(
ctx
);
}
else
{
}
/*
else{
Elphel.reorderJP4Blocks(ctx,"JP4");
if (settings.precise){
...
...
@@ -153,12 +157,15 @@
}
}
*/
// RGB -> YCbCr x SATURATION -> RGB
// Taking SATURATION[0] = 1/GAMMA[0] (green pixel of GR-line)
//saturation(ctx,SATURATION[0]);
}
Elphel
.
drawScaled
(
cnv_working
,
cnv_display
,
settings
.
width
);
console
.
log
(
"#"
+
elem
.
attr
(
"id"
)
+
", time: "
+
(
Date
.
now
()
-
t0
)
/
1000
+
" s"
);
// custom event
$
(
this
).
trigger
(
"canvas_ready"
);
if
(
settings
.
refresh
)
get_image
();
...
...
@@ -167,10 +174,50 @@
}
function
quickestPreview
(
ctx
){
Elphel
.
reorderJP4Blocks
(
ctx
,
"JP4"
,
settings
.
mosaic
,
settings
.
fast
);
Elphel
.
applySaturation
(
ctx
,
SATURATION
[
0
]);
var
worker
=
new
Worker
(
'js/webworker.js'
);
var
width
=
ctx
.
canvas
.
width
;
var
height
=
ctx
.
canvas
.
height
;
var
image
=
ctx
.
getImageData
(
0
,
0
,
width
,
height
);
var
pixels
=
image
.
data
;
worker
.
postMessage
({
mosaic
:
settings
.
mosaic
,
format
:
IMAGE_FORMAT
,
width
:
ctx
.
canvas
.
width
,
height
:
ctx
.
canvas
.
height
,
pixels
:
pixels
.
buffer
,
settings
:
{
fast
:
settings
.
fast
,
channel
:
settings
.
channel
,
diff
:
settings
.
diff
,
ndvi
:
settings
.
ndvi
},
},[
pixels
.
buffer
]);
worker
.
onmessage
=
function
(
e
){
var
pixels
=
new
Uint8Array
(
e
.
data
.
pixels
);
var
working_context
=
cnv_working
[
0
].
getContext
(
'2d'
);
var
width
=
e
.
data
.
width
;
var
height
=
e
.
data
.
height
;
Elphel
.
Canvas
.
putImageData
(
working_context
,
pixels
,
width
,
height
);
Elphel
.
Canvas
.
drawScaled
(
cnv_working
,
cnv_display
,
settings
.
width
);
}
}
/**
* plugin globals get changed
* @FLIPV - not used
* @FLIPH - not used
* @BAYER - not used
* @IMAGE_FORMAT - used
* @SATURATION[i] - not used
*/
function
parseEXIFMakerNote
(
src
){
var
exif_orientation
=
EXIF
.
getTag
(
src
,
"Orientation"
);
...
...
@@ -239,7 +286,7 @@
*/
for
(
i
=
0
;
i
<
4
;
i
++
)
{
//SATURATION[i] = 1/gammas[i];
//SATURATION[i] = 1.75; //
nightmate
time
//SATURATION[i] = 1.75; //
nightmarish
time
SATURATION
[
i
]
=
2
;
}
//console.log("MakerNote: Saturations: "+SATURATION[0]+" "+SATURATION[1]+" "+SATURATION[2]+" "+SATURATION[3]);
...
...
src/jp4-canvas/webworker.js
0 → 100644
View file @
e233bb6d
importScripts
(
'elphel.js'
);
self
.
onmessage
=
function
(
e
)
{
var
W
=
e
.
data
.
width
;
var
H
=
e
.
data
.
height
;
var
Mosaic
=
e
.
data
.
mosaic
;
var
Format
=
e
.
data
.
format
;
var
settings
=
e
.
data
.
settings
;
var
Pixels
=
new
Uint8Array
(
e
.
data
.
pixels
);
var
reorderedPixels
=
Elphel
.
Pixels
.
reorderBlocksJPx
(
Pixels
,
W
,
H
,
Format
,
Mosaic
,
settings
.
fast
);
//reorder first then downscale
if
(
settings
.
fast
){
W
=
W
/
2
;
H
=
H
/
2
;
}
Elphel
.
Pixels
.
applySaturation
(
reorderedPixels
,
W
,
H
,
2
);
postMessage
({
width
:
W
,
height
:
H
,
pixels
:
reorderedPixels
.
buffer
},[
reorderedPixels
.
buffer
]);
//Elphel.test();
};
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment