Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RangeError: Array buffer allocation failed #42

Open
AlexanderPodorov opened this issue Jan 29, 2025 · 2 comments · May be fixed by image-js/iobuffer#75
Open

RangeError: Array buffer allocation failed #42

AlexanderPodorov opened this issue Jan 29, 2025 · 2 comments · May be fixed by image-js/iobuffer#75

Comments

@AlexanderPodorov
Copy link

Hi, thanks for this library!
Is it possible to generate huge PNGs, e.g. 6600x81000 with RGBA?
Using this library https://github.com/pngjs/pngjs I was able to do it.
I'm getting:

Uncaught (in promise) RangeError: Array buffer allocation failed
    at new ArrayBuffer (<anonymous>)
    at new Uint8Array (<anonymous>)
    at IOBuffer.ensureAvailable (IOBuffer.js:185:30)
    at IOBuffer.writeUint8 (IOBuffer.js:365:14)
    at IOBuffer.writeByte (IOBuffer.js:374:21)
    at writeDataBytes (PngEncoder.js:139:17)
    at PngEncoder.encodeData (PngEncoder.js:70:26)
    at PngEncoder.encode (PngEncoder.js:27:14)
    at encodePng (index.js:19:20)

This is probably because of https://github.com/image-js/iobuffer which is used as the dependency, and when it tries to resize twice as the original size, it fails on Chrome (limit is 2Gb). However if we allocated less memory, we could have reached bigger PNG sizes.

This is my test code:

// works with 135 inches, does not work with 136 inches and above.
// should work with up to 270 inches in Chrome (Uint8Array size is limited to 2^31-1, ~2Gb)
const buffer = new Uint8Array(
    22 * 135 * 300 * 300 * 4 // 22x135 inches, 300 dpi, 4 channels
);
const encoded = encode({
    width: 22 * 300,
    height: 135 * 300,
    data: buffer,
});
@targos
Copy link
Member

targos commented Feb 1, 2025

I'm trying to find a way to detect what's limit for Uint8Array length but it's not easy: image-js/iobuffer#75

@AlexanderPodorov
Copy link
Author

@targos , thank you!
Probably it could be an array of smaller Uint8Arrays.
I actually ended up with writing my own PNG encoder (I did not need decoder), using browser’s Stream API. Deflate compression is supported by browsers natively, the main bottleneck for PNG encoder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants