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>
31 #endif /* __LQR_DEBUG__ */
33 /**** SEAMS BUFFER FUNCTIONS ****/
37 lqr_vmap_new(gint
*buffer
, gint width
, gint height
, gint depth
, gint orientation
)
41 LQR_TRY_N_N(vmap
= g_try_new(LqrVMap
, 1));
42 vmap
->buffer
= buffer
;
44 vmap
->height
= height
;
45 vmap
->orientation
= orientation
;
52 lqr_vmap_destroy(LqrVMap
*vmap
)
60 lqr_vmap_get_data(LqrVMap
*vmap
)
67 lqr_vmap_get_width(LqrVMap
*vmap
)
74 lqr_vmap_get_height(LqrVMap
*vmap
)
81 lqr_vmap_get_depth(LqrVMap
*vmap
)
88 lqr_vmap_get_orientation(LqrVMap
*vmap
)
90 return vmap
->orientation
;
93 /* dump the visibility level of the image */
96 lqr_vmap_dump(LqrCarver
*r
)
99 gint w
, h
, w1
, x
, y
, z0
, vs
;
103 /* save current size */
106 /* temporarily set the size to the original */
107 lqr_carver_set_width(r
, r
->w_start
);
109 w
= lqr_carver_get_width(r
);
110 h
= lqr_carver_get_height(r
);
111 depth
= r
->w0
- r
->w_start
;
113 LQR_TRY_N_N(buffer
= g_try_new(gint
, w
* h
));
115 lqr_cursor_reset(r
->c
);
116 for (y
= 0; y
< r
->h
; y
++) {
117 for (x
= 0; x
< r
->w
; x
++) {
118 vs
= r
->vs
[r
->c
->now
];
119 if (!r
->transposed
) {
127 buffer
[z0
] = vs
- depth
;
129 lqr_cursor_next(r
->c
);
134 lqr_carver_set_width(r
, w1
);
135 lqr_cursor_reset(r
->c
);
137 LQR_TRY_N_N(vmap
= lqr_vmap_new(buffer
, w
, h
, depth
, r
->transposed
));
142 /* dump the visibility level of the image */
145 lqr_vmap_internal_dump(LqrCarver
*r
)
148 gint w
, h
, w1
, x
, y
, z0
, vs
;
154 /* save current size */
157 /* temporarily set the size to the original */
158 lqr_carver_set_width(r
, r
->w_start
);
160 w
= lqr_carver_get_width(r
);
161 h
= lqr_carver_get_height(r
);
162 depth
= r
->w0
- r
->w_start
;
164 LQR_CATCH_MEM(buffer
= g_try_new(gint
, w
* h
));
166 lqr_cursor_reset(r
->c
);
167 for (y
= 0; y
< r
->h
; y
++) {
168 for (x
= 0; x
< r
->w
; x
++) {
169 vs
= r
->vs
[r
->c
->now
];
170 if (!r
->transposed
) {
178 buffer
[z0
] = vs
- depth
;
180 lqr_cursor_next(r
->c
);
185 lqr_carver_set_width(r
, w1
);
186 lqr_cursor_reset(r
->c
);
188 LQR_CATCH_MEM(vmap
= lqr_vmap_new(buffer
, w
, h
, depth
, r
->transposed
));
190 LQR_CATCH_MEM(r
->flushed_vs
= lqr_vmap_list_append(r
->flushed_vs
, vmap
));
197 lqr_vmap_load(LqrCarver
*r
, LqrVMap
*vmap
)
206 LQR_CATCH_F(!r
->active
);
208 if (!r
->transposed
) {
209 LQR_CATCH_F((r
->w_start
== w
) && (r
->h_start
== h
));
211 LQR_CATCH_F((r
->w_start
== h
) && (r
->h_start
== w
));
214 LQR_CATCH(lqr_carver_flatten(r
));
216 if (vmap
->orientation
!= r
->transposed
) {
217 LQR_CATCH(lqr_carver_transpose(r
));
220 for (y
= 0; y
< r
->h
; y
++) {
221 for (x
= 0; x
< r
->w
; x
++) {
222 if (!r
->transposed
) {
229 r
->vs
[z1
] = vmap
->buffer
[z0
];
233 LQR_CATCH(lqr_carver_inflate(r
, vmap
->depth
));
235 lqr_cursor_reset(r
->c
);
237 lqr_carver_set_enl_step(r
, 2.0);