Created attachment 65137 [details] [review] DeviceN support in splash The attached patch implements DeviceN support in Splash. Running pdftoppm with the option overprint especially especially improves the output of the Ghent PDF Workgroup Output Suite.
Can you explain what this is supposed to do? 2300 lines and only "implements DeviceN support" seems a bit short for an explanation ;-) I'm mostly interested in knowing what all those new .h functions are supposed to do hasDifferntResultSet? createMapping? updateFillColorSpace and updateStrokeColorSpace that are only called once? What's a GooList *getSeparationList()? deviceNTransfer? Do we really need splashModeDeviceN8? hasDifferntResultSet has a typo ;-) this->copy() seems like it could be copy() only Should i expect any change in a regular run of pdftoppm without overprint?
But "implements DeviceN support" is exactly that what it does :-). To explain it a little bit more I copy a few lines from "Patch 8.01 — DeviceN Support (6 colors)" of the Ghent PDF workgroup: "This patch tests the DeviceN capabilities of a workflow. If DeviceN is not handled correctly the colors are converted to CMYK. Instead of the check marks an X will appear in the lower left corner of each image and in the gradient. In addition you could inspect the color separations. The objects should appear only in the Black, Pantone 265C and GWG Green separations as indicated in the captions." Without the patch all DeviceN colors are immediately converted to CMYK (with SPLASH_CMYK). This leads especially to problems, if overprint is used: in overprint mode a CMYK color will knockout the underlying CMYK components, BUT neither any spot colors. But if underlying spot colors are immediately converted to CMYK colors, they will be kocked out then, too! The patch now spends up to four (or up to SPOT_NCOMPS) additional spot colors in the splash bitmap, so the order in the bitmap will be CMYKSTUVCMYKSTUVCMYKSTUV... where S, T, U, V are spot colors (I would use S1,S2, S3, S4 if it's possible to use indexes), and all painting operations are done now in this new device. Only at the end, when we want to store the bitmap in a CMYK or RGB color, the spot colors are converted and their alternate CMYK components are added to the normal CMYK components. According to the PDF spec are PDF writer should use different spot color names if they have a different appearance in their alternate CMYK colorspace. "hasDifferntResultSet" (sorry for the typo) proofs that: if the same spot color name is reused BUT has a different appearance in the alternate colorspace, it will be converted immediately to its alternate colorspace. "createMapping" is used so that getDeviceN (color) returns the components in the correct order according their appearance in the splash bitmap, i.e. the fourth detected spot color must be placed in index 7 of the color array. updateFill- and updateStrokeColorspace are needed to create this mapping at the appropriate place. And they are not called once but everytime the colorspace changed in the PDF (but of course only once in Gfx). The GooList *getSeparationList() is used to store the functions for converting the spot colors to their alternate colorspace in order of their appearance in the splash bitmap. The functions are needed to compare if a spot color with the same name has really the same appearance and at the end when the splash bitmap has to be converted to a CMYK or RGB bitmap (s. ahead). deviceNTransfer is needed simular to rgbTransferX or cmykTransferX if a transfer function is specified in the ExtGState and splash uses the DeviceN8. "Do we really need splashModeDeviceN8?": Do we really need splashModeXBGR8? But kidding aside: splashModeDeviceN8 needs four more components than splashModeCMYK8, so the bitmap size in memory doubles the size of a pure CMYK bitmap, and it is only needed if the PDF uses spot colors. So I think it's a good idea to spend an additional mode and let it up to the calling application and the cirumstances if it wants to use this new mode or not. Once again: sorry for the typo, and of course this->copy() is the same as copy(). You shouldn't expect any change in a "regular" run, and as far as I remember I tested that. I also made some tests with valgrind to see that the allocated memory in this new mode is freed correctly.
Pushed
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.