[cairo] cairo_surface_set_mime_data

Uli Schlachter psychon at znc.in
Fri Jun 14 06:59:47 PDT 2013


On 13.06.2013 15:09, François Bianco wrote:
> Since it is my first use of Cairo, I started with a minimal example (attached). 
> My example is working correctly, but it rises some questions to me:

First some explanation on how this mime data API is supposed to be used:

Before these new functions were available, you would load a JPEG file from disk
and decode it into a cairo image surface. As you noticed, this causes big PDF
files and thus isn't all that nice.

Thus, *additionally* to the above, you can attach the raw JPEG file as mime data
to the surface. If cairo has to embed the image into the PDF file, it will
instead use the mime data for this. However, cairo doesn't have to do this, as
will be seen below.

> 1. Why is my code with 'cairo_image_surface_create' not displaying any image 
> in the exported PDF ? as it does when creating a buggy image surface with 
> 'cairo_image_surface_create_for_data' fed with raw JPG data ? (see lines with 
> fixme in code)

When you use cairo_image_surface_create(), you create an "empty" image whose
content is all black. Cairo tracks this information. When it has to write out
the PDF, it notices that the image is all black. Instead of embedding a JPEG
which is only black, something better/smaller is used instead.

As you see, cairo assumes that the bitmap content and the attached mime data
describes the same image!

> 2. In the Cairo documentation for 'cairo_surface_set_mime_data', it is stated 
> "Caution: the associated MIME data will be discarded if you draw on the 
> surface afterwards. Use this function with care. "
> Could one of you demonstrate (by changing my code) or explain me which cairo 
> functions would cause a redraw of the surface which would finally results in 
> loosing the MIME JPG data ?

Any cairo functions which (in your case) draw to "image". For example,
cairo_paint(cairo_create(image)), but also cairo_surface_flush().

If you ever want to figure out when some MIME data was discarded, you could call
cairo_surface_set_mime_data() with a callback function that prints something to
the console or add a breakpoint to the callback.

As already mentions, cairo assumes that the image surface and the mime data do
describe the same image. Thus, if you change the image surface, cairo knows for
sure that the mime data is stale and has to be detached.

> I ask that since I ported my example in Inkscape
> code, but the final output is always bitmaps. I am not able to locate which 
> part of the code could cause this issue. I tried and implemented in my example 
> a stupid rotation/scaling/translation to the image, but the surface is still 
> perfectly exported with its jpg MIME data.

Uhm... Yeah, add a breakpoint to your callback function and your debugger will
give you the backtrace when this happens.

- Captain, I think I should tell you I've never
  actually landed a starship before.
- That's all right, Lieutenant, neither have I.

More information about the cairo mailing list