[cairo] Embedding jpeg in pdf

Benjamin Otte otte at gnome.org
Mon Jul 14 07:23:30 PDT 2008


Vladimir Vukicevic <vladimir <at> pobox.com> writes:

> > The second patch implements PDF embedding of jpeg images. The third
> > patch adds the API function:
> >
> > cairo_surface_t *
> > cairo_image_surface_create_from_jpeg (const char   *filename)
> 
> I dislike this part -- the png stuff is in cairo because of testing,  
> but I don't think we need to do jpeg decoding in cairo and especially  
> don't need to add a dependency on libjpeg.  If an application wants to  
> embed jpeg images, it's probably already decoding jpeg images for its  
> own purpose -- there's no reason for cairo to duplicate that  
> functionality.  (For testing purposes, it's probably ok to add a  
> dependancy on libjpeg for the test itself, though.)
> 
I would have said this API is the only sane way to support any image format. But
this is likely because Swfdec as a library tries to live without its own image
handling library.
Anyway, there's some problems I have with not depending on libjpeg:
1) I think most backends that support JPEG only support a subset. I guess you'd
need libjpeg to figure out if the current JPEG data is supported anyway. (The
same would likely be true for other image formats, too.)
2) rendering to a surface with attached JPEG data would invalidate this data.
Should the surface be reencoded to JPEG when writing to a PDF or should it be
written as raw image data?
3) Cairo not providing the ability to decompress JPEG files confuses many
newcomers to the Cairo API. How to render JPEG and SVG files are two of the most
common questions in #cairo. JPEG not being available is extra confusing because
decoding works for PNG files.

My idea of how to support embedded images would have been to use the pattern API
as they should not be written to. I would have imagined it working something
like this:
cairo_pattern_create_from_png (const char *filename);
cairo_pattern_create_from_png_stream (cairo_read_func_t func, void *closure);
cairo_pattern_create_from_jpeg (const char *filename);
cairo_pattern_create_from_jpeg_stream (cairo_read_func_t func, void *closure);

Those functions would either return a CAIRO_PATTERN_TYPE_SURFACE and
cairo_pattern_get_surface() would cause the decoding to happen or they would be
a new pattern type that does not provide accessors to the decoded image and you
would need to cairo_paint() the pattern to an image surface for that.

This approach has two problems:
a) It requires linking to libjpeg
b) It does not provide a way for applications that handle decoding themselves to
attach the decoded image. The best idea I can come up with here is providing an
API like:
cairo_pattern_create_from_decoded_jpeg (cairo_surface_t *surface, 
    const unsigned char *data, size_t size);

Thoughts?

Cheers,
Benjamin



More information about the cairo mailing list