[Bug Report]Uint8Arry exception in TranscodeCRNToDXT.js

Hi I’m testing a b3dm tiles contain crn textures.

I saw a strange thins : some textures were displayed and some textures were not displayed. It was not a particular texture problem.

And found a exception at worker side (occurs in createTaskProcessorWorker.js:57 line

function createTaskProcessorWorker(workerFunction) {
var postMessage;
var transferableObjects = ;
var responseMessage = {
id : undefined,
result : undefined,
error : undefined

    return function(event) {
        /*global self*/
        var data = event.data;

        transferableObjects.length = 0;
        responseMessage.id = data.id;
        responseMessage.error = undefined;
        responseMessage.result = undefined;

        try {
            responseMessage.result = workerFunction(data.parameters, transferableObjects);
        } catch (e) {
            if (e instanceof Error) {
                // Errors can't be posted in a message, copy the properties
                responseMessage.error = {
                    name : e.name,
                    message : e.message,
                    stack : e.stack
            } else {
                responseMessage.error = e;

        if (!defined(postMessage)) {
            postMessage = defaultValue(self.webkitPostMessage, self.postMessage);

        if (!data.canTransferArrayBuffer) {
            transferableObjects.length = 0;

        try {
            postMessage(responseMessage, transferableObjects);
        } catch (e) {
            // something went wrong trying to post the message, post a simpler
            // error that we can be sure will be cloneable
            responseMessage.result = undefined;
            responseMessage.error = 'postMessage failed with error: ' + formatError(e) + '\n  with responseMessage: ' + JSON.stringify(responseMessage);


**Exception detail => **

"RangeError: Source is too large

at Uint8Array.set (native)

at transcodeCRNToDXT (Workers/transcodeCRNToDXT.js:136:23 )

at createTaskProcessorWorker.js:55:42"

**So I looked at transcodeCRNToDXT exception point( **transcodeCRNToDXT.js:136 line)

=> level0DXTData.set(dxtData, 0)

function transcodeCRNToDXT(arrayBuffer, transferableObjects) {
// Copy the contents of the arrayBuffer into emscriptens heap.
var srcSize = arrayBuffer.byteLength;
var bytes = new Uint8Array(arrayBuffer);
var src = crunch._malloc(srcSize);
arrayBufferCopy(bytes, crunch.HEAPU8, src, srcSize);

    // Determine what type of compressed data the file contains.
    var crnFormat = crunch._crn_get_dxt_format(src, srcSize);
    var format = DXT_FORMAT_MAP[crnFormat];
    if (!defined(format)) {
        throw new RuntimeError('Unsupported compressed format.');

    // Gather basic metrics about the DXT data.
    var levels = crunch._crn_get_levels(src, srcSize);
    var width = crunch._crn_get_width(src, srcSize);
    var height = crunch._crn_get_height(src, srcSize);

    // Determine the size of the decoded DXT data.
    var dstSize = 0;
    var i;
    for (i = 0; i < levels; ++i) {
        dstSize += PixelFormat.compressedTextureSizeInBytes(format, width >> i, height >> i);

    // Allocate enough space on the emscripten heap to hold the decoded DXT data
    // or reuse the existing allocation if a previous call to this function has
    // already acquired a large enough buffer.
    if(cachedDstSize < dstSize) {
        if(defined(dst)) {
        dst = crunch._malloc(dstSize);
        dxtData = new Uint8Array(crunch.HEAPU8.buffer, dst, dstSize);
        cachedDstSize = dstSize;

    // Decompress the DXT data from the Crunch file into the allocated space.
    crunch._crn_decompress(src, srcSize, dst, dstSize, 0, levels);

    // Release the crunch file data from the emscripten heap.

    // Mipmaps are unsupported, so copy the level 0 texture
    // When mipmaps are supported, a copy will still be necessary as dxtData is a view on the heap.
    var length = PixelFormat.compressedTextureSizeInBytes(format, width, height);
    var level0DXTData = new Uint8Array(length);
    level0DXTData.set(dxtData, 0);

    return new CompressedTextureBuffer(format, width, height, level0DXTData);


I think cache buffer(dxtData) is too big to copy to result buffer(level0DXTData).

So I replaced

level0DXTData.set(dxtData, 0);


level0DXTData = dxtData.slice(0, length);

And it works.

I’m not sure it is perfect solution. so I hope cesium team review my solution.



Thanks for another bug report! We chose to avoid using slice because it is not support in IE11, but missed this edge case. I opened a PR here: https://github.com/AnalyticalGraphicsInc/cesium/pull/5618/files. Can you test if that works for you?

Thanks, It works!

I’ve tested it only on chrome and firefox.

PS: Before this patch, I also couldn’t see crn texture on IE11 and Edge. So I guessed crouch decoder js(emscripten) can not run on IE11 and Edge. I’m not sure.