Release 0.3
[liblqr.git] / lqr / lqr_carver_bias.c
blob683934da0353d82f4b717c23cacbef61b90c5fde
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_F (r->active);
45 if ((r->w != r->w0) || (r->w_start != r->w0) ||
46 (r->h != r->h0) || (r->h_start != r->h0))
48 CATCH (lqr_carver_flatten(r));
50 if (r->transposed)
52 CATCH (lqr_carver_transpose(r));
55 x1 = MAX (0, x_off);
56 y1 = MAX (0, y_off);
57 x2 = MIN (r->w, width + x_off);
58 y2 = MIN (r->h, height + y_off);
60 for (y = 0; y < y2 - y1; y++)
62 for (x = 0; x < x2 - x1; x++)
64 bias = (gfloat) ((gdouble) bias_factor * buffer[y * width + x] / 2);
66 r->bias[(y + y1) * r->w0 + (x + x1)] += bias;
72 return LQR_OK;
76 LQR_PUBLIC
77 LqrRetVal
78 lqr_carver_bias_add(LqrCarver *r, gdouble *buffer, gint bias_factor)
80 return lqr_carver_bias_add_area(r, buffer, bias_factor, r->w0, r->h0, 0, 0);
83 LQR_PUBLIC
84 LqrRetVal
85 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)
87 gint x, y, k, c_channels;
88 gboolean has_alpha;
89 gint x0, y0, x1, y1, x2, y2;
90 gint transposed = 0;
91 gint sum;
92 gfloat bias;
94 if (bias_factor == 0)
96 return TRUE;
99 CATCH_F (r->active);
100 if ((r->w != r->w0) || (r->w_start != r->w0) ||
101 (r->h != r->h0) || (r->h_start != r->h0))
103 CATCH (lqr_carver_flatten(r));
105 if (r->transposed)
107 transposed = 1;
108 CATCH (lqr_carver_transpose(r));
111 has_alpha = (channels == 2 || channels >= 4);
112 c_channels = channels - (has_alpha ? 1 : 0);
114 x0 = MIN (0, x_off);
115 y0 = MIN (0, y_off);
116 x1 = MAX (0, x_off);
117 y1 = MAX (0, y_off);
118 x2 = MIN (r->w0, width + x_off);
119 y2 = MIN (r->h0, height + y_off);
121 for (y = 0; y < y2 - y1; y++)
123 for (x = 0; x < x2 - x1; x++)
125 sum = 0;
126 for (k = 0; k < c_channels; k++)
128 sum += rgb[((y - y0) * width + (x - x0)) * channels + k];
131 bias = (gfloat) ((gdouble) bias_factor * sum / (2 * 255 * c_channels));
132 if (has_alpha)
134 bias *= (gfloat) rgb[((y - y0) * width + (x - x0) + 1) * channels - 1] / 255;
137 r->bias[(y + y1) * r->w0 + (x + x1)] += bias;
143 if (transposed)
145 CATCH (lqr_carver_transpose(r));
148 return LQR_OK;
151 LQR_PUBLIC
152 LqrRetVal
153 lqr_carver_bias_add_rgb(LqrCarver *r, guchar *rgb, gint bias_factor, gint channels)
155 return lqr_carver_bias_add_rgb_area(r, rgb, bias_factor, channels, r->w0, r->h0, 0, 0);
159 /**** END OF LQR_CARVER_BIAS CLASS FUNCTIONS ****/