verify-raster-budget.mjs 2.4 KB

1234567891011121314151617181920212223242526272829303132
  1. // Synthetic header/allocation regressions; complete image decoding is intentionally separate.
  2. import assert from 'node:assert/strict'
  3. import { rasterDimensions, rasterAllocation, tileRasterBudget, rasterLimits } from './raster-budget.mjs'
  4. function png(width, height) {
  5. const bytes = Buffer.alloc(33)
  6. Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]).copy(bytes)
  7. bytes.writeUInt32BE(13, 8); bytes.write('IHDR', 12); bytes.writeUInt32BE(width, 16); bytes.writeUInt32BE(height, 20)
  8. return { bytes, mimeType: 'image/png' }
  9. }
  10. function jpeg(marker, width, height) {
  11. const bytes = Buffer.from([255, 216, 255, 224, 0, 4, 0, 0, 255, marker, 0, 11, 8, 0, 0, 0, 0, 1, 1, 17, 0])
  12. bytes.writeUInt16BE(height, 13); bytes.writeUInt16BE(width, 15)
  13. return bytes
  14. }
  15. assert.deepEqual(rasterDimensions(png(256, 32).bytes, 'image/png'), { width: 256, height: 32 })
  16. for (const marker of [192, 194]) assert.deepEqual(rasterDimensions(jpeg(marker, 300, 200), 'image/jpeg'), { width: 300, height: 200 })
  17. assert.equal(rasterAllocation(png(1, 1).bytes, 'image/png').mipBytes, 4)
  18. assert.equal(rasterAllocation(png(3, 5).bytes, 'image/png').mipBytes, 72)
  19. const image = png(512, 512)
  20. const one = tileRasterBudget([image], [{ source: 0 }])
  21. assert.equal(one.rgbaBytes, 1048576); assert.equal(one.decodedTextureBytes, 1398100)
  22. assert.equal(tileRasterBudget([image], [{ source: 0 }, { source: 0 }]).decodedTextureBytes, 2796200)
  23. assert.equal(tileRasterBudget([], []).decodedTextureBytes, 0)
  24. assert.throws(() => rasterAllocation(png(65536, 65536).bytes, 'image/png'), /dimension budget/)
  25. assert.throws(() => rasterDimensions(png(0, 256).bytes, 'image/png'), /dimensions/)
  26. assert.throws(() => rasterDimensions(image.bytes.subarray(0, 20), 'image/png'), /header/)
  27. assert.throws(() => rasterDimensions(jpeg(194, 30, 20).subarray(0, 15), 'image/jpeg'), /truncated/)
  28. assert.throws(() => rasterDimensions(Buffer.from([255, 216, 255, 218]), 'image/jpeg'), /missing JPEG SOF/)
  29. assert.throws(() => tileRasterBudget([image], [{ source: 1 }]), /image index/)
  30. assert.throws(() => tileRasterBudget([image], [{ source: 0 }], { ...rasterLimits, maxRasterBytes: 32 }), /embedded raster/)
  31. assert.throws(() => tileRasterBudget([image], Array.from({ length: 4 }, () => ({ source: 0 }))), /decoded texture budget/)
  32. console.log(JSON.stringify({ passed: true, scope: 'synthetic PNG/JPEG headers, dimensions, RGBA8 mip allocations, rejection paths' }))