1 /* LiquidRescaling Library
2 * Copyright (C) 2007-2009 Carlo Baldassi (the "Author") <carlobaldassi@gmail.com>.
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/>
27 #include <lqr/lqr_all.h>
33 /**** LQR_CARVER_BIAS STRUCT FUNTIONS ****/
37 lqr_carver_bias_clear(LqrCarver
*r
)
41 r
->nrg_uptodate
= FALSE
;
46 lqr_carver_bias_add_xy(LqrCarver
*r
, gdouble bias
, gint x
, gint y
)
55 if (r
->nrg_active
== FALSE
) {
56 LQR_CATCH(lqr_carver_init_energy_related(r
));
59 if ((r
->w
!= r
->w0
) || (r
->w_start
!= r
->w0
) || (r
->h
!= r
->h0
) || (r
->h_start
!= r
->h0
)) {
60 LQR_CATCH(lqr_carver_flatten(r
));
62 if (r
->bias
== NULL
) {
63 LQR_CATCH_MEM(r
->bias
= g_try_new0(gfloat
, r
->w0
* r
->h0
));
66 xt
= r
->transposed
? y
: x
;
67 yt
= r
->transposed
? x
: y
;
69 r
->bias
[yt
* r
->w0
+ xt
] += (gfloat
) bias
/ 2;
71 r
->nrg_uptodate
= FALSE
;
78 lqr_carver_bias_add_area(LqrCarver
*r
, gdouble
*buffer
, gint bias_factor
, gint width
, gint height
, gint x_off
,
84 gint x0
, y0
, x1
, y1
, x2
, y2
;
89 if (bias_factor
== 0) {
93 if ((r
->w
!= r
->w0
) || (r
->w_start
!= r
->w0
) || (r
->h
!= r
->h0
) || (r
->h_start
!= r
->h0
)) {
94 LQR_CATCH(lqr_carver_flatten(r
));
97 if (r
->nrg_active
== FALSE
) {
98 LQR_CATCH(lqr_carver_init_energy_related(r
));
101 if (r
->bias
== NULL
) {
102 LQR_CATCH_MEM(r
->bias
= g_try_new0(gfloat
, r
->w
* r
->h
));
105 wt
= r
->transposed
? r
->h
: r
->w
;
106 ht
= r
->transposed
? r
->w
: r
->h
;
112 x2
= MIN(wt
, width
+ x_off
);
113 y2
= MIN(ht
, height
+ y_off
);
115 for (y
= 0; y
< y2
- y1
; y
++) {
116 for (x
= 0; x
< x2
- x1
; x
++) {
117 bias
= (gfloat
) ((gdouble
) bias_factor
* buffer
[(y
- y0
) * width
+ (x
- x0
)] / 2);
119 xt
= r
->transposed
? y
: x
;
120 yt
= r
->transposed
? x
: y
;
122 r
->bias
[(yt
+ y1
) * r
->w0
+ (xt
+ x1
)] += bias
;
126 r
->nrg_uptodate
= FALSE
;
133 lqr_carver_bias_add(LqrCarver
*r
, gdouble
*buffer
, gint bias_factor
)
135 return lqr_carver_bias_add_area(r
, buffer
, bias_factor
, lqr_carver_get_width(r
), lqr_carver_get_height(r
), 0, 0);
140 lqr_carver_bias_add_rgb_area(LqrCarver
*r
, guchar
*rgb
, gint bias_factor
, gint channels
, gint width
, gint height
,
141 gint x_off
, gint y_off
)
143 gint x
, y
, k
, c_channels
;
147 gint x0
, y0
, x1
, y1
, x2
, y2
;
153 if ((r
->w
!= r
->w0
) || (r
->w_start
!= r
->w0
) || (r
->h
!= r
->h0
) || (r
->h_start
!= r
->h0
)) {
154 LQR_CATCH(lqr_carver_flatten(r
));
157 if (r
->nrg_active
== FALSE
) {
158 LQR_CATCH(lqr_carver_init_energy_related(r
));
161 if (bias_factor
== 0) {
165 if (r
->bias
== NULL
) {
166 LQR_CATCH_MEM(r
->bias
= g_try_new0(gfloat
, r
->w
* r
->h
));
169 has_alpha
= (channels
== 2 || channels
>= 4);
170 c_channels
= channels
- (has_alpha
? 1 : 0);
172 wt
= r
->transposed
? r
->h
: r
->w
;
173 ht
= r
->transposed
? r
->w
: r
->h
;
179 x2
= MIN(wt
, width
+ x_off
);
180 y2
= MIN(ht
, height
+ y_off
);
182 for (y
= 0; y
< y2
- y1
; y
++) {
183 for (x
= 0; x
< x2
- x1
; x
++) {
185 for (k
= 0; k
< c_channels
; k
++) {
186 sum
+= rgb
[((y
- y0
) * width
+ (x
- x0
)) * channels
+ k
];
189 bias
= ((gdouble
) bias_factor
* sum
/ (2 * 255 * c_channels
));
191 bias
*= (gdouble
) rgb
[((y
- y0
) * width
+ (x
- x0
) + 1) * channels
- 1] / 255;
194 xt
= r
->transposed
? y
: x
;
195 yt
= r
->transposed
? x
: y
;
197 r
->bias
[(yt
+ y1
) * r
->w0
+ (xt
+ x1
)] += (gfloat
) bias
;
201 r
->nrg_uptodate
= FALSE
;
208 lqr_carver_bias_add_rgb(LqrCarver
*r
, guchar
*rgb
, gint bias_factor
, gint channels
)
210 return lqr_carver_bias_add_rgb_area(r
, rgb
, bias_factor
, channels
, lqr_carver_get_width(r
),
211 lqr_carver_get_height(r
), 0, 0);
214 /**** END OF LQR_CARVER_BIAS CLASS FUNCTIONS ****/