55
55
56
56
#include < stdio.h>
57
57
#include < string.h>
58
- #if _MSC_VER
58
+ #ifdef _MSC_VER
59
59
#include < cstdlib>
60
60
#else
61
61
#include < stdlib.h>
62
62
#endif
63
63
#include < math.h>
64
64
65
+ #if defined(HAVE__ALIGNED_MALLOC) || defined(HAVE_MEMALIGN)
66
+ #include < malloc.h>
67
+ #endif
68
+
65
69
#include < vips/vips.h>
66
70
#include < vips/internal.h>
67
71
#include < vips/debug.h>
@@ -159,7 +163,8 @@ vips_composite_base_dispose( GObject *gobject )
159
163
G_OBJECT_CLASS ( vips_composite_base_parent_class )->dispose ( gobject );
160
164
}
161
165
162
- /* Our sequence value.
166
+ /* Our sequence value. This must be aligned on a 16-byte boundary when
167
+ * HAVE_VECTOR_ARITH is defined.
163
168
*/
164
169
typedef struct {
165
170
VipsCompositeBase *composite;
@@ -189,17 +194,46 @@ typedef struct {
189
194
VipsPel **p;
190
195
191
196
#ifdef HAVE_VECTOR_ARITH
192
- /* A pointer to the 'real' memory.
193
- */
194
- void *mem;
195
-
196
197
/* max_band as a vector, for the RGBA case.
197
198
*/
198
199
v4f max_band_vec;
199
200
#endif /* HAVE_VECTOR_ARITH*/
200
201
201
202
} VipsCompositeSequence;
202
203
204
+ #ifdef HAVE_VECTOR_ARITH
205
+ /* Allocate aligned memory. The return value can be released
206
+ * by calling the vips_free_aligned() function, for example:
207
+ * VIPS_FREEF( vips_free_aligned, ptr );
208
+ */
209
+ static inline void *
210
+ vips_alloc_aligned ( size_t sz, size_t align )
211
+ {
212
+ g_assert ( !(align & (align - 1 )) );
213
+ #ifdef HAVE__ALIGNED_MALLOC
214
+ return _aligned_malloc ( sz, align );
215
+ #elif defined(HAVE_POSIX_MEMALIGN)
216
+ void *ptr;
217
+ if ( posix_memalign ( &ptr, align, sz ) ) return NULL ;
218
+ return ptr;
219
+ #elif defined(HAVE_MEMALIGN)
220
+ return memalign ( align, sz );
221
+ #else
222
+ #error Missing aligned alloc implementation
223
+ #endif
224
+ }
225
+
226
+ static inline void
227
+ vips_free_aligned ( void * ptr )
228
+ {
229
+ #ifdef HAVE__ALIGNED_MALLOC
230
+ _aligned_free ( ptr );
231
+ #else /* defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_MEMALIGN)*/
232
+ free ( ptr );
233
+ #endif
234
+ }
235
+ #endif /* HAVE_VECTOR_ARITH*/
236
+
203
237
static int
204
238
vips_composite_stop ( void *vseq, void *a, void *b )
205
239
{
@@ -221,10 +255,7 @@ vips_composite_stop( void *vseq, void *a, void *b )
221
255
VIPS_FREE ( seq->p );
222
256
223
257
#ifdef HAVE_VECTOR_ARITH
224
- /* Must use g_free here, otherwise we end up writing to a
225
- * pointer that we just freed.
226
- */
227
- g_free ( seq->mem );
258
+ VIPS_FREEF ( vips_free_aligned, seq );
228
259
#else /* !defined(HAVE_VECTOR_ARITH)*/
229
260
VIPS_FREE ( seq );
230
261
#endif /* HAVE_VECTOR_ARITH*/
@@ -238,37 +269,18 @@ vips_composite_start( VipsImage *out, void *a, void *b )
238
269
VipsImage **in = (VipsImage **) a;
239
270
VipsCompositeBase *composite = (VipsCompositeBase *) b;
240
271
241
- void *mem;
242
272
VipsCompositeSequence *seq;
243
- int i, n, size;
244
-
245
- /* The size of our struct.
246
- */
247
- size = sizeof ( VipsCompositeSequence );
273
+ int i, n;
248
274
249
275
#ifdef HAVE_VECTOR_ARITH
250
276
/* Ensure that the memory is aligned on a 16-byte boundary.
251
277
*/
252
- size += 16 - 1 ;
253
- #endif /* HAVE_VECTOR_ARITH*/
254
-
255
- /* Allocate a new chunk of memory.
256
- */
257
- if ( !(mem = vips_malloc ( NULL , size )) )
258
- return ( NULL );
259
-
260
- #ifdef HAVE_VECTOR_ARITH
261
- /* Our aligned pointer.
262
- */
263
- seq = (VipsCompositeSequence *)
264
- (((guintptr) mem + 15 ) & ~(guintptr) 0x0F );
265
-
266
- /* Store the pointer to the 'real' memory.
267
- */
268
- seq->mem = mem;
278
+ if ( !(seq = ((VipsCompositeSequence *) vips_alloc_aligned (
279
+ sizeof ( VipsCompositeSequence ), 16 ))) )
269
280
#else /* !defined(HAVE_VECTOR_ARITH)*/
270
- seq = ( VipsCompositeSequence *) mem;
281
+ if ( !( seq = VIPS_NEW ( NULL , VipsCompositeSequence )) )
271
282
#endif /* HAVE_VECTOR_ARITH*/
283
+ return ( NULL );
272
284
273
285
seq->composite = composite;
274
286
seq->input_regions = NULL ;
0 commit comments