Implementing an Image Type

Should it be necessary, support for new types of image can be implemented fairly simply, by defining a structure derived from a fz_image. Perhaps:


\begin{lstlisting}
typedef struct
{
fz_image super;
<foo specific fields>
} foo_image;
\end{lstlisting}

Then we'd define a new image creation function, fz_new_image_from_foo, of the form:


\begin{lstlisting}
fz_image *fz_new_image_from_foo(fz_context *ctx, <foo specifi...
...fields from foo specific parameters>
\par
return &foo->super;
}
\end{lstlisting}

The key call here is the call to fz_new_image. This is a macro which wraps a call to fz_new_image_of_size:


\begin{lstlisting}
/*
fz_new_image_of_size: Internal function to make a new fz_...
...image_of_size(CTX,W,H,B,CS,X,Y,I,IM,D,C,M,sizeof(T),G,S,Z), ...

The macro takes identical parameters to the function other than passing the structure type in place of the structure type saved, and performing a typecast to simplify the typical enclosing code.

Both function and macro take pointers to 3 functions that need to be defined for the new format. Firstly, foo_get is of the following type:


\begin{lstlisting}
/*
fz_get_pixmap_fn: Function type to get a decoded pixmap
...
... fz_image *im, fz_irect *subarea, int w, int h, int *l2factor);
\end{lstlisting}

Secondly, foo_get_size will be of type:


\begin{lstlisting}
/*
fz_image_get_size_fn: Function type to get the given stor...
...ypedef size_t (fz_image_get_size_fn)(fz_context *, fz_image *);
\end{lstlisting}

Finally, foo_drop will be of type:


\begin{lstlisting}
/*
fz_drop_image_fn: Function type to destroy an images data...
...edef void (fz_drop_image_fn)(fz_context *ctx, fz_image *image);
\end{lstlisting}

The actual deallocation of the fz_image block and its associated resources will be done on return from this function. The fz_drop_image_fn is responsible just for deallocating its implementation specific resources (i.e. the contents of foo_image rather than fz_image).