-
Notifications
You must be signed in to change notification settings - Fork 24
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
PDF Filters #25
PDF Filters #25
Conversation
@messense can I get some help on how I should be wrapping the callbacks? The |
I'll take a look later. |
This article could be helpful: https://adventures.michaelfbryan.com/posts/rust-closures-in-ffi/ |
I had read the article you linked before, but that only seems to be for functions with a void* parameter. In these cases can use that to pass your state around, but the mupdf functions I'm trying to implement don't. In that case I would have to use a global, but there's got to be a better solution. Although it doesn't have to be a global; the For reference, here are some usages of the functions I'm trying to implement in C. But none of these use external variables (I think). Page filter: Annotations filter:
The docs don't help much either, and neither does the source code. |
I've implemented an example of how it could work with a "global". Maybe we could use |
src/pdf/filter.rs
Outdated
|
||
unsafe extern "C" fn image_filter_callback( | ||
_ctx: *mut fz_context, | ||
_opaque: *mut c_void, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the opaque
argument should be passed into the callback? Otherwise it means we miss some context information in the callback.
In upstream it is used in some filters, for example https://github.com/ArtifexSoftware/mupdf/blob/a230d9c4255d4fefc6b3e71ba41447f5b0620e82/source/pdf/pdf-clean.c#L547
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where exactly should I pass that? I don't really understand why it's assigning its value to a pdf_page. And with the mupdf-rs bindings it's not like you can pass a pointer to void anywhere as a user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like opaque
is only set once here: https://github.com/ArtifexSoftware/mupdf/blob/a230d9c4255d4fefc6b3e71ba41447f5b0620e82/source/pdf/pdf-clean.c#L756
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm starting to think that opaque
is the void*
we can use to pass our own parameters... But that would be bad naming... I've asked in their Discord and I'll update this once I know more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, opaque
is meant to be used to pass the data around. Now that I've fixed that I've got one last doubt: perhaps we should be using the _ctx
value instead of ignoring it? Not sure how that works.
Ok so the new implementation is closer to what we wanted and I've made sure it works, now using the
Edit: the issue seems to be that the closure address is different in the callback compared to when it's set. Maybe I'm missing a |
Sorry for lack of response recently, I'll take a look at the CI failure this weekend. |
Have you tried |
Yeah I tried to use a Pin + Box but that didn't work either. I'll try again this weekend with a different approach, maybe I did that incorrectly. |
Looks like a double-free bug. |
Problem resolved, CI is passing now. |
Oh wow great job! I completely missed that. On my machine there's a test that does fail randomly, but I don't think that's related to this PR:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you.
The only remaining question is this: // TODO: `context()` inside this function should probably use the
// parameter's value instead of the global value, right? But it doesn't seem to be a problem because the |
Please open a new issue for this, thanks! |
I guess it's not a big deal, we can deal with it when problem does occur. 😅 |
Ok! Thanks for the help and for maintaining this great library :) |
This adds:
Page::filter
Annotation::filter
And
PdfFilterOptions
incrate::pdf::filter
to configure them.What do you think about the names? Do you prefer
filter
orfilter_contents
?Closes #24