├── .gitmodules
├── AlexaX2.labin
├── Amira709.labin
├── CHANGELOG.md
├── CWLSB.png
├── CWMSB.png
├── Cine709.labin
├── GrayLSB.png
├── GrayMSB.png
├── HDRPreviewLSB.png
├── HDRPreviewMSB.png
├── LC709.labin
├── LC709A.labin
├── LDRPreviewLSB.png
├── LDRPreviewMSB.png
├── LICENSE
├── LUTCalc.icns
├── README.md
├── V709.labin
├── apple-touch-icon.png
├── blob
├── Blob.js
├── LICENSE.md
└── README.md
├── cpoutdaylight.labin
├── cpouttungsten.labin
├── favicon-16x16.png
├── favicon-192x192.png
├── favicon-32x32.png
├── favicon.ico
├── filesaver
├── FileSaver.js
├── FileSaver.min.js
└── FileSaver.min.js.map
├── img
├── Screenshot-Tall-1.png
├── Screenshot-Wide-1.png
├── lutcalc-1024.png
├── lutcalc-128.png
├── lutcalc-16.png
├── lutcalc-19.png
├── lutcalc-256.png
├── lutcalc-32.png
├── lutcalc-38.png
├── lutcalc-48.png
├── lutcalc-512.png
├── lutcalc-60.png
├── lutcalc-64.png
└── lutcalc-90.png
├── index.html
├── indexunminified.html
├── js
├── background.js
├── bounding.js
├── brent.js
├── colourspace.js
├── colourspaceworker.js
├── colourspaceworkerscombined.js
├── gamma.js
├── gammaworker.js
├── gammaworkerscombined.js
├── lut-3dl.js
├── lut-cube.js
├── lut-davinci.js
├── lut-la.js
├── lut-lut.js
├── lut-ncp.js
├── lut-spi1d.js
├── lut-spi3d.js
├── lut-vlt.js
├── lut.js
├── lutanalyst.js
├── lutcalc.js
├── lutcalccombined.js
├── lutcamerabox.js
├── lutfile.js
├── lutformats.js
├── lutgammabox.js
├── lutgeneratebox.js
├── lutinfobox.js
├── lutlutbox.js
├── lutmessage.js
├── lutmobile.js
├── lutpreview.js
├── luttweaksbox.js
├── ring.js
├── splash.js
├── twk-asccdl.js
├── twk-blank.js
├── twk-blkgam.js
├── twk-blkhi.js
├── twk-cs.js
├── twk-display.js
├── twk-fc.js
├── twk-gamlim.js
├── twk-hg.js
├── twk-knee.js
├── twk-la.js
├── twk-multi.js
├── twk-psstcdl.js
├── twk-sampler.js
├── twk-sdrsat.js
└── twk-white.js
├── manifest.json
├── mobile.css
├── pngs
├── cust-asc-1.png
├── cust-asc.png
├── cust-bgm-1.png
├── cust-bgm.png
├── cust-bhi-1.png
├── cust-bhi-2.png
├── cust-bhi-3.png
├── cust-bhi.png
├── cust-colour-1.png
├── cust-colour-2.png
├── cust-colour.png
├── cust-dcc-1.png
├── cust-dcc.png
├── cust-fc-1.png
├── cust-fc.png
├── cust-glim-1.png
├── cust-glim-2.png
├── cust-glim-3.png
├── cust-glim.png
├── cust-header.png
├── cust-hg-1.png
├── cust-hg.png
├── cust-knee-1.png
├── cust-knee.png
├── cust-la-1.png
├── cust-la-2.png
├── cust-la-3.png
├── cust-la.png
├── cust-multi-1.jpg
├── cust-multi-2.jpg
├── cust-multi.png
├── cust-psst-1.png
├── cust-psst-2.jpg
├── cust-psst-3.png
├── cust-psst.png
├── cust-samp-1.png
├── cust-samp.png
├── cust-sdrs.png
├── cust-wht-1.png
├── cust-wht-2.png
├── cust-wht.png
├── ins-cam-1.png
├── ins-cust-wht-1.png
├── ins-gam-1.png
├── ins-inf-1.png
├── ins-lut-1.png
├── ins-lut-2.png
├── ins-pre-1.jpg
├── ins-pre-2.jpg
├── ins-pre-3.png
├── main-but-gen.png
├── main-but-gst.png
├── main-but-pre.png
├── main-but-set.png
├── main-cam.png
├── main-footer.png
├── main-gam.png
├── main-header.png
├── main-inf.png
├── main-lut.png
├── main-twk.png
├── mob-chart-icon.png
└── mob-preview-icon.png
├── s709.labin
├── style.css
├── window.html
├── xyuvLSB.png
└── xyuvMSB.png
/.gitmodules:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/.gitmodules
--------------------------------------------------------------------------------
/AlexaX2.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/AlexaX2.labin
--------------------------------------------------------------------------------
/Amira709.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/Amira709.labin
--------------------------------------------------------------------------------
/CWLSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/CWLSB.png
--------------------------------------------------------------------------------
/CWMSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/CWMSB.png
--------------------------------------------------------------------------------
/Cine709.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/Cine709.labin
--------------------------------------------------------------------------------
/GrayLSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/GrayLSB.png
--------------------------------------------------------------------------------
/GrayMSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/GrayMSB.png
--------------------------------------------------------------------------------
/HDRPreviewLSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/HDRPreviewLSB.png
--------------------------------------------------------------------------------
/HDRPreviewMSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/HDRPreviewMSB.png
--------------------------------------------------------------------------------
/LC709.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/LC709.labin
--------------------------------------------------------------------------------
/LC709A.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/LC709A.labin
--------------------------------------------------------------------------------
/LDRPreviewLSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/LDRPreviewLSB.png
--------------------------------------------------------------------------------
/LDRPreviewMSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/LDRPreviewMSB.png
--------------------------------------------------------------------------------
/LUTCalc.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/LUTCalc.icns
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | LUTCalc
2 | =======
3 |
4 | A Web App for generating 1D and 3D Lookup Tables (LUTs) for video cameras that shoot log gammas, principally the Sony CineAlta line.
5 |
6 | LUTCalc generates 1D and 3D .cube format LUTs suitable for use in DaVinci Resolve, Adobe Speedgrade and as user 3D LUTs in Sony's log-recording video cameras. These include the PMW-F5, PMW-F55 and PXW-FS7.
7 |
8 | How To Start
9 | ------------
10 | Mac OSX Safari: For Mac OSX users, the sister [LUTCalc For Mac](https://github.com/cameramanben/LUTCalc-For-Mac) project provides a native app version using a sandbox-friendly Objective-C Webkit wrapper around the LUTCalc Javascript.
11 | Chrome (Windows, Mac or Linux): LUTCalc currently needs to be run as an app extension. Either click Window->Extensions in the menu bar or type chrome://extensions in the address bar. Check 'developer mode' in the top right, then click 'Load unpacked extension' and find the main LUTCalc directory and click select. LUTCalc should then show up on the list of installed extensions. You can now uncheck developer mode and start LUTCalc either by clicking 'Launch' or from the Chrome App Launcher.
12 | Firefox: I have been developing using Firefox, so opening index.html in the main directory should work.
13 | Internet Explorer: currently looking in to making this work.
14 |
15 | Gamma / Gamut Information
16 | -------------------------
17 |
18 | The sources of information used are white papers and standards documents, analysis and comparison of test images and LUT calculations using known reference LUTs.
19 |
20 | Sony S-Log3 - [Technical Summary for S-Gamut3.Cine/S-Log3 and S-Gamut3/S-Log3](http://community.sony.com/sony/attachments/sony/large-sensor-camera-F5-F55/12359/2/TechnicalSummary_for_S-Gamut3Cine_S-Gamut3_S-Log3_V1_00.pdf)
21 |
22 | Sony S-Gamut3 / S-Gamut3.cine - [Sony Excel spreadsheet of various gamut matrices](http://community.sony.com/sony/attachments/sony/large-sensor-camera-F5-F55/12359/3/S-Gamut3_S-Gamut3Cine_Matrix.xlsx)
23 |
24 | Sony S-Log2 - [Sony technical paper on S-Log2](https://pro.sony.com/bbsccms/assets/files/micro/dmpc/training/S-Log2_Technical_PaperV1_0.pdf)
25 |
26 | Sony S-Log - [S-Log: A new LUT for digital production mastering and interchange applications](https://pro.sony.com/bbsccms/assets/files/mkt/cinema/solutions/slog_manual.pdf)
27 |
28 | Sony Look Profile LUTs - [Sony Community Website](http://community.sony.com/t5/F5-F55/Release-version-3DLUT-s-for-S-Gamut3-Cine-S-Log3/td-p/287847)
29 |
30 | Arri LogC / Wide Gamut - [ALEXA Log C Curve - Usage in VFX](http://www.arri.com/?eID=registration&file_uid=8026)
31 |
32 | Canon C-Log - [Canon-Log Cine Optoelectronic Transfer Function](http://learn.usa.canon.com/app/pdfs/white_papers/White_Paper_Clog_optoelectronic.pdf)
33 |
34 | Canon LUTs and Gamut Information - [Canon C500 Support Site](http://www.canon-europe.com/Support/Consumer_Products/products/digital_cinema/digital_cinema_camera/EOS_C500.aspx?type=download)
35 |
36 | Canon C300 Input Device Transform (IDT) - [Canon C300 Support Site](http://www.usa.canon.com/cusa/professional/products/professional_cameras/cinema_eos_cameras/eos_c300#DriversAndSoftware) - under 'Software'. You have to specify 'Mountain Lion' on a Mac or 'Windows XP' on a PC for it to be displayed. C500 and C100 have the same IDTs for CP Lock, though the C500 also offers 'Cinema Gamut' (see above link).
37 |
38 | Panasonic Varicam V-Log and V-Gamut - [V-Log/V-Gamut Reference Manual](http://pro-av.panasonic.net/en/varicam/common/pdf/VARICAM_V-Log_V-Gamut.pdf)
39 |
40 | Cineon - [Understanding Cineon](http://www.digital-intermediate.co.uk/film/pdf/Cineon.pdf)
41 |
42 | Rec709 - [ITU BT.709-5](http://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.709-5-200204-I!!PDF-E.pdf)
43 |
44 | sRGB - [Wikipedia entry](http://en.wikipedia.org/wiki/SRGB)
45 |
46 | Dolby PQ and alternative prospective transfer functions for HDR displays - [Non-linear Opto-Electrical Transfer Functions for High Dynamic Range Television](http://www.bbc.co.uk/rd/publications/whitepaper283)
47 |
48 | Chromatic adaptation and Von Kries transform for colour temperature adjustments - [Wikipedia article](http://en.wikipedia.org/wiki/Chromatic_adaptation)
49 |
50 |
51 | LUTCalc File List
52 | =================
53 |
54 | Main Files
55 | ----------
56 | * index.html (window.html) - HTML5 base of LUTCalc. Launch to start.
57 | * lutcalc.js - main Javascript file. Initialises all the UI and calculation objects and sets up the event handlers.
58 |
59 | UI Files
60 | --------
61 | * lutcamerabox.js - builds the UI object where camera and ISO are chosen.
62 | * lutgammabox.js - builds the UI object for transfer curve (gamma) and colour space (gamut) selection.
63 | * luttweaksbox.js - builds the UI object for customising the transfer (gamma) curves and colour spaces / gamuts.
64 | * lutanalyst.js - extension to luttweaksbox which reads and then analyses LUTs into transfer function and colour space components so that they can be adapted for use with other input colour spaces and further tweaked as with the built-in options.
65 | * lutlutbox.js - builds the UI object containing options concerning the LUT format.
66 | * lutgeneratebox.js - builds the 'Generate' button that triggers the LUT generation, plus the generation logic itself.
67 | * lutpreview.js - builds the UI object which previews LUTs on test images.
68 | * lutinfobox.js - builds the UI object which shows instructions, plots of the input and output gammas against stop and IRE and data values for correct exposure with the chosen output gamma.
69 |
70 | LUT I/O
71 | -------
72 | * lutformats.js - controller object for the parsers and builders of various LUT formats.
73 | * lut-cube.js - .cube format parsing and building (Adobe format and DaVinci format).
74 | * lut-davinci.js - DaVinci Resolve 1D .ilut input LUT and .olut output LUT parsing and building.
75 | * lut-vlt.js - Panasonic .vlt MLUT format parsing and building.
76 | * lut-3dl.js - .3dl format parsing and building (Assimilate, Autodesk and Kodak formats).
77 | * lut-lut.js - Assimilate 1D .lut parsing and building.
78 | * lut-spi1d.js - Sony Pictures International 1D .spi1d format parsing and building.
79 | * lut-spi3d.js - Sony Pictures International 3D .spi3d format parsing and building.
80 | * lut-la.js - cube-based .lacube and .labin LUTAnalyst parsing and building.
81 |
82 | Adjustment Files
83 | ----------------
84 | * twk-wb.js - white balance (colour temperature / fluori green / magenta) adjustment.
85 | * twk-asccdl.js - adjustment based on the ASC-CDL operations.
86 | * twk-psstcdl.js - colour-specific adjustment based on the ASC-CDL controls.
87 | * twk-hg.js - adjustment to allow for a second choice of gamut in the highlights.
88 | * twk-blkhi.js - adjustment of the black level and a user-selectable scene reflectance response level.
89 | * twk-fc.js - false colour overlay option.
90 | * twk-la.js - LUTAnalyst UI controls.
91 | * twk-blank.js - empty example object which demonstrates the layout.
92 |
93 | Web Workers
94 | -----------
95 | * lutmessage.js - handles creation and message passing for multiple web worker calculation threads.
96 | * gamma.js - handles all the calculations relating to transfer functions (gammas).
97 | * colourspace.js - handles all the functions relating to colour spaces (gamuts).
98 |
99 | Binary LUT Files
100 | ----------------
101 | * LC709.labin - little-endian Float64Array buffer of colour space (S-Log3 to S-Log3, S-Gamut3.cine to LC709) data based on Sony's look profile.
102 | * LC709A.labin - colour space data based on Sony's look profile.
103 | * V709.labin - experimental colour space data based on Panasonic's reference V-log to V709 LUT.
104 | * cpoutdaylight.labin - Canon CP lock to S-Gamut3.cine data developed by testing against Canon's reference daylight IDT.
105 | * cpouttungsten.labin - Canon CP lock to S-Gamut3.cine data developed by testing against Canon's reference tungsten IDT.
106 |
107 | Helper Javascript
108 | -----------------
109 | * splash.js - displays a splash screen and sets the version.
110 | * tests.js - performs Javascript capabilities tests to see whether and how LUTCalc will run in a given environment.
111 | * lut.js - LUT handling object. Will calculate interpolated values from LUTs using cubic and tricubic interpolation. Also includes code for breaking a 3D LUT into gamma and gamut component LUTs and changing the input gamma / gamut (as used by the LUTAnalyst tool).
112 | * ring.js - ring spline object. Like a 1D LUT which connects back on itself. Used in the PSST-CDL calculations.
113 | * lutfile.js - file handling object.
114 | * lutinputs.js - simple object into which the other objects can place their form input objects, to allow interaction without globals.
115 | * brent.js - Brent's method of root finding for LUTAnalyst.
116 | * tests.js - object containing feature / environment detection tests.
117 | * window.html - web app version of index.html.
118 | * background.js - web app required code.
119 | * manifest.webapp - web app manifest.
120 | * manifest.json - alternative web app manifest format.
121 |
122 | Style Sheets
123 | ------------
124 | * reset.css - DOM reset stylesheet.
125 | * fonts.css - font options stylesheet.
126 | * ui.css - style sheet controlling specific UI elements.
127 | * style.css - base stylesheet controlling the look of the app. All dimensions (greater than 1 pixel) are em values.
128 | * info.css - stylesheet controlling the information / instructions window.
129 |
130 | Other Files
131 | -----------
132 | * background.js - Chrome packaged app requirement
133 | * LUTCalc.icns - icon file containing a logo in a format suitable for Mac OSX Apps in XCode.
134 | * logo(x).png - various sizes of png containing the LUTCalc logo for the Chrome app.
135 | * LDR / HDR Preview LSB / MSB .png - test images for use in the preview window. Low dynamic range / contrast (LDR) and high dynamic range (HDR) from 16-bit originals broken into 8-bit most significant and least significant byte images (MSB and LSB) for Javascript.
136 | * Gray LSB/ MSB .png - 16-stop grayscale test image.
137 | * CW LSB / MSB .png - Representation image of the Rec709 Colour Gamut for use in the preview window.
138 | * README.md - this file.
139 | * CHANGELOG.md - changelog.
140 | * LICENSE - GPL2 License document.
141 |
142 | External Code Used
143 | ------------------
144 | * [FileSaver.js](https://github.com/eligrey/FileSaver.js/) - Cross-browser Javascript file saving.
145 | * [Blob.js](https://github.com/eligrey/Blob.js) - Cross-browser Javascript Blob implementation.
146 | * The function 'createRadioElement' is used to dynamically create radio buttons. This came from a tip by Prestaul on [stackoverflow](http://stackoverflow.com/questions/118693/how-do-you-dynamically-create-a-radio-button-in-javascript-that-works-in-all-bro)
147 |
148 | All other code is by me, Ben Turley.
149 |
--------------------------------------------------------------------------------
/V709.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/V709.labin
--------------------------------------------------------------------------------
/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/apple-touch-icon.png
--------------------------------------------------------------------------------
/blob/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright © 2014 [Eli Grey][1].
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 |
25 | [1]: http://eligrey.com
26 |
--------------------------------------------------------------------------------
/blob/README.md:
--------------------------------------------------------------------------------
1 | Blob.js
2 | ==============
3 |
4 | Blob.js implements the W3C [`Blob`][1] interface in browsers that do
5 | not natively support it.
6 |
7 | Supported browsers
8 | ------------------
9 |
10 | Blob.js shares the [same supported browsers as FileSaver.js][2].
11 |
12 | 
13 |
14 | [1]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
15 | [2]: https://github.com/eligrey/FileSaver.js#supported-browsers
--------------------------------------------------------------------------------
/cpoutdaylight.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/cpoutdaylight.labin
--------------------------------------------------------------------------------
/cpouttungsten.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/cpouttungsten.labin
--------------------------------------------------------------------------------
/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/favicon-16x16.png
--------------------------------------------------------------------------------
/favicon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/favicon-192x192.png
--------------------------------------------------------------------------------
/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/favicon-32x32.png
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/favicon.ico
--------------------------------------------------------------------------------
/filesaver/FileSaver.js:
--------------------------------------------------------------------------------
1 | (function (global, factory) {
2 | if (typeof define === "function" && define.amd) {
3 | define([], factory);
4 | } else if (typeof exports !== "undefined") {
5 | factory();
6 | } else {
7 | var mod = {
8 | exports: {}
9 | };
10 | factory();
11 | global.FileSaver = mod.exports;
12 | }
13 | })(this, function () {
14 | "use strict";
15 |
16 | /*
17 | * FileSaver.js
18 | * A saveAs() FileSaver implementation.
19 | *
20 | * By Eli Grey, http://eligrey.com
21 | *
22 | * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
23 | * source : http://purl.eligrey.com/github/FileSaver.js
24 | */
25 | // The one and only way of getting global scope in all environments
26 | // https://stackoverflow.com/q/3277182/1008999
27 | var _global = typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : void 0;
28 |
29 | function bom(blob, opts) {
30 | if (typeof opts === 'undefined') opts = {
31 | autoBom: false
32 | };else if (typeof opts !== 'object') {
33 | console.warn('Deprecated: Expected third argument to be a object');
34 | opts = {
35 | autoBom: !opts
36 | };
37 | } // prepend BOM for UTF-8 XML and text/* types (including HTML)
38 | // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
39 |
40 | if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
41 | return new Blob([String.fromCharCode(0xFEFF), blob], {
42 | type: blob.type
43 | });
44 | }
45 |
46 | return blob;
47 | }
48 |
49 | function download(url, name, opts) {
50 | var xhr = new XMLHttpRequest();
51 | xhr.open('GET', url);
52 | xhr.responseType = 'blob';
53 |
54 | xhr.onload = function () {
55 | saveAs(xhr.response, name, opts);
56 | };
57 |
58 | xhr.onerror = function () {
59 | console.error('could not download file');
60 | };
61 |
62 | xhr.send();
63 | }
64 |
65 | function corsEnabled(url) {
66 | var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker
67 |
68 | xhr.open('HEAD', url, false);
69 |
70 | try {
71 | xhr.send();
72 | } catch (e) {}
73 |
74 | return xhr.status >= 200 && xhr.status <= 299;
75 | } // `a.click()` doesn't work for all browsers (#465)
76 |
77 |
78 | function click(node) {
79 | try {
80 | node.dispatchEvent(new MouseEvent('click'));
81 | } catch (e) {
82 | var evt = document.createEvent('MouseEvents');
83 | evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
84 | node.dispatchEvent(evt);
85 | }
86 | } // Detect WebView inside a native macOS app by ruling out all browsers
87 | // We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
88 | // https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
89 |
90 |
91 | var isMacOSWebView = /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent);
92 | var saveAs = _global.saveAs || ( // probably in some web worker
93 | typeof window !== 'object' || window !== _global ? function saveAs() {}
94 | /* noop */
95 | // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
96 | : 'download' in HTMLAnchorElement.prototype && !isMacOSWebView ? function saveAs(blob, name, opts) {
97 | var URL = _global.URL || _global.webkitURL;
98 | var a = document.createElement('a');
99 | name = name || blob.name || 'download';
100 | a.download = name;
101 | a.rel = 'noopener'; // tabnabbing
102 | // TODO: detect chrome extensions & packaged apps
103 | // a.target = '_blank'
104 |
105 | if (typeof blob === 'string') {
106 | // Support regular links
107 | a.href = blob;
108 |
109 | if (a.origin !== location.origin) {
110 | corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = '_blank');
111 | } else {
112 | click(a);
113 | }
114 | } else {
115 | // Support blobs
116 | a.href = URL.createObjectURL(blob);
117 | setTimeout(function () {
118 | URL.revokeObjectURL(a.href);
119 | }, 4E4); // 40s
120 |
121 | setTimeout(function () {
122 | click(a);
123 | }, 0);
124 | }
125 | } // Use msSaveOrOpenBlob as a second approach
126 | : 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, opts) {
127 | name = name || blob.name || 'download';
128 |
129 | if (typeof blob === 'string') {
130 | if (corsEnabled(blob)) {
131 | download(blob, name, opts);
132 | } else {
133 | var a = document.createElement('a');
134 | a.href = blob;
135 | a.target = '_blank';
136 | setTimeout(function () {
137 | click(a);
138 | });
139 | }
140 | } else {
141 | navigator.msSaveOrOpenBlob(bom(blob, opts), name);
142 | }
143 | } // Fallback to using FileReader and a popup
144 | : function saveAs(blob, name, opts, popup) {
145 | // Open a popup immediately do go around popup blocker
146 | // Mostly only available on user interaction and the fileReader is async so...
147 | popup = popup || open('', '_blank');
148 |
149 | if (popup) {
150 | popup.document.title = popup.document.body.innerText = 'downloading...';
151 | }
152 |
153 | if (typeof blob === 'string') return download(blob, name, opts);
154 | var force = blob.type === 'application/octet-stream';
155 |
156 | var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;
157 |
158 | var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
159 |
160 | if ((isChromeIOS || force && isSafari || isMacOSWebView) && typeof FileReader !== 'undefined') {
161 | // Safari doesn't allow downloading of blob URLs
162 | var reader = new FileReader();
163 |
164 | reader.onloadend = function () {
165 | var url = reader.result;
166 | url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
167 | if (popup) popup.location.href = url;else location = url;
168 | popup = null; // reverse-tabnabbing #460
169 | };
170 |
171 | reader.readAsDataURL(blob);
172 | } else {
173 | var URL = _global.URL || _global.webkitURL;
174 | var url = URL.createObjectURL(blob);
175 | if (popup) popup.location = url;else location.href = url;
176 | popup = null; // reverse-tabnabbing #460
177 |
178 | setTimeout(function () {
179 | URL.revokeObjectURL(url);
180 | }, 4E4); // 40s
181 | }
182 | });
183 | _global.saveAs = saveAs.saveAs = saveAs;
184 |
185 | if (typeof module !== 'undefined') {
186 | module.exports = saveAs;
187 | }
188 | });
189 |
--------------------------------------------------------------------------------
/filesaver/FileSaver.min.js:
--------------------------------------------------------------------------------
1 | (function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,"undefined"!=typeof module&&(module.exports=g)});
2 |
3 | //# sourceMappingURL=FileSaver.min.js.map
--------------------------------------------------------------------------------
/filesaver/FileSaver.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["../src/FileSaver.js"],"names":[],"mappings":"uLAkBA,QAAS,CAAA,CAAT,CAAc,CAAd,CAAoB,CAApB,CAA0B,OACJ,WAAhB,QAAO,CAAA,CADa,CACS,CAAI,CAAG,CAAE,OAAO,GAAT,CADhB,CAEC,QAAhB,QAAO,CAAA,CAFQ,GAGtB,OAAO,CAAC,IAAR,CAAa,oDAAb,CAHsB,CAItB,CAAI,CAAG,CAAE,OAAO,CAAE,CAAC,CAAZ,CAJe,EASpB,CAAI,CAAC,OAAL,EAAgB,6EAA6E,IAA7E,CAAkF,CAAI,CAAC,IAAvF,CATI,CAUf,GAAI,CAAA,IAAJ,CAAS,UAA8B,CAA9B,CAAT,CAA8C,CAAE,IAAI,CAAE,CAAI,CAAC,IAAb,CAA9C,CAVe,CAYjB,CACR,CAED,QAAS,CAAA,CAAT,CAAmB,CAAnB,CAAwB,CAAxB,CAA8B,CAA9B,CAAoC,CAClC,GAAI,CAAA,CAAG,CAAG,GAAI,CAAA,cAAd,CACA,CAAG,CAAC,IAAJ,CAAS,KAAT,CAAgB,CAAhB,CAFkC,CAGlC,CAAG,CAAC,YAAJ,CAAmB,MAHe,CAIlC,CAAG,CAAC,MAAJ,CAAa,UAAY,CACvB,CAAM,CAAC,CAAG,CAAC,QAAL,CAAe,CAAf,CAAqB,CAArB,CACP,CANiC,CAOlC,CAAG,CAAC,OAAJ,CAAc,UAAY,CACxB,OAAO,CAAC,KAAR,CAAc,yBAAd,CACD,CATiC,CAUlC,CAAG,CAAC,IAAJ,EACD,CAED,QAAS,CAAA,CAAT,CAAsB,CAAtB,CAA2B,CACzB,GAAI,CAAA,CAAG,CAAG,GAAI,CAAA,cAAd,CAEA,CAAG,CAAC,IAAJ,CAAS,MAAT,CAAiB,CAAjB,IAHyB,CAIzB,GAAI,CACF,CAAG,CAAC,IAAJ,EACD,CAAC,MAAO,CAAP,CAAU,CAAE,CACd,MAAqB,IAAd,EAAA,CAAG,CAAC,MAAJ,EAAmC,GAAd,EAAA,CAAG,CAAC,MACjC,CAGD,QAAS,CAAA,CAAT,CAAgB,CAAhB,CAAsB,CACpB,GAAI,CACF,CAAI,CAAC,aAAL,CAAmB,GAAI,CAAA,UAAJ,CAAe,OAAf,CAAnB,CACD,CAAC,MAAO,CAAP,CAAU,CACV,GAAI,CAAA,CAAG,CAAG,QAAQ,CAAC,WAAT,CAAqB,aAArB,CAAV,CACA,CAAG,CAAC,cAAJ,CAAmB,OAAnB,OAAwC,MAAxC,CAAgD,CAAhD,CAAmD,CAAnD,CAAsD,CAAtD,CAAyD,EAAzD,CACsB,EADtB,aACsD,CADtD,CACyD,IADzD,CAFU,CAIV,CAAI,CAAC,aAAL,CAAmB,CAAnB,CACD,CACF,C,GAtDG,CAAA,CAAO,CAAqB,QAAlB,QAAO,CAAA,MAAP,EAA8B,MAAM,CAAC,MAAP,GAAkB,MAAhD,CACV,MADU,CACe,QAAhB,QAAO,CAAA,IAAP,EAA4B,IAAI,CAAC,IAAL,GAAc,IAA1C,CACT,IADS,CACgB,QAAlB,QAAO,CAAA,MAAP,EAA8B,MAAM,CAAC,MAAP,GAAkB,MAAhD,CACP,MADO,O,CAyDP,CAAc,CAAG,YAAY,IAAZ,CAAiB,SAAS,CAAC,SAA3B,GAAyC,cAAc,IAAd,CAAmB,SAAS,CAAC,SAA7B,CAAzC,EAAoF,CAAC,SAAS,IAAT,CAAc,SAAS,CAAC,SAAxB,C,CAEtG,CAAM,CAAG,CAAO,CAAC,MAAR,GAEQ,QAAlB,QAAO,CAAA,MAAP,EAA8B,MAAM,GAAK,CAA1C,CACI,UAAmB,CAAc,CADrC,CAIG,YAAc,CAAA,iBAAiB,CAAC,SAAhC,EAA6C,CAAC,CAA/C,CACA,SAAiB,CAAjB,CAAuB,CAAvB,CAA6B,CAA7B,CAAmC,IAC/B,CAAA,CAAG,CAAG,CAAO,CAAC,GAAR,EAAe,CAAO,CAAC,SADE,CAE/B,CAAC,CAAG,QAAQ,CAAC,aAAT,CAAuB,GAAvB,CAF2B,CAGnC,CAAI,CAAG,CAAI,EAAI,CAAI,CAAC,IAAb,EAAqB,UAHO,CAKnC,CAAC,CAAC,QAAF,CAAa,CALsB,CAMnC,CAAC,CAAC,GAAF,CAAQ,UAN2B,CAWf,QAAhB,QAAO,CAAA,CAXwB,EAajC,CAAC,CAAC,IAAF,CAAS,CAbwB,CAc7B,CAAC,CAAC,MAAF,GAAa,QAAQ,CAAC,MAdO,CAmB/B,CAAK,CAAC,CAAD,CAnB0B,CAe/B,CAAW,CAAC,CAAC,CAAC,IAAH,CAAX,CACI,CAAQ,CAAC,CAAD,CAAO,CAAP,CAAa,CAAb,CADZ,CAEI,CAAK,CAAC,CAAD,CAAI,CAAC,CAAC,MAAF,CAAW,QAAf,CAjBsB,GAuBjC,CAAC,CAAC,IAAF,CAAS,CAAG,CAAC,eAAJ,CAAoB,CAApB,CAvBwB,CAwBjC,UAAU,CAAC,UAAY,CAAE,CAAG,CAAC,eAAJ,CAAoB,CAAC,CAAC,IAAtB,CAA6B,CAA5C,CAA8C,GAA9C,CAxBuB,CAyBjC,UAAU,CAAC,UAAY,CAAE,CAAK,CAAC,CAAD,CAAK,CAAzB,CAA2B,CAA3B,CAzBuB,CA2BpC,CA5BC,CA+BA,oBAAsB,CAAA,SAAtB,CACA,SAAiB,CAAjB,CAAuB,CAAvB,CAA6B,CAA7B,CAAmC,CAGnC,GAFA,CAAI,CAAG,CAAI,EAAI,CAAI,CAAC,IAAb,EAAqB,UAE5B,CAAoB,QAAhB,QAAO,CAAA,CAAX,CAUE,SAAS,CAAC,gBAAV,CAA2B,CAAG,CAAC,CAAD,CAAO,CAAP,CAA9B,CAA4C,CAA5C,CAVF,KACE,IAAI,CAAW,CAAC,CAAD,CAAf,CACE,CAAQ,CAAC,CAAD,CAAO,CAAP,CAAa,CAAb,CADV,KAEO,CACL,GAAI,CAAA,CAAC,CAAG,QAAQ,CAAC,aAAT,CAAuB,GAAvB,CAAR,CACA,CAAC,CAAC,IAAF,CAAS,CAFJ,CAGL,CAAC,CAAC,MAAF,CAAW,QAHN,CAIL,UAAU,CAAC,UAAY,CAAE,CAAK,CAAC,CAAD,CAAK,CAAzB,CACX,CAIJ,CAhBC,CAmBA,SAAiB,CAAjB,CAAuB,CAAvB,CAA6B,CAA7B,CAAmC,CAAnC,CAA0C,CAS1C,GANA,CAAK,CAAG,CAAK,EAAI,IAAI,CAAC,EAAD,CAAK,QAAL,CAMrB,CALI,CAKJ,GAJE,CAAK,CAAC,QAAN,CAAe,KAAf,CACA,CAAK,CAAC,QAAN,CAAe,IAAf,CAAoB,SAApB,CAAgC,gBAGlC,EAAoB,QAAhB,QAAO,CAAA,CAAX,CAA8B,MAAO,CAAA,CAAQ,CAAC,CAAD,CAAO,CAAP,CAAa,CAAb,CAAf,CATY,GAWtC,CAAA,CAAK,CAAiB,0BAAd,GAAA,CAAI,CAAC,IAXyB,CAYtC,CAAQ,CAAG,eAAe,IAAf,CAAoB,CAAO,CAAC,WAA5B,GAA4C,CAAO,CAAC,MAZzB,CAatC,CAAW,CAAG,eAAe,IAAf,CAAoB,SAAS,CAAC,SAA9B,CAbwB,CAe1C,GAAI,CAAC,CAAW,EAAK,CAAK,EAAI,CAAzB,EAAsC,CAAvC,GAAgF,WAAtB,QAAO,CAAA,UAArE,CAAiG,CAE/F,GAAI,CAAA,CAAM,CAAG,GAAI,CAAA,UAAjB,CACA,CAAM,CAAC,SAAP,CAAmB,UAAY,CAC7B,GAAI,CAAA,CAAG,CAAG,CAAM,CAAC,MAAjB,CACA,CAAG,CAAG,CAAW,CAAG,CAAH,CAAS,CAAG,CAAC,OAAJ,CAAY,cAAZ,CAA4B,uBAA5B,CAFG,CAGzB,CAHyB,CAGlB,CAAK,CAAC,QAAN,CAAe,IAAf,CAAsB,CAHJ,CAIxB,QAAQ,CAAG,CAJa,CAK7B,CAAK,CAAG,IACT,CAT8F,CAU/F,CAAM,CAAC,aAAP,CAAqB,CAArB,CACD,CAXD,IAWO,IACD,CAAA,CAAG,CAAG,CAAO,CAAC,GAAR,EAAe,CAAO,CAAC,SAD5B,CAED,CAAG,CAAG,CAAG,CAAC,eAAJ,CAAoB,CAApB,CAFL,CAGD,CAHC,CAGM,CAAK,CAAC,QAAN,CAAiB,CAHvB,CAIA,QAAQ,CAAC,IAAT,CAAgB,CAJhB,CAKL,CAAK,CAAG,IALH,CAML,UAAU,CAAC,UAAY,CAAE,CAAG,CAAC,eAAJ,CAAoB,CAApB,CAA0B,CAAzC,CAA2C,GAA3C,CACX,CACF,CA1FU,C,CA6Fb,CAAO,CAAC,MAAR,CAAiB,CAAM,CAAC,MAAP,CAAgB,C,CAEX,WAAlB,QAAO,CAAA,M,GACT,MAAM,CAAC,OAAP,CAAiB,C","file":"FileSaver.min.js","sourcesContent":["/*\n* FileSaver.js\n* A saveAs() FileSaver implementation.\n*\n* By Eli Grey, http://eligrey.com\n*\n* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)\n* source : http://purl.eligrey.com/github/FileSaver.js\n*/\n\n// The one and only way of getting global scope in all environments\n// https://stackoverflow.com/q/3277182/1008999\nvar _global = typeof window === 'object' && window.window === window\n ? window : typeof self === 'object' && self.self === self\n ? self : typeof global === 'object' && global.global === global\n ? global\n : this\n\nfunction bom (blob, opts) {\n if (typeof opts === 'undefined') opts = { autoBom: false }\n else if (typeof opts !== 'object') {\n console.warn('Deprecated: Expected third argument to be a object')\n opts = { autoBom: !opts }\n }\n\n // prepend BOM for UTF-8 XML and text/* types (including HTML)\n // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n if (opts.autoBom && /^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })\n }\n return blob\n}\n\nfunction download (url, name, opts) {\n var xhr = new XMLHttpRequest()\n xhr.open('GET', url)\n xhr.responseType = 'blob'\n xhr.onload = function () {\n saveAs(xhr.response, name, opts)\n }\n xhr.onerror = function () {\n console.error('could not download file')\n }\n xhr.send()\n}\n\nfunction corsEnabled (url) {\n var xhr = new XMLHttpRequest()\n // use sync to avoid popup blocker\n xhr.open('HEAD', url, false)\n try {\n xhr.send()\n } catch (e) {}\n return xhr.status >= 200 && xhr.status <= 299\n}\n\n// `a.click()` doesn't work for all browsers (#465)\nfunction click (node) {\n try {\n node.dispatchEvent(new MouseEvent('click'))\n } catch (e) {\n var evt = document.createEvent('MouseEvents')\n evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80,\n 20, false, false, false, false, 0, null)\n node.dispatchEvent(evt)\n }\n}\n\n// Detect WebView inside a native macOS app by ruling out all browsers\n// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too\n// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos\nvar isMacOSWebView = /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent)\n\nvar saveAs = _global.saveAs || (\n // probably in some web worker\n (typeof window !== 'object' || window !== _global)\n ? function saveAs () { /* noop */ }\n\n // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView\n : ('download' in HTMLAnchorElement.prototype && !isMacOSWebView)\n ? function saveAs (blob, name, opts) {\n var URL = _global.URL || _global.webkitURL\n var a = document.createElement('a')\n name = name || blob.name || 'download'\n\n a.download = name\n a.rel = 'noopener' // tabnabbing\n\n // TODO: detect chrome extensions & packaged apps\n // a.target = '_blank'\n\n if (typeof blob === 'string') {\n // Support regular links\n a.href = blob\n if (a.origin !== location.origin) {\n corsEnabled(a.href)\n ? download(blob, name, opts)\n : click(a, a.target = '_blank')\n } else {\n click(a)\n }\n } else {\n // Support blobs\n a.href = URL.createObjectURL(blob)\n setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s\n setTimeout(function () { click(a) }, 0)\n }\n }\n\n // Use msSaveOrOpenBlob as a second approach\n : 'msSaveOrOpenBlob' in navigator\n ? function saveAs (blob, name, opts) {\n name = name || blob.name || 'download'\n\n if (typeof blob === 'string') {\n if (corsEnabled(blob)) {\n download(blob, name, opts)\n } else {\n var a = document.createElement('a')\n a.href = blob\n a.target = '_blank'\n setTimeout(function () { click(a) })\n }\n } else {\n navigator.msSaveOrOpenBlob(bom(blob, opts), name)\n }\n }\n\n // Fallback to using FileReader and a popup\n : function saveAs (blob, name, opts, popup) {\n // Open a popup immediately do go around popup blocker\n // Mostly only available on user interaction and the fileReader is async so...\n popup = popup || open('', '_blank')\n if (popup) {\n popup.document.title =\n popup.document.body.innerText = 'downloading...'\n }\n\n if (typeof blob === 'string') return download(blob, name, opts)\n\n var force = blob.type === 'application/octet-stream'\n var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari\n var isChromeIOS = /CriOS\\/[\\d]+/.test(navigator.userAgent)\n\n if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== 'undefined') {\n // Safari doesn't allow downloading of blob URLs\n var reader = new FileReader()\n reader.onloadend = function () {\n var url = reader.result\n url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;')\n if (popup) popup.location.href = url\n else location = url\n popup = null // reverse-tabnabbing #460\n }\n reader.readAsDataURL(blob)\n } else {\n var URL = _global.URL || _global.webkitURL\n var url = URL.createObjectURL(blob)\n if (popup) popup.location = url\n else location.href = url\n popup = null // reverse-tabnabbing #460\n setTimeout(function () { URL.revokeObjectURL(url) }, 4E4) // 40s\n }\n }\n)\n\n_global.saveAs = saveAs.saveAs = saveAs\n\nif (typeof module !== 'undefined') {\n module.exports = saveAs;\n}\n"]}
--------------------------------------------------------------------------------
/img/Screenshot-Tall-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/Screenshot-Tall-1.png
--------------------------------------------------------------------------------
/img/Screenshot-Wide-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/Screenshot-Wide-1.png
--------------------------------------------------------------------------------
/img/lutcalc-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-1024.png
--------------------------------------------------------------------------------
/img/lutcalc-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-128.png
--------------------------------------------------------------------------------
/img/lutcalc-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-16.png
--------------------------------------------------------------------------------
/img/lutcalc-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-19.png
--------------------------------------------------------------------------------
/img/lutcalc-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-256.png
--------------------------------------------------------------------------------
/img/lutcalc-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-32.png
--------------------------------------------------------------------------------
/img/lutcalc-38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-38.png
--------------------------------------------------------------------------------
/img/lutcalc-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-48.png
--------------------------------------------------------------------------------
/img/lutcalc-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-512.png
--------------------------------------------------------------------------------
/img/lutcalc-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-60.png
--------------------------------------------------------------------------------
/img/lutcalc-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-64.png
--------------------------------------------------------------------------------
/img/lutcalc-90.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/img/lutcalc-90.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | LUTCalc
16 |
17 |
18 | LUTCalc - 1D & 3D Cube LUT Calculator
19 |
20 | *** Please Allow Javascript To Run On This Page ***
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/indexunminified.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | LUTCalc
16 |
17 |
18 | LUTCalc - 1D & 3D Cube LUT Calculator
19 |
20 | *** Please Allow Javascript To Run On This Page ***
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/js/background.js:
--------------------------------------------------------------------------------
1 | chrome.app.runtime.onLaunched.addListener(function() {
2 | chrome.app.window.create('window.html', {
3 | 'bounds': {
4 | 'width': 1400,
5 | 'height': 700
6 | }
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/js/brent.js:
--------------------------------------------------------------------------------
1 | /* brent.js
2 | * JS implementation of the Brent's method of root finding
3 | *
4 | * 6th February 2015
5 | *
6 | * The 'findRoot' method tries to find the tightest bracket (sign change) to one side or the other of an initial guess 'I'
7 | * and then performs Brent's method. If a given bracket distance suggests roots on either side of 'I', both brackets are
8 | * evaluated and then the root closest to 'I' is returned. If no root is found, extremes are returned which can then be
9 | * replaced with minimum and maximum values found across the set.
10 | *
11 | * Sources of information:
12 | * Wikipedia: http://en.wikipedia.org/wiki/Brent%27s_method
13 | * Matlab Script by David Eagle: http://uk.mathworks.com/matlabcentral/fileexchange/39973-a-matlab-script-for-earth-to-mars-mission-design/content/brent.m
14 | *
15 | * By Ben Turley, http://turley.tv
16 | * First License: GPLv2
17 | */
18 | function Brent(func, a, b) {
19 | this.func = func; // Object providing function / data set for analysis - requires a method 'f' which supplies f(x)
20 | if (typeof a === 'number' && typeof b === 'number') {
21 | this.setRange(a,b);
22 | } else {
23 | this.setRange(0,1);
24 | }
25 | this.delta = 1;
26 | this.tol = 0.00000001; // tolerence - OK for Float64s, too small for Float32s
27 | }
28 | Brent.prototype.setRange = function(a,b) {
29 | this.a = a; // For f(x), minimum value of x
30 | this.fMin = this.func.f(a);
31 | this.b = b; // For f(x), maximum value of x
32 | this.fMax = this.func.f(b);
33 | this.mid = this.func.f((a+b)/2);
34 | };
35 | Brent.prototype.setDelta = function(d) {
36 | this.delta = d;
37 | };
38 | Brent.prototype.setTolerance = function(tol) {
39 | this.tol = tol;
40 | };
41 | Brent.prototype.minMax = function(x) {
42 | if (x < this.a) {
43 | this.a = x;
44 | this.fMin = this.o;
45 | } else if (x > this.b) {
46 | this.b = x;
47 | this.fMax = this.o;
48 | }
49 | };
50 | Brent.prototype.getMinMax = function() {
51 | return { a: this.a, fMin: this.fMin, b: this.b, fMax: this.fMax };
52 | };
53 | Brent.prototype.findRoot = function(I,O) { // Public single root method, O is the f(x) to match to if not zero (root), finds closest root to I
54 | var tol = this.tol;
55 | if (typeof O === 'number') {
56 | this.o = O;
57 | } else {
58 | this.o = 0;
59 | }
60 | var y0 = this.func.f(I) - this.o;
61 | if (Math.abs(y0) 65536) {
113 | return 65536;
114 | } else if (i < -65536) {
115 | return -65536;
116 | } else {
117 | return i;
118 | }
119 | };
120 | Brent.prototype.brent = function(a,fa,b,fb,rtol) {
121 | var eps = 2.22e-16; // Machine epsilon for Float64Arrays
122 | var e = 0;
123 | var tol1, xm, min, tmp;
124 | var p, q, r, s;
125 | var fc = fb;
126 | for (var j=0; j<80; j++) {
127 | if (fb * fc > 0) {
128 | c = a;
129 | fc = fa;
130 | d = b - a;
131 | e = d;
132 | }
133 | if (Math.abs(fc) < Math.abs(fb)) {
134 | a = b;
135 | b = c;
136 | c = a;
137 | fa = fb;
138 | fb = fc;
139 | fc = fa;
140 | }
141 | tol1 = (2*eps*Math.abs(b))+(0.5*rtol);
142 | xm = 0.5 * (c - b);
143 | if (Math.abs(xm) <= tol1 || fb === 0) {
144 | return b;
145 | }
146 | if (Math.abs(e) >= tol1 && Math.abs(fa) > Math.abs(fb)) {
147 | s = fb / fa;
148 | if (a === c) {
149 | p = 2*xm*s;
150 | q = 1-s;
151 | } else {
152 | q = fa/fc;
153 | r = fb/fc;
154 | p = s*((2*xm*q*(q - r))-((b - a)*(r - 1)));
155 | q = (q - 1)*(r - 1)*(s - 1);
156 | }
157 | if (p > 0) {
158 | q = -q;
159 | }
160 | p = Math.abs(p);
161 | min = Math.abs(e * q);
162 | tmp = (3*xm*q) - Math.abs(tol1*q);
163 | if (min < tmp) {
164 | min = tmp;
165 | }
166 | if (2*p < min) {
167 | e = d;
168 | d = p / q;
169 | } else {
170 | d = xm;
171 | e = d;
172 | }
173 | } else {
174 | d = xm;
175 | e = d;
176 | }
177 | a = b;
178 | fa = fb;
179 | if (Math.abs(d) > tol1) {
180 | b = b + d;
181 | } else {
182 | if (xm >=0) {
183 | b = b + tol1;
184 | } else {
185 | b = b - tol1;
186 | }
187 | }
188 | fb = this.func.f(b) - this.o;
189 | }
190 | console.log('none');
191 | return b;
192 | };
193 | // Stringify for inline Web Workers
194 | function getBrentString() {
195 | var out = "";
196 | // Brent
197 | out += Brent.toString() + "\n";
198 | for (var j in Brent.prototype) {
199 | out += 'Brent.prototype.' + j + '=' + Brent.prototype[j].toString() + "\n";
200 | }
201 | return out;
202 | }
203 | var workerBrentString = getBrentString();
204 |
--------------------------------------------------------------------------------
/js/colourspaceworker.js:
--------------------------------------------------------------------------------
1 | var lutCSWorker;
2 | if (typeof importScripts === 'function') {
3 | importScripts('colourspaceworkerscombined.js');
4 | lutCSWorker = new LUTCSWorker();
5 | }
--------------------------------------------------------------------------------
/js/gammaworker.js:
--------------------------------------------------------------------------------
1 | var lutGammaWorker;
2 | if (typeof importScripts === 'function') {
3 | importScripts('gammaworkerscombined.js');
4 | lutGammaWorker = new LUTGammaWorker();
5 | }
--------------------------------------------------------------------------------
/js/lut-3dl.js:
--------------------------------------------------------------------------------
1 | /* lut-3dl.js
2 | * .3dl LUT building / parsing for the LUTCalc Web App.
3 | * 3rd June 2015
4 | *
5 | * LUTCalc generates 1D and 3D Lookup Tables (LUTs) for video cameras that shoot log gammas,
6 | * principally the Sony CineAlta line.
7 | *
8 | * By Ben Turley, http://turley.tv
9 | * First License: GPLv2
10 | * Github: https://github.com/cameramanben/LUTCalc
11 | */
12 | function threedlLUT(messages, isLE, flavour) {
13 | this.messages = messages;
14 | this.isLE = isLE;
15 | this.flavour = flavour;
16 | }
17 | threedlLUT.prototype.build = function(buff, fileName, ext) {
18 | var info = {};
19 | this.messages.getInfo(info);
20 | var lut = new Float64Array(buff);
21 | var max = lut.length;
22 | var d = '';
23 | max = info.dimension;
24 | var mult = (Math.pow(2,info.inBits)-1)/(max-1);
25 | for (var j=0; j 0) {
37 | d += Math.round(lut[ t ]*mult).toString() + ' ';
38 | } else {
39 | d += '0 ';
40 | }
41 | if (lut[t+1] > 0) {
42 | d += Math.round(lut[t+1]*mult).toString() + ' ';
43 | } else {
44 | d += '0 ';
45 | }
46 | if (lut[t+2] > 0) {
47 | d += Math.round(lut[t+2]*mult).toString() + "\n";
48 | } else {
49 | d += '0' + "\n";
50 | }
51 | }
52 | }
53 | }
54 | switch (this.flavour) {
55 | case 1: // Flame
56 | return {
57 | lut: this.header(info) + d,
58 | fileName: fileName,
59 | ext: ext
60 | };
61 | case 2: // Lustre
62 | return {
63 | lut: this.header(info) + d + this.footer(info),
64 | fileName: fileName,
65 | ext: ext
66 | };
67 | case 3: // Kodak
68 | return {
69 | lut: this.header(info) + d,
70 | fileName: fileName,
71 | ext: ext
72 | };
73 | }
74 | };
75 | threedlLUT.prototype.header = function(info) {
76 | var out = '';
77 | var date = new Date();
78 | out += '# Created with LUTCalc ' + info.version + ' by Ben Turley ' + info.date + ' #' + "\n";
79 | out += '# IDENTIFICATION: LUTCalc - 3DLUT' + "\n";
80 | out += '# CREATOR: LUTCalc ' + info.version + "\n";
81 | out += '# USER: LUTCalc' + "\n";
82 | out += '# DATA: ' +
83 | date.getUTCFullYear() + '-' +
84 | this.addZero(date.getUTCMonth()) + '-' +
85 | this.addZero(date.getUTCDate()) + 'T' +
86 | this.addZero(date.getUTCHours()) + ':' +
87 | this.addZero(date.getUTCMinutes()) + ':' +
88 | this.addZero(date.getUTCSeconds()) + ' #' + "\n";
89 | out += '# NUMBER OF COLUMNS: 3' + "\n";
90 | out += '# NUMBER OF ROWS: ' + Math.pow(info.dimension,3).toString() + "\n";
91 | out += '# NUMBER OF NODES: ' + info.dimension.toString() + "\n";
92 | out += '# INPUT RANGE: ' + info.inBits.toString() + "\n";
93 | out += '# OUTPUT RANGE: ' + info.outBits.toString() + "\n";
94 | out += '# TITLE : ' + info.name + "\n";
95 | out += '# DESCRIPTION : ';
96 | if (info.nul) {
97 | out += ' Null LUT';
98 | } else {
99 | if (info.mlut) {
100 | out += 'MLUT';
101 | }
102 | if (info.doFC) {
103 | out += '*** FALSE COLOUR - DO NOT BAKE IN *** ';
104 | }
105 | if (this.doHG) {
106 | out += info.inGammaName + '/' + info.inGamutName + ' -> ' + info.outGammaName + '/' + info.outGamutName + '(' + info.hgGamutName + ' in the highlights)';
107 | } else {
108 | out += info.inGammaName + '/' + info.inGamutName + ' -> ' + info.outGammaName + '/' + info.outGamutName;
109 | }
110 | out += ', Stop Shift ' + info.cineEI.toFixed(2).toString();
111 | out += ', Black Level ' + info.blackLevel + '% IRE';
112 | if (info.legalIn) {
113 | out += ', Legal Input -> ';
114 | } else {
115 | out += ', Data Input -> ';
116 | }
117 | if (info.legalOut) {
118 | out += 'Legal Output';
119 | } else {
120 | out += 'Data Output';
121 | }
122 | }
123 | out += "\n";
124 | if (this.flavour === 2) {
125 | out += '3DMESH' + "\n";
126 | out += 'Mesh ';
127 | switch (info.dimension) {
128 | case 9: out += '3 ';
129 | break;
130 | case 17: out += '4 ';
131 | break;
132 | case 33: out += '5 ';
133 | break;
134 | case 65: out += '6 ';
135 | break;
136 | case 129: out += '7 ';
137 | break;
138 | }
139 | out += info.outBits.toString() + "\n";
140 | }
141 | return out;
142 | };
143 | threedlLUT.prototype.addZero = function(i) {
144 | if (i < 10) {
145 | i = '0' + i;
146 | }
147 | return i;
148 | };
149 | threedlLUT.prototype.footer = function(info) {
150 | var out = '';
151 | out += 'LUT8' + "\n";
152 | out += 'gamma 1.0' + "\n";
153 | return out;
154 | };
155 | threedlLUT.prototype.parse = function(title, text, lutMaker, lutDest) {
156 | var size = false;
157 | var minimum = [0,0,0];
158 | var maximum = [1,1,1];
159 | var maxIn = 0;
160 | var setMaxIn = false;
161 | var maxOut = false;
162 | var mOut = 0;
163 | var format = 'threedl1';
164 | var mesh = false;
165 | var outBits = false;
166 | var shaper;
167 | var max = text.length;
168 | if (max === 0) {
169 | return false;
170 | }
171 | var i;
172 | for (i=0; i maxIn) {
184 | maxIn = shaper[l];
185 | }
186 | if (isNaN(shaper[l])) {
187 | return false;
188 | }
189 | }
190 | i++;
191 | break;
192 | } else if (lower.search('3dmesh') >= 0) {
193 | // 3DMESH line distinguishes two types
194 | mesh = true;
195 | format = 'threedl2';
196 | } else if (lower.search('mesh') >= 0) {
197 | mesh = true;
198 | format = 'threedl2';
199 | var bits = line.substr(lower.search('mesh') + 4).trim().split(/\s+/g);
200 | if (!isNaN(bits[0]) && !isNaN(bits[1])) {
201 | size = Math.pow(2,parseInt(bits[0]))+1;
202 | outBits = parseInt(bits[1]);
203 | maxOut = Math.pow(2,outBits)-1;
204 | }
205 | } else if (lower.search('number of rows:') >= 0) {
206 | var val = parseFloat(line.substr(lower.search('number of rows:') + 15));
207 | if (!isNaN(val)) {
208 | size = Math.round(Math.pow(val, 1/3));
209 | }
210 | } else if (lower.search('number of nodes:') >= 0) {
211 | var val = parseInt(line.substr(lower.search('number of nodes:') + 16));
212 | if (!isNaN(val)) {
213 | size = val;
214 | }
215 | } else if (lower.search('input range:') >= 0) {
216 | var val = parseInt(line.substr(lower.search('input range:') + 12).trim());
217 | if (!isNaN(val)) {
218 | maxIn = Math.pow(2,val)-1;
219 | }
220 | } else if (lower.search('output range:') >= 0) {
221 | var val = parseInt(line.substr(lower.search('output range:') + 13).trim());
222 | if (!isNaN(val)) {
223 | outBits = val;
224 | maxOut = Math.pow(2,outBits)-1;
225 | }
226 | } else if (lower.search('title:') >= 0) {
227 | title = line.substr(lower.search('title:') + 6).trim();
228 | } else if (lower.search('gamma') >= 0) {
229 | // Unused at the moment
230 | } else if (lower.search('lut8') >= 0) {
231 | // Unused at the moment
232 | }
233 | }
234 | if (!size) {
235 | // 3D LUT dimension does not need to match shaper, without 'Mesh', must be gauged from the number of entries. Yuck!
236 | size = 0;
237 | for (var k=i; k 0) {
247 | var spline = false;
248 | var doShaper = false;
249 | var m = shaper.length;
250 | if (!setMaxIn) {
251 | if (maxIn < 511) {
252 | maxIn = 255;
253 | } else if (maxIn < 2047) {
254 | maxIn = 1023;
255 | } else if (maxIn < 8191) {
256 | maxIn = 4095;
257 | } else if (maxIn < 32767) {
258 | maxIn = 16383;
259 | } else {
260 | maxIn = 65535;
261 | }
262 | }
263 | for (var j=0; j mOut) {
301 | mOut = R[s];
302 | }
303 | if (G[s] > mOut) {
304 | mOut = G[s];
305 | }
306 | if (B[s] > mOut) {
307 | mOut = B[s];
308 | }
309 | }
310 | b++;
311 | if (b === size) {
312 | b=0;
313 | g++;
314 | }
315 | if (g === size) {
316 | g=0;
317 | r++;
318 | }
319 | s++;
320 | }
321 | }
322 | /*
323 | else if (lower.search('gamma') >= 0) {
324 | // Unused at the moment
325 | } else if (lower.search('lut8') >= 0) {
326 | // Unused at the moment
327 | }
328 | */
329 | }
330 | if (s === arraySize) {
331 | if (!maxOut) {
332 | if (mOut < 511) {
333 | maxOut = 255;
334 | } else if (mOut < 2047) {
335 | maxOut = 1023;
336 | } else if (mOut < 8191) {
337 | maxOut = 4095;
338 | } else if (mOut < 32767) {
339 | maxOut = 16383;
340 | } else {
341 | maxOut = 65535;
342 | }
343 | for (var j=0; j ' + info.outGammaName;
66 | } else if (this.doHG) {
67 | out += info.inGammaName + '/' + info.inGamutName + ' -> ' + info.outGammaName + '/' + info.outGamutName + '(' + info.hgGamutName + ' in the highlights)';
68 | } else {
69 | out += info.inGammaName + '/' + info.inGamutName + ' -> ' + info.outGammaName + '/' + info.outGamutName;
70 | }
71 | out += ', CineEI Shift ' + info.cineEI.toFixed(2).toString();
72 | out += ', Black Level ' + info.blackLevel + '% IRE';
73 | if (info.legalIn) {
74 | out += ', Input 100% -> ';
75 | } else {
76 | out += ', Input 109% -> ';
77 | }
78 | if (info.legalOut) {
79 | out += 'Output 100%';
80 | } else {
81 | out += 'Output 109%';
82 | }
83 | }
84 | out += ' - ' + 'Created with LUTCalc ' + info.version + ' by Ben Turley ' + info.date + "\n";
85 | return out;
86 | };
87 | cubeLUT.prototype.parse = function(title, text, lutMaker, lutDest) {
88 | var dimensions = false;
89 | var size = false;
90 | var minimum = [0,0,0];
91 | var maximum = [1,1,1];
92 | var sysCS = '';
93 | var laCS = '';
94 | var laTF = '';
95 | var laRG = '';
96 | var laEX = true;
97 | var laMin,laMax;
98 | var baseISO = false;
99 | var interpolation = false;
100 | var laMX = false;
101 | var laMLines = 0;
102 | var max = text.length;
103 | if (max === 0) {
104 | return false;
105 | }
106 | var i;
107 | for (i=0; i= 0) {
114 | title = line.substr(lower.search('title') + 5).trim().replace(/"/g, '');
115 | } else if (lower.search('lut_3d_size') >= 0) {
116 | var dim = line.substr(lower.search('lut_3d_size') + 11).trim();
117 | if (!isNaN(dim)) {
118 | dimensions = 3;
119 | size = parseInt(dim);
120 | }
121 | } else if (lower.search('lut_1d_size') >= 0) {
122 | var dim = line.substr(parseInt(lower.search('lut_1d_size')) + 11).trim();
123 | if (!isNaN(dim)) {
124 | dimensions = 1;
125 | size = parseInt(dim);
126 | }
127 | } else if (lower.search('domain_min') >= 0) {
128 | var dom = line.substr(parseInt(lower.search('domain_min')) + 10).trim().split(/\s+/g);
129 | if (!isNaN(dom[0]) && !isNaN(dom[1]) && !isNaN(dom[2])) {
130 | minimum[0] = parseFloat(dom[0]);
131 | minimum[1] = parseFloat(dom[1]);
132 | minimum[2] = parseFloat(dom[2]);
133 | }
134 | } else if (lower.search('domain_max') >= 0) {
135 | var dom = line.substr(parseInt(lower.search('domain_max')) + 10).trim().split(/\s+/g);
136 | if (!isNaN(dom[0]) && !isNaN(dom[1]) && !isNaN(dom[2])) {
137 | maximum[0] = parseFloat(dom[0]);
138 | maximum[1] = parseFloat(dom[1]);
139 | maximum[2] = parseFloat(dom[2]);
140 | }
141 | } else if (lower.search('lut_3d_input_range') >= 0) {
142 | var ran = line.substr(parseInt(lower.search('lut_3d_input_range')) + 18).trim().split(/\s+/g);
143 | if (!isNaN(ran[0]) && !isNaN(ran[1])) {
144 | minimum[0] = parseFloat(ran[0]);
145 | minimum[1] = minimum[0];
146 | minimum[2] = minimum[0];
147 | maximum[0] = parseFloat(ran[1]);
148 | maximum[1] = maximum[0];
149 | maximum[2] = maximum[0];
150 | }
151 | } else if (lower.search('lut_1d_input_range') >= 0) {
152 | var ran = line.substr(parseInt(lower.search('lut_1d_input_range')) + 18).trim().split(/\s+/g);
153 | if (!isNaN(ran[0]) && !isNaN(ran[1])) {
154 | minimum[0] = parseFloat(ran[0]);
155 | minimum[1] = minimum[0];
156 | minimum[2] = minimum[0];
157 | maximum[0] = parseFloat(ran[1]);
158 | maximum[1] = maximum[0];
159 | maximum[2] = maximum[0];
160 | }
161 | } else if (lower.search('# la_system_colourspace') >= 0) {
162 | sysCS = line.substr(parseInt(lower.search('# la_system_colourspace')) + 23).trim();
163 | } else if (lower.search('# la_input_colourspace') >= 0) {
164 | laCS = line.substr(parseInt(lower.search('# la_input_colourspace')) + 22).trim();
165 | } else if (lower.search('# la_input_transfer_function') >= 0) {
166 | laTF = line.substr(parseInt(lower.search('# la_input_transfer_function')) + 28).trim();
167 | } else if (lower.search('# la_base_iso') >= 0) {
168 | baseISO = parseInt(line.substr(parseInt(lower.search('# la_base_iso')) + 13).trim());
169 | if (isNaN(baseISO)) {
170 | baseISO = false;
171 | }
172 | } else if (lower.search('# la_interpolation') >= 0) {
173 | switch (line.substr(parseInt(lower.search('# la_interpolation')) + 18).trim().toLowerCase()) {
174 | case 'tricubic': interpolation = 0;
175 | break;
176 | case 'tetrahedral': interpolation = 1;
177 | break;
178 | case 'trilinear': interpolation = 2;
179 | break;
180 | }
181 | } else if (lower.search('# la_input_range') >= 0) {
182 | laRG = line.substr(parseInt(lower.search('# la_input_range')) + 16).trim();
183 | if (laRG === '100') {
184 | laEX = false;
185 | }
186 | } else if (lower.search('# la_input_min') >= 0) {
187 | minimum[0] = parseFloat(line.substr(parseInt(lower.search('# la_input_min')) + 14).trim());
188 | if (isNaN(minimum[0])) {
189 | minimum[0] = 0;
190 | } else {
191 | minimum[1] = minimum[0];
192 | minimum[2] = minimum[0];
193 | }
194 | } else if (lower.search('# la_input_max') >= 0) {
195 | maximum[0] = parseFloat(line.substr(parseInt(lower.search('# la_input_max')) + 14).trim());
196 | if (isNaN(maximum[0])) {
197 | minimum[0] = 1;
198 | } else {
199 | maximum[1] = maximum[0];
200 | maximum[2] = maximum[0];
201 | }
202 | } else if (lower.search('# la_input_matrix_r') >= 0) {
203 | var mat = line.substr(parseInt(lower.search('# la_input_matrix_r')) + 19).trim().split(/\s+/g);
204 | if (!isNaN(mat[0]) && !isNaN(mat[1]) && !isNaN(mat[2])) {
205 | if (laMLines === 0) {
206 | laMX = new Float64Array([1,0,0,0,1,0,0,0,1]);
207 | }
208 | laMX[0] = mat[0];
209 | laMX[1] = mat[1];
210 | laMX[2] = mat[2];
211 | laMLines++;
212 | }
213 | } else if (lower.search('# la_input_matrix_g') >= 0) {
214 | var mat = line.substr(parseInt(lower.search('# la_input_matrix_g')) + 19).trim().split(/\s+/g);
215 | if (!isNaN(mat[0]) && !isNaN(mat[1]) && !isNaN(mat[2])) {
216 | if (laMLines === 0) {
217 | laMX = new Float64Array([1,0,0,0,1,0,0,0,1]);
218 | }
219 | laMX[3] = mat[0];
220 | laMX[4] = mat[1];
221 | laMX[5] = mat[2];
222 | laMLines++;
223 | }
224 | } else if (lower.search('# la_input_matrix_b') >= 0) {
225 | var mat = line.substr(parseInt(lower.search('# la_input_matrix_b')) + 19).trim().split(/\s+/g);
226 | if (!isNaN(mat[0]) && !isNaN(mat[1]) && !isNaN(mat[2])) {
227 | if (laMLines === 0) {
228 | laMX = new Float64Array([1,0,0,0,1,0,0,0,1]);
229 | }
230 | laMX[6] = mat[0];
231 | laMX[7] = mat[1];
232 | laMX[8] = mat[2];
233 | laMLines++;
234 | }
235 | }
236 | }
237 | if (dimensions && size) {
238 | var arraySize = size;
239 | if (dimensions === 3) {
240 | arraySize = size*size*size;
241 | }
242 | var R = new Float64Array(arraySize);
243 | var G = new Float64Array(arraySize);
244 | var B = new Float64Array(arraySize);
245 | var s=0;
246 | for (var k=i; k ' + info.outGammaName;
51 | } else if (this.doHG) {
52 | out += info.inGammaName + '/' + info.inGamutName + ' -> ' + info.outGammaName + '/' + info.outGamutName + '(' + info.hgGamutName + ' in the highlights)';
53 | } else {
54 | out += info.inGammaName + '/' + info.inGamutName + ' -> ' + info.outGammaName + '/' + info.outGamutName;
55 | }
56 | out += ', CineEI Shift ' + info.cineEI.toFixed(2).toString();
57 | out += ', Black Level ' + info.blackLevel + '% IRE';
58 | if (info.legalIn) {
59 | out += ', Legal Input -> ';
60 | } else {
61 | out += ', Data Input -> ';
62 | }
63 | if (info.legalOut) {
64 | out += 'Legal Output' + "\n";
65 | } else {
66 | out += 'Data Output' + "\n";
67 | }
68 | }
69 | out += 'LUT: 3 ' + info.dimension.toString() + "\n";
70 | return out;
71 | };
72 | lutLUT.prototype.parse = function(title, text, lutMaker, lutDest) {
73 | var dimensions = 1;
74 | var channels = false;
75 | var size = false;
76 | var max = text.length;
77 | if (max === 0) {
78 | return false;
79 | }
80 | var i;
81 | for (i=0; i= 0) {
88 | var data = line.substr(parseInt(lower.search('lut:')) + 4).trim().split(/\s+/g);
89 | channels = parseInt(data[0]);
90 | size = parseInt(data[1]);
91 | }
92 | }
93 | if (channels && size) {
94 | var arraySize = size;
95 | var div = size-1;
96 | if (channels === 1) {
97 | var L = new Float64Array(arraySize);
98 | var s=0;
99 | max = i+size;
100 | for (var k=i; k= 3) {
136 | var R = new Float64Array(arraySize);
137 | var G = new Float64Array(arraySize);
138 | var B = new Float64Array(arraySize);
139 | var s=0;
140 | max = i+size;
141 | for (var k=i; k yMax) {
54 | yMax = y;
55 | }
56 | }
57 | if (yMin < 0) {
58 | yMin = 0;
59 | }
60 | if (yMax > 1) {
61 | yMax = 1;
62 | }
63 | var yScale = 1/(yMax - yMin);
64 | var h = new Uint8Array(64);
65 | this.header(h, Math.round(yMin*255), Math.round(yMax*255), info);
66 | var p = new Uint8Array(58);
67 | p[0] = 18;
68 | var k = 0;
69 | var i = 0;
70 | for (var j=0; j<18; j++) {
71 | i = j * 15;
72 | p[k+1] = i;
73 | p[k+2] = Math.min(255,Math.max(0,Math.round(((
74 | (0.2126 * (lut[ (i*3) ])) +
75 | (0.7152 * (lut[(i*3)+1])) +
76 | (0.0722 * (lut[(i*3)+2]))
77 | )-yMin)*yScale*255)));
78 | k += 2;
79 | }
80 | var d = new Uint8Array(512);
81 | k=0;
82 | for (var j=0; j 20) {
123 | title = title.substr(0,20);
124 | } else if (title.length === 0) {
125 | title = 'LUTCalc';
126 | }
127 | this.beString(title,out,k); // Title
128 | k += 20;
129 | var profile = 2;
130 | var m = this.profileName.length;
131 | for (var j=0; j= 0) {
69 | break;
70 | } else if (lower.search('version') >= 0) {
71 | version = parseInt(line.substr(parseInt(lower.search('version')) + 7).trim());
72 | } else if (lower.search('from') >= 0) {
73 | var data = line.substr(parseInt(lower.search('from')) + 4).trim().split(/\s+/g);
74 | from = parseFloat(data[0]);
75 | to = parseFloat(data[1]);
76 | } else if (lower.search('length') >= 0) {
77 | size = parseInt(line.substr(parseInt(lower.search('length')) + 6).trim());
78 | } else if (lower.search('components') >= 0) {
79 | channels = parseInt(line.substr(parseInt(lower.search('components')) + 10).trim());
80 | }
81 | }
82 | if (channels && size) {
83 | var arraySize = size;
84 | i++;
85 | if (channels === 1) {
86 | var L = new Float64Array(arraySize);
87 | var s=0;
88 | for (var k=i; k= 0) {
59 | var i;
60 | for (i=0; i 3) {
79 | // stop parsing when the LUT data is reached
80 | break;
81 | }
82 | }
83 | }
84 | if (dimensions && size) {
85 | var arraySize = size;
86 | if (dimensions === 3) {
87 | arraySize = size[0]*size[1]*size[2];
88 | }
89 | var R = new Float64Array(arraySize);
90 | var G = new Float64Array(arraySize);
91 | var B = new Float64Array(arraySize);
92 | var s;
93 | var t=0;
94 | for (var k=i; k= 0) {
56 | title = line.substr(lower.search('title') + 5).trim().replace(/"/g, '');
57 | } else if (lower.search('lut_3d_size') >= 0) {
58 | var dim = line.substr(lower.search('lut_3d_size') + 11).trim();
59 | if (!isNaN(dim)) {
60 | dimensions = 3;
61 | size = parseInt(dim);
62 | }
63 | } else if (lower.search('lut_1d_size') >= 0) {
64 | var dim = line.substr(parseInt(lower.search('lut_1d_size')) + 11).trim();
65 | if (!isNaN(dim)) {
66 | dimensions = 1;
67 | size = parseInt(dim);
68 | }
69 | } else if (lower.search('domain_min') >= 0) {
70 | var dom = line.substr(parseInt(lower.search('domain_min')) + 10).trim().split(/\s+/g);
71 | if (!isNaN(dom[0]) && !isNaN(dom[1]) && !isNaN(dom[2])) {
72 | minimum[0] = parseInt(dom[0]);
73 | minimum[1] = parseInt(dom[1]);
74 | minimum[2] = parseInt(dom[2]);
75 | }
76 | } else if (lower.search('domain_max') >= 0) {
77 | var dom = line.substr(parseInt(lower.search('domain_max')) + 10).trim().split(/\s+/g);
78 | if (!isNaN(dom[0]) && !isNaN(dom[1]) && !isNaN(dom[2])) {
79 | maximum[0] = parseInt(dom[0]);
80 | maximum[1] = parseInt(dom[1]);
81 | maximum[2] = parseInt(dom[2]);
82 | }
83 | } else if (lower.search('lut_3d_input_range') >= 0) {
84 | var ran = line.substr(parseInt(lower.search('lut_3d_input_range')) + 18).trim().split(/\s+/g);
85 | if (!isNaN(ran[0]) && !isNaN(ran[1])) {
86 | minimum[0] = parseInt(ran[0]);
87 | minimum[1] = minimum[0];
88 | minimum[2] = minimum[0];
89 | maximum[0] = parseInt(ran[1]);
90 | maximum[1] = maximum[0];
91 | maximum[2] = maximum[0];
92 | }
93 | } else if (lower.search('lut_1d_input_range') >= 0) {
94 | var ran = line.substr(parseInt(lower.search('lut_1d_input_range')) + 18).trim().split(/\s+/g);
95 | if (!isNaN(ran[0]) && !isNaN(ran[1])) {
96 | minimum[0] = parseInt(ran[0]);
97 | minimum[1] = minimum[0];
98 | minimum[2] = minimum[0];
99 | maximum[0] = parseInt(ran[1]);
100 | maximum[1] = maximum[0];
101 | maximum[2] = maximum[0];
102 | }
103 | }
104 | }
105 | if (dimensions && size) {
106 | var arraySize = size;
107 | if (dimensions === 3) {
108 | arraySize = size*size*size;
109 | }
110 | var R = new Float64Array(arraySize);
111 | var G = new Float64Array(arraySize);
112 | var B = new Float64Array(arraySize);
113 | var s=0;
114 | for (var k=i; k= 0) {
137 | mono = 1;
138 | } else if (mono < 0) {
139 | mono = -1;
140 | }
141 | if ((C[1]-C[0])*mono <= 0) {
142 | C[0] = (2*C[1]) - C[2];
143 | if ((C[1]-C[0])*mono <= 0) { // still opposite slope to monotonic
144 | C[0] = C[1] - (0.0075 * mono / (m-1));
145 | }
146 | }
147 | if ((C[m-1]-C[m-2])*mono <= 0) {
148 | C[m-1] = (2*C[m-2]) - C[m-3];
149 | if ((C[m-1]-C[m-2])*mono <= 0) { // still opposite slope to monotonic
150 | C[m-1] = C[m-2] + (0.0075 * mono / (m-1));
151 | }
152 | }
153 | this.tf = this.lutMaker.newLUT({
154 | title: 'Transfer Function',
155 | format: 'cube',
156 | dims: 1,
157 | s: m,
158 | min: [0,0,0],
159 | max: [1,1,1],
160 | C: [buff.slice(0)],
161 | meta: {
162 | inputTF: inputTF
163 | }
164 | });
165 | this.tfSpline = new LUTRSpline({buff:buff, fL:0, fH:1});
166 | this.pass = 1;
167 | this.getCS();
168 | } else if (this.inLUT.is3D()) { // Colour Space Pass
169 | var m = dim*dim*dim;
170 | var R = new Float64Array(m);
171 | var G = new Float64Array(m);
172 | var B = new Float64Array(m);
173 | var rgb = this.inputData;
174 | var inputMatrix = new Float64Array(buff);
175 | // Run the test data through the input LUT
176 | var method;
177 | if (this.inputs.laIntMethod[0].checked) {
178 | method = 0;
179 | this.inLUT.RGBCub(rgb.buffer);
180 | } else if (this.inputs.laIntMethod[1].checked) {
181 | method = 1;
182 | this.inLUT.RGBTet(rgb.buffer);
183 | } else {
184 | method = 2;
185 | this.inLUT.RGBLin(rgb.buffer);
186 | }
187 | for (var j=0; j= 0) {
218 | mono = 1;
219 | } else if (mono < 0) {
220 | mono = -1;
221 | }
222 | if ((Y[1]-Y[0])*mono <= 0) {
223 | Y[0] = (2*Y[1]) - Y[2];
224 | if ((Y[1]-Y[0])*mono <= 0) { // still opposite slope to monotonic
225 | Y[0] = Y[1] - (0.0075 * mono / (dim-1));
226 | }
227 | }
228 | if ((Y[dim-1]-Y[dim-2])*mono <= 0) {
229 | Y[dim-1] = (2*Y[dim-2]) - Y[dim-3];
230 | if ((Y[dim-1]-Y[dim-2])*mono <= 0) { // still opposite slope to monotonic
231 | Y[dim-1] = Y[dim-2] + (0.0075 * mono / (dim-1));
232 | }
233 | }
234 | }
235 | var tfSpline = new LUTRSpline({buff:Y.buffer, fL:0, fH:1});
236 | tfSpline.setMethod(method);
237 | // Find the reverse of the LUTTed data
238 | tfSpline.R(R.buffer);
239 | tfSpline.R(G.buffer);
240 | tfSpline.R(B.buffer);
241 | // Limit the results
242 | var minMax = this.inLUT.minMax();
243 | var lo = Math.min( 0, tfSpline.r(Math.min(minMax[0],minMax[1],minMax[2]))); // 0, or the lowest value in the mesh, whichever the greater
244 | var hi = Math.max( 1, tfSpline.r(Math.max(minMax[3],minMax[4],minMax[5]))); // 1.0, or the highest value in the mesh, whichever the lesser
245 | var min = lo - (87.6/1023); // 10% IRE below the 'lo' value
246 | var max = hi + (175.2/1023); // 20% IRE above 'hi' value
247 | var dcLo = tfSpline.df(lo);
248 | var dcHi = tfSpline.df(hi);
249 | var numLo = Math.pow(min-lo,2);
250 | var denLo = min-lo;
251 | var numHi = Math.pow(max-hi,2);
252 | var denHi = max-hi;
253 | for (var j=0; j hi) {
257 | R[j] = max - (numHi/((dcHi*(R[j]-hi))+denHi));
258 | }
259 | if (G[j] < lo) {
260 | G[j] = min - (numLo/((dcLo*(G[j]-lo))+denLo));
261 | } else if (G[j] > hi) {
262 | G[j] = max - (numHi/((dcHi*(G[j]-hi))+denHi));
263 | }
264 | if (B[j] < lo) {
265 | B[j] = min - (numLo/((dcLo*(B[j]-lo))+denLo));
266 | } else if (B[j] > hi) {
267 | B[j] = max - (numHi/((dcHi*(B[j]-hi))+denHi));
268 | }
269 | }
270 | var inputCS = this.inputs.laGamutSelect.options[this.inputs.laGamutSelect.selectedIndex].text.trim();
271 | var meta = {
272 | inputTF: inputTF,
273 | systemCS: 'Sony S-Gamut3.cine',
274 | inputCS: inputCS,
275 | inputEX: !this.legIn,
276 | nativeTF: this.natTF,
277 | interpolation: method,
278 | inputMatrix: inputMatrix
279 | };
280 | if (inputTF.indexOf('LogC') !== -1) {
281 | meta.baseISO = parseInt(this.inputs.cineEI.value);
282 | }
283 | this.cs = this.lutMaker.newLUT({
284 | title: 'Colour Space',
285 | format: 'cube',
286 | dims: 3,
287 | s: dim,
288 | min: [0,0,0],
289 | max: [1,1,1],
290 | C: [R.buffer,G.buffer,B.buffer],
291 | meta: meta
292 | });
293 | this.showGt = true;
294 | this.updateLATF();
295 | this.updateLACS();
296 | } else {
297 | this.showGt = false;
298 | this.updateLATF();
299 | }
300 | };
301 | LUTAnalyst.prototype.updateLACS = function() {
302 | this.gtT = this.messages.getGamutThreads();
303 | var d = this.cs.getDetails();
304 | var meta = d.meta;
305 | if (typeof d.min === 'undefined') {
306 | d.min = new Float64Array([0,0,0]);
307 | }
308 | if (typeof d.max === 'undefined') {
309 | d.max = new Float64Array([1,1,1]);
310 | }
311 | var details = {
312 | title: d.title,
313 | format: d.format,
314 | dims: d.dims,
315 | s: d.s,
316 | min: d.min,
317 | max: d.max,
318 | meta: meta
319 | };
320 | if (d.d === 3 || d.C.length === 3) {
321 | details.C = [
322 | d.C[0].slice(0),
323 | d.C[1].slice(0),
324 | d.C[2].slice(0)
325 | ];
326 | } else {
327 | details.C = [d.C[0].slice(0)];
328 | }
329 | //set LUT here
330 | this.messages.gtTxAll(this.p,6,details);
331 | };
332 | LUTAnalyst.prototype.getRGB = function() {
333 | if (this.showGt) {
334 | return this.cs.getRGB();
335 | } else {
336 | return false;
337 | }
338 | };
339 | LUTAnalyst.prototype.setLUT = function(lut, data) {
340 | this[lut] = this.lutMaker.newLUT(data);
341 | if (typeof this[lut] !== 'undefined') {
342 | this.showGt = true;
343 | return true;
344 | } else {
345 | return false;
346 | }
347 | };
348 | LUTAnalyst.prototype.noCS = function() {
349 | this.showGt = false;
350 | };
351 | LUTAnalyst.prototype.showGamut = function() {
352 | return this.showGt;
353 | };
354 | // Loading progress bar
355 | if (typeof splash !== 'undefined') {
356 | splashProg();
357 | }
358 |
--------------------------------------------------------------------------------
/js/lutmobile.js:
--------------------------------------------------------------------------------
1 | /* lutmobile.js
2 | * Menu and control objects for using the LUTCalc Web App on mobiles.
3 | * 9th March 2017
4 | *
5 | * LUTCalc generates 1D and 3D Lookup Tables (LUTs) for video cameras that shoot log gammas,
6 | * principally the Sony CineAlta line.
7 | *
8 | * By Ben Turley, http://turley.tv
9 | * First License: GPLv2
10 | * Github: https://github.com/cameramanben/LUTCalc
11 | */
12 | function LUTMobile(fieldset, inputs, messages, modalBox, objects) {
13 | this.inputs = inputs;
14 | this.messages = messages;
15 | this.modalBox = modalBox;
16 | this.objects = objects;
17 | this.box = fieldset;
18 | this.p = 16;
19 | this.messages.addUI(this.p,this);
20 | this.io();
21 | this.ui();
22 | }
23 | LUTMobile.prototype.io = function() {
24 | // Main 'Hamburger' menu button
25 | this.menuButton = document.createElement('div');
26 | this.menuButton.id = 'mob-menu-button';
27 | this.menuButton.appendChild(document.createElement('div'));
28 | this.menuButton.appendChild(document.createElement('div'));
29 | this.menuButton.appendChild(document.createElement('div'));
30 | // Status text carrier
31 | this.statusText = document.createElement('span');
32 | this.statusText.id = 'mob-status-text';
33 | this.statusText.innerHTML = 'LUTCalc ' + this.inputs.version;
34 | // Preview toggle button
35 | this.preButton = document.createElement('div');
36 | this.preButton.className = 'mob-preview-icon';
37 | // Main menu options
38 | this.genButton = document.createElement('input');
39 | this.genButton.setAttribute('type','button');
40 | this.genButton.className = 'mob-button';
41 | this.genButton.value = 'Generate LUT';
42 | this.setButton = document.createElement('input');
43 | this.setButton.setAttribute('type','button');
44 | this.setButton.className = 'mob-button';
45 | this.setButton.value = 'Base Settings';
46 | this.twkButton = document.createElement('input');
47 | this.twkButton.setAttribute('type','button');
48 | this.twkButton.className = 'mob-button';
49 | this.twkButton.value = 'Adjustments';
50 | this.infButton = document.createElement('input');
51 | this.infButton.setAttribute('type','button');
52 | this.infButton.className = 'mob-button';
53 | this.infButton.value = 'Instructions';
54 | // Mobile-specific elements for the main DOM
55 | this.generateButton = document.createElement('input');
56 | this.generateButton.setAttribute('type','button');
57 | this.generateButton.className = 'mob-genbutton';
58 | this.generateButton.value = 'Generate LUT';
59 | // Get the DOM objects for each of the main options
60 | this.boxes = {
61 | cam: document.getElementById('box-cam'),
62 | gam: document.getElementById('box-gam'),
63 | twk: document.getElementById('box-twk'),
64 | lut: document.getElementById('box-lut'),
65 | pre: document.getElementById('box-pre'),
66 | inf: document.getElementById('box-inf'),
67 | rhs: document.getElementById('right')
68 | };
69 | // Get the DOM objects for each of the tweak options
70 | var twkBoxes = document.getElementById('tweaksholder').childNodes;
71 | var m = twkBoxes.length;
72 | for (var j=0; j top-2) {
90 | d1 = (this.L[(f + 3)%top] + this.r - this.L[f])/2;
91 | } else {
92 | d1 = (this.L[f + 2] - this.L[f])/2;
93 | }
94 | var a = (2 * p0) + d0 - (2 * p1) + d1;
95 | var b = - (3 * p0) - (2 * d0) + (3 * p1) - d1;
96 | var c = d0;
97 | var d = p0;
98 | L -= f;
99 | return (((((a * L) + b) * L) + c) * L) + d;
100 | };
101 | Ring.prototype.fCub = function(L) {
102 | if (this.mod) {
103 | return this.cubMod(L);
104 | } else {
105 | return this.cub(L);
106 | }
107 | };
108 | Ring.prototype.fLin = function(L) {
109 | if (this.mod) {
110 | return this.linMod(L);
111 | } else {
112 | return this.lin(L);
113 | }
114 | };
115 | Ring.prototype.cub = function(L) {
116 | var top = (this.s - 1);
117 | L = L%1;
118 | if (L<0) {
119 | L += 1;
120 | }
121 | L = L * top;
122 | var f = Math.floor(L);
123 | var p0,p1;
124 | var d0,d1;
125 | p0 = this.L[f];
126 | if (f === top) {
127 | p1 = this.L[1] + this.r;
128 | d0 = (p1 - this.L[f-1])/2;
129 | } else if (f === 0) {
130 | p1 = this.L[1];
131 | d0 = (p1 - this.L[top-1] + this.r)/2;
132 | } else {
133 | p1 = this.L[f+1];
134 | d0 = (p1 - this.L[f - 1])/2;
135 | }
136 | if (f > top-2) {
137 | d1 = (this.L[(f + 3)%top] + this.r - this.L[f])/2;
138 | } else {
139 | d1 = (this.L[f + 2] - this.L[f])/2;
140 | }
141 | var a = (2 * p0) + d0 - (2 * p1) + d1;
142 | var b = - (3 * p0) - (2 * d0) + (3 * p1) - d1;
143 | var c = d0;
144 | var d = p0;
145 | L -= f;
146 | return (((((a * L) + b) * L) + c) * L) + d;
147 | };
148 | Ring.prototype.cubMod = function(L) {
149 | var top = (this.s - 1);
150 | L = L%1;
151 | if (L<0) {
152 | L += 1;
153 | }
154 | L = L * top;
155 | var f = Math.floor(L);
156 | var mod = this.mod;
157 | var sp = mod * 0.5;
158 | var p0,p1;
159 | var pm1,p2;
160 | var d0,d1;
161 | p0 = this.L[f];
162 | if (f === top) {
163 | p1 = this.L[1] + this.r;
164 | pm1 = this.L[f-1];
165 | } else if (f === 0) {
166 | p1 = this.L[1];
167 | pm1 = this.L[top-1] - this.r;
168 | } else {
169 | p1 = this.L[f+1];
170 | pm1 = this.L[f - 1];
171 | }
172 | if (f > top-2) {
173 | p2 = this.L[(f + 3)%top] + this.r;
174 | } else {
175 | p2 = this.L[f + 2];
176 | }
177 | if (p0-pm1 > sp) {
178 | pm1 += mod;
179 | } else if (pm1-p0 > sp) {
180 | pm1 -= mod;
181 | }
182 | if (p0-p1 > sp) {
183 | p1 += mod;
184 | } else if (p1-p0 > sp) {
185 | p1 -= mod;
186 | }
187 | if (p0-p2 > sp) {
188 | p2 += mod;
189 | } else if (p2-p0 > sp) {
190 | p2 -= mod;
191 | }
192 | pm1 = pm1%mod;
193 | p0 = p0%mod;
194 | p1 = p1%mod;
195 | p2 = p2%mod;
196 | d0 = (p1 - pm1)/2;
197 | d1 = (p2 - p0)/2;
198 | var a = (2 * p0) + d0 - (2 * p1) + d1;
199 | var b = - (3 * p0) - (2 * d0) + (3 * p1) - d1;
200 | var c = d0;
201 | var d = p0;
202 | L -= f;
203 | return (((((a * L) + b) * L) + c) * L) + d;
204 | };
205 | Ring.prototype.lin = function(L) {
206 | var top = this.s - 1;
207 | L = L%1;
208 | if (L<0) {
209 | L += 1;
210 | }
211 | L *= top;
212 | var f = Math.floor(L);
213 | var dy = L - f;
214 | if (f === top) {
215 | return (this.L[f] * (1 - dy)) + ((this.L[1]+this.r) * dy);
216 | } else {
217 | return (this.L[f] * (1 - dy)) + (this.L[f + 1] * dy);
218 | }
219 | };
220 | Ring.prototype.linMod = function(L) {
221 | var top = this.s - 1;
222 | var mod = this.mod;
223 | var sp = mod * 0.5;
224 | L = L%1;
225 | if (L<0) {
226 | L += 1;
227 | }
228 | L *= top;
229 | var f = Math.floor(L);
230 | var dy = L - f;
231 | var p0 = this.L[f];
232 | var p1;
233 | if (f === top) {
234 | p1 = this.L[1]+this.r;
235 | } else {
236 | p1 = this.L[f + 1];
237 | }
238 | if (p0-p1 > sp) {
239 | p1 += mod;
240 | } else if (p1-p0 > sp) {
241 | p1 -= mod;
242 | }
243 | p1 = p1%mod;
244 | return (p0 * (1 - dy)) + (p1 * dy);
245 | };
246 | Ring.prototype.lLsCub = function(buff) {
247 | if (this.mod) {
248 | this.cubsMod(buff);
249 | } else {
250 | this.cubs(buff);
251 | }
252 | };
253 | Ring.prototype.cubs = function(buff) {
254 | var o = new Float64Array(buff);
255 | var m = o.length;
256 | var max = this.s - 1;
257 | var f;
258 | var p0,p1;
259 | var d0,d1;
260 | var a,b,c,d;
261 | for (var j=0; j max-2) {
280 | d1 = (this.L[(f + 3)%max] + this.r - this.L[f])/2;
281 | } else {
282 | d1 = (this.L[f + 2] - this.L[f])/2;
283 | }
284 | a = (2 * p0) + d0 - (2 * p1) + d1;
285 | b = - (3 * p0) - (2 * d0) + (3 * p1) - d1;
286 | c = d0;
287 | d = p0;
288 | o[j] -= f;
289 | o[j] = (((((a * o[j]) + b) * o[j]) + c) * o[j]) + d;
290 | }
291 | };
292 | Ring.prototype.cubsMod = function(buff) {
293 | var o = new Float64Array(buff);
294 | var m = o.length;
295 | var max = this.s - 1;
296 | var f;
297 | var p0,p1;
298 | var pm1,p2;
299 | var d0,d1;
300 | var a,b,c,d;
301 | var mod = this.mod;
302 | var sp = mod * 0.5;
303 | for (var j=0; j max-2) {
322 | p2 = this.L[(f + 3)%max] + this.r;
323 | } else {
324 | p2 = this.L[f + 2];
325 | }
326 | if (p0-pm1 > sp) {
327 | pm1 += mod;
328 | } else if (pm1-p0 > sp) {
329 | pm1 -= mod;
330 | }
331 | if (p0-p1 > sp) {
332 | p1 += mod;
333 | } else if (p1-p0 > sp) {
334 | p1 -= mod;
335 | }
336 | if (p0-p2 > sp) {
337 | p2 += mod;
338 | } else if (p2-p0 > sp) {
339 | p2 -= mod;
340 | }
341 | pm1 = pm1%mod;
342 | p0 = p0%mod;
343 | p1 = p1%mod;
344 | p2 = p2%mod;
345 | d0 = (p1 - pm1)/2;
346 | d1 = (p2 - p0)/2;
347 | a = (2 * p0) + d0 - (2 * p1) + d1;
348 | b = - (3 * p0) - (2 * d0) + (3 * p1) - d1;
349 | c = d0;
350 | d = p0;
351 | o[j] -= f;
352 | o[j] = (((((a * o[j]) + b) * o[j]) + c) * o[j]) + d;
353 | }
354 | };
355 | Ring.prototype.lLsLin = function(buff) {
356 | if (this.mod) {
357 | this.linsMod(buff);
358 | } else {
359 | this.lins(buff);
360 | }
361 | };
362 | Ring.prototype.lins = function(buff) {
363 | var o = new Float64Array(buff);
364 | var m = o.length;
365 | var max = this.s - 1;
366 | var f, dy;
367 | for (var j=0; j sp) {
405 | p1 += mod;
406 | } else if (p1-p0 > sp) {
407 | p1 -= mod;
408 | }
409 | p1 = p1%mod;
410 | o[j] = (p0 * (1 - dy)) + (p1 * dy);
411 | }
412 | };
413 | // Stringify for inline Web Workers
414 | function getRingString() {
415 | var out = "";
416 | // Ring
417 | out += Ring.toString() + "\n";
418 | for (var j in Ring.prototype) {
419 | out += 'Ring.prototype.' + j + '=' + Ring.prototype[j].toString() + "\n";
420 | }
421 | return out;
422 | }
423 | var workerRingString = getRingString();
424 |
--------------------------------------------------------------------------------
/js/splash.js:
--------------------------------------------------------------------------------
1 | /* splash.js
2 | * Changes Javascript warning into a splash screen in the LUTCalc Web App.
3 | * Also creates browser feature test and global data objects
4 | * 17th March 2017
5 | *
6 | * LUTCalc generates 1D and 3D Lookup Tables (LUTs) for video cameras that shoot log gammas,
7 | * principally the Sony CineAlta line.
8 | *
9 | * By Ben Turley, http://turley.tv
10 | * First License: GPLv2
11 | * Github: https://github.com/cameramanben/LUTCalc
12 | */
13 | /************************* LUTInputs *************************/
14 | /*********** Data available globally within LUTCalc **********/
15 | function LUTInputs() {
16 | this.ready = [true,
17 | false, // 1 - camerabox
18 | false, // 2 - gammabox
19 | false, // 3 - tweaksbox
20 | false, // 4 - lutbox
21 | false, // 5 - generatebox
22 | false, // 6 - infobox
23 | false, // 7 - LUTAnalyst
24 | false, // 8 - preview
25 | false, // 9 - twkHG
26 | false, // 10 - twkLA
27 | ];
28 | this.isMobile = false; // Assume not on a mobile until proven otherwise
29 | }
30 | LUTInputs.prototype.addInput = function(inputName,inputValue) {
31 | try {
32 | this[inputName] = inputValue;
33 | return true;
34 | } catch(err) {
35 | return false;
36 | }
37 | };
38 | LUTInputs.prototype.isReady = function(ui) {
39 | var ready = true;
40 | var m = this.ready.length;
41 | for (var j=0; j 0) {
129 | lutInputs.addInput('isLE', true);
130 | } else {
131 | lutInputs.addInput('isLE', false);
132 | }
133 | };
134 | LUTTests.prototype.isTransTest = function(worker) { // Test that web workers can use transferrable objects
135 | var trans;
136 | try {
137 | var test = new ArrayBuffer(1);
138 | worker.postMessage(test, [test]);
139 | trans = (test.byteLength === 0);
140 | } catch(error) {
141 | trans = false;
142 | }
143 | this.inputs.isTrans = trans;
144 | };
145 | /******* Modal box to freeze all UI buttons and inputs *******/
146 | var modalBox = document.createElement('div');
147 | modalBox.className = 'modalbox-hide';
148 | modalBox.onclick = function(here){ return function(){
149 | // Do nothing - stops anything else from happening whilst the modal box is active.
150 | };}(this);
151 | /********************* Splash screen code ********************/
152 | function splashStart() {
153 | document.getElementById('titlebar').className = 'titlebar-hide';
154 | document.getElementById('lutcalcform').className = 'lutcalcform-hide';
155 | document.getElementById('footer').className = 'footer-hide';
156 | var splash = document.getElementById('javascriptwarning');
157 | splash.removeChild(splash.firstChild);
158 | splash.className = 'splash';
159 | splashTxt(splash);
160 | return splash;
161 | }
162 | var splashInterval = false;
163 | function splashTxt(splash) {
164 | var splashText = document.createElement('div');
165 | var splashTitle = document.createElement('h1');
166 | splashTitle.innerHTML = 'LUTCalc ' + lutInputs.version;
167 | splashText.appendChild(splashTitle);
168 | splashText.appendChild(document.createElement('br'));
169 | var splashCredit = document.createElement('h5');
170 | splashCredit.innerHTML = 'Ben Turley ' + lutInputs.date;
171 | splashText.appendChild(splashCredit);
172 | splash.appendChild(splashText);
173 | lutInputs.addInput('splashProgress',document.createElement('span'));
174 | lutInputs.addInput('splashPer',0);
175 | var progressBox = document.createElement('span');
176 | progressBox.id = 'splash-progress-box';
177 | lutInputs.splashProgress.id = 'splash-progress';
178 | lutInputs.splashProgress.style.width = lutInputs.splashPer.toString() + '%';
179 | progressBox.appendChild(lutInputs.splashProgress);
180 | splash.appendChild(progressBox);
181 | splashInterval = setInterval(updateSplash,10);
182 | }
183 | function splashProg(step) {
184 | var s;
185 | if (typeof step === 'undefined') {
186 | s = 0.25;
187 | } else {
188 | s = step;
189 | }
190 | lutInputs.splashPer += s;
191 | }
192 | function updateSplash() {
193 | if (lutInputs.splashPer <= 100) {
194 | lutInputs.splashProgress.style.width = Math.round(lutInputs.splashPer).toString() + '%';
195 | } else {
196 | clearInterval(splashInterval);
197 | return;
198 | }
199 | }
200 |
201 | /********************** Start things up **********************/
202 | var lutInputs = new LUTInputs();
203 | lutInputs.addInput('version','v4.09');
204 | lutInputs.addInput('versionNum', 4.09);
205 | lutInputs.addInput('date','February 2025');
206 | var splash = splashStart();
207 | var lutTests = new LUTTests(lutInputs);
208 |
--------------------------------------------------------------------------------
/js/twk-asccdl.js:
--------------------------------------------------------------------------------
1 | /* twk-asccdl.js
2 | * ASC-CDL object for the LUTCalc Web App.
3 | * 10th April 2015
4 | *
5 | * LUTCalc generates 1D and 3D Lookup Tables (LUTs) for video cameras that shoot log gammas,
6 | * principally the Sony CineAlta line.
7 | *
8 | * By Ben Turley, http://turley.tv
9 | * First License: GPLv2
10 | * Github: https://github.com/cameramanben/LUTCalc
11 | */
12 | function TWKASCCDL(tweaksBox, inputs, messages) {
13 | this.tweaksBox = tweaksBox;
14 | this.inputs = inputs;
15 | this.messages = messages;
16 | this.io();
17 | this.ui();
18 | }
19 | TWKASCCDL.prototype.io = function() {
20 | // Tweak Checkbox
21 | this.tweakCheck = document.createElement('input');
22 | this.tweakCheck.setAttribute('type','checkbox');
23 | this.tweakCheck.className = 'twk-checkbox';
24 | this.tweakCheck.checked = false;
25 |
26 | // Saturation Slider
27 | this.satS = new lutSlider({
28 | min: 0,
29 | max: 2,
30 | value: 1,
31 | step: 0.05,
32 | title: false,
33 | lhs: 'Saturation',
34 | minLabel: false,
35 | maxLabel: false,
36 | input: 'number',
37 | inputLim: false,
38 | reset: true
39 | });
40 | // Colour Channel Selector
41 | this.channelSelect = document.createElement('select');
42 | this.channelSelect.className = 'twk-select';
43 | this.channelList();
44 | // SOP Arrays
45 | this.sS = [];
46 | this.oS = [];
47 | this.pS = [];
48 | for (var j=0; j<4; j++) {
49 | this.sS[j] = new lutSlider({
50 | min: 0,
51 | mid: 1,
52 | max: 10,
53 | value: 1,
54 | step: 0.0001,
55 | title: false,
56 | lhs: 'Slope',
57 | minLabel: false,
58 | maxLabel: false,
59 | input: 'number',
60 | inputLim: false,
61 | reset: true,
62 | resetAll: true
63 | });
64 | this.oS[j] = new lutSlider({
65 | min: -0.5,
66 | max: 0.5,
67 | value: 0,
68 | step: 0.01,
69 | title: false,
70 | lhs: 'Offset',
71 | minLabel: false,
72 | maxLabel: false,
73 | input: 'number',
74 | inputLim: false,
75 | reset: true,
76 | resetAll: true
77 | });
78 | this.pS[j] = new lutSlider({
79 | min: 0,
80 | mid: 1,
81 | max: 10,
82 | value: 1,
83 | step: 0.01,
84 | title: false,
85 | lhs: 'Power',
86 | minLabel: false,
87 | maxLabel: false,
88 | input: 'number',
89 | inputLim: false,
90 | reset: true,
91 | resetAll: true
92 | });
93 | }
94 | };
95 | TWKASCCDL.prototype.ui = function() {
96 | // General Tweak Holder (Including Checkbox)
97 | this.holder = document.createElement('div');
98 | this.holder.className = 'tweakholder-hide';
99 | this.tweaksBox.appendChild(this.holder);
100 | this.holder.appendChild(document.createElement('label').appendChild(document.createTextNode('ASC-CDL')));
101 | this.holder.appendChild(this.tweakCheck);
102 | // Tweak Box - Inputs Which Appear When the Tweak Checkbox Is Ticked
103 | this.box = document.createElement('div');
104 | this.box.className = 'tweak-hide';
105 | // Tweak - Specific UI Elements
106 | // Saturation
107 | this.box.appendChild(this.satS.element);
108 | // Channel Selector
109 | this.box.appendChild(this.channelSelect);
110 | this.box.appendChild(document.createElement('br'));
111 | // SOP Boxes
112 | this.sop = [];
113 | for (var j=0; j<4; j++) {
114 | this.sop[j] = document.createElement('div');
115 | if (j === 0) {
116 | this.sop[j].className = 'twk-tab';
117 | } else {
118 | this.sop[j].className = 'twk-tab-hide';
119 | }
120 | this.sop[j].appendChild(this.sS[j].element);
121 | this.sop[j].appendChild(this.oS[j].element);
122 | this.sop[j].appendChild(this.pS[j].element);
123 | this.box.appendChild(this.sop[j]);
124 | }
125 | // Build Box Hierarchy
126 | this.holder.appendChild(this.box);
127 | };
128 | TWKASCCDL.prototype.toggleTweaks = function() {
129 | // If The Overall Checkbox Is Ticked
130 | if (this.inputs.tweaks.checked) {
131 | if (this.inputs.outGamma.options[this.inputs.outGamma.selectedIndex].lastChild.nodeValue !== 'Null') {
132 | this.holder.className = 'tweakholder';
133 | } else {
134 | this.holder.className = 'tweakholder-hide';
135 | this.tweakCheck.checked = false;
136 | }
137 | if (this.inputs.d[1].checked) {
138 | this.satS.show();
139 | } else {
140 | this.satS.hide();
141 | }
142 | } else {
143 | this.holder.className = 'tweakholder-hide';
144 | this.tweakCheck.checked = false;
145 | }
146 | this.toggleTweak();
147 | };
148 | TWKASCCDL.prototype.toggleTweak = function() {
149 | if (this.tweakCheck.checked) {
150 | this.box.className = 'tweak';
151 | } else {
152 | this.box.className = 'tweak-hide';
153 | }
154 | };
155 | TWKASCCDL.prototype.getTFParams = function(params) {
156 | var out = {};
157 | var tweaks = this.inputs.tweaks.checked;
158 | var tweak = this.tweakCheck.checked;
159 | if (tweaks && tweak) {
160 | out.doASCCDL = true;
161 | var cdl = new Float64Array(10);
162 | for (var j=0; j<3; j++) {
163 | cdl[ j ] = this.sS[j+1].getValue();
164 | cdl[j+3] = this.oS[j+1].getValue();
165 | cdl[j+6] = this.pS[j+1].getValue();
166 | }
167 | cdl[9] = this.satS.getValue();
168 | out.cdl = cdl.buffer;
169 | } else {
170 | out.doASCCDL = false;
171 | }
172 | params.twkASCCDL = out;
173 | };
174 | TWKASCCDL.prototype.getCSParams = function(params) {
175 | var out = {};
176 | var tweaks = this.inputs.tweaks.checked;
177 | var tweak = this.tweakCheck.checked;
178 | if (tweaks && tweak) {
179 | out.doASCCDL = true;
180 | var cdl = new Float64Array(10);
181 | for (var j=0; j<3; j++) {
182 | cdl[ j ] = this.sS[j+1].getValue();
183 | cdl[j+3] = this.oS[j+1].getValue();
184 | cdl[j+6] = this.pS[j+1].getValue();
185 | }
186 | cdl[9] = this.satS.getValue();
187 | out.cdl = cdl.buffer;
188 | } else {
189 | out.doASCCDL = false;
190 | }
191 | params.twkASCCDL = out;
192 | };
193 | TWKASCCDL.prototype.setParams = function(params) {
194 | if (typeof params.twkASCCDL !== 'undefined') {
195 | var p = params.twkASCCDL;
196 | this.toggleTweaks();
197 | }
198 | };
199 | TWKASCCDL.prototype.getSettings = function(data) {
200 | var cdl = [];
201 | for (var j=0; j<3; j++) {
202 | cdl[ j ] = this.sS[j+1].getValue();
203 | cdl[j+3] = this.oS[j+1].getValue();
204 | cdl[j+6] = this.pS[j+1].getValue();
205 | }
206 | cdl[9] = this.satS.getValue();
207 | data.ascCDL = {
208 | doASCCDL: this.tweakCheck.checked,
209 | cdl: cdl.toString(),
210 | channel: this.channelSelect.options[this.channelSelect.selectedIndex].lastChild.nodeValue
211 | };
212 | };
213 | TWKASCCDL.prototype.setSettings = function(settings) {
214 | if (typeof settings.ascCDL !== 'undefined') {
215 | var data = settings.ascCDL;
216 | if (typeof data.doASCCDL === 'boolean') {
217 | this.tweakCheck.checked = data.doASCCDL;
218 | this.toggleTweak();
219 | }
220 | if (typeof data.cdl !== 'undefined') {
221 | var cdl = data.cdl.split(',').map(Number);
222 | this.sS[0].setValue((parseFloat(cdl[0])+parseFloat(cdl[1])+parseFloat(cdl[2]))/3);
223 | this.oS[0].setValue((parseFloat(cdl[3])+parseFloat(cdl[4])+parseFloat(cdl[5]))/3);
224 | this.pS[0].setValue((parseFloat(cdl[6])+parseFloat(cdl[7])+parseFloat(cdl[8]))/3);
225 | for (var j=0; j<3; j++) {
226 | this.sS[j+1].setValue(parseFloat(cdl[ j ]));
227 | this.oS[j+1].setValue(parseFloat(cdl[j+3]));
228 | this.pS[j+1].setValue(parseFloat(cdl[j+6]));
229 | }
230 | this.satS.setValue(parseFloat(cdl[9]));
231 | }
232 | if (typeof data.channel !== 'undefined') {
233 | var m = this.channelSelect.options.length;
234 | for (var j=0; j= clip) {
240 | here.clipS.setValue(start + 0.05);
241 | }
242 | here.messages.gaSetParams();
243 | };}(this);
244 | this.clipS.action = function(here){ return function(){
245 | var clip = this.getValue();
246 | var start = here.startS.getValue();
247 | if (start >= clip) {
248 | here.startS.setValue(start - 0.05);
249 | }
250 | here.messages.gaSetParams();
251 | };}(this);
252 | this.slopeS.action = function(here){ return function(){
253 | here.messages.gaSetParams();
254 | };}(this);
255 | this.smoothS.action = function(here){ return function(){
256 | here.messages.gaSetParams();
257 | };}(this);
258 | };
259 | // Tweak-Specific Code
260 | TWKKnee.prototype.createRadioElement = function(name, checked) {
261 | var radioInput;
262 | try {
263 | var radioHtml = '';
268 | radioInput = document.createElement(radioHtml);
269 | } catch( err ) {
270 | radioInput = document.createElement('input');
271 | radioInput.setAttribute('type', 'radio');
272 | radioInput.setAttribute('name', name);
273 | if ( checked ) {
274 | radioInput.setAttribute('checked', 'checked');
275 | }
276 | }
277 | return radioInput;
278 | };
279 | // Loading progress bar
280 | if (typeof splash !== 'undefined') {
281 | splashProg();
282 | }
283 |
--------------------------------------------------------------------------------
/js/twk-sdrsat.js:
--------------------------------------------------------------------------------
1 | /* twk-sdrsat.js
2 | * Adjustment using gamma correction to up the saturation of HLG signals in SDR viewing
3 | * 4th April 2019
4 | *
5 | * LUTCalc generates 1D and 3D Lookup Tables (LUTs) for video cameras that shoot log gammas,
6 | * principally the Sony CineAlta line.
7 | *
8 | * By Ben Turley, http://turley.tv
9 | * First License: GPLv2
10 | * Github: https://github.com/cameramanben/LUTCalc
11 | */
12 | function TWKSDRSat(tweaksBox, inputs, messages) {
13 | this.tweaksBox = tweaksBox;
14 | this.inputs = inputs;
15 | this.messages = messages;
16 | this.io();
17 | this.ui();
18 | this.events();
19 | }
20 | TWKSDRSat.prototype.io = function() {
21 | // Tweak Checkbox
22 | this.tweakCheck = document.createElement('input');
23 | this.tweakCheck.setAttribute('type','checkbox');
24 | this.tweakCheck.className = 'twk-checkbox';
25 | this.tweakCheck.checked = false;
26 | // Tweak - Specific Inputs
27 | this.gamma = new lutSlider({
28 | min: 1,
29 | max: 2,
30 | value: 1.2,
31 | step: 0.05,
32 | title: false,
33 | lhs: 'Saturation',
34 | minLabel: false,
35 | maxLabel: false,
36 | input: 'number',
37 | reset: true
38 | });
39 | this.hdrs = [
40 | // 'Rec2100 PQ (PQ OOTF)',
41 | // 'Rec2100 PQ (HLG OOTF)',
42 | 'Rec2100 HLG',
43 | // 'PQ (EOTF Only)',
44 | 'ITU Proposal (400%)',
45 | 'ITU Proposal (800%)',
46 | 'BBC WHP283 (400%)',
47 | 'BBC WHP283 (800%)'
48 | ];
49 | this.wgts = [
50 | 'Rec2020',
51 | 'Rec2100'
52 | ];
53 | };
54 | TWKSDRSat.prototype.ui = function() {
55 | // General Tweak Holder (Including Checkbox)
56 | this.holder = document.createElement('div');
57 | this.holder.className = 'tweakholder-hide';
58 | this.tweaksBox.appendChild(this.holder);
59 | this.holder.appendChild(document.createElement('label').appendChild(document.createTextNode('SDR Saturation')));
60 | this.holder.appendChild(this.tweakCheck);
61 | // Tweak Box - Inputs Which Appear When the Tweak Checkbox Is Ticked
62 | this.box = document.createElement('div');
63 | this.box.className = 'tweak-hide';
64 | // Tweak - Specific UI Elements
65 | this.box.appendChild(this.gamma.element);
66 | // Build Box Hierarchy
67 | this.holder.appendChild(this.box);
68 | };
69 | TWKSDRSat.prototype.toggleTweaks = function() {
70 | // If The Overall Checkbox Is Ticked
71 | if (this.inputs.tweaks.checked && this.inputs.d[1].checked) { // This checks for 'Customisations' to be checked and LUT type set to '3D' (the d[1] item)
72 | var oG = this.inputs.outGamma.options[this.inputs.outGamma.selectedIndex].lastChild.nodeValue;
73 | var oGt = this.inputs.outGamut.options[this.inputs.outGamut.selectedIndex].lastChild.nodeValue;
74 | if (this.hdrs.indexOf(oG) > -1 && this.wgts.indexOf(oGt) > -1) {
75 | this.holder.className = 'tweakholder';
76 | } else {
77 | this.holder.className = 'tweakholder-hide';
78 | this.tweakCheck.checked = false;
79 | }
80 | } else {
81 | this.holder.className = 'tweakholder-hide';
82 | this.tweakCheck.checked = false;
83 | }
84 | this.toggleTweak();
85 | };
86 | TWKSDRSat.prototype.toggleTweak = function() {
87 | if (this.tweakCheck.checked) {
88 | this.box.className = 'tweak';
89 | } else {
90 | this.box.className = 'tweak-hide';
91 | }
92 | };
93 | TWKSDRSat.prototype.getTFParams = function(params) {
94 | // No parameters are relevent
95 | };
96 | TWKSDRSat.prototype.getCSParams = function(params) {
97 | var out = {};
98 | var tweaks = this.inputs.tweaks.checked;
99 | var tweak = this.tweakCheck.checked;
100 | if (tweaks && tweak) {
101 | out.doSDRSat = true;
102 | out.gamma = this.gamma.getValue();
103 | } else {
104 | out.doSDRSat = false;
105 | }
106 | params.twkSDRSat = out;
107 | };
108 | TWKSDRSat.prototype.setParams = function(params) {
109 | if (typeof params.twkSDRSat !== 'undefined') {
110 | var p = params.twkSDRSat;
111 | this.toggleTweaks();
112 | }
113 | };
114 | TWKSDRSat.prototype.getSettings = function(data) {
115 | data.sdrsat = {
116 | doSDRSat: this.tweakCheck.checked,
117 | gamma: this.gamma.getValue()
118 | };
119 | };
120 | TWKSDRSat.prototype.setSettings = function(settings) {
121 | if (typeof settings.SDRSAT !== 'undefined') {
122 | var data = settings.SDRSAT;
123 | if (typeof data.doSDRSat === 'boolean') {
124 | this.tweakCheck.checked = data.doSDRSat;
125 | this.gamma.setValue(parseFloat(data.gamma));
126 | this.toggleTweak();
127 | }
128 | }
129 | };
130 | TWKSDRSat.prototype.getInfo = function(info) {
131 | // Provides metadata to LUT formats
132 | var tweaks = this.inputs.tweaks.checked;
133 | var tweak = this.tweakCheck.checked;
134 | if (tweaks && tweak) {
135 | info.doSDRSat = true;
136 | } else {
137 | info.doSDRSat = false;
138 | }
139 | };
140 | TWKSDRSat.prototype.isCustomGamma = function() {
141 | return false;
142 | };
143 | TWKSDRSat.prototype.isCustomGamut = function() {
144 | var tweaks = this.inputs.tweaks.checked;
145 | var tweak = this.tweakCheck.checked;
146 | if (tweaks && tweak) {
147 | return true;
148 | } else {
149 | return false;
150 | }
151 | };
152 | TWKSDRSat.prototype.events = function() {
153 | this.tweakCheck.onclick = function(here){ return function(){
154 | here.toggleTweak();
155 | here.messages.gtSetParams();
156 | };}(this);
157 | this.gamma.action = function(here){ return function(){
158 | here.messages.gtSetParams();
159 | };}(this);
160 | };
161 | // Tweak-Specific Code
162 | // Methods called by event responses should go here
163 | // Requirements:
164 | // style.display should be avoided, use className = 'value';
165 | // for showing and hiding, it should be of the form className = 'twk-itemclass' and className = 'twk-itemclass-hide'
166 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "LUTCalc",
3 | "name": "LUTCalc",
4 | "version": "4.06",
5 | "developer": {
6 | "name": "Ben Turley",
7 | "url": "https://turley.tv"
8 | },
9 | "default_locale": "en",
10 | "lang": "en-gb",
11 | "type": "web",
12 | "icons": [
13 | {
14 | "src": "./img/lutcalc-16.png",
15 | "type": "image/png",
16 | "sizes": "16x16"
17 | },
18 | {
19 | "src": "./img/lutcalc-19.png",
20 | "type": "image/png",
21 | "sizes": "19x19"
22 | },
23 | {
24 | "src": "./img/lutcalc-32.png",
25 | "type": "image/png",
26 | "sizes": "32x32"
27 | },
28 | {
29 | "src": "./img/lutcalc-38.png",
30 | "type": "image/png",
31 | "sizes": "38x38"
32 | },
33 | {
34 | "src": "./img/lutcalc-48.png",
35 | "type": "image/png",
36 | "sizes": "48x48"
37 | },
38 | {
39 | "src": "./img/lutcalc-60.png",
40 | "type": "image/png",
41 | "sizes": "60x60"
42 | },
43 | {
44 | "src": "./img/lutcalc-64.png",
45 | "type": "image/png",
46 | "sizes": "64x64"
47 | },
48 | {
49 | "src": "./img/lutcalc-90.png",
50 | "type": "image/png",
51 | "sizes": "90x90"
52 | },
53 | {
54 | "src": "./img/lutcalc-128.png",
55 | "type": "image/png",
56 | "sizes": "128x128"
57 | },
58 | {
59 | "src": "./img/lutcalc-256.png",
60 | "type": "image/png",
61 | "sizes": "256x256"
62 | },
63 | {
64 | "src": "./img/lutcalc-512.png",
65 | "type": "image/png",
66 | "sizes": "512x512"
67 | },
68 | {
69 | "src": "./img/lutcalc-1024.png",
70 | "type": "image/png",
71 | "sizes": "1024x1024"
72 | }
73 | ],
74 | "start_url": "./index.html",
75 | "launch_path": "./index.html",
76 | "background_color": "#eaeaea",
77 | "display": "standalone",
78 | "scope": "./",
79 | "theme_color": "#202090",
80 | "shortcuts": [],
81 | "description": "Camera LUT Generator / Analyser / Visualiser.",
82 | "screenshots": [
83 | {
84 | "src": "./img/Screenshot-Wide-1.png",
85 | "type": "image/png",
86 | "sizes": "720x389",
87 | "form_factor": "wide"
88 | },
89 | {
90 | "src": "./img/Screenshot-Tall-1.png",
91 | "type": "image/png",
92 | "sizes": "649x720",
93 | "form_factor": "narrow"
94 | }
95 | ]
96 | }
97 |
--------------------------------------------------------------------------------
/pngs/cust-asc-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-asc-1.png
--------------------------------------------------------------------------------
/pngs/cust-asc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-asc.png
--------------------------------------------------------------------------------
/pngs/cust-bgm-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-bgm-1.png
--------------------------------------------------------------------------------
/pngs/cust-bgm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-bgm.png
--------------------------------------------------------------------------------
/pngs/cust-bhi-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-bhi-1.png
--------------------------------------------------------------------------------
/pngs/cust-bhi-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-bhi-2.png
--------------------------------------------------------------------------------
/pngs/cust-bhi-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-bhi-3.png
--------------------------------------------------------------------------------
/pngs/cust-bhi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-bhi.png
--------------------------------------------------------------------------------
/pngs/cust-colour-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-colour-1.png
--------------------------------------------------------------------------------
/pngs/cust-colour-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-colour-2.png
--------------------------------------------------------------------------------
/pngs/cust-colour.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-colour.png
--------------------------------------------------------------------------------
/pngs/cust-dcc-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-dcc-1.png
--------------------------------------------------------------------------------
/pngs/cust-dcc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-dcc.png
--------------------------------------------------------------------------------
/pngs/cust-fc-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-fc-1.png
--------------------------------------------------------------------------------
/pngs/cust-fc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-fc.png
--------------------------------------------------------------------------------
/pngs/cust-glim-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-glim-1.png
--------------------------------------------------------------------------------
/pngs/cust-glim-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-glim-2.png
--------------------------------------------------------------------------------
/pngs/cust-glim-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-glim-3.png
--------------------------------------------------------------------------------
/pngs/cust-glim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-glim.png
--------------------------------------------------------------------------------
/pngs/cust-header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-header.png
--------------------------------------------------------------------------------
/pngs/cust-hg-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-hg-1.png
--------------------------------------------------------------------------------
/pngs/cust-hg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-hg.png
--------------------------------------------------------------------------------
/pngs/cust-knee-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-knee-1.png
--------------------------------------------------------------------------------
/pngs/cust-knee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-knee.png
--------------------------------------------------------------------------------
/pngs/cust-la-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-la-1.png
--------------------------------------------------------------------------------
/pngs/cust-la-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-la-2.png
--------------------------------------------------------------------------------
/pngs/cust-la-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-la-3.png
--------------------------------------------------------------------------------
/pngs/cust-la.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-la.png
--------------------------------------------------------------------------------
/pngs/cust-multi-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-multi-1.jpg
--------------------------------------------------------------------------------
/pngs/cust-multi-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-multi-2.jpg
--------------------------------------------------------------------------------
/pngs/cust-multi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-multi.png
--------------------------------------------------------------------------------
/pngs/cust-psst-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-psst-1.png
--------------------------------------------------------------------------------
/pngs/cust-psst-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-psst-2.jpg
--------------------------------------------------------------------------------
/pngs/cust-psst-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-psst-3.png
--------------------------------------------------------------------------------
/pngs/cust-psst.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-psst.png
--------------------------------------------------------------------------------
/pngs/cust-samp-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-samp-1.png
--------------------------------------------------------------------------------
/pngs/cust-samp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-samp.png
--------------------------------------------------------------------------------
/pngs/cust-sdrs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-sdrs.png
--------------------------------------------------------------------------------
/pngs/cust-wht-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-wht-1.png
--------------------------------------------------------------------------------
/pngs/cust-wht-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-wht-2.png
--------------------------------------------------------------------------------
/pngs/cust-wht.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/cust-wht.png
--------------------------------------------------------------------------------
/pngs/ins-cam-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-cam-1.png
--------------------------------------------------------------------------------
/pngs/ins-cust-wht-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-cust-wht-1.png
--------------------------------------------------------------------------------
/pngs/ins-gam-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-gam-1.png
--------------------------------------------------------------------------------
/pngs/ins-inf-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-inf-1.png
--------------------------------------------------------------------------------
/pngs/ins-lut-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-lut-1.png
--------------------------------------------------------------------------------
/pngs/ins-lut-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-lut-2.png
--------------------------------------------------------------------------------
/pngs/ins-pre-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-pre-1.jpg
--------------------------------------------------------------------------------
/pngs/ins-pre-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-pre-2.jpg
--------------------------------------------------------------------------------
/pngs/ins-pre-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/ins-pre-3.png
--------------------------------------------------------------------------------
/pngs/main-but-gen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-but-gen.png
--------------------------------------------------------------------------------
/pngs/main-but-gst.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-but-gst.png
--------------------------------------------------------------------------------
/pngs/main-but-pre.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-but-pre.png
--------------------------------------------------------------------------------
/pngs/main-but-set.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-but-set.png
--------------------------------------------------------------------------------
/pngs/main-cam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-cam.png
--------------------------------------------------------------------------------
/pngs/main-footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-footer.png
--------------------------------------------------------------------------------
/pngs/main-gam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-gam.png
--------------------------------------------------------------------------------
/pngs/main-header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-header.png
--------------------------------------------------------------------------------
/pngs/main-inf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-inf.png
--------------------------------------------------------------------------------
/pngs/main-lut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-lut.png
--------------------------------------------------------------------------------
/pngs/main-twk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/main-twk.png
--------------------------------------------------------------------------------
/pngs/mob-chart-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/mob-chart-icon.png
--------------------------------------------------------------------------------
/pngs/mob-preview-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/pngs/mob-preview-icon.png
--------------------------------------------------------------------------------
/s709.labin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/s709.labin
--------------------------------------------------------------------------------
/window.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | LUTCalc
16 |
17 |
18 | LUTCalc - 1D & 3D Cube LUT Calculator
19 |
20 | *** Please Allow Javascript To Run On This Page ***
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/xyuvLSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/xyuvLSB.png
--------------------------------------------------------------------------------
/xyuvMSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cameramanben/LUTCalc/fc70eba2198ba577cc87d5a614506bd5e4d49330/xyuvMSB.png
--------------------------------------------------------------------------------