Skip to content

Commit

Permalink
Update decoder to correctly handle grayscale PNGs (#23393)
Browse files Browse the repository at this point in the history
This PR updates the Squoosh PNG decoder, which fixes #22929 in GoogleChromeLabs/squoosh#971.

## Bug

- [x] Fixes #22929
- [x] Integration tests added

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.

## Documentation / Examples

- [ ] Make sure the linting passes
  • Loading branch information
shuding authored Apr 1, 2021
1 parent 65c2216 commit 2ed54cd
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 12 deletions.
39 changes: 27 additions & 12 deletions packages/next/next-server/server/lib/squoosh/png/squoosh_png.js
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) ||
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions test/integration/image-optimizer/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' } }
Expand Down

0 comments on commit 2ed54cd

Please sign in to comment.