LogLuvLoader.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. ( function () {
  2. class LogLuvLoader extends THREE.DataTextureLoader {
  3. constructor( manager ) {
  4. super( manager );
  5. this.type = THREE.HalfFloatType;
  6. }
  7. parse( buffer ) {
  8. const ifds = UTIF.decode( buffer );
  9. UTIF.decodeImage( buffer, ifds[ 0 ] );
  10. const rgba = UTIF.toRGBA( ifds[ 0 ], this.type );
  11. return {
  12. width: ifds[ 0 ].width,
  13. height: ifds[ 0 ].height,
  14. data: rgba,
  15. format: THREE.RGBAFormat,
  16. type: this.type,
  17. flipY: true
  18. };
  19. }
  20. setDataType( value ) {
  21. this.type = value;
  22. return this;
  23. }
  24. }
  25. // from https://github.com/photopea/UTIF.js (MIT License)
  26. const UTIF = {};
  27. UTIF.decode = function ( buff, prm ) {
  28. if ( prm == null ) prm = {
  29. parseMN: true,
  30. debug: false
  31. }; // read MakerNote, debug
  32. var data = new Uint8Array( buff ),
  33. offset = 0;
  34. var id = UTIF._binBE.readASCII( data, offset, 2 );
  35. offset += 2;
  36. var bin = id == 'II' ? UTIF._binLE : UTIF._binBE;
  37. bin.readUshort( data, offset );
  38. offset += 2;
  39. var ifdo = bin.readUint( data, offset );
  40. var ifds = [];
  41. while ( true ) {
  42. var cnt = bin.readUshort( data, ifdo ),
  43. typ = bin.readUshort( data, ifdo + 4 );
  44. if ( cnt != 0 ) if ( typ < 1 || 13 < typ ) {
  45. console.log( 'error in TIFF' );
  46. break;
  47. }
  48. UTIF._readIFD( bin, data, ifdo, ifds, 0, prm );
  49. ifdo = bin.readUint( data, ifdo + 2 + cnt * 12 );
  50. if ( ifdo == 0 ) break;
  51. }
  52. return ifds;
  53. };
  54. UTIF.decodeImage = function ( buff, img, ifds ) {
  55. if ( img.data ) return;
  56. var data = new Uint8Array( buff );
  57. var id = UTIF._binBE.readASCII( data, 0, 2 );
  58. if ( img[ 't256' ] == null ) return; // No width => probably not an image
  59. img.isLE = id == 'II';
  60. img.width = img[ 't256' ][ 0 ]; //delete img["t256"];
  61. img.height = img[ 't257' ][ 0 ]; //delete img["t257"];
  62. var cmpr = img[ 't259' ] ? img[ 't259' ][ 0 ] : 1; //delete img["t259"];
  63. var fo = img[ 't266' ] ? img[ 't266' ][ 0 ] : 1; //delete img["t266"];
  64. if ( img[ 't284' ] && img[ 't284' ][ 0 ] == 2 ) console.log( 'PlanarConfiguration 2 should not be used!' );
  65. if ( cmpr == 7 && img[ 't258' ] && img[ 't258' ].length > 3 ) img[ 't258' ] = img[ 't258' ].slice( 0, 3 );
  66. var bipp; // bits per pixel
  67. if ( img[ 't258' ] ) bipp = Math.min( 32, img[ 't258' ][ 0 ] ) * img[ 't258' ].length; else bipp = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1;
  68. // Some .NEF files have t258==14, even though they use 16 bits per pixel
  69. if ( cmpr == 1 && img[ 't279' ] != null && img[ 't278' ] && img[ 't262' ][ 0 ] == 32803 ) {
  70. bipp = Math.round( img[ 't279' ][ 0 ] * 8 / ( img.width * img[ 't278' ][ 0 ] ) );
  71. }
  72. var bipl = Math.ceil( img.width * bipp / 8 ) * 8;
  73. var soff = img[ 't273' ];
  74. if ( soff == null ) soff = img[ 't324' ];
  75. var bcnt = img[ 't279' ];
  76. if ( cmpr == 1 && soff.length == 1 ) bcnt = [ img.height * ( bipl >>> 3 ) ];
  77. if ( bcnt == null ) bcnt = img[ 't325' ];
  78. //bcnt[0] = Math.min(bcnt[0], data.length); // Hasselblad, "RAW_HASSELBLAD_H3D39II.3FR"
  79. var bytes = new Uint8Array( img.height * ( bipl >>> 3 ) ),
  80. bilen = 0;
  81. if ( img[ 't322' ] != null ) {
  82. var tw = img[ 't322' ][ 0 ],
  83. th = img[ 't323' ][ 0 ];
  84. var tx = Math.floor( ( img.width + tw - 1 ) / tw );
  85. var ty = Math.floor( ( img.height + th - 1 ) / th );
  86. var tbuff = new Uint8Array( Math.ceil( tw * th * bipp / 8 ) | 0 );
  87. for ( var y = 0; y < ty; y ++ ) for ( var x = 0; x < tx; x ++ ) {
  88. var i = y * tx + x;
  89. for ( var j = 0; j < tbuff.length; j ++ ) tbuff[ j ] = 0;
  90. UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, tbuff, 0, fo );
  91. // Might be required for 7 too. Need to check
  92. if ( cmpr == 6 ) bytes = tbuff; else UTIF._copyTile( tbuff, Math.ceil( tw * bipp / 8 ) | 0, th, bytes, Math.ceil( img.width * bipp / 8 ) | 0, img.height, Math.ceil( x * tw * bipp / 8 ) | 0, y * th );
  93. }
  94. bilen = bytes.length * 8;
  95. } else {
  96. var rps = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height;
  97. rps = Math.min( rps, img.height );
  98. for ( var i = 0; i < soff.length; i ++ ) {
  99. UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, bytes, Math.ceil( bilen / 8 ) | 0, fo );
  100. bilen += bipl * rps;
  101. }
  102. bilen = Math.min( bilen, bytes.length * 8 );
  103. }
  104. img.data = new Uint8Array( bytes.buffer, 0, Math.ceil( bilen / 8 ) | 0 );
  105. };
  106. UTIF.decode._decompress = function ( img, ifds, data, off, len, cmpr, tgt, toff ) {
  107. //console.log("compression", cmpr);
  108. //var time = Date.now();
  109. if ( cmpr == 34676 ) UTIF.decode._decodeLogLuv32( img, data, off, len, tgt, toff ); else console.log( 'Unsupported compression', cmpr );
  110. //console.log(Date.now()-time);
  111. var bps = img[ 't258' ] ? Math.min( 32, img[ 't258' ][ 0 ] ) : 1;
  112. var noc = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1,
  113. bpp = bps * noc >>> 3,
  114. h = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height,
  115. bpl = Math.ceil( bps * noc * img.width / 8 );
  116. // convert to Little Endian /*
  117. if ( bps == 16 && ! img.isLE && img[ 't33422' ] == null )
  118. // not DNG
  119. for ( var y = 0; y < h; y ++ ) {
  120. //console.log("fixing endianity");
  121. var roff = toff + y * bpl;
  122. for ( var x = 1; x < bpl; x += 2 ) {
  123. var t = tgt[ roff + x ];
  124. tgt[ roff + x ] = tgt[ roff + x - 1 ];
  125. tgt[ roff + x - 1 ] = t;
  126. }
  127. } //*/
  128. if ( img[ 't317' ] && img[ 't317' ][ 0 ] == 2 ) {
  129. for ( var y = 0; y < h; y ++ ) {
  130. var ntoff = toff + y * bpl;
  131. if ( bps == 16 ) for ( var j = bpp; j < bpl; j += 2 ) {
  132. var nv = ( tgt[ ntoff + j + 1 ] << 8 | tgt[ ntoff + j ] ) + ( tgt[ ntoff + j - bpp + 1 ] << 8 | tgt[ ntoff + j - bpp ] );
  133. tgt[ ntoff + j ] = nv & 255;
  134. tgt[ ntoff + j + 1 ] = nv >>> 8 & 255;
  135. } else if ( noc == 3 ) for ( var j = 3; j < bpl; j += 3 ) {
  136. tgt[ ntoff + j ] = tgt[ ntoff + j ] + tgt[ ntoff + j - 3 ] & 255;
  137. tgt[ ntoff + j + 1 ] = tgt[ ntoff + j + 1 ] + tgt[ ntoff + j - 2 ] & 255;
  138. tgt[ ntoff + j + 2 ] = tgt[ ntoff + j + 2 ] + tgt[ ntoff + j - 1 ] & 255;
  139. } else for ( var j = bpp; j < bpl; j ++ ) tgt[ ntoff + j ] = tgt[ ntoff + j ] + tgt[ ntoff + j - bpp ] & 255;
  140. }
  141. }
  142. };
  143. UTIF.decode._decodeLogLuv32 = function ( img, data, off, len, tgt, toff ) {
  144. var w = img.width,
  145. qw = w * 4;
  146. var io = 0,
  147. out = new Uint8Array( qw );
  148. while ( io < len ) {
  149. var oo = 0;
  150. while ( oo < qw ) {
  151. var c = data[ off + io ];
  152. io ++;
  153. if ( c < 128 ) {
  154. for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io + j ];
  155. oo += c;
  156. io += c;
  157. } else {
  158. c = c - 126;
  159. for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io ];
  160. oo += c;
  161. io ++;
  162. }
  163. }
  164. for ( var x = 0; x < w; x ++ ) {
  165. tgt[ toff + 0 ] = out[ x ];
  166. tgt[ toff + 1 ] = out[ x + w ];
  167. tgt[ toff + 2 ] = out[ x + w * 2 ];
  168. tgt[ toff + 4 ] = out[ x + w * 3 ];
  169. toff += 6;
  170. }
  171. }
  172. };
  173. UTIF.tags = {};
  174. //UTIF.ttypes = { 256:3,257:3,258:3, 259:3, 262:3, 273:4, 274:3, 277:3,278:4,279:4, 282:5, 283:5, 284:3, 286:5,287:5, 296:3, 305:2, 306:2, 338:3, 513:4, 514:4, 34665:4 };
  175. // start at tag 250
  176. UTIF._types = function () {
  177. var main = new Array( 250 );
  178. main.fill( 0 );
  179. main = main.concat( [ 0, 0, 0, 0, 4, 3, 3, 3, 3, 3, 0, 0, 3, 0, 0, 0, 3, 0, 0, 2, 2, 2, 2, 4, 3, 0, 0, 3, 4, 4, 3, 3, 5, 5, 3, 2, 5, 5, 0, 0, 0, 0, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 5, 5, 3, 0, 3, 3, 4, 4, 4, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] );
  180. var rest = {
  181. 33432: 2,
  182. 33434: 5,
  183. 33437: 5,
  184. 34665: 4,
  185. 34850: 3,
  186. 34853: 4,
  187. 34855: 3,
  188. 34864: 3,
  189. 34866: 4,
  190. 36864: 7,
  191. 36867: 2,
  192. 36868: 2,
  193. 37121: 7,
  194. 37377: 10,
  195. 37378: 5,
  196. 37380: 10,
  197. 37381: 5,
  198. 37383: 3,
  199. 37384: 3,
  200. 37385: 3,
  201. 37386: 5,
  202. 37510: 7,
  203. 37520: 2,
  204. 37521: 2,
  205. 37522: 2,
  206. 40960: 7,
  207. 40961: 3,
  208. 40962: 4,
  209. 40963: 4,
  210. 40965: 4,
  211. 41486: 5,
  212. 41487: 5,
  213. 41488: 3,
  214. 41985: 3,
  215. 41986: 3,
  216. 41987: 3,
  217. 41988: 5,
  218. 41989: 3,
  219. 41990: 3,
  220. 41993: 3,
  221. 41994: 3,
  222. 41995: 7,
  223. 41996: 3,
  224. 42032: 2,
  225. 42033: 2,
  226. 42034: 5,
  227. 42036: 2,
  228. 42037: 2,
  229. 59932: 7
  230. };
  231. return {
  232. basic: {
  233. main: main,
  234. rest: rest
  235. },
  236. gps: {
  237. main: [ 1, 2, 5, 2, 5, 1, 5, 5, 0, 9 ],
  238. rest: {
  239. 18: 2,
  240. 29: 2
  241. }
  242. }
  243. };
  244. }();
  245. UTIF._readIFD = function ( bin, data, offset, ifds, depth, prm ) {
  246. var cnt = bin.readUshort( data, offset );
  247. offset += 2;
  248. var ifd = {};
  249. if ( prm.debug ) console.log( ' '.repeat( depth ), ifds.length - 1, '>>>----------------' );
  250. for ( var i = 0; i < cnt; i ++ ) {
  251. var tag = bin.readUshort( data, offset );
  252. offset += 2;
  253. var type = bin.readUshort( data, offset );
  254. offset += 2;
  255. var num = bin.readUint( data, offset );
  256. offset += 4;
  257. var voff = bin.readUint( data, offset );
  258. offset += 4;
  259. var arr = [];
  260. //ifd["t"+tag+"-"+UTIF.tags[tag]] = arr;
  261. if ( type == 1 || type == 7 ) {
  262. arr = new Uint8Array( data.buffer, num < 5 ? offset - 4 : voff, num );
  263. }
  264. if ( type == 2 ) {
  265. var o0 = num < 5 ? offset - 4 : voff,
  266. c = data[ o0 ],
  267. len = Math.max( 0, Math.min( num - 1, data.length - o0 ) );
  268. if ( c < 128 || len == 0 ) arr.push( bin.readASCII( data, o0, len ) ); else arr = new Uint8Array( data.buffer, o0, len );
  269. }
  270. if ( type == 3 ) {
  271. for ( var j = 0; j < num; j ++ ) arr.push( bin.readUshort( data, ( num < 3 ? offset - 4 : voff ) + 2 * j ) );
  272. }
  273. if ( type == 4 || type == 13 ) {
  274. for ( var j = 0; j < num; j ++ ) arr.push( bin.readUint( data, ( num < 2 ? offset - 4 : voff ) + 4 * j ) );
  275. }
  276. if ( type == 5 || type == 10 ) {
  277. var ri = type == 5 ? bin.readUint : bin.readInt;
  278. for ( var j = 0; j < num; j ++ ) arr.push( [ ri( data, voff + j * 8 ), ri( data, voff + j * 8 + 4 ) ] );
  279. }
  280. if ( type == 8 ) {
  281. for ( var j = 0; j < num; j ++ ) arr.push( bin.readShort( data, ( num < 3 ? offset - 4 : voff ) + 2 * j ) );
  282. }
  283. if ( type == 9 ) {
  284. for ( var j = 0; j < num; j ++ ) arr.push( bin.readInt( data, ( num < 2 ? offset - 4 : voff ) + 4 * j ) );
  285. }
  286. if ( type == 11 ) {
  287. for ( var j = 0; j < num; j ++ ) arr.push( bin.readFloat( data, voff + j * 4 ) );
  288. }
  289. if ( type == 12 ) {
  290. for ( var j = 0; j < num; j ++ ) arr.push( bin.readDouble( data, voff + j * 8 ) );
  291. }
  292. if ( num != 0 && arr.length == 0 ) {
  293. console.log( tag, 'unknown TIFF tag type: ', type, 'num:', num );
  294. if ( i == 0 ) return;
  295. continue;
  296. }
  297. if ( prm.debug ) console.log( ' '.repeat( depth ), tag, type, UTIF.tags[ tag ], arr );
  298. ifd[ 't' + tag ] = arr;
  299. if ( tag == 330 || tag == 34665 || tag == 34853 || tag == 50740 && bin.readUshort( data, bin.readUint( arr, 0 ) ) < 300 || tag == 61440 ) {
  300. var oarr = tag == 50740 ? [ bin.readUint( arr, 0 ) ] : arr;
  301. var subfd = [];
  302. for ( var j = 0; j < oarr.length; j ++ ) UTIF._readIFD( bin, data, oarr[ j ], subfd, depth + 1, prm );
  303. if ( tag == 330 ) ifd.subIFD = subfd;
  304. if ( tag == 34665 ) ifd.exifIFD = subfd[ 0 ];
  305. if ( tag == 34853 ) ifd.gpsiIFD = subfd[ 0 ]; //console.log("gps", subfd[0]); }
  306. if ( tag == 50740 ) ifd.dngPrvt = subfd[ 0 ];
  307. if ( tag == 61440 ) ifd.fujiIFD = subfd[ 0 ];
  308. }
  309. if ( tag == 37500 && prm.parseMN ) {
  310. var mn = arr;
  311. //console.log(bin.readASCII(mn,0,mn.length), mn);
  312. if ( bin.readASCII( mn, 0, 5 ) == 'Nikon' ) ifd.makerNote = UTIF[ 'decode' ]( mn.slice( 10 ).buffer )[ 0 ]; else if ( bin.readUshort( data, voff ) < 300 && bin.readUshort( data, voff + 4 ) <= 12 ) {
  313. var subsub = [];
  314. UTIF._readIFD( bin, data, voff, subsub, depth + 1, prm );
  315. ifd.makerNote = subsub[ 0 ];
  316. }
  317. }
  318. }
  319. ifds.push( ifd );
  320. if ( prm.debug ) console.log( ' '.repeat( depth ), '<<<---------------' );
  321. return offset;
  322. };
  323. UTIF.toRGBA = function ( out, type ) {
  324. const w = out.width,
  325. h = out.height,
  326. area = w * h,
  327. data = out.data;
  328. let img;
  329. switch ( type ) {
  330. case THREE.HalfFloatType:
  331. img = new Uint16Array( area * 4 );
  332. break;
  333. case THREE.FloatType:
  334. img = new Float32Array( area * 4 );
  335. break;
  336. default:
  337. console.error( 'THREE.LogLuvLoader: Unsupported texture data type:', type );
  338. }
  339. let intp = out[ 't262' ] ? out[ 't262' ][ 0 ] : 2;
  340. const bps = out[ 't258' ] ? Math.min( 32, out[ 't258' ][ 0 ] ) : 1;
  341. if ( out[ 't262' ] == null && bps == 1 ) intp = 0;
  342. if ( intp == 32845 ) {
  343. for ( let y = 0; y < h; y ++ ) {
  344. for ( let x = 0; x < w; x ++ ) {
  345. const si = ( y * w + x ) * 6,
  346. qi = ( y * w + x ) * 4;
  347. let L = data[ si + 1 ] << 8 | data[ si ];
  348. L = Math.pow( 2, ( L + 0.5 ) / 256 - 64 );
  349. const u = ( data[ si + 3 ] + 0.5 ) / 410;
  350. const v = ( data[ si + 5 ] + 0.5 ) / 410;
  351. // Luv to xyY
  352. const sX = 9 * u / ( 6 * u - 16 * v + 12 );
  353. const sY = 4 * v / ( 6 * u - 16 * v + 12 );
  354. const bY = L;
  355. // xyY to XYZ
  356. const X = sX * bY / sY,
  357. Y = bY,
  358. Z = ( 1 - sX - sY ) * bY / sY;
  359. // XYZ to linear RGB
  360. const r = 2.690 * X - 1.276 * Y - 0.414 * Z;
  361. const g = - 1.022 * X + 1.978 * Y + 0.044 * Z;
  362. const b = 0.061 * X - 0.224 * Y + 1.163 * Z;
  363. if ( type === THREE.HalfFloatType ) {
  364. img[ qi ] = THREE.DataUtils.toHalfFloat( Math.min( r, 65504 ) );
  365. img[ qi + 1 ] = THREE.DataUtils.toHalfFloat( Math.min( g, 65504 ) );
  366. img[ qi + 2 ] = THREE.DataUtils.toHalfFloat( Math.min( b, 65504 ) );
  367. img[ qi + 3 ] = THREE.DataUtils.toHalfFloat( 1 );
  368. } else {
  369. img[ qi ] = r;
  370. img[ qi + 1 ] = g;
  371. img[ qi + 2 ] = b;
  372. img[ qi + 3 ] = 1;
  373. }
  374. }
  375. }
  376. } else {
  377. console.log( 'Unsupported Photometric interpretation: ' + intp );
  378. }
  379. return img;
  380. };
  381. UTIF._binBE = {
  382. nextZero: function ( data, o ) {
  383. while ( data[ o ] != 0 ) o ++;
  384. return o;
  385. },
  386. readUshort: function ( buff, p ) {
  387. return buff[ p ] << 8 | buff[ p + 1 ];
  388. },
  389. readShort: function ( buff, p ) {
  390. var a = UTIF._binBE.ui8;
  391. a[ 0 ] = buff[ p + 1 ];
  392. a[ 1 ] = buff[ p + 0 ];
  393. return UTIF._binBE.i16[ 0 ];
  394. },
  395. readInt: function ( buff, p ) {
  396. var a = UTIF._binBE.ui8;
  397. a[ 0 ] = buff[ p + 3 ];
  398. a[ 1 ] = buff[ p + 2 ];
  399. a[ 2 ] = buff[ p + 1 ];
  400. a[ 3 ] = buff[ p + 0 ];
  401. return UTIF._binBE.i32[ 0 ];
  402. },
  403. readUint: function ( buff, p ) {
  404. var a = UTIF._binBE.ui8;
  405. a[ 0 ] = buff[ p + 3 ];
  406. a[ 1 ] = buff[ p + 2 ];
  407. a[ 2 ] = buff[ p + 1 ];
  408. a[ 3 ] = buff[ p + 0 ];
  409. return UTIF._binBE.ui32[ 0 ];
  410. },
  411. readASCII: function ( buff, p, l ) {
  412. var s = '';
  413. for ( var i = 0; i < l; i ++ ) s += String.fromCharCode( buff[ p + i ] );
  414. return s;
  415. },
  416. readFloat: function ( buff, p ) {
  417. var a = UTIF._binBE.ui8;
  418. for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + 3 - i ];
  419. return UTIF._binBE.fl32[ 0 ];
  420. },
  421. readDouble: function ( buff, p ) {
  422. var a = UTIF._binBE.ui8;
  423. for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + 7 - i ];
  424. return UTIF._binBE.fl64[ 0 ];
  425. },
  426. writeUshort: function ( buff, p, n ) {
  427. buff[ p ] = n >> 8 & 255;
  428. buff[ p + 1 ] = n & 255;
  429. },
  430. writeInt: function ( buff, p, n ) {
  431. var a = UTIF._binBE.ui8;
  432. UTIF._binBE.i32[ 0 ] = n;
  433. buff[ p + 3 ] = a[ 0 ];
  434. buff[ p + 2 ] = a[ 1 ];
  435. buff[ p + 1 ] = a[ 2 ];
  436. buff[ p + 0 ] = a[ 3 ];
  437. },
  438. writeUint: function ( buff, p, n ) {
  439. buff[ p ] = n >> 24 & 255;
  440. buff[ p + 1 ] = n >> 16 & 255;
  441. buff[ p + 2 ] = n >> 8 & 255;
  442. buff[ p + 3 ] = n >> 0 & 255;
  443. },
  444. writeASCII: function ( buff, p, s ) {
  445. for ( var i = 0; i < s.length; i ++ ) buff[ p + i ] = s.charCodeAt( i );
  446. },
  447. writeDouble: function ( buff, p, n ) {
  448. UTIF._binBE.fl64[ 0 ] = n;
  449. for ( var i = 0; i < 8; i ++ ) buff[ p + i ] = UTIF._binBE.ui8[ 7 - i ];
  450. }
  451. };
  452. UTIF._binBE.ui8 = new Uint8Array( 8 );
  453. UTIF._binBE.i16 = new Int16Array( UTIF._binBE.ui8.buffer );
  454. UTIF._binBE.i32 = new Int32Array( UTIF._binBE.ui8.buffer );
  455. UTIF._binBE.ui32 = new Uint32Array( UTIF._binBE.ui8.buffer );
  456. UTIF._binBE.fl32 = new Float32Array( UTIF._binBE.ui8.buffer );
  457. UTIF._binBE.fl64 = new Float64Array( UTIF._binBE.ui8.buffer );
  458. UTIF._binLE = {
  459. nextZero: UTIF._binBE.nextZero,
  460. readUshort: function ( buff, p ) {
  461. return buff[ p + 1 ] << 8 | buff[ p ];
  462. },
  463. readShort: function ( buff, p ) {
  464. var a = UTIF._binBE.ui8;
  465. a[ 0 ] = buff[ p + 0 ];
  466. a[ 1 ] = buff[ p + 1 ];
  467. return UTIF._binBE.i16[ 0 ];
  468. },
  469. readInt: function ( buff, p ) {
  470. var a = UTIF._binBE.ui8;
  471. a[ 0 ] = buff[ p + 0 ];
  472. a[ 1 ] = buff[ p + 1 ];
  473. a[ 2 ] = buff[ p + 2 ];
  474. a[ 3 ] = buff[ p + 3 ];
  475. return UTIF._binBE.i32[ 0 ];
  476. },
  477. readUint: function ( buff, p ) {
  478. var a = UTIF._binBE.ui8;
  479. a[ 0 ] = buff[ p + 0 ];
  480. a[ 1 ] = buff[ p + 1 ];
  481. a[ 2 ] = buff[ p + 2 ];
  482. a[ 3 ] = buff[ p + 3 ];
  483. return UTIF._binBE.ui32[ 0 ];
  484. },
  485. readASCII: UTIF._binBE.readASCII,
  486. readFloat: function ( buff, p ) {
  487. var a = UTIF._binBE.ui8;
  488. for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + i ];
  489. return UTIF._binBE.fl32[ 0 ];
  490. },
  491. readDouble: function ( buff, p ) {
  492. var a = UTIF._binBE.ui8;
  493. for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + i ];
  494. return UTIF._binBE.fl64[ 0 ];
  495. },
  496. writeUshort: function ( buff, p, n ) {
  497. buff[ p ] = n & 255;
  498. buff[ p + 1 ] = n >> 8 & 255;
  499. },
  500. writeInt: function ( buff, p, n ) {
  501. var a = UTIF._binBE.ui8;
  502. UTIF._binBE.i32[ 0 ] = n;
  503. buff[ p + 0 ] = a[ 0 ];
  504. buff[ p + 1 ] = a[ 1 ];
  505. buff[ p + 2 ] = a[ 2 ];
  506. buff[ p + 3 ] = a[ 3 ];
  507. },
  508. writeUint: function ( buff, p, n ) {
  509. buff[ p ] = n >>> 0 & 255;
  510. buff[ p + 1 ] = n >>> 8 & 255;
  511. buff[ p + 2 ] = n >>> 16 & 255;
  512. buff[ p + 3 ] = n >>> 24 & 255;
  513. },
  514. writeASCII: UTIF._binBE.writeASCII
  515. };
  516. UTIF._copyTile = function ( tb, tw, th, b, w, h, xoff, yoff ) {
  517. //log("copyTile", tw, th, w, h, xoff, yoff);
  518. var xlim = Math.min( tw, w - xoff );
  519. var ylim = Math.min( th, h - yoff );
  520. for ( var y = 0; y < ylim; y ++ ) {
  521. var tof = ( yoff + y ) * w + xoff;
  522. var sof = y * tw;
  523. for ( var x = 0; x < xlim; x ++ ) b[ tof + x ] = tb[ sof + x ];
  524. }
  525. };
  526. THREE.LogLuvLoader = LogLuvLoader;
  527. } )();