在带有(Array)Buffers的NodeJs代码中,使用了本机readUInt16BE,但我的上下文是浏览器,所以我想使用DataView.getUint16来代替

问题描述 投票:0回答:1

我在 Node.js 中发现了一个 JPEG 解析函数,我正在尝试将其改编为在浏览器环境中使用。原始代码可以在这里找到。

原始代码使用Node.js的Buffer类。因为我想将它用于浏览器环境,所以我们必须使用

DataView.getUint16(0, false /* big endian */)
而不是
buffer.readUInt16BE(0) /*BE = big endian */

有趣的是,DataView 在 NodeJs 中也可用,因此结果可能是跨环境的。

这是我迄今为止发现的:

  • 引入从 4 开始的变量
    j
    有助于获得第一次迭代的正确偏移量,因为缓冲区的前 4 个字节被切片:
  let j=4 // match the buffer slicing above
  • 将 + 2 添加到 j 以进行下一次读取并不能帮助获得下一次迭代的正确偏移量,尽管缓冲区被正好分割为两个字节
    j+=2; // match the buffer slicing below ( i + 2 )
    buffer = buffer.slice(i + 2); // Buffer is sliced of two bytes, 0 offset is now 2 bytes further ?

这是添加日志记录的功能

function calculate (buffer) {

  // Skip 4 chars, they are for signature
  buffer = buffer.slice(4);
  let j=4 // match the buffer slicing above
  let aDataView=new DataView(buffer.buffer);
  var i, next;
  while (buffer.length) {
    // read length of the next block
    i = buffer.readUInt16BE(0);
    console.log("i="+i,"read="+aDataView.getUint16(j,false));
    j+=2; // match the buffer slicing below ( i + 2 )
    // ensure correct format
    validateBuffer(buffer, i);

    // 0xFFC0 is baseline standard(SOF)
    // 0xFFC1 is baseline optimized(SOF)
    // 0xFFC2 is progressive(SOF2)
    next = buffer[i + 1];
    if (next === 0xC0 || next === 0xC1 || next === 0xC2) {
      return extractSize(buffer, i + 5);
    }

    // move to the next block
    buffer = buffer.slice(i + 2);
  }

  throw new TypeError('Invalid JPG, no size found');
}

此图片的实际结果:

node .\start.js 
i=16 read=16 # Seems to be the correct offset
i=91 read=19014 # Wrong offset
i=132 read=18758

到目前为止我的调试步骤是: 从 npm 安装了 buffer-image-size

npm install buffer-image-size --save
start.js写成如下

var sizeOf = require('buffer-image-size');
const fs = require('fs');

fileBuffer = fs.readFileSync("flowers.jpg");
var dimensions = sizeOf(fileBuffer);
console.log(dimensions.width, dimensions.height);

编辑“node_modules uffer-image-size\lib ypes\jpg.js”添加提到的行和日志记录

你有什么提示吗

  • 为什么在
    j
    上加 2 并不能帮助获得正确的偏移量。
  • 如何在不一遍又一遍地分割缓冲区的情况下获得相同的算法

我感谢任何有关解决此问题的见解或指导。谢谢!

javascript node.js dataview arraybuffer
1个回答
0
投票

是的,避免提前偏移并重新切片缓冲区,这只会让您感到困惑。我会写

function calculate(typedArray) {
  const view = new DataView(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);
  let i = 0;
  // Skip 4 chars, they are for signature
  i += 4;

  while (i < view.length) {
    // read length of the next block
    const blockLen = view.getUint16(i, false /* big endian */);

    // ensure correct format
    // index should be within buffer limits
    if (i + blockLen > view.length) {
      throw new TypeError('Corrupt JPG, exceeded buffer limits');
    }
    // Every JPEG block must begin with a 0xFF
    if (view.getUint8(i + blockLen) !== 0xFF) {
      throw new TypeError('Invalid JPG, marker table corrupted');
    }

    // 0xFFC0 is baseline standard(SOF)
    // 0xFFC1 is baseline optimized(SOF)
    // 0xFFC2 is progressive(SOF2)
    const next = view.getUint8(i + blockLen + 1);
    if (next === 0xC0 || next === 0xC1 || next === 0xC2) {
      return extractSize(view, i + blockLen + 5);
    }

    // move to the next block
    i += blockLen + 2;
  }

  throw new TypeError('Invalid JPG, no size found');
}
© www.soinside.com 2019 - 2024. All rights reserved.