Table of Contents
List of Tables
List of Examples
Table of Contents
Liquid Rescale Library Manual.
Copyright (C) 2007-2009 Carlo Baldassi <carlobaldassi@gmail.com>
This manual is released under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 dated June, 2007.
You should have received a copy of the GNU General Public License along with the library; if not, see http://www.gnu.org/licenses
This manual describes in detail the Liquid Rescale library API, starting from a brief overview on seam carving, the internal image representation, a minimal list of basic methods and the full explanation of all the library public methods.
In the `examples' directory, you will find a minimal example program, which only
uses basic methods, and a full-featured demo program, which uses almost all of the methods described in
this document. Both programs are fully commented, see also the README file in the
`examples' directory.
Refer to the README file for information about installing and compiling.
The latest version of the Liquid Rescale library and of this manual can be found at http://liblqr.wikidot.com.
Basically, the rescaling algorithm tries to find out which parts of the image are important, and which are not, based on the contrast between adjacent pixels; then, the image is resized through the elimination or insertion of continuous paths, called `seams'. The seams connect the top of the image with the bottom when rescaling horizontally, or they connect the left side with the right side when rescaling vertically. In the seam carving process, seams are removed in sequence, therefore shrinking the image by one pixel at a time. The seam insertion process mirrors the seam carving process, introducing interpolated seams in regions where they would have been carved.
Once it has been computed, the carving information can be efficiently stored in a so called multi-sized image, which can be used to reproduce the carving operation on the fly at any later moment.
It often happens that the automatic feature detection fails to identify as significant some image regions; in these cases a preservation mask can be specified, which marks those regions. In fact, the feature recognition process can be manually driven quite easily to its full extent, by using custom masks.
See also the References section for more information about the algorithm.
As mentioneed above, the enlargment process mirrors the carving process. More precisely, in order to enlarge the image by a given amount of pixels, say N, the library first computes which would be the first N seams to be removed; then, it inserts N new seams nearby those.
This means that it is clearly not possible to go beyond twice the original size in a single step. It also means that doubling the image size in this way is just equivalent to standard scaling, since the result is that each seam is just duplicated. For these reasons, the library rescaling engine automatically divides enlarging sessions in steps, and allows to set the step size.
This same issue also affects in a tricky way the preservation of image areas when enlarging: suppose your image is 1000 pixels wide, and you have protected an area which is 800 pixels wide. It is then clear that you cannot shrink the image to less than 800 pixels without affecting the preserved area, but the same is true when enlarging, so you should not go beyond 1200 pixels in a single step (= 1000 + (1000 - 800)), i.e. you should use a value lower than 1.2 for the enlargement step size.
In general, however, the optimal enlargement step size depends on the image, since large step sizes have the disadvantages discussed above, while small step sizes will tend to inflate the same areas of the image over and over at each step.
The Liquid Rescale library is written in C, but can be used into C++ programs without any modification. It has an
object-oriented design, so that the terminology in this manual is borrowed from C++. The central class
of the library is called LqrCarver. Carver objects can generate and store multi-size images, or load
them, and read them out at the desired size.
Internally, multi-size images are stored simply as plain images with the addition of a visibility map. Each pixel in the image has its own visibility level. Whether to display a pixel or not simply depends on the comparison of each pixel's visibility with a given global visibility level. In this way, images of different sizes can be read out, simply by setting a global visibility level.
Therefore, once the visibility map has been computed, it allows effortless, real-time scaling. However, visibility maps also necessarily have an orientation, either horizontal or vertical. If we want to resize on the other direction, the visibility map has to be computed afresh, and the previous visibility map becomes useless, because the two maps are not consistent one with the other.
This also implies that the resizing order affects the final result: rescaling horizontally first, then vertically, does not yield the same result as following the reverse order. Moreover, one could choose an intermediate way, e.g. by rescaling by one pixel in one direction, one in the other, then iterating as needed to reach the final size.
The default behaviour of the library is to rescale horizontally first, then vertically, but this order can be reversed.
Visibility maps can be stored in objects of type LqrVMap. When an LqrCarver object is created from
an input image, the visibility of each pixel is uninitialised. At this point, one could either import a
previously computed LqrVMap, or activate the LqrCarver so that it creates one afresh when asked to.
In either case, there's a single method to call, specifiying the new desired size; all the rest will automatically be computed as necessary. By default, the visibility maps are only computed up to the extent to which they are needed for resizing.
Following is a list of the basic public methods associated with the LqrCarver objects:
constructors and destructor
LqrCarver * lqr_carver_new (guchar *buffer, gint width, gint height, gint channels);
LqrCarver * lqr_carver_new_ext (void *buffer, gint width, gint height, gint channels, LqrColDepth colour_depth);
void lqr_carver_destroy (LqrCarver *carver);
initialization
LqrRetVal lqr_carver_init (LqrCarver *carver, gint delta_x, gfloat rigidity);
image manipulations
LqrRetVal lqr_carver_resize (LqrCarver *carver, gint new_width, gint new_width);
LqrRetVal lqr_carver_flatten (LqrCarver *carver);
readout
gboolean lqr_carver_scan (LqrCarver *carver, gint *x, gint *y, guchar **rgb);
gboolean lqr_carver_scan_ext (LqrCarver *carver, gint *x, gint *y, void **rgb);
gboolean lqr_carver_scan_by_row (LqrCarver *carver);
gboolean lqr_carver_scan_line (LqrCarver *carver, gint *n, guchar **rgb);
gboolean lqr_carver_scan_line_ext (LqrCarver *carver, gint *n, void **rgb);
get values
gint lqr_carver_get_width (LqrCarver *carver);
gint lqr_carver_get_height (LqrCarver *carver);
gint lqr_carver_get_channels (LqrCarver *carver);
LqrColDepth lqr_carver_get_col_depth (LqrCarver *carver);
The fastest way to see how they work is having a look at the code of
examples/liquidrescale-basic.cpp, which is a very simple and fully commented
demostrative program.
The return value of many functions is of type LqrRetVal. This is just an enum
type which can be used for signal handling, see the Signal handling
section.
The other classes are optional: the class LqrVMap is used to hold the carving information (and the
class LqrVMapList is used to retrieve it from the LqrCarver ojects); the class LqrProgress is used to
customize progress report from the resizing engine (by default it is turned off).
A complete list of the library public methods can be found in the reference at the end of this document.
Table of Contents
Many library functions return a value of type LqrRetVal. This is an enum type
which can hold the values:
LQR_OKeveryting OK
LQR_ERRORgeneric fatal error
LQR_NOMEMnot enough memory
LQR_USRCANCELaction cancelled by the user
At top level, it is important that the user handle these values explicitly, because the library functions don't do anything else than stopping and returning an error signal in case of errors. An easy way is setting up some macros and wrap each function call with those, as shown in the example files.
Below top level, the library provides some convenient macros which can be used to wrap function calls, in order to propagate these signals:
LQR_CATCH (expr)
if expr is equal to LQR_OK it does nothing, otherwise it
returns expr (or the result of the execution of
expr if it happens to be a function)
LQR_CATCH_F (expr)
returns LQR_ERROR if expr is FALSE
LQR_CATCH_MEM (expr)
returns LQR_NOMEM if expr is NULL
The names of these macros have changed since version 0.4; the previous names
CATCH, CATCH_F and CATCH_MEM are
still available, but they can be disabled at configure time if they cause conflicts
(configure --help for details).
The LqrCarver objects are initialised from a plain buffer representing an image. The default
constructor assumes a colour depth of 8 bits per channel:
LqrCarver * lqr_carver_new( | guchar * | buffer, |
| gint | width, | |
| gint | height, | |
| gint | channels); |
Here, buffer is the array representing an image of size
width by height with channels
colour channels per pixels. Thus, the overall buffer size has to be of
unsigned characters, and ordered such that the
widht * height *
channels k-th colour of the pixel at row
y and column x is found at:
buffer[(y * width + x) * channels + k]
(this assumes that
x, y and
k all start from 0 and reach the maximum
values widht-1, height-1 and
channels-1, respectively)
The function returns a pointer to the newly allocated LqrCarver upon success, or
NULL in case of insufficient memory.
In order to create LqrCarver objects with more than 8 bits per channel, an extended version of the
constructor must be used:
LqrCarver * lqr_carver_new_ext( | void * | buffer, |
| gint | width, | |
| gint | height, | |
| gint | channels, | |
| LqrColDepth | colour_depth); |
The differnece with the default version is that the input buffer must be passed as void, and its
type must be specified through the additional parameter colour_depth, which
can take one of the following values:
LQR_COLDEPTH_8I8 bit unsigned integers (guchar)
LQR_COLDEPTH_16I16 bit unsigned integers (guint16)
LQR_COLDEPTH_32F32 bit floating point (gfloat)
LQR_COLDEPTH_64F64 bit floating point (gdouble)
Floating point type values must range between 0 and 1.
The library has some support for different image types and color models. When a LqrCarver object is
created, the image type is automatically set from the number of channels (basically, assuming that
the image is either grayscale or RGB with possibly an alpha channel), but it is important to set it
manually using the function lqr_carver_set_image_type if your program has to
deal with different color models. See the section Choosing the image
type for more details.
By default, the buffer is assumed to be a copy of the original image, and therefore it is owned by
the LqrCarver object and must not be accessed directly any more (and of course it must not be
freed, the LqrCarver destructor does it). If, instead, you want the
Liquid Rescale library to keep the buffer intact, you must flag the LqrCarver after creation (or after
activation), using this function:
void lqr_carver_set_preserve_input_image( | LqrCarver * | carver); |
This function must be used before any other operation takes place.
The newly created LqrCarver consists only of the image buffer plus an uninitialised visibility map.
If one had a previously computed visibility map, it could be imported into the LqrCarver and that
would be enough (see the Importing a visibility map in a carver
section).
If the visibility map has to be computed, the LqrCarver needs to be initialised through this
function:
LqrRetVal lqr_carver_init( | LqrCarver * | carver, |
| gint | delta_x, | |
| gfloat | rigidity); |
Here, delta_x is the maximum allowed transversal step of the seams (0 means
straight seams, the typical value is 1), while the rigidity parameter can be
used to introduce a global bias for non-straight seams (the typical value is 0; a nonzero value can
be modulated locally for specific areas using the functions described in section
Adding a rigidity mask).
It is currently an error to initalise a carver object if a visibility map has been imported already.
The library supports a small number of different image types/color models in order to correctly compute quantities such as the brightness of a pixel, which are important for automatic feature detection.
The image type can be set manually using the function:
LqrRetVal lqr_carver_set_image_type( | LqrCarver * | carver, |
| LqrImageType | image_type); |
The type LqrImageType is an enum which can take these values:
LQR_GREY_IMAGELQR_GREYA_IMAGELQR_RGB_IMAGELQR_RGBA_IMAGELQR_CMY_IMAGELQR_CMYK_IMAGELQR_CMYKA_IMAGELQR_CUSTOM_IMAGE
When creating a LqrCarver object, the image type is inferred from the number of channels according
to this table:
Table 2.1. Image types assigned by default
| channels | type |
|---|---|
| 1 | LQR_GREY_IMAGE |
| 2 | LQR_GREYA_IMAGE |
| 3 | LQR_RGB_IMAGE |
| 4 | LQR_RGBA_IMAGE |
| 5 | LQR_CMYKA_IMAGE |
| >5 | LQR_CUSTOM_IMAGE |
When setting a carver to LQR_CUSTOM_IMAGE, it is assumed that there are no alpha or black channels,
but if there are, their index can be specified with the functions:
LqrRetVal lqr_carver_set_alpha_channel( | LqrCarver * | carver, |
| gint | channel_index); |
LqrRetVal lqr_carver_set_black_channel( | LqrCarver * | carver, |
| gint | channel_index); |
Use the value -1 in the indices arguments to unset those channels. Note that
using LQR_CUSTOM_IMAGE in a carver normally requires special care in the choice and definitions of
the energy functions (see the Automatic feature detection section).
Setting manually the alpha or black channel with the above functions automatically sets the
carver image type to LQR_CUSTOM_IMAGE.
The support for CMY (and derived) color models is very naïve, since no color profiles are yet managed by the library.
Once initialised, or if a visibility map has been loaded, the image can be resized through this function:
LqrRetVal lqr_carver_resize( | LqrCarver * | carver, |
| gint | new_width, | |
| gint | new_height); |
This function decides automatically whether it can use the already computed visibility map, it has to update it or waste it completely and start afresh. This last event occurs when the map was computed for horizontal resizing and a vertical resize has been requested, or vice versa, and also when the required enlargment is bigger than the enlargement step value (see Setting the enlargement step). Note that only initialised carvers can update or change the visibility map; if this is not the case, an error is returned.
The function also takes advantage of the fact that the enlargment process mirrors the shrink
process. For example, if the original size of the image is (w0,
h0) and lqr_carver_resize is invoked with
(w0 - 100, h0) as an argument, then subsequent
calls to the function will allow on-the-fly resizing in the whole range from
(w0 - 100, h0) to (w0
+ 100, h0). (But note that this may be overcome if
w0 + 100 is bigger than the enlargement step.)
In order to resize in more than one step, the image can be flattened in its current state, thrugh this function:
gboolean lqr_carver_flatten( | LqrCarver * | carver); |
The return value is FALSE in case of insufficient memory, TRUE otherwise.
This function destroys the current visibility map and reinitialises the multi-size image from its current state.
Every time that the image is flattened (including when changing the resize direction) the original image and all information about it is lost.
The resizing and flattening operations can be aborted using this function:
LqrRetVal lqr_carver_cancel( | LqrCarver * | carver); |
This function can be invoked asynchronously, from a different thread with respect to the one in
which the resizing or flattening methods were called. If successful, this function will return
LQR_OK, and any ongoing resizing or flattening functions will immidiately abort and return the
special value LQR_USRCANCEL; however, this function will have no effect if no operation was in
progress when calling it.
This function can be called multiple times.
Whenever a function returns LQR_USRCANCEL, it means that the LqrCarver object is in an
inconsistent state, and there is currently no way to recover from this situation. Therefore, any
further operation on it must be avoided, and it must be destroyed.
The functions lqr_carver_resize and lqr_carver_flatten
are not the only ones which can return LQR_USRCANCEL; instead, any function in the library whose
return type is LqrRetVal and which operates on LqrCarver objects can
return such value: for example, any function will do so if called over a LqrCarver object for
which an operation was actually cancelled (but this is not the only possibility).
Once you have rescaled the image, you can read out the result through the functions:
gboolean lqr_carver_scan( | LqrCarver * | carver, |
| gint* | x, | |
| gint* | y, | |
| guchar** | rgb); |
or
gboolean lqr_carver_scan_ext( | LqrCarver * | carver, |
| gint* | x, | |
| gint* | y, | |
| void** | rgb); |
Here, x and y are pointers to the varaibles which will
hold the pixel coordinate, while rgb is a pointer to an array which will
contain the pixel colour information. If the carver was created using the standard 8-bit constructor
lqr_carver_new, the first form can be used, otherwise you must use the extended
form lqr_carver_scan_ext. In this last case, the output pointer
rgb must be passed as a pointer to void*, but the outcome should
actually be cast to a pointer to an array of the appropriate type, depending on the LqrCarver
colour depth.
The return value is FALSE when the end of the image is reached, or the buffer has the wrong
number of bits, TRUE otherwise.
Each time these functions are invoked, they will store the coordinates and rgb information in the
output pointers and move to the next pixel. If they reach the end, they reset the reader and return
FALSE.
Here is a sample code usage:
Example 2.1. A simple readout example
gint x, y;
guchar *rgb;
while (lqr_carver_scan (carver, &x, &y, &rgb) {
my_plot (x, y, rgb[0], rgb[1], rgb[2]);
}
In this example, it is assumed that the image has three 8-bit colour channels, and that there exist
some function my_plot which writes out the pixels somewhere.
The same readout example with different colour depth would read like this:
Example 2.2. A simple readout example - extended version
gint x, y;
void *rgb;
gdouble *rgb_out;
while (lqr_carver_scan (carver, &x, &y, &rgb) {
rgb_out = (gdouble*) rgb;
my_plot (x, y, rgb_out[0], rgb_out[1], rgb_out[2]);
}
In this example it is assumed that the carver was loaded with the LQR_COLDEPTH_64F as the
colour_depth argument in the constructor
lqr_carver_new_ext, and that it has 3 colour channels (see
the constructor section for details); therefore, the output is
cast to type gdouble before using it.
The rgb array is owned by to the carver object, so it doesn't need
initialization, as in the example. Indeed, it must be used for read-only purposes, and the
content should always be copyed after each call to a scan function.
The image can also be read one line at a time, but it is not possible to freely decide if it is to be read by row or by column. Instead, this has to be queried by calling this function:
gboolean lqr_carver_scan_by_row( | LqrCarver* | carver); |
The function returns TRUE if the image is read by row, and FALSE if it is read by
column.
Then, the image can be read through these functions:
gboolean lqr_carver_scan_line( | LqrCarver* | carver, |
| gint* | n, | |
| guchar** | rgb); |
or
gboolean lqr_carver_scan_line_ext( | LqrCarver* | carver, |
| gint* | n, | |
| void** | rgb); |
These functions work exactly the same way as lqr_carver_scan and
lqr_carver_scan_ext, but only one coordinate is stored (either the row or the
column number), and the rgb array will contain a whole line.
Here is a sample code usage for the standard 8-bit case:
Example 2.3. Line-by-line readout example
gint n;
guchar *rgb;
gboolean by_row;
by_row = lqr_carver_scan_by_row (carver);
while (lqr_carver_scan_line (carver, &n, &rgb) {
by_row ? my_plot_row (n, rgb) : my_plot_col (n, rgb);
}
where, as before, it is assumed that the my_plot_row and
my_plot_col functions have been previously defined and "know what to do".
The extended version for images with more colour depth is very similar, it only requires an additional cast:
Example 2.4. Line-by-line readout example - extended version
gint n;
void *rgb;
guchar *rgb_out;
gboolean by_row;
by_row = lqr_carver_scan_by_row (carver);
while (lqr_carver_scan_line_ext (carver, &n, &rgb) {
rgb_out = (gboolean*) rgb;
by_row ? my_plot_row (n, rgb_out) : my_plot_col (n, rgb_out);
}
The automatic feature detection relies on the evaluation of the relevance of each pixel; this quantity is called `energy': the higher the energy of a pixel, the less likely it will be that such pixel will be directly involved in the rescaling. The energy function which the library uses can be customised; normally, edge detector filters are the best choices for this purpose.
There is a unified framework in the Liquid Rescale library for energy fucntions: briefly, each energy function used by the library receives the current position and image size as parameters, and is provided access to a square of values from the image, centered around the current position. This access is provided through an object which is called a "reading window", and the image pixels are not read directly, but rather they are accessed according to a "reader type", which means that the energy function can get e.g. the brightness of a pixel without needing to care for the underlying image representation, i.e. the image type or the colour depth.
The library provides a small set of very simple (yet normally effective) gradient-based energy functions, and a customisation framework for defining more functions.
The library has some builtin functions for energy evaluation; in order to set one of the builtin
functions in a LqrCarver object this function is used:
LqrRetVal lqr_carver_set_energy_function_builtin( | LqrCarver* | carver, |
| LqrEnergyFunctionBuiltinType | ef_ind); |
The currently available builtin functions which can be used as ef_ind are:
LQR_EF_GRAD_XABSabsolute value of the brightness gradient in the direction of the rescaling (this is the default)
LQR_EF_GRAD_SUMABSsum of absolute values of the brightness gradients in both directions
LQR_EF_GRAD_NORMnorm of the brightness gradient
LQR_EF_LUMA_GRAD_XABSabsolute value of the luma gradient in the direction of the rescaling
LQR_EF_LUMA_GRAD_SUMABSsum of absolute values of the luma gradients in both directions
LQR_EF_LUMA_GRAD_NORMnorm of the luma gradient
LQR_EF_NULLnull
All of the above gradient functions have a radius of 1 pixel.
Custom energy functions for a LqrCarver object are set using this function:
LqrRetVal lqr_carver_set_energy_function( | LqrCarver* | carver, |
| LqrEnergyFunc | ef_func, | |
| gint | radius, | |
| LqrEnergyReaderType | reader_type, | |
| gpointer | extra_data); |
Here, ef_func is the function (the prototype will be explained below),
radius is used to set the size of the square region around each pixel which
is used to evaluate the energy for that pixel, reader_type is used to set
which quantity is used for the energy computation (e.g. brightness, luma etc.) and
extra_data is a (void) pointer which can be used to pass additional
parameters to the energy function.
The LqrEnergyReaderType is an enum which can take these values (also
noted is the number of channels of the corresponging output):
LQR_ER_BRIGHTNESSbrightness (1 channel)
LQR_ER_LUMAluma (1 channel)
LQR_ER_RGBARGBA (4 channels)
LQR_ER_CUSTOMread the normalised image channels as they are (as many channels as the image has)
These readouts always return values beetween 0 and 1.
Note that these readouts may have special meanings depending on the image type:
for LQR_GREY_IMAGE, LQR_GREYA_IMAGE and
LQR_CUSTOM_IMAGE images, the LQR_ER_LUMA
readout will yield the same result as LQR_ER_BRIGHTNESS
for LQR_CUSTOM_IMAGE images, the LQR_ER_BRIGHTNESS
readout will return the average pixel value (additive, i.e. if a black channel is
present the channel values will be inverted and multiplied by the black channel
inverse), multiplied by the alpha channel value.
for LQR_CUSTOM_IMAGE images, the LQR_ER_RGBA
readout cannot be used: it will always return
0
The custom energy function must be declared like in the following sample declaration:
Example 2.5. Custom energy declaration
gfloat my_energy (gint x, gint y, gint width, gint height, LqrReadingWindow *rwindow, gpointer extra_data);
This function should return the energy at pixel x, y,
based on the knowledge of the current image size (obtained from width and
height) and the content of the image in a square around that pixel, which is
passed through the rwindow reading window: in order to access this content,
this function must be used:
gdouble lqr_rwindow_read( | LqrReadingWindow * | rwindow, |
| gint | x, | |
| gint | y, | |
| channel | channel); |
When reading out the content from a window, the x and
y parameters are relative to the window centre (which instead is given by the
x, y parameters passed to the custom energy function),
and they both range between -radius and
radius included (radius being the same
one which is used in lqr_carver_set_energy_function). The parameter
channel specifies which channel to read out; depending on the
read_type passed to lqr_carver_set_energy_function the
range and meaning of this parameter will change: for the cases LQR_ER_BRIGHTNESS and
LQR_ER_LUMA it must be 0, because the readout consists of a
single channel, for LQR_ER_RGBA it must be between 0 and
3 (and then the readout will contain the RGBA information), while for
LQR_ER_CUSTOM it must be one of the original image channels.
The rwindow parameters can be read out from within a custom defined energy
function using these functions:
LqrEnergyReaderType lqr_rwindow_get_read_t( | LqrReadingWindow * | rwindow); |
gint lqr_rwindow_get_radius( | LqrReadingWindow * | rwindow); |
gint lqr_rwindow_get_channels( | LqrReadingWindow * | rwindow); |
Following is an example of how a simple Sobel fliter can be defined and used within this framework:
Example 2.6. Custom energy definition and setup
/* definition */
gfloat sobel(gint x, gint y, gint width, gint height, LqrReadingWindow *rw, gpointer extra_data)
{
gint i, j;
gdouble ex = 0;
gdouble ey = 0;
gdouble k[3][3] = {{0.125, 0.25, 0.125}, {0, 0, 0}, {-0.125, -0.25, -0.125}};
for (i = -1; i <=1; i++) {
for (j = -1; j <=1; j++) {
ex += k[i + 1][j + 1] * lqr_rwindow_read(rw, i, j, 0);
ey += k[j + 1][i + 1] * lqr_rwindow_read(rw, i, j, 0);
}
}
return (gfloat) sqrt(ex * ex + ey * ey);
}
/* usage */
lqr_carver_set_energy_function (carver, sobel, 1, LQR_ER_BRIGHTNESS, NULL);
In the above sobel function it is assumed that the radius is 1 and that the
readout will consist of a single channel. Furthermore, no boundary checking is performed, and
therefore the parameters x, y, width and height are not used. Also, no extra
parameters are passed to the function.
The function lqr_rwindow_read returns 0 when the
requested value is out of the image boundary or beyond the reading window radius.
The energy functions are called over the transposed image in case of vertical scaling,
therefore, if they are asymmetrical, the result will be different depending on the scaling
orientation (this is the case for example for the LQR_EF_GRAD_XABS builtin
function).
The energy function output should be normalised in order to be comparable with the builtin
functions, otherwise the scale of the bias would be different depending on the energy function
used. This is the reason why in the Sobel filter written above the kernel
k is scaled so that the sum of the absolute values of the matrix is equal
to 1.
In actual code, the call to lqr_carver_set_energy_function should be
protected to test its return value.
The energy can be read out with three similar functions, all of which fill a buffer provided by the user, but in different ways: two of them are suitable for plotting, while the third one can be used to retreive the true values of the energy, as used internally.
The first function can be used to get a buffer of normalised values, and it has a simple syntax:
LqrRetVal lqr_carver_get_energy( | LqrCarver * | carver, |
| gfloat * | buffer, | |
| gint | orientation); |
This function writes the the energy values at the time of calling to the given
buffer, ordered by row and then by column. All values range between
0 and 1. The buffer must be allocated by the user before
calling it.
The orientation parameter determines which orientation will be used when
computing the energy: 0 means horizontal, 1 means vertical.
The carver need not be initialised; if a bias was added to it (see the
Adding a bias section), its effect is included in the output.
The above function does not return the true energy which is used internally, because that would not be suitable for plotting, since the energy range is arbitrary (only the energy differences are meaningful, and there is no upper nor lower bound to the values). In order to get the true energy values used internally, this function must be used instead (with the same syntax):
LqrRetVal lqr_carver_get_true_energy( | LqrCarver * | carver, |
| gfloat * | buffer, | |
| gint | orientation); |
The last function can be used to fill directly an image buffer:
LqrRetVal lqr_carver_get_energy_image( | LqrCarver * | carver, |
| void * | buffer, | |
| gint | orientation, | |
| LqrColDepth | col_depth, | |
| LqrImageType | image_type); |
In this case, the buffer must be passed as void*, while the
col_depth and image_type are used to specify the
colour depth and the image type, in the same way as is done when creating an LqrCarver object (see
Carver objcet creation and the
Choosing the image type sections). The only restriction is that it
is not possible to ask for LQR_CUSTOM_IMAGE image types.
For any choice of the parameters, the buffer will hold a greyscale image,
ranging from black (lowest energy) to white (highest energy). The opacity (alpha) will be set to
1, if present. All the information will be stored in the black channel in
LQR_CMYK_IMAGE and LQR_CMYKA_IMAGE image types.
Calling the function lqr_carver_get_energy_image with LQR_COLDEPTH_32F and
LQR_GREY_IMAGE arguments will yield the same result as calling the function
lqr_carver_get_image, but the latter is slightly more efficient.
The automatic feature detection can be driven manually by adding a bias to the pixels of the image.
For example, it is possible to protect regions of the image by adding a positive bias to the corresponding pixels. This will make the seams more unlikely to cross those regions, thus avoiding distortion (but increasing distortion of the other regions).
It is also possible to make the seams more likely to cross some regions by adding a negative bias to them. In this case, reducing the size of the image will tend to erase those regions, while (possibly) keeping the rest of the image in a consistent state.
The bias has to be added before the resizing takes place (but it can be added before initialisation since version 0.4).
In all of the bias-related functions, the bias is added on top of the existing one, so that all of the functions can be called multiple times.
The function to use in order to add a bias to a given pixel is:
LqrRetVal lqr_carver_bias_add_xy( | LqrCarver* | carver, |
| gdouble | bias, | |
| gint | x, | |
| gint | y); |
Typical values for the bias parameter would be between 100
and 10000 in module.
It is possible to use a whole array of floating points at once through this function:
LqrRetVal lqr_carver_bias_add( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | bias_factor); |
Here, buffer is an array contining the bias values, and it is assumed to have
the same size as the image loaded in carver, while
bias_factor is an overall bias factor, which can be used to affect the global
bias level: if the elements of buffer are of order 1, a standard choice for
the bias_factor would be between 100 and 10000 (in module).
This function, and all the following, will not swallow the buffer (to the contrary of what
happens e.g. when creating a new LqrCarver object and allowing the default behaviour),
therefore the buffer must be freed by the user afterwards.
The bias can also be read from an 8-bit rgb buffer. This buffer has to be in the same format as the one used in the 8-bit LqrCarver constructor (but may have a different number of colours per channel). The function is:
LqrRetVal lqr_carver_bias_add_rgb( | LqrCarver* | carver, |
| guchar* | buffer, | |
| gint | bias_factor, | |
| gint | channels); |
As in the previous case, buffer is assumed to hold and image of the same size
as the one in the carver.
The buffer contents will be transformed into floating-points by averaging the
colour components and multiplying the result by the alpha channel (transparency) value.
The existence of an alpha channel is inferred from the channels value: if
this is 1 or 3, no alpha channel is assumed, if it is 2 or 4 or greater, it is assumed that the
last channel holds the alpha value. If this is not what you want, you should resort to one of
the previous methods.
The two previously described functions operate on the whole LqrCarver image. It is also possible
to access specific image regions in a similar way; for the floating point case use:
LqrRetVal lqr_carver_bias_add_area( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | bias_factor, | |
| gint | width, | |
| gint | height, | |
| gint | x_off, | |
| gint | y_off); |
while for the rgb image case use:
LqrRetVal lqr_carver_bias_add_rgb_area( | LqrCarver* | carver, |
| guchar* | buffer, | |
| gint | bias_factor, | |
| gint | channels, | |
| gint | width, | |
| gint | height, | |
| gint | x_off, | |
| gint | y_off); |
In both functions, width and height are used to specify the size of the area of interest,
while x_off and y_off specify its offset. For the
rest, both functions work in the same way as their global couterpart.
The provided buffers have to be of size (or
width * height for the rgb case) but the specified
areas need not to be strictly included inside the width * height * channelsLqrCarver image area : only the parts which
overlap with it will be used. For example, the offsets can also be negative.
The rigidity parameter which is set at carver activation time (see section Carver activation) normally affects the whole image. It is possible, however, to specify which areas of the image should be affected by using a rigidity mask.
When a rigidity mask is used, each pixel of the image acquires an individual rigidity coefficient, which has to be multiplied with the overall rigidity parameter to get the actual pixel's rigidity. This is useful in some situations to reduce distorsions in specific areas of the image while keeping the seams optimal in other areas.
The library interface to deal with rigidity masks follows very closely the scheme for bias masks as
described in the bias section, the main difference being that no
equivalent to the bias factor has to be provided (since it is already given in the
lqr_carver_init function).
The rigidity mask has to be added always after the LqrCarver
initialization and before resizing takes place. (Note that this is
different from the bias, which instead can also be added to non-initialised carver objects.)
Whenever a rigidity mask is set, all pixels for which the value is not explicitly defined will have coefficient 0, i.e. the rigidity setting will will be disabled.
All of the functions can be called multiple times, but their effect is not summed up, to the contrary of what happens for the bias functions; instead, new values will substitute old ones when the affected regions overlap.
The function to use in order to set the rigidity mask at a given pixel is:
LqrRetVal lqr_carver_rigmask_add_xy( | LqrCarver* | carver, |
| gdouble | rigidity, | |
| gint | x, | |
| gint | y); |
It is possible to use a whole array of floating points at once through this function:
LqrRetVal lqr_carver_rigmask_add( | LqrCarver* | carver, |
| gdouble* | buffer); |
Here, buffer is an array contining the rigidity coefficients values, and it
is assumed to have the same size as the image loaded in carver.
This function, and all the following, will not swallow the buffer (to the contrary of what
happens e.g. when creating a new LqrCarver object and allowing the default behaviour),
therefore the buffer must be freed by the user afterwards.
The rigidity mask can also be read from an 8-bit rgb buffer. This buffer has to be in the same format as the one used in the 8-bit LqrCarver constructor (but may have a different number of colours per channel). The function is:
LqrRetVal lqr_carver_rigmask_add_rgb( | LqrCarver* | carver, |
| guchar* | buffer, | |
| gint | channels); |
As in the previous case, buffer is assumed to hold and image of the same size
as the one in the carver.
The buffer contents will be transformed into floating-points by averaging the
colour components and multiplying the result by the alpha channel (transparency) value.
The existence of an alpha channel is inferred from the channels value: if
this is 1 or 3, no alpha channel is assumed, if it is 2 or 4, it is assumed that the last
channel is holds the alpha value. If this is not what you want, you should resort to one of the
previous methods.
The two previously described functions operate on the whole LqrCarver image. It is also possible
to access specific image regions in a similar way; for the floating point use:
LqrRetVal lqr_carver_rigmask_add_area( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | width, | |
| gint | height, | |
| gint | x_off, | |
| gint | y_off); |
while for the rgb image use:
LqrRetVal lqr_carver_rigmask_add_rgb_area( | LqrCarver* | carver, |
| guchar* | buffer, | |
| gint | channels, | |
| gint | width, | |
| gint | height, | |
| gint | x_off, | |
| gint | y_off); |
In both functions, width and height are used to specify the size of the area of interest,
while x_off and y_off specify its offset. For the
rest, both functions work in the same way as their global couterpart.
The provided buffers have to be of size (or
width * height for the rgb case) but the specified
areas need not to be strictly included inside the width * height * channelsLqrCarver image area : only the parts which
overlap with it will be used. For example, the offsets can also be negative.
The behaviour can be tuned through some additional functions.
As mentioned in About enlarging, if the requested final size is too big, the rescaling is automatically divided in steps.
For example, let us suppose that we have created an LqrCarver object from a 100 by 100 pixels
image, and that we call lqr_carver_resize with 600 and 100 as width and height
arguments. With the default settings, the rescaling of the width will be performed in 3 steps:
first, from 100 to 199, then from 199 to 397, and finally from 397 to 600.
The rule here is that the maximum size which can be reached in a single step is equal to twice the
original size minus one, and that at each step the original size is reset to the current size
(through an internal call to lqr_carver_flatten).
In most situations, however, the steps should be smaller in order to obtain good results. This can be set with this function:
LqrRetVal lqr_carver_set_enl_step( | LqrCarver * | carver, |
| gfloat | enl_step); |
The value of enl_step must be strictly grater then 1.0 and less then (or
equal to) 2.0. The default value is 2.0 (for back-compatibility reasons); any other value will
result in the function returning an error. The new maximum size for a step will then be obtained by
multiplying the original size by the enlargement step and subtracting 1.
The current value of the enlargement step can be retrieved with this function:
gfloat lqr_carver_get_enl_step( | LqrCarver * | carver); |
When the function lqr_carver_resize is asked to resize along both directions in
a single step, it has to choose which direction to resize first. The resize order can be changed
through this function:
void lqr_carver_set_resize_order( | LqrCarver* | carver, |
| LqrResizeOrder | resize_order); |
The possible values for resize_order are:
LQR_RES_ORDER_HORresize horizonally first (this is the default)
LQR_RES_ORDER_VERTresize vertically first
When the function lqr_carver_resize is invoked, it chooses at each step the
optimal seam to carve based on the relvance value for each pixel. However, in the case two seams
are equivalent (which may happen when large portions of the image have the same colour, for
example), the algorithm always chooses the seams from one side, which might be a problem (e.g. an
object centered in the original image might not be centered any more in the resulting image).
In order to overcome this effect, an option is given to automatically switch the favoured side during rescaling, at the cost of a slightly worse performance. The number of times such a switching event occurs for each rescale operation can be set using the function:
void lqr_carver_set_side_switch_frequency( | LqrCarver* | carver, |
| guint | switch_frequency); |
The default value for newly created LqrCarver objects is 0, which is equivalent
to disabling this feature. Giving a value greater than the number of pixels by which to rescale
produces a switch for each pixel, therefore you could set switch_freqency to
a ridicolously high value in order to be sure to get this effect.
As for the final result, a very small value (e.g. 1) will
normally suffice to balance the left and right side of the image (or the top and the bottom sides
for vertical rescalings), without noticeable computational costs. However, in order to obtain a
smoother behaviour for the visibiliy map, i.e. for the intermediate steps, higher values may be
required.
to 4
By default, the library tries to cache some quantities in order to save computational time. The cache may be disabled in order to save memory instead, using this function:
void lqr_carver_set_use_cache( | LqrCarver* | carver, |
| gboolean | use_cache); |
To disable the cache, set use_cache to FALSE. To
re-enable it back, set it to TRUE.
The visibility map can be saved at any moment by calling the function:
LqrVMap* lqr_vmap_dump( | LqrCarver* | carver); |
This function will return a pointer to a newly allocated LqrVMap object, or NULL in case of
failure. See also the section "The visibility map objects".
By default, the computed visibility maps are wasted. Instead of saving them individually, it is
possible to automatically dump them at the end of the carving process, attaching them to their
associated LqrCarver. In order to activate this feature, the following function has to be called:
void lqr_carver_set_dump_vmaps( | LqrCarver* | carver); |
This will have the effect of dumping the visibility map each time
lqr_carver_resize is invoked, and storing it internally. When resizing along
both directions, two maps will be dumped, one for each direction.
In order to revert the effect of lqr_carver_set_dump_vmaps, thus stopping the
automatic dumping, use the function
void lqr_carver_set_no_dump_vmaps( | LqrCarver* | carver); |
Alternatively, the internal storage mechanism can be called over the current visibility map at any given moment by calling this function:
LqrRetVal lqr_vmap_internal_dump( | LqrCarver* | carver); |
The dumped maps are stored inside LqrVMap objects, and these are attached to their corresponing
LqrCarver object through a linked list, whose type is LqrVMapList
To access the maps attached to a carver one has first to obtain the pointer to the list, with the function:
LqrVMapList* lqr_vmap_list_start( | LqrCarver* | carver); |
Then, one can iterate through the attached maps by using these two functions:
LqrVMap* lqr_vmap_list_current( | LqrVMapList* | list); |
LqrVMapList* lqr_vmap_list_next( | LqrVMapList* | list); |
Here is a sample code usage:
Example 2.7. Accessing visibility maps #1
LqrVMap *vmap;
LqrVMapList *list;
list = lqr_vmap_list_start (carver);
while (list) {
vmap = lqr_vmap_list_current (list);
/* ... do something on vmap ... */
list = lqr_vmap_list_next (list);
}
The maps will always be accessed in the order in which they were dumped.
Alternatively, one can apply a function to all the elements of the list, through this function:
LqrRetVal lqr_vmap_list_foreach( | LqrVMapList* | list, |
| LqrVMapFunc | func, | |
| gpointer | data); |
To use this second method, you'll need to define a function first, as in this sample code:
Example 2.8. Accessing visibility maps #2
LqrRetVal my_func (LqrVMap vmap, gpointer data)
{
/* ... do something on vmap ... */
return LQR_OK;
}
LqrVMapList *list;
list = lqr_vmap_list_start (carver);
lqr_vmap_list_foreach (list, my_func, NULL);
In the above example, no data is actually passed on to the function.
In actual code the call to lqr_vmap_list_foreach should be protected to
test its return value, which is LQR_OK if all my_func calls have been
successful, or it will hold the first non-successful return value from
my_func.
The LqrVMap objects contain an int buffer with the actual map data (plain array, ordered by row),
plus all the information needed to be able to recover it from scratch.
The information can be extracted with these functions:
gint*lqr_vmap_get_data(LqrVMap*vmap); gintlqr_vmap_get_width(LqrVMap*vmap); gintlqr_vmap_get_height(LqrVMap*vmap); gintlqr_vmap_get_orientation(LqrVMap*vmap); gintlqr_vmap_get_depth(LqrVMap*vmap);
The first one returns a pointer to the data buffer.
The orientation of the map is 0 if the map is to be used for horizontal rescaling, 1 otherwise.
The depth of the map is the maximum amount of rescaling possible with that map, either shrinking or enlarging.
Example 2.9. Reading visibility maps data
If we have a LqrVMap pointer called vmap, we could access the
value at (x,y) by:
gint *buffer;
gint width;
gint vis;
buffer = lqr_vmap_get_data (vmap);
width = lqr_vmap_get_width (vmap);
vis = buffer[y * width + x];
Uninitialised points will yield vis = 0. For
initialised points, vis will store a positive value between
1 (least visible points, the first to be carved away or to be duplicated)
and ( (most visible points, the last to be carved away
or to be duplicated).
depth + 1)
If the orientation is 0, the map allows resizing in the whole range form ( to width
- depth)(. If the
orientation is 1, the analogue formula holds with width + depth)height in place of width.
Having an LqrVMap object, one can load it in an LqrCarver simply by calling this function:
LqrRetVal lqr_vmap_load( | LqrCarver* | carver, |
| LqrVMap* | vmap); |
The carver must not to be initialised, neither before nor after invoking this function.
This implies that the map cannot be updated, and that it will only be possible to resize the
carver by an amount depth along the orientation given by
lqr_vmap_orientation. The enlargment step is also set to its maximum, 2.0.
Invoking lqr_carver_resize with an out-of-bounds argument results in a
fatal error (i.e. it returns LQR_ERROR).
Do not attach other carvers after you have loaded a visibility map (see also the Attaching extra images section).
Given an LqrCarver object, it is possible to attach an arbitrary number of extra carvers to it:
these will passively undergo the same carving process as the root carver. In order for this to be
possible, the carvers must be all of the same size.
The function to use is simply:
LqrRetVal lqr_carver_attach( | LqrCarver* | carver, |
| LqrCarver* | aux); |
This attaches aux to carver.
It is not necessary that the parent LqrCarver is activated. In fact, a carver can be attached to a
carver which is itself attached to another one.
Needless to say, no resizing operation should be done directly on an LqrCarver once it has been
attached to another LqrCarver, and neither should the cancel method be invoked directly on them.
The carvers always have to be attached before loading visibility maps.
Attached carvers can be read-out in the same way as their parents. There are however also methods
to span all them, in a way very similar to that in which internally dumped LqrVMap's are
accessed, but LqrVMapList objects are substitued in this case by LqrCarverList objects.
First, the starting point of the list has to be retreived through:
LqrCarverList* lqr_carver_list_start( | LqrCarver* | carver); |
Then, one can iterate through the attached carvers by using these two functions:
LqrCarver* lqr_carver_list_current( | LqrCarverList* | list); |
LqrCarverList* lqr_carver_list_next( | LqrCarverList* | list); |
Here is a sample code usage:
Example 2.10. Accessing attached carvers #1
LqrCarver *aux;
LqrCarverList *list;
list = lqr_carver_list_start (carver);
while (list) {
aux = lqr_carver_list_current (list);
/* ... do something on aux ... */
list = lqr_carver_list_next (list);
}
The carvers will always be accessed in the order in which they were attached.
Alternatively, one can apply a function to all the elements of the list (and recursively to all the elements of their attached lists, if there are any), through this function:
LqrRetVal lqr_carver_list_foreach_recursive( | LqrCarverList* | list, |
| LqrCarverFunc | func, | |
| LqrDataTok | data); |
To use this second method, you'll need to define a function first, as in the following sample code:
Example 2.11. Accessing attached carvers #2
LqrRetVal my_func (LqrCarver *aux, LqrDataTok data)
{
/* ... do something on aux ... */
return LQR_OK;
}
LqrCarverList *list;
LqrDataTok data_tok;
list = lqr_carver_list_start (carver);
data_tok->data = NULL;
lqr_carver_list_foreach_recursive (list, my_func, data_tok);
The data to be passed on to the LqrCarverFunc is of type LqrDataTok. This is defined as a union, with the following fields:
LqrCarver* carver
gint integer
gpointer data
In the above example, no data is actually passed on to the function.
In actual code, the call to lqr_carver_list_foreach_recursive should be
protected to test its return value, which is LQR_OK if all my_func calls have been successful
(or if the list is empty), or it will hold the first non-successful return value from
my_func.
By default, the resizing performed silently. However, it is possible to define progress report
functions, to receive feedback while the resizing is in progress. This is done through the LqrProgress
objects.
A LqrProgress object is created through the function:
LqrProgress* lqr_progress_new( | void); |
and can be associated to an LqrCarver object through this function:
void lqr_carver_set_progress( | LqrCarver* | carver, |
| LqrProgress* | p); |
Newly created progress objects are inactive, and need to be set up.
First, hook functions have to be set, which specify the action to take as the rescaling process starts, progresses, and ends, by using the functions:
LqrRetVallqr_progress_set_init(LqrProgress*p, LqrProgressFuncInitinit_func) LqrRetVallqr_progress_set_update(LqrProgress*p, LqrProgressFuncUpdateupdate_func) LqrRetVallqr_progress_set_end(LqrProgress*p, LqrProgressFuncEndend_func)
as in this sample piece of code:
Example 2.12. Setting progress hooks
LqrProgress *p;
p = lqr_progress_new();
lqr_progress_set_init (p, my_init);
lqr_progress_set_update (p, my_update);
lqr_progress_set_end (p, my_end);
The above example requires that the hook functions my_init,
my_update and my_end are defined as in the following
sample declarations:
Example 2.13. Progress hooks declaration
LqrRetVal my_init (const gchar *init_message);
LqrRetVal my_update (gdouble percentage);
LqrRetVal my_end (const gchar *end_message);
The init and end hooks will be called at the beginning and at the end of each rescaling operation by
function lqr_carver_resize. The messages that will be passed to these hooks
will change, depending if the resizing is occurring in the horizontal or in the vertical direction.
The defaults for newly created LqrProgress objects are:
Table 2.2. Default progress messages
| init | end | |
|---|---|---|
| horizontal | "Resizing width..." | "done" |
| vertical | "Resizing height..." | "done" |
These can be changed using these functions:
LqrRetVallqr_progress_set_init_width_message(LqrProgress*p, const gchar *message) LqrRetVallqr_progress_set_init_height_message(LqrProgress*p, const gchar *message) LqrRetVallqr_progress_set_end_width_message(LqrProgress*p, const gchar *message) LqrRetVallqr_progress_set_end_height_message(LqrProgress*p, const gchar *message)
LqrCarver objects can be destroyed using this function:
void lqr_carver_destroy( | LqrCarver* | carver); |
This function also destroys any attached object, thus it should never be called on attached carvers.
LqrVMap objects can be destroyed using this function:
void lqr_vmap_destroy( | LqrVMap* | vmap); |
Table of Contents
LqrRetVal — the return value of many Liquid Rescale library functions
The return type of many functions in the Liquid Rescale library is LqrRetVal, which is an
enum type that can take these values:
LQR_OKeveryting OK
LQR_ERRORgeneric fatal error
LQR_NOMEMnot enough memory
LQR_USRCANCELaction cancelled by the user
The user should handle the error values explicitly at each function call returning this type.
LqrColDepth — carver objects colour depth specification
The default LqrCarver object constructor lqr_carver_new uses a colour
depth of 8 bits per channel, and therefore its input must be an array of unsigned
chars. However, the LqrCarver objects can handle images of grater colour depth, if
they are created with the lqr_carver_new_ext constructor. The possible
colour depths are specified through variables of type LqrColDepth, which is an enum
type; its possible values, and the type of the input buffer associated with them, are:
LQR_COLDEPTH_8Iuse type guchar (8 bit unsigned integers) - the default
LQR_COLDEPTH_16Iuse type guint16 (16 bit unsigned integers)
LQR_COLDEPTH_32Fuse type gfloat (32 bit floating point)
LQR_COLDEPTH_64Fuse type gdouble (64 bit floating point)
These values are also relevant when reading out a LqrCarver object with the functions
lqr_carver_scan_ext or lqr_carver_scan_line_ext, since
the readout buffer must be cast to the appropriate type to be actually read.
The colour depth of an LqrCarver object can be obtained with the function
lqr_carver_get_col_depth.
LqrImageType — carver objects image type (colour model) specification
The LqrCarver objects use knowledge about the image type they're working on in order to compute
correctly some quantities (e.g. the brightness) for the automatic feature detection. Image types
are set automatically by the constructors, but they can also be specified manually using
quantities of the type LqrImageType, which is an enum which can
take these values:
LQR_GREY_IMAGELQR_GREYA_IMAGELQR_RGB_IMAGELQR_RGBA_IMAGELQR_CMY_IMAGELQR_CMYK_IMAGELQR_CMYKA_IMAGELQR_CUSTOM_IMAGE
Use the function lqr_carver_set_image_type(3) to set the image type of
a carver, and the function lqr_carver_get_image_type(3) to read it out.
lqr_carver_new — the LqrCarver object constructorslqr_carver_destroy — the LqrCarver object destructorlqr_carver_init — activates an LqrCarver objectlqr_carver_set_image_type — sets the image type of an LqrCarver objectlqr_carver_set_alpha_channel — sets the alpha channel index in a LqrCarver objectlqr_carver_set_black_channel — sets the black channel index in a LqrCarver objectlqr_carver_resize — liquid rescale a LqrCarver objectlqr_carver_flatten — flatten a LqrCarver objectlqr_carver_cancel — cancel ongoing operations on a LqrCarver objectlqr_carver_scan_reset — reset the readout cursor of a multi-size imagelqr_carver_scan — read out a multi-size image one pixel at a timelqr_carver_scan_by_row — tells if the image in LqrCarver will be scanned by row or by columnlqr_carver_scan_line — read out a multi-size image one line at a timelqr_carver_get_width — get the current width of a LqrCarver objectlqr_carver_get_height — get the current height of a LqrCarver objectlqr_carver_get_ref_width — get the reference width of a LqrCarver objectlqr_carver_get_ref_height — get the reference height of a LqrCarver objectlqr_carver_get_channels — get the number of channels in a LqrCarver objectlqr_carver_get_col_depth — get the colour depth of a LqrCarver objectlqr_carver_get_image_type — get the image type of a LqrCarver objectlqr_carver_get_enl_step — get the enlargement step of a LqrCarver objectlqr_carver_get_orientation — get the orientation of a LqrCarver objectlqr_carver_get_depth — get the depth of a LqrCarver objectlqr_carver_set_enl_step — set the enlargement step of a LqrCarver objectlqr_carver_set_resize_order — set LqrCarver object resize orderlqr_carver_set_dump_vmaps — set the visibility maps autodump for an LqrCarver objectlqr_carver_set_side_switch_frequency — set LqrCarver object side switch frequencylqr_carver_set_progress — set the progress report function for an LqrCarver objectlqr_carver_set_preserve_input_image — set a flag to preserve the buffer passed to a LqrCarver object upon creationlqr_carver_set_use_cache — enable/disable LqrCarver object cachelqr_carver_attach — attach an LqrCarver to another LqrCarverlqr_carver_list_start — get the staritng point of the attachement list in an LqrCarver objectlqr_carver_list_current — get current LqrCarver object in a LqrCarverList objectlqr_carver_list_next — advance the LqrCarverList objectlqr_carver_list_foreach — perform operations on all LqrCarver objects in an LqrCarverList objectlqr_carver_new, lqr_carver_new_ext — the LqrCarver object constructors
#include <lqr.h>
LqrCarver* lqr_carver_new( | guchar* | buffer, |
| gint | width, | |
| gint | height, | |
| gint | channels); |
LqrCarver* lqr_carver_new_ext( | void* | buffer, |
| gint | width, | |
| gint | height, | |
| gint | channels, | |
| LqrColDepth | colour_depth); |
The functions lqr_carver_new and lqr_carver_new_ext
create a new LqrCarver object from an image of size width * height with channels
colour channels.
The image must be stored in buffer as a plain array of unsigned chars
(for lqr_carver_new) or the appropriate type cast to void (for
lqr_carver_new_ext), ordered by row, then by column, then by colour
channel.
In the extended constructor lqr_carver_new_ext, the additional parameter
colour_depth is required to specify the colour depth of the buffer (see
LqrColDepth(3) for more information).
After calling the function, the buffer will be owned by the LqrCarver object and must not be
accessed any more, unless you subsequently call the lqr_carver_set_preserve_input_image(3) function.
The image type is et automatically from the value of channels according
to this table:
Table 3.1. Image types assigned by default
| channels | type |
|---|---|
| 1 | LQR_GREY_IMAGE |
| 2 | LQR_GREYA_IMAGE |
| 3 | LQR_RGB_IMAGE |
| 4 | LQR_RGBA_IMAGE |
| 5 | LQR_CMYKA_IMAGE |
| >5 | LQR_CUSTOM_IMAGE |
lqr_carver_destroy — the LqrCarver object destructor
#include <lqr.h>
void lqr_carver_destroy( | LqrCarver* | carver); |
The function lqr_carver_destroy destroys the LqrCarver object pointed to
by carver, and all of its attched components (visibility maps and
attached carvers). It must never be invoked over a carver which is attached to another one.
This function will not release the memory buffer passed to
lqr_carver_new(3) if it was protected by calling
lqr_carver_set_preserve_input_image(3).
lqr_carver_init — activates an LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_init( | LqrCarver* | carver, |
| gint | delta_x, | |
| gfloat | rigidity); |
The function lqr_carver_init initialises the LqrCarver pointed to by
carver, so that it can compute the visibility maps as needed upon calls
of lqr_carver_resize.
The parameter delta_x controls the maximum transversal step a seam can
make. A value of 0 means straight seams. Normally, it is set to 1.
The parameter rigidity can be used to add a negative bias to non-straight
seams, and it is normally set to 0.
Visibility maps must not be loaded with the function lqr_vmap_load when
using this function, neither before nor after invoking it.
lqr_carver_set_image_type — sets the image type of an LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_set_image_type( | LqrCarver* | carver, |
| LqrImageType | image_type); |
The function lqr_carver_set_image_type sets the image type of the
LqrCarver pointed to by carver to image_type.
If image_type is equal to LQR_CUSTOM_IMAGE, it is assumed that there are
no alpha or black channels. You can set those independently using
lqr_carver_set_alpha_channel(3) and
lqr_carver_set_black_channel(3).
lqr_carver_set_alpha_channel — sets the alpha channel index in a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_set_alpha_channel( | LqrCarver * | carver, |
| gint | channel_index); |
The function lqr_carver_set_alpha_channel sets the alpha channel index of
the image stored in the LqrCarver pointed to by carver to
channel_index (between 0 and channels -
1, where channels is the number of colour channels of the
carver).
Use a negative value for cahnnel_index to specify that no alpha channel
is present.
If the specified channel coincides with the current value of the black channel, the black channel is unset.
Calling this function sets the image time of the carver to
LQR_CUSTOM_IMAGE.
lqr_carver_set_black_channel — sets the black channel index in a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_set_black_channel( | LqrCarver * | carver, |
| gint | channel_index); |
The function lqr_carver_set_black_channel sets the black channel index of
the image stored in the LqrCarver pointed to by carver to
channel_index (between 0 and channels -
1, where channels is the number of colour channels of the
carver).
Use a negative value for cahnnel_index to specify that no black channel
is present.
If the specified channel coincides with the current value of the alpha channel, the alpha channel is unset.
Calling this function sets the image time of the carver to
LQR_CUSTOM_IMAGE. Furthermore, the image color model will be assumed to be subtractive by the
function lqr_rwindow_read(3) when it computes the brightness or the luma.
lqr_carver_resize — liquid rescale a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_resize( | LqrCarver* | carver, |
| gint | new_width, | |
| gint | new_height); |
The function lqr_carver_resize performs the liquid rescaling over the
LqrCarver object pointed to by carver. If a visibility map was loaded
through the function lqr_vmap_load, and the carver was not initialised, the
resizing operations must be limited to the direction and the sizes included in the loaded map.
If the carver was initialised through the function lqr_carver_init, there
are no limitations to the final size.
The resizing function can be called multiple times, and it will decide automatically whether the
computation of the visibility map is necessary or not. In case it isn't, the function returns
almost immediately, otherwise operations will proceed following the order given through the
function lqr_carver_set_resize_order. Currently, on-the-fly rescaling
without computation is only possible for a single direction at a time.
If the new size (in one direction or in both) is greater than or equal to the original size
multiplied by the enlargement step of the carver object (as obtained
through lqr_carver_get_enl_step(3)), the rescaling will be performed in
multiple steps. At each step, the original size stored internally is reset to the new value;
therefore, each step in the process can be bigger then the previous one.
Whenever the resizing dirction changes (this may happen in a single call of the rescaling
function or through multiple calls), or if performing a multiple steps enlargement as per the
previous paragraph, the visibility map computed during the first direction rescale is dropped to
make place for the one for the second (and the original size of the image is reset to the
current value). These visibility maps can be saved by using the
lqr_carver_set_vmap_dump function, for inspection or future use.
lqr_carver_flatten — flatten a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_flatten( | LqrCarver* | carver); |
The function lqr_carver_flatten can be used to discard the visibility map
information and flatten the multi-size image contained in the LqrCarver object pointed to by
carver to its current state.
It will also reset the internally stored original width and height, as if the image was just
loaded in the LqrCarver object.
This function must only be invoked over initialised LqrCarver objects.
This function is called internally each time the rescaling direction changes, or at each new
step in a multiple-step enlargement, but, when calling it manually, the discarded visibility map
will not be dumped automatically by it; use the functions
lqr_vmap_dump(3) or lqr_vmap_internal_dump(3)
in order to save it before invoking this function.
lqr_carver_cancel — cancel ongoing operations on a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_cancel( | LqrCarver* | carver); |
The function lqr_carver_cancel can be used to cancel an ongoing operation
which is currently being performed on the the LqrCarver object pointed to by
carver. It must be used asynchronouly, from within an independent thread.
If an operation is in fact cancelled by this function, the function which was performing the
operation will return the value LQR_USRCANCEL, and so will do any other operation successively
called on the same LqrCarver object whose return type is LqrRetVal;
otherwise it will have no effect.
Whenever a function returns LQR_USRCANCEL, it means that the LqrCarver object is in an
inconsistent state, and, since there is currently no way to recover from this situation, any
further operation on that object must be avoided, and it must be destroyed.
This function will fail if invoked over attached LqrCarver objects.
lqr_carver_scan_reset — reset the readout cursor of a multi-size image
#include <lqr.h>
void lqr_carver_scan_reset( | LqrCarver* | carver); |
The function lqr_carver_scan_reset resets the readout pointer associated
with the LqrCarver object pointed to by carver to the start of the
image. (Normally, calling this function isn't needed, as the pointer is reset automatically
whenever an operation is performed or once a readout has completed.)
lqr_carver_scan, lqr_carver_scan_ext — read out a multi-size image one pixel at a time
#include <lqr.h>
gboolean lqr_carver_scan( | LqrCarver* | carver, |
| gint* | x, | |
| gint* | y, | |
| guchar** | rgb); |
gboolean lqr_carver_scan_ext( | LqrCarver* | carver, |
| gint* | x, | |
| gint* | y, | |
| void** | rgb); |
The functions lqr_carver_scan and lqr_carver_scan_ext
are used to read out the multi-size image contained in the LqrCarver object pointed to by
carver one pixel at a time. They store the pixel coordinates in the
variables pointed to by x and y, and the pixel
content in the array pointed to by rgb; then they move the readout
pointer to the next pixel, or they reset it if the end of the image is reached.
The first one must only be used on the LqrCarver objects created with
lqr_carver_new, i.e. with 8-bit images, while the second one is general
(see LqrColDepth(3)), but the rgb pointer must
be cast to the appropriate type to be used (i.e pass the address of a pointer to
void to the function lqr_carver_scan_ext, then cast it
to a pointer of the appropriate type and use this last one for reading the output).
The rgb variable will point to an array which is internal to the
LqrCarver object, so there is no need to allocate memory for it. However, it should only be
accessed right after a call to the scan functions, and writing to it must be avoided.
lqr_carver_scan_by_row — tells if the image in LqrCarver will be scanned by row or by column
#include <lqr.h>
gboolean lqr_carver_scan_by_row( | LqrCarver* | carver); |
The function lqr_carver_scan_by_row must be used before calling the
functions
lqr_carver_scan_line and
lqr_carver_scan_line_ext,
in order to ascertain if those functions will scan the multi-size image contained in the
LqrCarver object pointed to by carver by row or by column, which depends
on which was last rescaling direction and cannot be controlled directly by the user.
lqr_carver_scan_line, lqr_carver_scan_line_ext — read out a multi-size image one line at a time
#include <lqr.h>
gboolean lqr_carver_scan_line( | LqrCarver* | carver, |
| gint* | n, | |
| guchar** | rgb); |
gboolean lqr_carver_scan_line_ext( | LqrCarver* | carver, |
| gint* | n, | |
| void** | rgb); |
The functions lqr_carver_scan_line and
lqr_carver_scan_line_ext are used to read out the multi-size image
contained in the LqrCarver object pointed to by carver one line at a
time. They store the line number (row or column) in the variable pointed to by
n and the colour values in the array pointed to by
rgb; then they move the readout pointer to the next line, or they reset
it if the end of the image is reached.
The first one must only be used on the LqrCarver objects created with
lqr_carver_new, i.e. with 8-bit images, while the second one is general,
but the rgb pointer must be cast to the appropriate type to be used (i.e
pass the address of a pointer to void to the function
lqr_carver_scan_line_ext, then cast it to a pointer of the appropriate type
and use this last one for reading the output).
Use the function lqr_carver_scan_by_row(3) before calling these to know
whether your image will be scanned by row or by column.
lqr_carver_get_width — get the current width of a LqrCarver object
#include <lqr.h>
gint lqr_carver_get_width( | LqrCarver* | carver); |
lqr_carver_get_height — get the current height of a LqrCarver object
#include <lqr.h>
gint lqr_carver_get_height( | LqrCarver* | carver); |
lqr_carver_get_ref_width — get the reference width of a LqrCarver object
#include <lqr.h>
gint lqr_carver_get_ref_width( | LqrCarver* | carver); |
The function lqr_carver_get_ref_width returns the internal reference width
of the image contained in the LqrCarver object pointed to by carver, in
pixel units.
The reference width is set as the original height at carver initialization, and reset any time
the carver gets subsequently flattened, either explicitly through lqr_carver_flatten(3) or implicitly when the rescale direction changes or
an enlargment beyond the maximum enlargement step is performed.
lqr_carver_get_ref_height — get the reference height of a LqrCarver object
#include <lqr.h>
gint lqr_carver_get_ref_height( | LqrCarver* | carver); |
The function lqr_carver_get_ref_height returns the internal reference
height of the image contained in the LqrCarver object pointed to by
carver, in pixel units.
The reference height is set as the original height at carver initialization, and reset any time
the carver gets subsequently flattened, either explicitly through lqr_carver_flatten(3) or implicitly when the rescale direction changes or
an enlargment beyond the maximum enlargement step is performed.
lqr_carver_get_channels, lqr_carver_get_bpp — get the number of channels in a LqrCarver object
#include <lqr.h>
gint lqr_carver_get_channels( | LqrCarver* | carver); |
gint lqr_carver_get_bpp( | LqrCarver* | carver); |
The functions lqr_carver_get_channels returns the number of colour channels
of the image contained in the LqrCarver object pointed to by carver.
The function lqr_carver_get_bpp is an alias for
lqr_carver_get_channels, it is deprecated and it is maintained for backward
compatibility purposes only.
lqr_carver_get_col_depth — get the colour depth of a LqrCarver object
#include <lqr.h>
LqrColDepth lqr_carver_get_col_depth( | LqrCarver* | carver); |
lqr_carver_get_image_type — get the image type of a LqrCarver object
#include <lqr.h>
LqrImageType lqr_carver_get_image_type( | LqrCarver* | carver); |
lqr_carver_get_enl_step — get the enlargement step of a LqrCarver object
#include <lqr.h>
gfloat lqr_carver_get_enl_step( | LqrCarver* | carver); |
The function lqr_carver_get_enl_step returns the enlargement step of the
LqrCarver object pointed to by carver, i.e. the maximum enlargement
allowed in a single step for that carver, expressed as the ratio with respect to its reference
width (for horizontal rescalings) or height (for vertical rescalings). The returned value is
strictly greater than 1 and less than 2.
lqr_carver_get_orientation — get the orientation of a LqrCarver object
#include <lqr.h>
gint lqr_carver_get_orientation( | LqrCarver* | carver); |
lqr_carver_get_depth — get the depth of a LqrCarver object
#include <lqr.h>
gint lqr_carver_get_depth( | LqrCarver* | carver); |
The function lqr_carver_get_depth returns the current depth of the
visibility map internal to the LqrCarver object pointed to by vmap, i.e.
the maximum amount of scaling which can be performed with respect to the internal reference
sizes in the current orientation without updating the internal map.
lqr_carver_get_width(3), lqr_carver_get_height(3), lqr_carver_get_ref_width(3), lqr_carver_get_ref_height(3), lqr_carver_get_channels(3), lqr_carver_get_col_depth(3), lqr_carver_set_enl_step(3), lqr_carver_resize(3), lqr_carver_get_enl_step(3), lqr_carver_get_orientation(3), lqr_vmap_get_depth(3)
lqr_carver_set_enl_step — set the enlargement step of a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_set_enl_step( | LqrCarver* | carver, |
| gfloat | enl_step); |
The function lqr_carver_set_enl_step sets the enlargement step of the
LqrCarver object pointed to by carver to the value specified in
enl_step, which must be strictly greater than 1 and less than 2.
The enlargement step is the maximum enlargement ratio (with respect to either the original width
or original height of carver) which the function
lqr_carver_resize applies in a single step; if that function is asked a
greater enlargement, it divides the process in multiple steps (and updates the original sizes
accordingly at each new step - these can be readout at any time with
lqr_carver_get_ref_width(3) and
lqr_carver_get_ref_height(3)).
The default value for new LqrCarver objects is 2.0.
lqr_carver_set_resize_order — set LqrCarver object resize order
#include <lqr.h>
void lqr_carver_set_resize_order( | LqrCarver* | carver, |
| LqrResizeOrder | resize_order); |
When the function lqr_carver_resize(3) is invoked and both the
horizontal and vertical sizes are different from the current ones, the rescaling occurs first in
one direction and then in the other.
The function lqr_carver_set_resize_order can be used to set which direction
to rescale first for the LqrCarver object pointed to by carver. The
parameter resize_order can take either the value
LQR_RES_ORDER_HOR (horizontal rescale first) or
LQR_RES_ORDER_VERT (vertical rescale first). By default, when an LqrCarver
object is created, the value is set to LQR_RES_ORDER_HOR
lqr_carver_set_dump_vmaps, lqr_carver_set_no_dump_vmaps — set the visibility maps autodump for an LqrCarver object
#include <lqr.h>
void lqr_carver_set_dump_vmaps( | LqrCarver* | carver); |
void lqr_carver_set_no_dump_vmaps( | LqrCarver* | carver); |
Invoking function lqr_carver_set_dump_vmaps over the LqrCarver object
pointed to by carver has the effect of activating the automatic dumping
of visibility maps at each rescale operation (which by default is turned off).
Rescale operations involving both directions will dump two maps.
The dumped maps will be attached to the LqrCarver object and can be accessed at any later time
using the functions lqr_vmap_list_foreach(3) or a combination of
lqr_vmap_list_start(3), lqr_vmap_list_current(3)
and lqr_vmap_list_next(3).
Using this setting is pointless if the LqrCarver object is not initialised.
The function lqr_carver_set_no_dump_vmaps reverts the effect of the
previous one (but the maps dumped so far will be kept).
Note that it is also possible to dump the visibility maps manually; however, using the automatic
dump is the only way to get intermidiate maps when the function
lqr_carver_resize(3) performs the rescaling in both directions, or in
more than one step.
lqr_carver_init(3), lqr_carver_resize(3), lqr_carver_set_enl_step(3), lqr_carver_set_resize_order(3), lqr_carver_set_side_switch_frequency(3), lqr_carver_set_progress(3), lqr_carver_set_preserve_input_image(3), lqr_vmap_list_start(3), lqr_vmap_list_current(3), lqr_vmap_list_next(3), lqr_vmap_list_foreach(3), lqr_carver_set_use_cache(3)
lqr_carver_set_side_switch_frequency — set LqrCarver object side switch frequency
#include <lqr.h>
void lqr_carver_set_side_switch_frequency( | LqrCarver* | carver, |
| guint | switch_frequency); |
When the function lqr_carver_resize(3) is invoked, it computes a
relevance value for each pixel in the image, then chooses the optimal seam to carve based on
such relvance values. However, in the case two seams are equivalent (which may happen when
large portions of the image have the same colour, for example), the algorithm always chooses the
seams from one side.
In order to overcome this effect, an option is given to automatically switch the favoured side during rescaling, at the cost of a slightly worse performance.
The function lqr_carver_set_side_switch_frequency sets the side switch
frequency to switch_frequency for the LqrCarver object pointed to by
carver. This will have the effect that, for each rescale operation, the
favoured side will be switched switch_frequency times (or as much times
as the number of pixels to rescale).
The default value for newly created LqrCarver objects is 0.
As for the final result, a very small value (e.g. 1)
will normally suffice to balance the left and right side of the image (or the top and the boddom
sides for vertical rescalings), without noticeable computational costs. However, in order to
obtain a smoother behaviour for the visibiliy map, i.e. for the intermediate steps, higher
values may be required.
to 4
lqr_carver_set_progress — set the progress report function for an LqrCarver object
#include <lqr.h>
void lqr_carver_set_progress( | LqrCarver* | carver, |
| LqrProgress* | p); |
The function lqr_carver_set_progress associates the progress indicator
pointed to by progress to the LqrCarver object pointed to by
carver. Progress indicators objects are created with the function
lqr_progress_new(3).
By default, no progress indicator is used.
lqr_carver_set_preserve_input_image — set a flag to preserve the buffer passed to a LqrCarver object upon creation
#include <lqr.h>
void lqr_carver_set_preserve_input_image( | LqrCarver* | carver); |
The function lqr_carver_set_preserve_input_image flags the LqrCarver
object pointed to by carver so that it does not alter in any way the
buffer which is passed to it by the constructor. It must be used before any resizing-related
operation takes place, either after the carver construction or after the
calls to lqr_carver_init(3) or
lqr_vmap_load(3).
lqr_carver_set_use_cache — enable/disable LqrCarver object cache
#include <lqr.h>
void lqr_carver_set_use_cache( | LqrCarver* | carver, |
| gboolean | use_cache); |
lqr_carver_attach — attach an LqrCarver to another LqrCarver
#include <lqr.h>
LqrRetVal lqr_carver_attach( | LqrCarver* | carver, |
| LqrCarver* | aux); |
The function lqr_carver_attach is used to attach an LqrCarver object
(pointed to by aux) to another one (pointed to by
carver). This will have the effect that each operation performed over
the carver object will be reflected on aux (they
will share the same visibility map).
This function must not be used after a visibility map was loaded into the base object (the one
pointed to by carver).
The object pointed to by aux must have the same original size as the base
object. Note that the original size information is reset whenever a flattening operation
occurs, or the rescaling direction changes, so that this function should be called befor
rescaling occurs.
There is no limitation on the number of LqrCarver objects which is possible to attach. Nesting
is also possible. It is irrelevant if the aux carver is initialised or
not; from the moment of attachment, it will passively undergo all transformations performed over
carver.
lqr_carver_list_start — get the staritng point of the attachement list in an LqrCarver object
#include <lqr.h>
LqrCarverList* lqr_carver_list_start( | LqrCarver* | carver); |
The function lqr_carver_list_start returns the stating point of the
LqrCarverList object associated with the LqrCarver object pointed to by
carver, which is used to keep track of the LqrCarver objects attached to
it.
The returned value is NULL if there are no attached carvers.
Use the functions lqr_carver_list_current(3) and
lqr_carver_list_next(3) to access the list element individually, or the
function lqr_carver_list_foreach(3) to operate on whole lists.
lqr_carver_list_current — get current LqrCarver object in a LqrCarverList object
#include <lqr.h>
LqrCarver* lqr_carver_list_current( | LqrCarverList* | list); |
lqr_carver_list_next — advance the LqrCarverList object
#include <lqr.h>
LqrCarverList* lqr_carver_list_next( | LqrCarverList* | list); |
lqr_carver_list_foreach — perform operations on all LqrCarver objects in an LqrCarverList object
#include <lqr.h>
LqrRetVal lqr_carver_list_foreach( | LqrCarverList* | list, |
| LqrCarverFunc | func, | |
| LqrDataTok | data); |
LqrRetVal lqr_carver_list_foreach_recursive( | LqrCarverList* | list, |
| LqrCarverFunc | func, | |
| LqrDataTok | data); |
The function lqr_carver_list_foreach can be used to apply the function
func to all the LqrCarver objects listed in list.
The parameter data is used to pass arguments to the function.
The list value should be obtained through the function
lqr_carver_list_start(3). The order in the list will then follow the one
in which carver objects were attached.
The function func is of type LqrCarverFunc, whose
prototype is defined by:
typedef LqrRetVal (*LqrCarverFunc) (LqrCarver *carver, LqrDataTok data);
The data argument is of type LqrDataTok, which
is defined as a union with the following fields:
LqrCarver* carver
gint integer
gpointer data
The function lqr_carver_list_foreach_recursive is equivelant to
lqr_carver_list_foreach, but it works recursively if the LqrCarver objects
in list have themselves other attached LqrCarver objects attached. In
this case, the function func will be applied to each element of the list
and to each element of the attached list recursively, before moving on to the next element.
lqr_vmap_new — the LqrVMap object constructorlqr_vmap_destroy — the LqrVMap object destructorlqr_vmap_get_data — get varous LqrVMap object quantitieslqr_vmap_get_depth — get the depth of an LqrVMap objectlqr_vmap_get_width — get the width of an LqrVMap objectlqr_vmap_get_height — get the height of an LqrVMap objectlqr_vmap_get_orientation — get the orientation of an LqrVMap objectlqr_vmap_dump — dump an LqrVMap objectlqr_vmap_internal_dump — dump an LqrVMap objects into an LqrCarver objectlqr_vmap_load — load an LqrVMap object into an LqrCarver objectlqr_vmap_list_start — get the LqrVMapList list attached to an LqrCarverlqr_vmap_list_current — get current LqrVMap object in a LqrVMapList objectlqr_vmap_list_next — advance the LqrVMapList objectlqr_vmap_list_foreach — perform operations on all LqrVMap objects in an LqrVMapList objectlqr_vmap_new — the LqrVMap object constructor
#include <lqr.h>
LqrVMap* lqr_vmap_new( | gint* | buffer, |
| gint | width, | |
| gint | height, | |
| gint | depth, | |
| gint | orientation); |
The function lqr_vmap_new is the constructor for LqrVMap objects. It can
be used to convert saved data in a format which can be loaded in an LqrCarver object.
The parameter buffer must point to an an array of
ints holding the visibility information.
width * height
The parameter depth represents the maximum possible amount of rescaling
with the given map.
The parameter orientation must be 0 if the map is to
be used for horizontal rescaling, 1 if it is to be used for vertical
rescaling.
The buffer must be an array of integers of size
. For an
horizontally oriented visibility map, the format is as such: each row must contain all values
between 1 and width * heightdepth (included) exactly once, with low values indicating
the pixels which will be operated on first during rescaling. All other pixels must be 0, which
means that they won't be affected by rescaling. Such a map allows for horizontal rescaling in
the range from to
width - depth. The same
applies to vertically oriented visibility maps, with columns in place of rows and
width + depthheight in place of width.
lqr_vmap_destroy — the LqrVMap object destructor
#include <lqr.h>
void lqr_vmap_destroy( | LqrVMap* | vmap); |
lqr_vmap_get_data — get varous LqrVMap object quantities
#include <lqr.h>
gint* lqr_vmap_get_data( | LqrVMap* | vmap); |
The function lqr_vmap_get_data returns an array with the data stored into
the LqrVMap object pointed to by vmap, ordered first by row, then by
column.
Reading the data requires retrieval of the other quantities, through the functions
lqr_vmap_get_depth(3),
lqr_vmap_get_width(3),
lqr_vmap_get_height(3) and
lqr_vmap_get_orientation(3).
See the LqrVMap objects format description in the page for
lqr_vmap_new(3).
lqr_vmap_get_depth — get the depth of an LqrVMap object
#include <lqr.h>
gint lqr_vmap_get_depth( | LqrVMap* | vmap); |
The function lqr_vmap_get_depth returns the depth of the LqrVMap object
pointed to by vmap, i.e. the maximum scaling allowed by it.
See the LqrVMap objects format description in the page for
LqrVMap constructor and destructor.
lqr_vmap_get_width — get the width of an LqrVMap object
#include <lqr.h>
gint lqr_vmap_get_width( | LqrVMap* | vmap); |
The function lqr_vmap_get_width returns the width of the LqrVMap object
pointed to by vmap.
See the LqrVMap objects format description in the page for
LqrVMap constructor and destructor.
lqr_vmap_get_height — get the height of an LqrVMap object
#include <lqr.h>
gint lqr_vmap_get_height( | LqrVMap* | vmap); |
The function lqr_vmap_get_height returns the height of the LqrVMap
object pointed to by vmap.
See the LqrVMap objects format description in the page for
LqrVMap constructor and destructor.
lqr_vmap_get_orientation — get the orientation of an LqrVMap object
#include <lqr.h>
gint lqr_vmap_get_orientation( | LqrVMap* | vmap); |
The function lqr_vmap_get_orientation returns the orientation of the
LqrVMap object pointed to by vmap, which is 0 for
horizontally oriented maps, 1 for vertically oriented ones.
See the LqrVMap objects format description in the page for
LqrVMap constructor and destructor.
lqr_vmap_dump — dump an LqrVMap object
#include <lqr.h>
LqrVMap* lqr_vmap_dump( | LqrCarver* | carver); |
lqr_vmap_internal_dump — dump an LqrVMap objects into an LqrCarver object
#include <lqr.h>
LqrRetVal lqr_vmap_internal_dump( | LqrCarver* | carver); |
The function lqr_vmap_internal_dump dumps the current visibility map of the
LqrCarver object pointed to by carver internally to it, attaching it to
the same LqrVMapList object list as the one used for automatic dumping (as activated by
lqr_carver_set_dump_vmaps(3).
lqr_vmap_load — load an LqrVMap object into an LqrCarver object
#include <lqr.h>
LqrRetVal lqr_vmap_load( | LqrCarver* | carver, |
| LqrVMap* | vmap); |
The function lqr_vmap_load loads the visibility map contained in the
LqrVMap object pointed to by vmap in the LqrCarver object pointed to
by carver.
It can only be called over uninitialised carver objects, therefore care must be taken not to
exceed the loaded map depth when resizing (see the LqrVMap objects format description in the
page for lqr_vmap_new(3)).
The return value follows the Liquid Rescale library signalling system.
lqr_vmap_list_start — get the LqrVMapList list attached to an LqrCarver
#include <lqr.h>
LqrVMapList* lqr_vmap_list_start( | LqrCarver* | carver); |
The function lqr_vmap_list_start returns the stating point of the
LqrVMapList object associated with the LqrCarver object pointed to by
carver, which is used to keep track of the LqrVMap objects internally
dumped by it.
The returned value is NULL if there are no dumped visibility maps.
The function lqr_vmap_list_current returns the LqrVMap object
corresponding to the current value of the list parameter, or NULL
in case of errors.
Use the functions lqr_vmap_list_current(3) and
lqr_vmap_list_next(3) to access the list element individually, or the
function lqr_vmap_list_foreach(3) to operate on whole lists.
lqr_vmap_list_current — get current LqrVMap object in a LqrVMapList object
#include <lqr.h>
LqrVMap lqr_vmap_list_current( | LqrVMapList* | list); |
lqr_vmap_list_next — advance the LqrVMapList object
#include <lqr.h>
LqrVMapList lqr_vmap_list_next( | LqrVMapList* | list); |
lqr_vmap_list_foreach — perform operations on all LqrVMap objects in an LqrVMapList object
#include <lqr.h>
LqrRetVal lqr_vmap_list_foreach( | LqrVMapList* | list, |
| LqrVMapFunc | func, | |
| gpointer | data); |
The function lqr_vmap_list_foreach can be used to apply the function
func to all the LqrVMap objects listed in list.
The parameter data is used to pass arguments to the function.
The list value should be obtained through the function
lqr_vmap_list_start(3).
The function func is of type LqrVMapFunc, whose
prototype is defined by:
typedef LqrRetVal (*LqrVMapFunc) (LqrVMap *vmap, gpointer data);
The data argument is of type gpointer, which is
just a pointer to void.
lqr_carver_set_energy_function_builtin — set a builtin energy function for a LqrCarver objectlqr_carver_set_energy_function — set a custom energy function for a LqrCarver objectlqr_carver_get_energy — get the energy map for a LqrCarver objectlqr_rwindow_read — read the content of a LqrReadingWindow objectlqr_rwindow_get_read_t — get the reader type of a LqrReadingWindow objectlqr_rwindow_get_radius — get the size of the region accessible from a LqrReadingWindow objectlqr_rwindow_get_channels — get the number of channels of a LqrReadingWindow objectlqr_carver_set_gradient_function — set the gradient function for an LqrCarver objectlqr_carver_bias_set_energy_function_builtin — set a builtin energy function for a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_set_energy_function_builtin( | LqrCarver* | carver, |
| LqrEnergyFuncBuiltinType | ef_ind); |
The function lqr_carver_set_energy_function_builtin allows to pick a
builtin energy function for the LqrCarver object pointed to by carver.
The possible values for ef_ind are:
LQR_EF_GRAD_XABSabsolute value of the brightness gradient in the direction of the rescaling (this is the default)
LQR_EF_GRAD_SUMABSsum of absolute values of the brightness gradients in both directions
LQR_EF_GRAD_NORMnorm of the brightness gradient
LQR_EF_LUMA_GRAD_XABSabsolute value of the luma gradient in the direction of the rescaling
LQR_EF_LUMA_GRAD_SUMABSsum of absolute values of the luma gradients in both directions
LQR_EF_LUMA_GRAD_NORMnorm of the luma gradient
LQR_EF_NULLnull
All of the above gradient functions have a radius of 1 pixel.
lqr_carver_bias_set_energy_function — set a custom energy function for a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_set_energy_function( | LqrCarver* | carver, |
| LqrEnergyFunc | en_func, | |
| gint | radius, | |
| LqrEnergyReaderType | reader_type, | |
| gpointer | extra_data); |
The function lqr_carver_set_energy_function assigns the energy function
en_func to the LqrCarver object pointed to by
carver (see below for more details on custom functions definitions).
The parameter radius determines the size of the square region which
affects the computation around each pixel (the side of the square will be 2 *
pixels long).
radius + 1
The parameter reader_type sets the reader type used when reading the
image, and therefore it determines what quantity will be passed on to the function
en_func (see below for more details on reader types).
The parameter extra_data is a (void) pointer which can be used to pass on
additional values to the function ef_func.
The function en_func must be of type
LqrEnergyFunc, whose prototype is defined by:
typedef gfloat (*LqrEnergyFunc) (gint x, gint y, gint img_width, gint img_height, LqrReadingWindow * rwindow, gpointer extra_data);
Such a function is expected to compute the energy at pixel x, y based on the
knowledge of the current image size (obtained from width and height) and the content of
the image in a square around that pixel, which is passed through the
rwindow reading window.
In most cases, the parameters x, y, width and height would only be used
to determine whether the region under consideration is at the image boundary or not.
The rwindow content must be read using the function
lqr_rwindow_read(3).
The LqrEnergyReaderType is an enum which can take these values
(also noted is the number of channels of the corresponging reading window):
LQR_ER_BRIGHTNESSbrightness (1 channel)
LQR_ER_BRIGHTNESSluma (1 channel)
LQR_ER_RGBARGBA (4 channels)
LQR_ER_CUSTOMread the normalised image channels as they are (as many channels as the image has)
These readouts always return values beetween 0 and 1.
Note that these readouts may have special meanings depending on the image type:
for LQR_GREY_IMAGE, LQR_GREYA_IMAGE and
LQR_CUSTOM_IMAGE images, the LQR_ER_LUMA
readout will yield the same result as LQR_ER_BRIGHTNESS
for LQR_CUSTOM_IMAGE images, the LQR_ER_BRIGHTNESS
readout will return the average pixel value (additive, i.e. if a black channel is
present the channel values will be inverted and multiplied by the black channel
inverse), multiplied by the alpha channel value.
for LQR_CUSTOM_IMAGE images, the LQR_ER_RGBA
readout cannot be used: it will always return
0
lqr_carver_get_energy, lqr_carver_get_true_energy, lqr_carver_get_energy_image — get the energy map for a LqrCarver object
#include <lqr.h>
LqrRetVal lqr_carver_get_energy( | LqrCarver* | carver, |
| gfloat * | buffer, | |
| gint | orientation); |
#include <lqr.h>
LqrRetVal lqr_carver_get_true_energy( | LqrCarver* | carver, |
| gfloat * | buffer, | |
| gint | orientation); |
#include <lqr.h>
LqrRetVal lqr_carver_get_energy( | LqrCarver* | carver, |
| void * | buffer, | |
| gint | orientation, | |
| LqrColDepth | col_depth, | |
| LqrImageType | image_type); |
The function lqr_carver_get_energy writes the energy map of the LqrCarver
object pointed to by carver to the given buffer,
in a format suitable for plotting: all values are in the range between 0 and
1, and the true values are mapped nonlinearly and stretched on this whole
range, so that the differences between the middle values are enhanced with respect to very high
or very low values.
The orientation parameter must be either 0 to get the
energy map used for horizontal scalings, or 1 to get the map for vertical
scalings.
The buffer must be allocated by the user before calling this function, and its size must be at
least , where width * heightwidth and height are the current
width and height of the carver. The energy values are ordered by row
first, then by column.
The outcome will include the effect of the bias added to the carver, if
any.
This function can be called over non-initialised LqrCarver objects, e.g. to provide previews on
the effect of different energy functions, but it can also be invoked at any later time. Note,
however, that in this latter case the carver could be flattened if
necessary, therefore the function invocation is potentially destructive of the internal
visibiliy map.
The function lqr_carvet_get_true_energy is identical to the previous one,
but the resulting buffer will contain the true energy, not scaled nor shifted.
The function lqr_carver_get_energy_image is very similar to the function
lqr_carveR_get_energy, but it can be used to fill directly an image buffer
of the format specified through the additional parameters col_depth and
image_type (see LqrColDepth(3) and
LqrImageType(3)). The buffer must be passed as
void*, but it must point to a memory area with sufficient allocated space for the
chosen image type and colour depth. The image type cannot be LQR_CUSTOM_IMAGE.
For any choice of the parameters describing the image, the resulting
buffer will hold a greyscale image, ranging from black (lowest energy) to
white (highest energy). The opacity (alpha) will be set to 1, if present. All
the information will be stored in the black channel in LQR_CMYK_IMAGE and LQR_CMYKA_IMAGE
image types.
lqr_rwindow_read — read the content of a LqrReadingWindow object
#include <lqr.h>
gfloat lqr_rwindow_read( | LqrReadingWindow* | rwindow, |
| gint | x, | |
| gint | y, | |
| gint | channel); |
The function lqr_rwindow_read returns the content of the reading window
rwindow at point x, y and at channel
channel.
The coordinates x and y are relative to the rwindow
centre, and they both can range from -radius to radius
(extremes included), where radius can be obtained with the function
lqr_rwindow_get_radius(3).
The function returns 0 when the coordinates are out of range, either because
they are beyond the rwindow radius or because they are outside the image
boundary.
The channel parameter specifies which channel to read out; depending on
the rwindow reader type, the range and meaning of this parameter changes:
for the cases LQR_ER_BRIGHTNESS and LQR_ER_LUMA it must be
0, because the readout consists of a single channel, for
LQR_ER_RGBA it must be between 0 and 3
(and then the readout will contain the RGBA information), while for
LQR_ER_CUSTOM it must be one of the original image channels.
lqr_rwindow_get_read_t — get the reader type of a LqrReadingWindow object
#include <lqr.h>
LqrEnergyReaderType lqr_rwindow_get_read_t( | LqrReadingWindow* | rwindow); |
The function lqr_rwindow_get_read_t returns the reader type associated with
the reading window rwindow.
The reader types are described in the page for
lqr_carver_set_energy_function(3).
lqr_rwindow_get_radius — get the size of the region accessible from a LqrReadingWindow object
#include <lqr.h>
gint lqr_rwindow_get_radius( | LqrReadingWindow* | rwindow); |
lqr_rwindow_get_channels — get the number of channels of a LqrReadingWindow object
#include <lqr.h>
gint lqr_rwindow_get_channels( | LqrReadingWindow* | rwindow); |
The function lqr_rwindow_get_channels returns the number of channels of
reading window rwindow.
This function is actually only necessary when the rwindow reader type is
LQR_ER_CUSTOM.
The reader types are described in the page for
lqr_carver_set_energy_function(3).
lqr_carver_set_gradient_function — set the gradient function for an LqrCarver object
#include <lqr.h>
void lqr_carver_set_gradient_function( | LqrCarver* | carver, |
| LqrGradFuncType | gf_ind); |
The function lqr_carver_set_gradient_function is deprecated and should not
be used in newly written code. The function
lqr_carver_set_energy_function_builtin(3) should be used instead.
The function lqr_carver_set_gradient_function is still maintained for
backwards compatibility reasons; its result is equivalent to calling
lqr_carver_set_energy_function_builtin, with the following mapping between
the argument gs_ind of the former and the argument
ef_ind of the latter:
LqrGradFuncType | LqrEnergyFuncBuiltinType |
|---|---|
LQR_GF_XABS | LQR_EF_GRAD_XABS |
LQR_GF_SUMABS | LQR_EF_GRAD_SUMABS |
LQR_GF_NORM | LQR_EF_GRAD_NORM |
LQR_GF_NULL | LQR_EF_NULL |
lqr_carver_bias_add — update an LqrCarver biaslqr_carver_bias_clear — clear an LqrCarver biaslqr_carver_bias_add_xy, lqr_carver_bias_add_area, lqr_carver_bias_add, lqr_carver_bias_add_rgb_area, lqr_carver_bias_add_rgb — update an LqrCarver bias
#include <lqr.h>
LqrRetVal lqr_carver_bias_add_xy( | LqrCarver* | carver, |
| gdouble | bias, | |
| gint | x, | |
| gint | y); |
LqrRetVal lqr_carver_bias_add_area( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | bias_factor, | |
| gint | width, | |
| gint | height, | |
| gint | x_off, | |
| gint | y_off); |
LqrRetVal lqr_carver_bias_add( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | bias_factor); |
LqrRetVal lqr_carver_bias_add_rgb_area( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | bias_factor, | |
| gint | channels, | |
| gint | width, | |
| gint | height, | |
| gint | x_off, | |
| gint | y_off); |
LqrRetVal lqr_carver_bias_add_rgb( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | bias_factor, | |
| gint | channels); |
All the functions described in this page are used to add a bias to LqrCarver objects. A
positive biased pixel will be more likely to be avoided by seams, and thus be preserved during
rescaling, while a negative bias has the opposite effect.
All of these functions must be called before lqr_carver_resize(3). If
called multiple times, the biases added at each call will sum up.
The function lqr_carver_bias_add_xy adds a bias to the x, y
pixel of the image loaded into the LqrCarver object pointed to by carver
A typical value for bias_factor would be 1000 (in
absolute value).
The function lqr_carver_bias_add_area adds a bias to an area of the image
loaded into the LqrCarver object pointed to by carver.
The parameter buffer must point to an array of doubles of
size , ordered
first by rows, then by columns.
width * height
The offset of the area relative to the image can be specified through
x_off and y_off. The bias area can exceed the
boundary of the image, and the offsets can be negative.
The parameter bias_factor is an overall bias scale. A typical value when
the buffer contents are of the order of 1 would be 1000
(in absolute value).
The function lqr_carver_bias_add can be used when the area to add is of the
same size of the image loaded in the LqrCarver object and the offsets are 0.
The functions lqr_carver_bias_add_rgb_area and
lqr_carver_bias_add_rgb are very similar to
lqr_carver_bias_add_area and lqr_carver_bias_add,
except that they use 8-bit multi-channel images as inputs.
The number of channels in the image is passed via the parameter channels.
The last channel is assumed to be the alpha (opacity) channel if channels
is equal to 2 or greater than 3 (if this is not the case,
use the previous functions).
The bias is computed from the average of the colour channels, multiplied by the value of the
alpha channel if present. For example, in RGBA images a white, nontransparent pixel is
equivalent to a value of 1.0 when using a buffer in
lqr_carver_bias_add_area.
lqr_carver_rigmask_add — update an LqrCarver rigidity masklqr_carver_rigmask_clear — clear an LqrCarver rigidity masklqr_carver_rigmask_add_xy, lqr_carver_rigmask_add_area, lqr_carver_rigmask_add, lqr_carver_rigmask_add_rgb_area, lqr_carver_rigmask_add_rgb — update an LqrCarver rigidity mask
#include <lqr.h>
LqrRetVal lqr_carver_rigmask_add_xy( | LqrCarver* | carver, |
| gdouble | rigidity, | |
| gint | x, | |
| gint | y); |
LqrRetVal lqr_carver_rigmask_add_area( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | width, | |
| gint | height, | |
| gint | x_off, | |
| gint | y_off); |
LqrRetVal lqr_carver_rigmask_add( | LqrCarver* | carver, |
| gdouble* | buffer); |
LqrRetVal lqr_carver_rigmask_add_area( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | channels, | |
| gint | width, | |
| gint | height, | |
| gint | x_off, | |
| gint | y_off); |
LqrRetVal lqr_carver_rigmask_add_rgb( | LqrCarver* | carver, |
| gdouble* | buffer, | |
| gint | channels); |
All the functions described in this page are used to add a rigidity mask to LqrCarver objects.
Whenever one of these functions is called, a rigidity mask is activated for the whole image; the
mask contains coefficients which modulate the value of the rigidity (which is set with
lqr_carver_init(3)) in different areas of the image.
It is very important to note that using no rigidity masks at all is equivalent to use a rigidity
mask over the whole image with all the values set to 1.0, but, when first
adding a rigidity mask to a LqrCarver object, all the pixels outside the affected area will
have their rigidity set to zero; therefore, the functions
lqr_carver_rigmask_add_xy, lqr_carver_rigmask_add_area
and lqr_carver_rigmask_add_rgb_area actually affect the whole image,
despite their name.
All the functions must be called after lqr_carver_init and before
lqr_carver_resize. If called multiple times over the same area, new values
will replace the old ones.
The function lqr_carver_rigmask_add_xy sets the rigidity mask value of the
x, y pixel of the image loaded into the LqrCarver object pointed to by
carver
The function lqr_carver_rigmask_add_area adds a rigidity mask to an area of
the image loaded in the LqrCarver object pointed to by carver.
The parameter buffer must point to an array of doubles of
size , ordered
first by rows, then by columns.
width * height
The offset of the area relative to the image are specified through x_off
and y_off. The rigidity mask area can exceed the boundary of the image,
and the offsets can be negative.
The values in the given buffer are scaled by the overall
rigidity value set when calling the function
lqr_carver_init.
The function lqr_carver_rigmask_add can be used when the area to add is of
the same size of the image loaded in the LqrCarver object and the offsets are
0.
The functions lqr_carver_rigmask_add_rgb_area and
lqr_carver_rigmask_add_rgb are very similar to
lqr_carver_rigmask_add_area and
lqr_carver_rigmask_add, but use 8-bit multi-channel images as inputs.
The number of channels in the image is passed via the parameter channels.
The last channel is assumed to be the alpha (opacity) channel if channels
is equal to 2 or greater than 3 (if this is not the case,
use the previous functions).
The rigidity value is computed from the average of the colour channels, multiplied by the value
of the alpha channel if present. For example, in RGBA images a white, nontransparent pixel is
equivalent to a value of 1.0 when using a buffer in
lqr_carver_rigmask_add_area.
lqr_progress_new — the LqrProgress object constructorlqr_progress_set_init — execude custom code before each rescaling operationlqr_progress_set_update — execude custom code at regular steps during each rescaling operationlqr_progress_set_end — execude custom code after each rescaling operationlqr_progress_set_update_step — setup update step for LqrProgress objectslqr_progress_set_init_width_message — setup width message for init hooks in LqrProgress objectslqr_progress_set_init_height_message — setup height message for init hooks in LqrProgress objectslqr_progress_set_end_width_message — setup width message for end hooks in LqrProgress objectslqr_progress_set_end_height_message — setup height message for end hooks in LqrProgress objectslqr_progress_new — the LqrProgress object constructor
#include <lqr.h>
LqrProgress* lqr_progress_new( | void); |
The function lqr_progress_new is the constructor for LqrProgress objects. It
can be used to setup a progress report indicator for rescale operations performed through
lqr_carver_resize(3).
Newly created LqrProgress objects are inactive, and need to be set up using the functions
lqr_progress_set_init(3),
lqr_progress_set_update(3) and
lqr_progress_set_end(3).
LqrProgress objects are associated to LqrCarver objects using the function
lqr_carver_set_progress(3)
The function returns the newly created LqrProgress if successful, or NULL in case of
insufficient memory.
lqr_progress_set_init(3), lqr_progress_set_update(3), lqr_progress_set_end(3), lqr_progress_set_init_width_message(3), lqr_progress_set_init_height_message(3), lqr_progress_set_end_width_message(3), lqr_progress_set_end_height_message(3), lqr_progress_set_update_step(3), lqr_carver_set_progress(3)
lqr_progress_set_init — execude custom code before each rescaling operation
#include <lqr.h>
LqrRetVal lqr_progress_set_init( | LqrProgress* | p, |
| LqrProgressFuncInit | init_func); |
The function lqr_progress_set_init sets the hook
init_func to the LqrProgress object pointed to by
p.
The function init_func is of type
LqrProgressFuncInit, whose prototype is defined by:
typedef LqrRetVal (*LqrProgressFuncInit) (const gchar* init_message);
Each time that the function lqr_carver_resize(3) performs a rescale
operation (recall that it can perform more than one rescale operation at each call) this
function will be called first, with a string argument passed through the parameter
init_message, which is different for horizontal and vertical rescalings.
The message arguments can be set with the functions
lqr_progress_set_init_width_message(3) and
lqr_progress_set_init_height_message(3).
The default values for newly created LqrProgress objects are:
"Resizing width..."
"Resizing height..."
LqrRetVal(3), lqr_progress_new(3), lqr_progress_set_update(3), lqr_progress_set_end(3), lqr_progress_set_init_width_message(3), lqr_progress_set_init_height_message(3), lqr_progress_set_end_width_message(3), lqr_progress_set_end_height_message(3), lqr_progress_set_update_step(3), lqr_carver_set_progress(3)
lqr_progress_set_update — execude custom code at regular steps during each rescaling operation
#include <lqr.h>
LqrRetVal lqr_progress_set_update( | LqrProgress* | p, |
| LqrProgressFuncUpdate | update_func); |
The function lqr_progress_set_update sets the hook
update_func to the LqrProgress object pointed to by
p.
The function update_func is of type
LqrProgressFuncUpdate, whose prototype is defined by:
typedef LqrRetVal (*LqrProgressFuncUpdate) (gdouble completion_percentage);
Each time that the function lqr_carver_resize(3) performs a rescale
operation (recall that it can perform more than one rescale operation at each call) this
function will be called at regular intervale, with the current completion percentage
completion_percentage as an argument.
The update step can be set with the function
lqr_progress_set_update_step(3).
LqrRetVal(3), lqr_progress_new(3), lqr_progress_set_init(3), lqr_progress_set_end(3), lqr_progress_set_init_width_message(3), lqr_progress_set_init_height_message(3), lqr_progress_set_end_width_message(3), lqr_progress_set_end_height_message(3), lqr_progress_set_update_step(3), lqr_carver_set_progress(3)
lqr_progress_set_end — execude custom code after each rescaling operation
#include <lqr.h>
LqrRetVal lqr_progress_set_end( | LqrProgress* | p, |
| LqrProgressFuncEnd | end_func); |
The function lqr_progress_set_end sets the hook
end_func to the LqrProgress object pointed to by p.
The function end_func is of type
LqrProgressFuncEnd, whose prototype is defined by:
typedef LqrRetVal (*LqrProgressFuncEnd) (const gchar* end_message);
Each time that the function lqr_carver_resize(3) performs a rescale
operation (recall that it can perform more than one rescale operation at each call) this
function will be called at the end, with a string argument passed through the parameter
end_message, which is different for horizontal and vertical rescalings.
The message arguments can be set with the functions
lqr_progress_set_end_width_message(3) and
lqr_progress_set_end_height_message(3).
LqrRetVal(3), lqr_progress_new(3), lqr_progress_set_init(3), lqr_progress_set_update(3), lqr_progress_set_init_width_message(3), lqr_progress_set_init_height_message(3), lqr_progress_set_end_width_message(3), lqr_progress_set_end_height_message(3), lqr_progress_set_update_step(3), lqr_carver_set_progress(3)
lqr_progress_set_update_step — setup update step for LqrProgress objects
#include <lqr.h>
LqrRetVal lqr_progress_set_update_step( | LqrProgress* | p, |
| gfloat | update_step); |
lqr_progress_set_init_width_message — setup width message for init hooks in LqrProgress objects
#include <lqr.h>
LqrRetVal lqr_progress_set_init_width_message( | LqrProgress* | p, |
| const guchar* | message); |
The function lqr_progress_set_init_width_message sets the string
message in the LqrProgress object pointed to by p
as the argument when rescaling the width for init hooks set with
lqr_progress_set_init(3)
The default value for newly created LqrProgress objects is: "Resizing width..."
LqrRetVal(3), lqr_progress_new(3), lqr_progress_set_init(3), lqr_progress_set_update(3), lqr_progress_set_end(3), lqr_progress_set_init_height_message(3), lqr_progress_set_end_width_message(3), lqr_progress_set_end_height_message(3), lqr_progress_set_update_step(3), lqr_carver_set_progress(3)
lqr_progress_set_init_height_message — setup height message for init hooks in LqrProgress objects
#include <lqr.h>
LqrRetVal lqr_progress_set_init_height_message( | LqrProgress* | p, |
| const guchar* | message); |
The function lqr_progress_set_init_height_message sets the string
message in the LqrProgress object pointed to by p
as the argument when rescaling the height for init hooks set with
lqr_progress_set_init(3)
The default value for newly created LqrProgress objects is: "Resizing height..."
LqrRetVal(3), lqr_progress_new(3), lqr_progress_set_init(3), lqr_progress_set_update(3), lqr_progress_set_end(3), lqr_progress_set_init_width_message(3), lqr_progress_set_end_width_message(3), lqr_progress_set_end_height_message(3), lqr_progress_set_update_step(3), lqr_carver_set_progress(3)
lqr_progress_set_end_width_message — setup width message for end hooks in LqrProgress objects
#include <lqr.h>
LqrRetVal lqr_progress_set_end_width_message( | LqrProgress* | p, |
| const guchar* | message); |
The function lqr_progress_set_end_width_message sets the string
message in the LqrProgress object pointed to by p
as the argument when rescaling the width for end hooks set with
lqr_progress_set_end(3)
The default value for newly created LqrProgress objects is:
"done".
LqrRetVal(3), lqr_progress_new(3), lqr_progress_set_init(3), lqr_progress_set_update(3), lqr_progress_set_end(3), lqr_progress_set_init_width_message(3), lqr_progress_set_init_height_message(3), lqr_progress_set_end_height_message(3), lqr_progress_set_update_step(3), lqr_carver_set_progress(3)
lqr_progress_set_end_height_message — setup height message for end hooks in LqrProgress objects
#include <lqr.h>
LqrRetVal lqr_progress_set_end_height_message( | LqrProgress* | p, |
| const guchar* | message); |
The function lqr_progress_set_end_height_message sets the string
message in the LqrProgress object pointed to by p
as the argument when rescaling the height for end hooks set with
lqr_progress_set_end(3)
The default value for newly created LqrProgress objects is:
"done".
LqrRetVal(3), lqr_progress_new(3), lqr_progress_set_init(3), lqr_progress_set_update(3), lqr_progress_set_end(3), lqr_progress_set_init_width_message(3), lqr_progress_set_init_height_message(3), lqr_progress_set_end_width_message(3), lqr_progress_set_update_step(3), lqr_carver_set_progress(3)
The library implements the algorithm described in the paper "Seam Carving for Content-Aware Image Resizing" by Shai Avidan and Ariel Shamir, which can be found at http://www.faculty.idc.ac.il/arik/imret.pdf
Table of Contents
lqr_carver_get_enl_step |
lqr_carver_set_enl_step |
lqr_carver_get_ref_width |
lqr_carver_get_ref_height |
lqr_carver_get_orientation |
lqr_carver_get_depth |