I'm not fully satisfied by my code but it seems to work fine. I would like the ImageXObject to be able to generate up to two streams, but I didn't find a way to make it work.
Dumping the stream for the smask early, from Image::add_to_layer does the work, but it feels a bit hacky. The main issue is that of "locality", that is the masks of all images will be dumped at the very beginning of the file, instead of next to the image they modify. But hey, it works.
Also, I think that ImageXObject::{try_from, from_dynamic_image} would be better as members of Image, but I don't know how you would feel about such a change in a public interface. I changed only the return value to make the SMask separate, because an ImageXObject simply can't contain another ImageXObject.
Then, I removed the SMask type, that was never actually fully used, and that matte member of type Vec<i64> that made two unneeded conversions of the mask data.
And finally, since I was already editing that function, I moved a piece of duplicated code into preprocess_image_with_alpha().
This PR fixes #166, I think.
The problem was that the SMask was being streamed directly into the parent image dictionary, something like:
But that is not allowed by the PDF specification, although some parsers seem to be able to read just fine. Others will ignore the whole XObject.
The proper way would be to dump the SMask first, and then the Image with a ref:
I'm not fully satisfied by my code but it seems to work fine. I would like the
ImageXObject
to be able to generate up to two streams, but I didn't find a way to make it work.Dumping the stream for the
smask
early, fromImage::add_to_layer
does the work, but it feels a bit hacky. The main issue is that of "locality", that is the masks of all images will be dumped at the very beginning of the file, instead of next to the image they modify. But hey, it works.Also, I think that
ImageXObject::{try_from, from_dynamic_image}
would be better as members ofImage
, but I don't know how you would feel about such a change in a public interface. I changed only the return value to make theSMask
separate, because anImageXObject
simply can't contain anotherImageXObject
.Then, I removed the
SMask
type, that was never actually fully used, and thatmatte
member of typeVec<i64>
that made two unneeded conversions of the mask data.And finally, since I was already editing that function, I moved a piece of duplicated code into
preprocess_image_with_alpha()
.