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/>
24 #include <lqr/lqr_all.h>
27 lqr_energy_buffer_fill_std (LqrEnergyBuffer
* ebuffer
, LqrCarver
* r
, gint x
, gint y
)
29 gfloat
** buffer_float
;
32 buffer_float
= (float **) (ebuffer
->buffer
);
34 LqrReadFunc read_float
;
36 switch (ebuffer
->read_t
)
39 read_float
= lqr_carver_read_brightness
;
42 read_float
= lqr_carver_read_luma
;
47 #endif /* __LQR_DEBUG__ */
51 for (i
= -ebuffer
->radius
; i
<= ebuffer
->radius
; i
++)
53 for (j
= -ebuffer
->radius
; j
<= ebuffer
->radius
; j
++)
55 if (x
+ i
< 0 || x
+ i
>= r
->w
|| y
+ j
< 0 || y
+ j
>= r
->h
)
57 buffer_float
[i
][j
] = 0;
61 buffer_float
[i
][j
] = read_float (r
, x
+ i
, y
+ j
);
70 lqr_energy_buffer_fill_rgba (LqrEnergyBuffer
* ebuffer
, LqrCarver
* r
, gint x
, gint y
)
77 lqr_energy_buffer_fill_custom (LqrEnergyBuffer
* ebuffer
, LqrCarver
* r
, gint x
, gint y
)
85 lqr_energy_buffer_fill (LqrEnergyBuffer
* ebuffer
, LqrCarver
* r
, gint x
, gint y
)
89 switch (ebuffer
->read_t
)
93 CATCH (lqr_energy_buffer_fill_std(ebuffer
, r
, x
, y
));
96 CATCH (lqr_energy_buffer_fill_rgba(ebuffer
, r
, x
, y
));
99 CATCH (lqr_energy_buffer_fill_custom(ebuffer
, r
, x
, y
));
109 lqr_energy_buffer_new_std (gint radius
, LqrEnergyReaderType read_func_type
)
111 LqrEnergyBuffer
* out_ebuffer
;
112 gfloat
** out_buffer_float
;
113 gfloat
* out_buffer_float_aux
;
115 gint buf_size1
, buf_size2
;
118 TRY_N_N (out_ebuffer
= g_try_new0 (LqrEnergyBuffer
, 1));
120 buf_size1
= (2 * radius
+ 1);
121 buf_size2
= buf_size1
* buf_size1
;
123 TRY_N_N (out_buffer_float_aux
= g_try_new0 (gfloat
, buf_size2
));
124 TRY_N_N (out_buffer_float
= g_try_new0 (gfloat
*, buf_size1
));
125 for (i
= 0; i
< buf_size1
; i
++)
127 out_buffer_float
[i
] = out_buffer_float_aux
+ radius
;
128 out_buffer_float_aux
+= buf_size1
;
130 out_buffer_float
+= radius
;
132 out_ebuffer
->buffer
= (void**) out_buffer_float
;
133 out_ebuffer
->radius
= radius
;
134 out_ebuffer
->read_t
= read_func_type
;
140 lqr_energy_buffer_new_rgba (gint radius
, LqrEnergyReaderType read_func_type
)
142 LqrEnergyBuffer
* out_ebuffer
;
144 TRY_N_N (out_ebuffer
= g_try_new0 (LqrEnergyBuffer
, 1));
146 out_ebuffer
->buffer
= NULL
;
147 out_ebuffer
->radius
= radius
;
148 out_ebuffer
->read_t
= read_func_type
;
155 lqr_energy_buffer_new_custom (gint radius
, LqrEnergyReaderType read_func_type
)
157 LqrEnergyBuffer
* out_ebuffer
;
159 TRY_N_N (out_ebuffer
= g_try_new0 (LqrEnergyBuffer
, 1));
161 out_ebuffer
->buffer
= NULL
;
162 out_ebuffer
->radius
= radius
;
163 out_ebuffer
->read_t
= read_func_type
;
170 lqr_energy_buffer_new (gint radius
, LqrEnergyReaderType read_func_type
)
172 switch (read_func_type
)
176 return lqr_energy_buffer_new_std(radius
, read_func_type
);
178 return lqr_energy_buffer_new_rgba(radius
, read_func_type
);
180 return lqr_energy_buffer_new_custom(radius
, read_func_type
);
184 #endif /* __LQR_DEBUG__ */
190 lqr_energy_buffer_destroy (LqrEnergyBuffer
* ebuffer
)
192 gfloat
** buffer_float
;
199 if (ebuffer
->buffer
== NULL
)
204 switch (ebuffer
->read_t
)
208 buffer_float
= (gfloat
**) (ebuffer
->buffer
);
209 buffer_float
-= ebuffer
->radius
;
210 buffer_float
[0] -= ebuffer
->radius
;
211 g_free(buffer_float
[0]);
212 g_free(buffer_float
);
215 buffer_float
= (gfloat
**) (ebuffer
->buffer
);
216 buffer_float
-= ebuffer
->radius
* 4;
217 buffer_float
[0] -= ebuffer
->radius
* 4;
218 g_free(buffer_float
[0]);
219 g_free(buffer_float
);
227 #endif /* __LQR_DEBUG__ */
234 lqr_energy_buffer_read_bright (LqrEnergyBuffer
* ebuffer
, gint x
, gint y
)
236 gfloat
** buffer_float
;
238 if (ebuffer
== NULL
|| ebuffer
->read_t
!= LQR_ER_BRIGHT
||
239 x
< -ebuffer
->radius
|| x
> ebuffer
->radius
||
240 y
< -ebuffer
->radius
|| y
> ebuffer
->radius
)
245 buffer_float
= (gfloat
**) (ebuffer
->buffer
);
247 return buffer_float
[x
][y
];
252 lqr_energy_buffer_read_luma (LqrEnergyBuffer
* ebuffer
, gint x
, gint y
)
254 gfloat
** buffer_float
;
256 if (ebuffer
== NULL
|| ebuffer
->read_t
!= LQR_ER_LUMA
||
257 x
< -ebuffer
->radius
|| x
> ebuffer
->radius
||
258 y
< -ebuffer
->radius
|| y
> ebuffer
->radius
)
264 buffer_float
= (gfloat
**) (ebuffer
->buffer
);
266 return buffer_float
[x
][y
];
271 lqr_energy_buffer_read_rgba (LqrEnergyBuffer
* ebuffer
, gint x
, gint y
, gint channel
)
273 gfloat
** buffer_float
;
275 if (ebuffer
== NULL
|| ebuffer
->read_t
!= LQR_ER_RGBA
||
276 x
< -ebuffer
->radius
|| x
> ebuffer
->radius
||
277 y
< -ebuffer
->radius
|| y
> ebuffer
->radius
||
278 channel
< 0 || channel
> 3)
283 buffer_float
= (gfloat
**) (ebuffer
->buffer
);
285 return buffer_float
[x
][y
] + channel
;
290 lqr_energy_buffer_read_custom (LqrEnergyBuffer
* ebuffer
, gint x
, gint y
, gint channel
)
292 /* gfloat ** buffer_float; */
294 if (ebuffer
== NULL
|| ebuffer
->read_t
!= LQR_ER_CUSTOM
||
295 x
< -ebuffer
->radius
|| x
> ebuffer
->radius
||
296 y
< -ebuffer
->radius
|| y
> ebuffer
->radius
)
301 /* buffer_float = (gfloat **) (ebuffer->buffer); */
303 /* return ebuffer->buffer[x][y] + channel; */
310 lqr_energy_buffer_get_read_t (LqrEnergyBuffer
* ebuffer
)
312 return ebuffer
->read_t
;
317 lqr_energy_buffer_get_radius (LqrEnergyBuffer
* ebuffer
)
319 return ebuffer
->radius
;