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: offset is out of bounds: Some PNG filters are not processable #3004

Open
tarekis opened this issue Nov 16, 2020 · 7 comments
Open

Comments

@tarekis
Copy link

tarekis commented Nov 16, 2020

Adding PNGs via addImage with certain filters throws an error:

offset is out of bounds RangeError: offset is out of bounds
    at Uint8Array.set (<anonymous>)
    at applyPngFilterMethod (http://raw.githack.com/MrRio/jsPDF/master/dist/jspdf.umd.js:21341:18)
    at compressBytes (http://raw.githack.com/MrRio/jsPDF/master/dist/jspdf.umd.js:21280:15)
    at Object.jsPDFAPI.processPNG (http://raw.githack.com/MrRio/jsPDF/master/dist/jspdf.umd.js:21650:23)
    at Object.processImageData (http://raw.githack.com/MrRio/jsPDF/master/dist/jspdf.umd.js:10309:56)
    at Object.jsPDFAPI.addImage (http://raw.githack.com/MrRio/jsPDF/master/dist/jspdf.umd.js:10245:36)
    at eval (eval at <anonymous> (http://raw.githack.com/MrRio/jsPDF/master/examples/js/editor.js:177:11), <anonymous>:2:5)
    at http://raw.githack.com/MrRio/jsPDF/master/examples/js/editor.js:177:11 RangeError: offset is out of bounds
    at Uint8Array.set (<anonymous>)
    at applyPngFilterMethod (png_support.js:167)
    at compressBytes (png_support.js:106)
    at Object.jsPDFAPI.processPNG (png_support.js:477)
    at Object.processImageData (addimage.js:883)
    at Object.jsPDFAPI.addImage (addimage.js:819)
    at eval (eval at <anonymous> (editor.js:177), <anonymous>:2:5)
    at editor.js:177

Please bear with me, I am certainly no expert on images, but I'd like to relay my findings on this error.
Some PNG images cannot be processed if they are directly added with addImage via URL (previously I have included them by creating a data URL from a canvas).
The issue is this code that seems to apply PNG filters: https://github.com/MrRio/jsPDF/blob/82d3b7d72861e06c4c167ec562715c6734c3f709/src/modules/png_support.js#L167

Previous method VS new method for context

Previous method

public static imageToDataUrl(
    image: HTMLImageElement,
    width: number = image.naturalWidth,
    height: number = image.naturalHeight,
    mode: 'contain' | 'scale' = 'contain'
): string {
    const canvas = document.createElement('canvas');

    canvas.height = height;
    canvas.width = width;

    const context = canvas.getContext('2d');

    context.clearRect(0, 0, width, height);

    const imgAr = +Big(image.naturalWidth).div(image.naturalHeight);
    const destinationAr = +Big(width).div(height);

    if (mode === 'scale' || imgAr === destinationAr) {
        context.drawImage(image, 0, 0, width, height);
    } else if (mode === 'contain') {
        if (imgAr < destinationAr) {
            const scaledWidth = +Big(height).times(imgAr);
            context.drawImage(image, +Big(width - scaledWidth).div(2), 0, scaledWidth, height);
        } else {
            const scaledHeight = +Big(width).div(imgAr);
            context.drawImage(image, 0, +Big(height - scaledHeight).div(2), width, scaledHeight);
        }
    }

    return canvas.toDataURL('image/png');
}

[...]

const image = await PDFCreator.loadImage(imageURL);
pdf.addImage(PDFCreator.imageToDataUrl(image), [...]);

New method

pdf.addImage(imageURL, [...]);

This was changed because now this generation happens in a offloaded worker, which no longer can access canvases BTW.

This can be worked around by changing the image source to a JPEG, that still works.
This does not occur on all PNG images, but only on certain ones, what exactly determines it will fail I don't know, but it seems it has nothing to do with the image mode (indexed/RGB/CMYK all seem to behave the same), I have tested a series of images for products where you can see the material the products are made of, all with the same material pattern fail, some other material patterns all work, which means of images by the same source - that probably have different filters because of the different materials - some fail and some don't

I have uploaded one failing image to imgur, you can replicate the error by opening the live demo and adding this code:

var doc = new jsPDF();
doc.addImage("https://i.imgur.com/LcEVqn4.png", 15, 40, 180, 180);
@michaelzangerle
Copy link

I just tried to replicate this issue and played a bit around with the image in Gimp. I found out that the image in question has Indexed as Image > Mode set. Setting it to RGB and exporting it (not just saving - maybe that makes a difference as well) with the default gimp settings seems to prevent the error from happening.

var doc = new jsPDF();
doc.addImage("https://i.imgur.com/ry7GVJ6.png", 15, 40, 180, 180);

I have no idea what making this change means in context of the code, but it would be nice if this could be solved in the code 🙈

@HackbrettXXX
Copy link
Collaborator

@michaelzangerle could you may try to fix this in the code? Since you already found out the reason for the issue, I think it should not be that hard to fix this in code.

@michaelzangerle
Copy link

@HackbrettXXX I just tried a bit around with GIMP as I am also affected by this issue in a project and had similar issues in the past. But I am afraid I am no JS developer and have no idea what this change of the image mode means in terms of the code here. Sorry 🙈 If I can be of some help otherwise I will gladly do so.

@github-actions
Copy link

github-actions bot commented Mar 4, 2021

This issue is stale because it has been open 90 days with no activity. It will be closed soon. Please comment/reopen if this issue is still relevant.

@Bogghi
Copy link

Bogghi commented Jun 6, 2023

Hi, i've encountered this issue in my code with this specific image. Has anyone found a solution? I'm not clear on what i have to do with the image, since the problem seems to be there.
carFilter

@tarekis
Copy link
Author

tarekis commented Jun 6, 2023

As @michaelzangerle has stated above, you need to change the color profile of your image to work, that is the current workaround.
E.g. changing the mode in GIMP works, whatever other image manipulation program you‘d use probably has a similar feature.

@Bogghi
Copy link

Bogghi commented Jun 9, 2023

@tarekis sorry for the late answer, being busy at work. That really helped and made me go throw the issue.

Thank you so much for the clarification.

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

No branches or pull requests

4 participants