[cairo] Re: Embeding JPG in PDF
Bill Spitzak
spitzak at d2.com
Tue Jan 9 13:39:30 PST 2007
Emmanuel Pacaud wrote:
> That would be better, and even better without a specific surface. A
> cairo_image_surface_create_from_jpeg () would load a jpeg image in
> memory and keep it as jpeg data, with some internal cairo API that would
> allow other backend to get directly these raw data. Only an
> acquire_image would trigger jpeg decompression.
If this is going to be done, it is probably a good idea to match what
most such libraries do today, which is to understand several image
types, ie jpeg, png, etc.
cairo_image_surface_create_from_file(filename) would identify the type
of file and make an image surface containing it's contents.
There also MUST be a cairo_image_surface_create_from_data(data,length)
which takes a memory-mapped file image. This allows the image to be
imbedded into the program or another database.
Typically there is also an implementation that takes caller-defined
read-block and close callbacks, similar to how the pdf surface can write
a file. This allows it to accept already-opened C++ streams or C FILE
objects. This must also take the data passed to the register function
described below.
To avoid having cairo link every image library known the solution seems
to be "register" a constructor function. This involves calling some
cairo api with a pointer to a function that takes a filename (used for
pattern-matching filenames, it is not opened), a block of data that is
the first 512 or so bytes of the file, and whatever arguments are passed
to the base class constructor such as the read+close callbacks. This
function figures out from the block of data (or the filename if it is
really stupid) if it can read the data, and if so constructs the proper
subclass and returns it. It returns null if the test fails. It helps a
lot if platform-specific tricks are done so that, for instance, the jpeg
subclass can be in the cairo library, but if the register for it is not
done it does not matter if libjpeg exists on the machine, the program
will work. Add a "register_common_images" function that gets you jpeg
and png.
A huge annoyance is that for most image file libraries it is quite
inefficient to measure the image without reading it at the same time, if
you assume there is any chance that after measuring the image the caller
will want the decompressed data. The result has usually been that it is
impossible to avoid the decompression when the object is constructed, or
at least when it is first used as a source. So the pdf example will
likely result in the image being decompressed into memory even if that
data is not used. Some file types can get the width/height from the
block of data used to id the file so they don't have this problem.
More information about the cairo
mailing list