Switch KTX2

This commit is contained in:
Surma
2021-05-19 15:26:49 +01:00
parent 558ee0e5ba
commit be41088fb8
8 changed files with 28 additions and 18 deletions

View File

@@ -16,26 +16,28 @@ val decode(std::string data) {
basist::etc1_global_selector_codebook sel_codebook = basist::etc1_global_selector_codebook(
basist::g_global_selector_cb_size, basist::g_global_selector_cb);
basist::basisu_transcoder transcoder = basist::basisu_transcoder(&sel_codebook);
basist::ktx2_transcoder transcoder = basist::ktx2_transcoder(&sel_codebook);
const void* dataPtr = reinterpret_cast<const void*>(data.c_str());
auto dataSize = data.size();
basist::basisu_image_info info;
transcoder.get_image_info(dataPtr, dataSize, info, 0 /* image_index */);
transcoder.init(dataPtr, dataSize);
transcoder.start_transcoding(dataPtr, dataSize);
auto buffer = std::vector<uint8_t>(info.m_width * info.m_height * 4);
auto header = transcoder.get_header();
auto image_width = static_cast<uint32_t>(header.m_pixel_width);
auto image_height = static_cast<uint32_t>(header.m_pixel_height);
transcoder.start_transcoding();
auto buffer = std::vector<uint8_t>(image_width * image_height * 4);
auto ok = transcoder.transcode_image_level(
dataPtr, dataSize,
/* image_index */ 0, /* level_index */ 0, buffer.data(), buffer.size() / 4,
basist::transcoder_texture_format::cTFRGBA32, 0 /* decode_flags */,
info.m_width /* output_row_pitch_in_blocks_or_pixels */);
0 /* level_index */, 0 /* layer_index */, 0 /* face_index */, buffer.data(),
buffer.size() / 4, basist::transcoder_texture_format::cTFRGBA32, 0 /* decode_flags */,
image_width /* output_row_pitch_in_blocks_or_pixels */);
if (!ok) {
return val(std::string("Could not decode"));
}
auto img_data_data = Uint8ClampedArray.new_(typed_memory_view(buffer.size(), buffer.data()));
auto imgData = ImageData.new_(img_data_data, info.m_width, info.m_height);
auto imgData = ImageData.new_(img_data_data, image_width, image_height);
return imgData;
}

View File

@@ -38,8 +38,8 @@ b+'", which is outside the valid range ['+d+", "+f+"]!");return m?p>>>0:p|0},arg
d+4,k=0;k<=f;++k){var h=d+4+k;if(k==f||0==B[h]){g=A(g,h-g);if(void 0===m)var m=g;else m+=String.fromCharCode(0),m+=g;g=h+1}}else{m=Array(f);for(k=0;k<f;++k)m[k]=String.fromCharCode(B[d+4+k]);m=m.join("")}Z(d);return m},toWireType:function(d,f){f instanceof ArrayBuffer&&(f=new Uint8Array(f));var g="string"===typeof f;g||f instanceof Uint8Array||f instanceof Uint8ClampedArray||f instanceof Int8Array||V("Cannot pass non-string to std::string");var k=(c&&g?function(){for(var l=0,p=0;p<f.length;++p){var q=
f.charCodeAt(p);55296<=q&&57343>=q&&(q=65536+((q&1023)<<10)|f.charCodeAt(++p)&1023);127>=q?++l:l=2047>=q?l+2:65535>=q?l+3:l+4}return l}:function(){return f.length})(),h=mb(4+k+1);J[h>>2]=k;if(c&&g)ha(f,h+4,k+1);else if(g)for(g=0;g<k;++g){var m=f.charCodeAt(g);255<m&&(Z(h),V("String has UTF-16 code units that do not fit in 8 bits"));B[h+4+g]=m}else for(g=0;g<k;++g)B[h+4+g]=f[g];null!==d&&d.push(Z,h);return h},argPackAdvance:8,readValueFromPointer:Qa,I:function(d){Z(d)}})},j:function(a,b,c){c=R(c);
if(2===b){var d=ja;var f=ka;var g=la;var k=function(){return D};var h=1}else 4===b&&(d=ma,f=na,g=oa,k=function(){return J},h=2);W(a,{name:c,fromWireType:function(m){for(var l=J[m>>2],p=k(),q,x=m+4,C=0;C<=l;++C){var n=m+4+C*b;if(C==l||0==p[n>>h])x=d(x,n-x),void 0===q?q=x:(q+=String.fromCharCode(0),q+=x),x=n+b}Z(m);return q},toWireType:function(m,l){"string"!==typeof l&&V("Cannot pass non-string to C++ string type "+c);var p=g(l),q=mb(4+p+b);J[q>>2]=p>>h;f(l,q+4,p+b);null!==m&&m.push(Z,q);return q},
argPackAdvance:8,readValueFromPointer:Qa,I:function(m){Z(m)}})},x:function(a,b){b=R(b);W(a,{X:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},f:Na,h:function(a){if(0===a)return Y(fb());var b=eb[a];a=void 0===b?R(a):b;return Y(fb()[a])},k:function(a){4<a&&(X[a].L+=1)},l:function(a,b,c,d){a||V("Cannot use deleted val. handle = "+a);a=X[a].value;var f=hb[b];if(!f){f="";for(var g=0;g<b;++g)f+=(0!==g?", ":"")+"arg"+g;var k="return function emval_allocator_"+b+"(constructor, argTypes, args) {\n";
for(g=0;g<b;++g)k+="var argType"+g+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+g+'], "parameter '+g+'");\nvar arg'+g+" = argType"+g+".readValueFromPointer(args);\nargs += argType"+g+"['argPackAdvance'];\n";f=(new Function("requireRegisteredType","Module","__emval_register",k+("var obj = new constructor("+f+");\nreturn __emval_register(obj);\n}\n")))(gb,e,Y);hb[b]=f}return f(a,c,d)},p:function(a,b){a=gb(a,"_emval_take_value");a=a.readValueFromPointer(b);return Y(a)},g:function(){y()},
argPackAdvance:8,readValueFromPointer:Qa,I:function(m){Z(m)}})},x:function(a,b){b=R(b);W(a,{X:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},g:Na,h:function(a){if(0===a)return Y(fb());var b=eb[a];a=void 0===b?R(a):b;return Y(fb()[a])},k:function(a){4<a&&(X[a].L+=1)},l:function(a,b,c,d){a||V("Cannot use deleted val. handle = "+a);a=X[a].value;var f=hb[b];if(!f){f="";for(var g=0;g<b;++g)f+=(0!==g?", ":"")+"arg"+g;var k="return function emval_allocator_"+b+"(constructor, argTypes, args) {\n";
for(g=0;g<b;++g)k+="var argType"+g+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+g+'], "parameter '+g+'");\nvar arg'+g+" = argType"+g+".readValueFromPointer(args);\nargs += argType"+g+"['argPackAdvance'];\n";f=(new Function("requireRegisteredType","Module","__emval_register",k+("var obj = new constructor("+f+");\nreturn __emval_register(obj);\n}\n")))(gb,e,Y);hb[b]=f}return f(a,c,d)},p:function(a,b){a=gb(a,"_emval_take_value");a=a.readValueFromPointer(b);return Y(a)},f:function(){y()},
s:function(a,b,c){B.copyWithin(a,b,b+c)},e:function(a){a>>>=0;var b=B.length;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);d=Math.max(16777216,a,d);0<d%65536&&(d+=65536-d%65536);a:{try{z.grow(Math.min(2147483648,d)-G.byteLength+65535>>>16);ra(z.buffer);var f=1;break a}catch(g){}f=void 0}if(f)return!0}return!1},u:function(){return 0},q:function(){},m:function(a,b,c,d){for(var f=0,g=0;g<c;g++){for(var k=F[b+8*g>>2],h=F[b+(8*g+4)>>2],m=0;m<h;m++){var l=B[k+
m],p=ib[a];if(0===l||10===l){for(l=0;p[l]&&!(NaN<=l);)++l;l=fa.decode(p.subarray?p.subarray(0,l):new Uint8Array(p.slice(0,l)));(1===a?da:v)(l);p.length=0}else p.push(l)}f+=h}F[d>>2]=f;return 0},a:z,r:function(){}};
(function(){function a(f){e.asm=f.exports;K=e.asm.A;L--;e.monitorRunDependencies&&e.monitorRunDependencies(L);0==L&&(null!==ya&&(clearInterval(ya),ya=null),M&&(f=M,M=null,f()))}function b(f){a(f.instance)}function c(f){return Ca().then(function(g){return WebAssembly.instantiate(g,d)}).then(f,function(g){v("failed to asynchronously prepare wasm: "+g);y(g)})}var d={a:nb};L++;e.monitorRunDependencies&&e.monitorRunDependencies(L);if(e.instantiateWasm)try{return e.instantiateWasm(d,a)}catch(f){return v("Module.instantiateWasm callback failed with error: "+

Binary file not shown.

View File

@@ -19,6 +19,9 @@ thread_local const val Uint8Array = val::global("Uint8Array");
val encode(std::string image_in, int image_width, int image_height, BasisOptions opts) {
basisu_encoder_init();
basist::etc1_global_selector_codebook sel_codebook(basist::g_global_selector_cb_size,
basist::g_global_selector_cb);
basis_compressor_params params;
basis_compressor compressor;
image img =
@@ -31,6 +34,11 @@ val encode(std::string image_in, int image_width, int image_height, BasisOptions
params.m_status_output = false;
// True => UASTC, False => ETC1S
params.m_uastc = opts.uastc;
// Use the standardized KTX2 format
params.m_create_ktx2_file = true;
// Codebook, whatever this exactly is or does.
params.m_pSel_codebook = &sel_codebook;
params.m_mip_gen = opts.mipmap;
params.m_quality_level = opts.quality;
params.m_compression_level = opts.compression;
@@ -44,7 +52,7 @@ val encode(std::string image_in, int image_width, int image_height, BasisOptions
return val(std::string("Well something went wrong during processing"));
}
auto comp_data = compressor.get_output_basis_file();
auto comp_data = compressor.get_output_ktx2_file();
auto js_result = Uint8Array.new_(typed_memory_view(comp_data.size(), &comp_data[0]));
// Not sure if there is anything to free here
return js_result;

Binary file not shown.

View File

@@ -97,7 +97,7 @@ async function decodeImage(
try {
if (!canDecode) {
if (mimeType === 'image/basisu') {
if (mimeType === 'image/ktx2') {
return await workerBridge.basisDecode(signal, blob);
}
if (mimeType === 'image/avif') {

View File

@@ -152,7 +152,7 @@ const magicNumberMapInput = [
[/^\x00\x00\x00 ftypavif\x00\x00\x00\x00/, 'image/avif'],
[/^\xff\x0a/, 'image/jxl'],
[/^\x00\x00\x00\x0cJXL \x0d\x0a\x87\x0a/, 'image/jxl'],
[/^sB/, 'image/basisu'],
[/^«KTX 20»\r\n/, 'image/ktx2'],
] as const;
export type ImageMimeTypes = typeof magicNumberMapInput[number][1];

View File

@@ -14,9 +14,9 @@ import { EncodeOptions } from 'codecs/basis/enc/basis_enc';
export { EncodeOptions };
export const label = 'Basis';
export const mimeType = 'image/basisu';
export const extension = 'basis';
export const label = 'KTX2 (Basis Universal)';
export const mimeType = 'image/ktx2';
export const extension = 'ktx2';
export const defaultOptions: EncodeOptions = {
quality: 128,
compression: 2,