Search code examples
javascriptarraybuffertyped-arrays

Swapping byte order with DataView and TypedArrays


Hi all I'm learning DataView and TypedArrays.

I have an array of LONG's and USIGGNED_LONG's, I'll just paste the LONG one below.

I've been trying to swap the array at bottom which is in ARGB to be RGBA. The first step I do is making it a Uint32Array but that after that I'm having trouble swapping bytes. Thanks

    var buffer = new ArrayBuffer(argb_16x16_LONG.length * 4);
    var view = new DataView(buffer);

var argb_16x16_LONG = [
    '16777215',
    '50331648',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '117440512',
    '50331648',
    '16777215',
    '117440512',
    '-179727685',
    '-13794122',
    '-7501709',
    '-2579612',
    '-12091753',
    '-11689787',
    '-8663845',
    '-8729638',
    '-12612424',
    '-12360329',
    '-4941740',
    '-670645',
    '-342721',
    '-106524059',
    '117440512',
    '520093696',
    '-1924502',
    '-3243974',
    '-1669338',
    '-9017258',
    '-15895118',
    '-13397058',
    '-10042412',
    '-10042412',
    '-13991247',
    '-16164456',
    '-16298359',
    '-10130877',
    '-600557',
    '-137156',
    '520093696',
    '587202560',
    '-2000091',
    '-2199019',
    '-2199024',
    '-8563138',
    '-15965032',
    '-11755851',
    '-10108719',
    '-10042669',
    '-13596748',
    '-16164712',
    '-15902826',
    '-16233077',
    '-12693681',
    '-669681',
    '587202560',
    '587202560',
    '-2066396',
    '-2133221',
    '-2660335',
    '-3126519',
    '-2206455',
    '-5019855',
    '-10505018',
    '-11227448',
    '-13004873',
    '-13005900',
    '-10636341',
    '-11559489',
    '-16434316',
    '-4224992',
    '587202560',
    '654311424',
    '-2066654',
    '-2133221',
    '-2133221',
    '-1666476',
    '-1001601',
    '-7692655',
    '-10307379',
    '-11557437',
    '-10767926',
    '-10636854',
    '-12744270',
    '-11428673',
    '-14722936',
    '-3237322',
    '654311424',
    '654311424',
    '-2066655',
    '-2133221',
    '-2066657',
    '-2324167',
    '-10773841',
    '-10572087',
    '-10506038',
    '-10506038',
    '-10901050',
    '-15904626',
    '-15839603',
    '-14326887',
    '-11563857',
    '-1390041',
    '654311424',
    '687865856',
    '-2132705',
    '-2923495',
    '-3510485',
    '-4092338',
    '-11497296',
    '-10837309',
    '-10771004',
    '-10771004',
    '-10837053',
    '-13536862',
    '-16434563',
    '-15975303',
    '-14068866',
    '-802546',
    '687865856',
    '704643072',
    '-5755123',
    '-6086910',
    '-8760247',
    '-11696978',
    '-11563854',
    '-11234117',
    '-11168068',
    '-11168068',
    '-11233860',
    '-12485462',
    '-16502669',
    '-16570265',
    '-7640013',
    '-548596',
    '704643072',
    '721420288',
    '-5100540',
    '-4246015',
    '-3513571',
    '-10724253',
    '-12162676',
    '-10721420',
    '-7048367',
    '-8553877',
    '-11961433',
    '-12751710',
    '-16044432',
    '-16638627',
    '-1590456',
    '-481270',
    '721420288',
    '754974720',
    '-3127291',
    '-2274304',
    '-2203377',
    '-2133221',
    '-2133221',
    '-2133221',
    '-2264291',
    '-2256322',
    '-11182995',
    '-16639135',
    '-16770980',
    '-16312757',
    '-666027',
    '-413935',
    '754974720',
    '771751936',
    '-2068969',
    '-2007285',
    '-2138099',
    '-5887736',
    '-5492214',
    '-4896748',
    '-6795731',
    '-12760969',
    '-14600580',
    '-16772007',
    '-13555655',
    '-5738717',
    '-268799',
    '-479193',
    '771751936',
    '805306368',
    '-2132966',
    '-2199019',
    '-2133992',
    '-3249890',
    '-10996944',
    '-16312751',
    '-13880445',
    '-15720598',
    '-13880957',
    '-12571067',
    '-2855395',
    '-1337332',
    '-935936',
    '-274084',
    '805306368',
    '822083584',
    '-2066404',
    '-2199024',
    '-2133226',
    '-2199021',
    '-2133223',
    '-5219036',
    '-9749959',
    '-9225160',
    '-7386577',
    '-2658787',
    '-2132966',
    '-1669883',
    '-871912',
    '-134302',
    '822083584',
    '520093696',
    '-106147016',
    '-2794469',
    '-2198244',
    '-2066144',
    '-2066148',
    '-1933785',
    '-1867216',
    '-1867215',
    '-1933779',
    '-2000089',
    '-2135789',
    '-1602038',
    '-132835',
    '-104553172',
    '520093696',
    '50331648',
    '822083584',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '1493172224',
    '822083584',
    '50331648'
];

Solution

  • You can use the read methods of DataView to read 16 or 32 bit values as little-endian or big-endian (default) like this:

    var uint32lsb = view.getUint32(0, true);  // little-endian, from byte-position 0 in buffer
    var uint32msb = view.getUint32(0, false); // big-endian, last argument is optional
    

    and of course the same for getInt32()/getUint16()/getInt16() (single bytes of course, does not have endianess, ie. getInt8() etc.).

    If the buffer is in big-endian and you read it manually as big-endian you can now shift and mask the values for each byte like this:

    var a = (uint32be & 0xff000000)>>>24;
    var r = (uint32be & 0xff0000)>>>16;
    var g = (uint32be & 0xff00)>>>8;
    var b = uint32be & 0xff;
    

    If you read it as little-endian, just reverse the order:

    var a = uint32le & 0xff;
    var r = (uint32le & 0xff00)>>>8;
    var g = (uint32le & 0xff0000)>>>16;
    var b = (uint32le & 0xff000000)>>>24;
    

    You can also read single bytes as long as you know the original order of the buffer. For example, if the buffer is big-endian you can read the four first bytes like this:

    var pos = 0;
    var a = view.getUint8(pos++);
    var r = view.getUint8(pos++);
    var g = view.getUint8(pos++);
    var b = view.getUint8(pos++);
    

    In your example the buffer is empty though so you will only get 0´s. To create a typed array buffer with 32 uint values, and then get a DataView you can do:

    var buffer32 = new Uint32Array(argb_16x16_LONG);
    var view = new DataView(buffer32.buffer);        // or the original argb_16x16_LONG directly
    

    (They point to the same underlying ArrayBuffer so there is no new memory allocated for the buffer.)

    Hope this helps.