Recovered useless GF's for API consistency + fixed black channel bugs
[liblqr.git] / lqr / lqr_carver_bias.c
blobc36f13c3b389209733273e1709b8480a38f193b2
1 /* LiquidRescaling Library
2 * Copyright (C) 2007-2009 Carlo Baldassi (the "Author") <carlobaldassi@gmail.com>.
3 * All Rights Reserved.
5 * This library implements the algorithm described in the paper
6 * "Seam Carving for Content-Aware Image Resizing"
7 * by Shai Avidan and Ariel Shamir
8 * which can be found at http://www.faculty.idc.ac.il/arik/imret.pdf
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; version 3 dated June, 2007.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>
23 #include <lqr/lqr_all.h>
25 #ifdef __LQR_DEBUG__
26 #include <assert.h>
27 #endif
29 /**** LQR_CARVER_BIAS STRUCT FUNTIONS ****/
31 LQR_PUBLIC
32 LqrRetVal
33 lqr_carver_bias_add_area(LqrCarver *r, gdouble *buffer, gint bias_factor, gint width, gint height, gint x_off, gint y_off)
35 gint x, y;
36 gint x1, y1, x2, y2;
37 gfloat bias;
39 if (bias_factor == 0)
41 return LQR_OK;
44 CATCH_CANC (r);
45 CATCH_F (r->active);
46 if ((r->w != r->w0) || (r->w_start != r->w0) ||
47 (r->h != r->h0) || (r->h_start != r->h0))
49 CATCH (lqr_carver_flatten(r));
51 if (r->transposed)
53 CATCH (lqr_carver_transpose(r));
56 x1 = MAX (0, x_off);
57 y1 = MAX (0, y_off);
58 x2 = MIN (r->w, width + x_off);
59 y2 = MIN (r->h, height + y_off);
61 for (y = 0; y < y2 - y1; y++)
63 for (x = 0; x < x2 - x1; x++)
65 bias = (gfloat) ((gdouble) bias_factor * buffer[y * width + x] / 2);
67 r->bias[(y + y1) * r->w0 + (x + x1)] += bias;
73 return LQR_OK;
77 LQR_PUBLIC
78 LqrRetVal
79 lqr_carver_bias_add(LqrCarver *r, gdouble *buffer, gint bias_factor)
81 return lqr_carver_bias_add_area(r, buffer, bias_factor, r->w0, r->h0, 0, 0);
84 LQR_PUBLIC
85 LqrRetVal
86 lqr_carver_bias_add_rgb_area(LqrCarver *r, guchar *rgb, gint bias_factor, gint channels, gint width, gint height, gint x_off, gint y_off)
88 gint x, y, k, c_channels;
89 gboolean has_alpha;
90 gint x0, y0, x1, y1, x2, y2;
91 gint transposed = 0;
92 gint sum;
93 gfloat bias;
95 if (bias_factor == 0)
97 return TRUE;
100 CATCH_CANC (r);
101 CATCH_F (r->active);
102 if ((r->w != r->w0) || (r->w_start != r->w0) ||
103 (r->h != r->h0) || (r->h_start != r->h0))
105 CATCH (lqr_carver_flatten(r));
107 if (r->transposed)
109 transposed = 1;
110 CATCH (lqr_carver_transpose(r));
113 has_alpha = (channels == 2 || channels >= 4);
114 c_channels = channels - (has_alpha ? 1 : 0);
116 x0 = MIN (0, x_off);
117 y0 = MIN (0, y_off);
118 x1 = MAX (0, x_off);
119 y1 = MAX (0, y_off);
120 x2 = MIN (r->w0, width + x_off);
121 y2 = MIN (r->h0, height + y_off);
123 for (y = 0; y < y2 - y1; y++)
125 for (x = 0; x < x2 - x1; x++)
127 sum = 0;
128 for (k = 0; k < c_channels; k++)
130 sum += rgb[((y - y0) * width + (x - x0)) * channels + k];
133 bias = (gfloat) ((gdouble) bias_factor * sum / (2 * 255 * c_channels));
134 if (has_alpha)
136 bias *= (gfloat) rgb[((y - y0) * width + (x - x0) + 1) * channels - 1] / 255;
139 r->bias[(y + y1) * r->w0 + (x + x1)] += bias;
145 if (transposed)
147 CATCH (lqr_carver_transpose(r));
150 return LQR_OK;
153 LQR_PUBLIC
154 LqrRetVal
155 lqr_carver_bias_add_rgb(LqrCarver *r, guchar *rgb, gint bias_factor, gint channels)
157 return lqr_carver_bias_add_rgb_area(r, rgb, bias_factor, channels, r->w0, r->h0, 0, 0);
161 /**** END OF LQR_CARVER_BIAS CLASS FUNCTIONS ****/