Fixed README
[liblqr.git] / lqr / lqr_vmap.c
blobdf43b79e18a6364c054f6f78487cb36fb95dca1b
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 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
27 #include <lqr/lqr_all.h>
29 #ifdef __LQR_DEBUG__
30 #include <assert.h>
31 #endif /* __LQR_DEBUG__ */
33 /**** SEAMS BUFFER FUNCTIONS ****/
35 /* LQR_PUBLIC */
36 LqrVMap *
37 lqr_vmap_new(gint *buffer, gint width, gint height, gint depth, gint orientation)
39 LqrVMap *vmap;
41 LQR_TRY_N_N(vmap = g_try_new(LqrVMap, 1));
42 vmap->buffer = buffer;
43 vmap->width = width;
44 vmap->height = height;
45 vmap->orientation = orientation;
46 vmap->depth = depth;
47 return vmap;
50 /* LQR_PUBLIC */
51 void
52 lqr_vmap_destroy(LqrVMap *vmap)
54 g_free(vmap->buffer);
55 g_free(vmap);
58 /* LQR_PUBLIC */
59 gint *
60 lqr_vmap_get_data(LqrVMap *vmap)
62 return vmap->buffer;
65 /* LQR_PUBLIC */
66 gint
67 lqr_vmap_get_width(LqrVMap *vmap)
69 return vmap->width;
72 /* LQR_PUBLIC */
73 gint
74 lqr_vmap_get_height(LqrVMap *vmap)
76 return vmap->height;
79 /* LQR_PUBLIC */
80 gint
81 lqr_vmap_get_depth(LqrVMap *vmap)
83 return vmap->depth;
86 /* LQR_PUBLIC */
87 gint
88 lqr_vmap_get_orientation(LqrVMap *vmap)
90 return vmap->orientation;
93 /* dump the visibility level of the image */
94 /* LQR_PUBLIC */
95 LqrVMap *
96 lqr_vmap_dump(LqrCarver *r)
98 LqrVMap *vmap;
99 gint w, h, w1, x, y, z0, vs;
100 gint *buffer;
101 gint depth;
103 /* save current size */
104 w1 = r->w;
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) {
120 z0 = y * r->w + x;
121 } else {
122 z0 = x * r->h + y;
124 if (vs == 0) {
125 buffer[z0] = 0;
126 } else {
127 buffer[z0] = vs - depth;
129 lqr_cursor_next(r->c);
133 /* recover size */
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));
139 return vmap;
142 /* dump the visibility level of the image */
143 /* LQR_PUBLIC */
144 LqrRetVal
145 lqr_vmap_internal_dump(LqrCarver *r)
147 LqrVMap *vmap;
148 gint w, h, w1, x, y, z0, vs;
149 gint *buffer;
150 gint depth;
152 LQR_CATCH_CANC(r);
154 /* save current size */
155 w1 = r->w;
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) {
171 z0 = y * r->w + x;
172 } else {
173 z0 = x * r->h + y;
175 if (vs == 0) {
176 buffer[z0] = 0;
177 } else {
178 buffer[z0] = vs - depth;
180 lqr_cursor_next(r->c);
184 /* recover size */
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));
192 return LQR_OK;
195 /* LQR_PUBLIC */
196 LqrRetVal
197 lqr_vmap_load(LqrCarver *r, LqrVMap *vmap)
199 gint w, h;
200 gint x, y, z0, z1;
202 w = vmap->width;
203 h = vmap->height;
205 LQR_CATCH_CANC(r);
206 LQR_CATCH_F(!r->active);
208 if (!r->transposed) {
209 LQR_CATCH_F((r->w_start == w) && (r->h_start == h));
210 } else {
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) {
223 z0 = y * r->w + x;
224 } else {
225 z0 = x * r->h + y;
227 z1 = y * r->w + x;
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);
239 return LQR_OK;