diff --git a/packages/next/next-server/server/lib/squoosh/png/squoosh_png.js b/packages/next/next-server/server/lib/squoosh/png/squoosh_png.js index 2971ef3cce647..300c68daf6309 100644 --- a/packages/next/next-server/server/lib/squoosh/png/squoosh_png.js +++ b/packages/next/next-server/server/lib/squoosh/png/squoosh_png.js @@ -1,5 +1,29 @@ +import { TextDecoder } from '../text-decoder' + let wasm +let cachedTextDecoder = new TextDecoder('utf-8', { + ignoreBOM: true, + fatal: true, +}) + +cachedTextDecoder.decode() + +let cachegetUint8Memory0 = null +function getUint8Memory0() { + if ( + cachegetUint8Memory0 === null || + cachegetUint8Memory0.buffer !== wasm.memory.buffer + ) { + cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer) + } + return cachegetUint8Memory0 +} + +function getStringFromWasm0(ptr, len) { + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)) +} + let cachegetUint8ClampedMemory0 = null function getUint8ClampedMemory0() { if ( @@ -30,17 +54,6 @@ function addHeapObject(obj) { return idx } -let cachegetUint8Memory0 = null -function getUint8Memory0() { - if ( - cachegetUint8Memory0 === null || - cachegetUint8Memory0.buffer !== wasm.memory.buffer - ) { - cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer) - } - return cachegetUint8Memory0 -} - let WASM_VECTOR_LEN = 0 function passArray8ToWasm0(arg, malloc) { @@ -161,7 +174,9 @@ async function init(input) { var ret = new ImageData(v0, arg2 >>> 0, arg3 >>> 0) return addHeapObject(ret) } - + imports.wbg.__wbindgen_throw = function (arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)) + } if ( typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || diff --git a/packages/next/next-server/server/lib/squoosh/png/squoosh_png_bg.wasm b/packages/next/next-server/server/lib/squoosh/png/squoosh_png_bg.wasm index 65f76eaa1946c..ef074fafe8b10 100644 Binary files a/packages/next/next-server/server/lib/squoosh/png/squoosh_png_bg.wasm and b/packages/next/next-server/server/lib/squoosh/png/squoosh_png_bg.wasm differ diff --git a/test/integration/image-optimizer/public/grayscale.png b/test/integration/image-optimizer/public/grayscale.png new file mode 100644 index 0000000000000..85c55456d8c79 Binary files /dev/null and b/test/integration/image-optimizer/public/grayscale.png differ diff --git a/test/integration/image-optimizer/test/index.test.js b/test/integration/image-optimizer/test/index.test.js index f5bf0e2847b96..c0f52abde1ad4 100644 --- a/test/integration/image-optimizer/test/index.test.js +++ b/test/integration/image-optimizer/test/index.test.js @@ -482,6 +482,26 @@ function runTests({ w, isDev, domains }) { await expectWidth(res, 400) }) + it('should not change the color type of a png', async () => { + // https://github.com/vercel/next.js/issues/22929 + // A grayscaled PNG with transparent pixels. + const query = { url: '/grayscale.png', w: largeSize, q: 80 } + const opts = { headers: { accept: 'image/png' } } + const res = await fetchViaHTTP(appPort, '/_next/image', query, opts) + expect(res.status).toBe(200) + expect(res.headers.get('Content-Type')).toBe('image/png') + expect(res.headers.get('cache-control')).toBe( + 'public, max-age=0, must-revalidate' + ) + + const png = await res.buffer() + + // Read the color type byte (offset 9 + magic number 16). + // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html + const colorType = png.readUIntBE(25, 1) + expect(colorType).toBe(4) + }) + it("should error if the resource isn't a valid image", async () => { const query = { url: '/test.txt', w, q: 80 } const opts = { headers: { accept: 'image/webp' } }