Summary: | Optional content groups logic bugs | ||
---|---|---|---|
Product: | MuPDF | Reporter: | Giorgio Bianchini <giorgio.bianchini> |
Component: | mupdf | Assignee: | MuPDF bugs <mupdf-bugs> |
Status: | UNCONFIRMED --- | ||
Severity: | normal | CC: | sumitp7816 |
Priority: | P2 | ||
Version: | 1.24.9 | ||
Hardware: | PC | ||
OS: | All | ||
Customer: | Word Size: | --- | |
Attachments: | PDF with optional content groups |
Are we going to commit any changes to this report? I have created a pull request that fixes these issues and more: https://github.com/ArtifexSoftware/mupdf/pull/51 |
Created attachment 26009 [details] PDF with optional content groups The attached PDF uses optional content groups and displays correctly in Firefox and Adobe Reader, but not in MuPDF (which completely ignores the OCGs and draws everything). This appears to be due to at least three separate issues: 1. The OCProperties dictionary in the PDF file specifies the default configuration in the D entry, but it does not have a Configs entry. As a result, MuPDF incorrectly reports that the document has 0 OCG configurations (pdf-layer.c, lines 752 and following). However, according to table 100 in the PDF 1.7 spec, the Configs entry is optional and specifies **alternate** optional content configuration dictionaries. Therefore, the default configuration specified by the D entry should also be taken into account when counting OCG configurations defined in the document. 2. Even after fixing the document by adding a Configs entry, the second issue is a bug in the logic that determines OCMD visibility, specifically lines 712-717 of pdf-layer.c: if ((combine & 1) == 0) hidden = !hidden; if (combine & 2) on &= hidden; else on |= hidden; When `combine` is 0 (AnyOn) or 3 (AllOff), this works as intended; however, if `combine` is 1 (AllOn), `on` ends up being always true (because the starting value is 1 and only OR operations are performed), and if `combine` is 2 (AnyOff) then `on` is always false (the starting value is 0 and only AND operations are performed). Replacing the lines above with the following should fix the issue: if (combine == 0 && !hidden) { on = 1; break; } else if (combine == 1 && hidden) { on = 0; break; } else if (combine == 2 && hidden) { on = 1; break; } else if (combine == 3 && !hidden) { on = 0; break; } 3. Finally, visibility expressions (VE entry in the OCMD dictionary) are completely ignored. Lines 679-683 in pdf-layer.c: obj = pdf_dict_get(ctx, ocg, PDF_NAME(VE)); if (pdf_is_array(ctx, obj)) { /* FIXME: Calculate visibility from array */ return 0; }