mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-14 09:39:15 +00:00
Switch KTX2
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
4
codecs/basis/dec/basis_dec.js
generated
4
codecs/basis/dec/basis_dec.js
generated
@@ -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.
@@ -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.
@@ -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') {
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user