1 /* Various useful definitions.
2  *
3  * J.Cupitt, 8/4/93
4  * 15/7/96 JC
5  *	- C++ stuff added
6  */
7 
8 /*
9 
10     This file is part of VIPS.
11 
12     VIPS is free software; you can redistribute it and/or modify
13     it under the terms of the GNU Lesser General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16 
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20     GNU Lesser General Public License for more details.
21 
22     You should have received a copy of the GNU Lesser General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25     02110-1301  USA
26 
27  */
28 
29 /*
30 
31     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
32 
33  */
34 
35 #ifndef VIPS_UTIL_H
36 #define VIPS_UTIL_H
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif /*__cplusplus*/
41 
42 #include <stdio.h>
43 #include <math.h>
44 
45 /* Some platforms don't have M_PI :-(
46  */
47 #define VIPS_PI (3.14159265358979323846)
48 
49 /* Convert degrees->rads and vice-versa.
50  */
51 #define VIPS_RAD( R ) (((R) / 360.0) * 2.0 * VIPS_PI)
52 #define VIPS_DEG( A ) (((A) / (2.0 * VIPS_PI)) * 360.0)
53 
54 #define VIPS_MAX( A, B ) ((A) > (B) ? (A) : (B))
55 #define VIPS_MIN( A, B ) ((A) < (B) ? (A) : (B))
56 
57 #define VIPS_CLIP( A, V, B ) VIPS_MAX( (A), VIPS_MIN( (B), (V) ) )
58 #define VIPS_FCLIP( A, V, B ) VIPS_FMAX( (A), VIPS_FMIN( (B), (V) ) )
59 
60 #define VIPS_NUMBER( R ) ((int) (sizeof(R) / sizeof(R[0])))
61 
62 #define VIPS_ABS( X ) (((X) >= 0) ? (X) : -(X))
63 
64 /* The built-in isnan and isinf functions provided by gcc 4+ and clang are
65  * up to 7x faster than their libc equivalent included from <math.h>.
66  */
67 #if defined(__clang__) || (__GNUC__ >= 4)
68 #define VIPS_ISNAN( V ) __builtin_isnan( V )
69 #define VIPS_FLOOR( V ) __builtin_floor( V )
70 #define VIPS_CEIL( V ) __builtin_ceil( V )
71 #define VIPS_RINT( V ) __builtin_rint( V )
72 #define VIPS_ROUND( V ) __builtin_round( V )
73 #define VIPS_FABS( V ) __builtin_fabs( V )
74 #define VIPS_FMAX( A, B ) __builtin_fmax( A, B )
75 #define VIPS_FMIN( A, B ) __builtin_fmin( A, B )
76 #else
77 #define VIPS_ISNAN( V ) isnan( V )
78 #define VIPS_FLOOR( V ) floor( V )
79 #define VIPS_CEIL( V ) ceil( V )
80 #define VIPS_RINT( V ) rint( V )
81 #define VIPS_ROUND( V ) round( V )
82 #define VIPS_FABS( V ) VIPS_ABS( V )
83 #define VIPS_FMAX( A, B ) VIPS_MAX( A, B )
84 #define VIPS_FMIN( A, B ) VIPS_MIN( A, B )
85 #endif
86 
87 /* Testing status before the function call saves a lot of time.
88  */
89 #define VIPS_ONCE( ONCE, FUNC, CLIENT ) \
90 G_STMT_START { \
91         if( G_UNLIKELY( (ONCE)->status != G_ONCE_STATUS_READY ) ) \
92 		(void) g_once( ONCE, FUNC, CLIENT ); \
93 } G_STMT_END
94 
95 /* VIPS_RINT() does "bankers rounding", it rounds to the nearest even integer.
96  * For things like image geometry, we want strict nearest int.
97  *
98  * If you know it's unsigned, _UINT is a little faster.
99  */
100 #define VIPS_ROUND_INT( R ) ((int) ((R) > 0 ? ((R) + 0.5) : ((R) - 0.5)))
101 #define VIPS_ROUND_UINT( R ) ((int) ((R) + 0.5))
102 
103 /* Round N down and up to the nearest multiple of P.
104  */
105 #define VIPS_ROUND_DOWN( N, P ) ((N) - ((N) % (P)))
106 #define VIPS_ROUND_UP( N, P ) (VIPS_ROUND_DOWN( (N) + (P) - 1, (P) ))
107 
108 #define VIPS_SWAP( TYPE, A, B ) \
109 G_STMT_START { \
110 	TYPE t = (A); \
111 	(A) = (B); \
112 	(B) = t; \
113 } G_STMT_END
114 
115 /* Duff's device. Do OPERation N times in a 16-way unrolled loop.
116  */
117 #define VIPS_UNROLL( N, OPER ) \
118 G_STMT_START { \
119 	if( (N) ) { \
120 		int duff_count = ((N) + 15) / 16; \
121 		\
122 		switch( (N) % 16 ) { \
123 		case 0:  do {   OPER;  \
124 		case 15:        OPER;  \
125 		case 14:        OPER;  \
126 		case 13:        OPER;  \
127 		case 12:        OPER;  \
128 		case 11:        OPER;  \
129 		case 10:        OPER;  \
130 		case 9:         OPER;  \
131 		case 8:         OPER;  \
132 		case 7:         OPER;  \
133 		case 6:         OPER;  \
134 		case 5:         OPER;  \
135 		case 4:         OPER;  \
136 		case 3:         OPER;  \
137 		case 2:         OPER;  \
138 		case 1: 	OPER;  \
139 			 } while( --duff_count > 0 ); \
140 		} \
141 	} \
142 } G_STMT_END
143 
144 /* The g_info() macro was added in 2.40.
145  */
146 #ifndef g_info
147 /* Hopefully we have varargs macros. Maybe revisit this.
148  */
149 #define g_info(...) \
150 	 g_log( G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__ )
151 #endif
152 
153 /* Various integer range clips. Record over/under flows.
154  */
155 #define VIPS_CLIP_UCHAR( V, SEQ ) \
156 G_STMT_START { \
157 	if( (V) < 0 ) {   \
158 		(SEQ)->underflow++;   \
159 		(V) = 0;   \
160 	}  \
161 	else if( (V) > UCHAR_MAX ) {   \
162 		(SEQ)->overflow++;   \
163 		(V) = UCHAR_MAX;   \
164 	}  \
165 } G_STMT_END
166 
167 #define VIPS_CLIP_CHAR( V, SEQ ) \
168 G_STMT_START { \
169 	if( (V) < SCHAR_MIN ) {   \
170 		(SEQ)->underflow++;   \
171 		(V) = SCHAR_MIN;   \
172 	}  \
173 	else if( (V) > SCHAR_MAX ) {   \
174 		(SEQ)->overflow++;   \
175 		(V) = SCHAR_MAX;   \
176 	}  \
177 } G_STMT_END
178 
179 #define VIPS_CLIP_USHORT( V, SEQ ) \
180 G_STMT_START { \
181 	if( (V) < 0 ) {   \
182 		(SEQ)->underflow++;   \
183 		(V) = 0;   \
184 	}  \
185 	else if( (V) > USHRT_MAX ) {   \
186 		(SEQ)->overflow++;   \
187 		(V) = USHRT_MAX;   \
188 	}  \
189 } G_STMT_END
190 
191 #define VIPS_CLIP_SHORT( V, SEQ ) \
192 G_STMT_START { \
193 	if( (V) < SHRT_MIN ) {   \
194 		(SEQ)->underflow++;   \
195 		(V) = SHRT_MIN;   \
196 	}  \
197 	else if( (V) > SHRT_MAX ) {   \
198 		(SEQ)->overflow++;   \
199 		(V) = SHRT_MAX;   \
200 	}  \
201 } G_STMT_END
202 
203 #define VIPS_CLIP_UINT( V, SEQ ) \
204 G_STMT_START { \
205 	if( (V) < 0 ) {   \
206 		(SEQ)->underflow++;   \
207 		(V) = 0;   \
208 	}  \
209 } G_STMT_END
210 
211 #define VIPS_CLIP_NONE( V, SEQ ) {}
212 
213 /* Not all platforms have PATH_MAX (eg. Hurd) and we don't need a platform one
214  * anyway, just a static buffer big enough for almost any path.
215  */
216 #define VIPS_PATH_MAX (4096)
217 
218 const char *vips_enum_string( GType enm, int value );
219 const char *vips_enum_nick( GType enm, int value );
220 int vips_enum_from_nick( const char *domain, GType type, const char *str );
221 int vips_flags_from_nick( const char *domain, GType type, const char *nick );
222 
223 gboolean vips_slist_equal( GSList *l1, GSList *l2 );
224 void *vips_slist_map2( GSList *list, VipsSListMap2Fn fn, void *a, void *b );
225 void *vips_slist_map2_rev( GSList *list, VipsSListMap2Fn fn, void *a, void *b );
226 void *vips_slist_map4( GSList *list,
227 	VipsSListMap4Fn fn, void *a, void *b, void *c, void *d );
228 void *vips_slist_fold2( GSList *list, void *start,
229 	VipsSListFold2Fn fn, void *a, void *b );
230 GSList *vips_slist_filter( GSList *list, VipsSListMap2Fn fn, void *a, void *b );
231 void vips_slist_free_all( GSList *list );
232 void *vips_map_equal( void *a, void *b );
233 
234 void *vips_hash_table_map( GHashTable *hash,
235 	VipsSListMap2Fn fn, void *a, void *b );
236 
237 char *vips_strncpy( char *dest, const char *src, int n );
238 char *vips_strrstr( const char *haystack, const char *needle );
239 gboolean vips_ispostfix( const char *a, const char *b );
240 gboolean vips_iscasepostfix( const char *a, const char *b );
241 gboolean vips_isprefix( const char *a, const char *b );
242 char *vips_break_token( char *str, const char *brk );
243 
244 void vips__chomp( char *str );
245 
246 int vips_vsnprintf( char *str, size_t size, const char *format, va_list ap );
247 int vips_snprintf( char *str, size_t size, const char *format, ... )
248 	__attribute__((format(printf, 3, 4)));
249 
250 int vips_filename_suffix_match( const char *path, const char *suffixes[] );
251 
252 gint64 vips_file_length( int fd );
253 int vips__write( int fd, const void *buf, size_t count );
254 
255 int vips__open( const char *filename, int flags, int mode );
256 int vips__open_read( const char *filename );
257 FILE *vips__fopen( const char *filename, const char *mode );
258 
259 FILE *vips__file_open_read( const char *filename,
260 	const char *fallback_dir, gboolean text_mode );
261 FILE *vips__file_open_write( const char *filename,
262 	gboolean text_mode );
263 char *vips__file_read( FILE *fp, const char *name, size_t *length_out );
264 char *vips__file_read_name( const char *name, const char *fallback_dir,
265 	size_t *length_out );
266 int vips__file_write( void *data, size_t size, size_t nmemb, FILE *stream );
267 gint64 vips__get_bytes( const char *filename,
268 	unsigned char buf[], gint64 len );
269 int vips__fgetc( FILE *fp );
270 
271 GValue *vips__gvalue_ref_string_new( const char *text );
272 void vips__gslist_gvalue_free( GSList *list );
273 GSList *vips__gslist_gvalue_copy( const GSList *list );
274 GSList *vips__gslist_gvalue_merge( GSList *a, const GSList *b );
275 char *vips__gslist_gvalue_get( const GSList *list );
276 
277 gint64 vips__seek_no_error( int fd, gint64 pos, int whence );
278 gint64 vips__seek( int fd, gint64 pos, int whence );
279 int vips__ftruncate( int fd, gint64 pos );
280 int vips_existsf( const char *name, ... )
281 	__attribute__((format(printf, 1, 2)));
282 int vips_isdirf( const char *name, ... )
283 	__attribute__((format(printf, 1, 2)));
284 int vips_mkdirf( const char *name, ... )
285 	__attribute__((format(printf, 1, 2)));
286 int vips_rmdirf( const char *name, ... )
287 	__attribute__((format(printf, 1, 2)));
288 int vips_rename( const char *old_name, const char *new_name );
289 
290 /**
291  * VipsToken:
292  * @VIPS_TOKEN_LEFT: left bracket
293  * @VIPS_TOKEN_RIGHT: right bracket
294  * @VIPS_TOKEN_STRING: string constant
295  * @VIPS_TOKEN_EQUALS: equals sign
296  * @VIPS_TOKEN_COMMA: comma
297  *
298  * Tokens returned by the vips lexical analyzer, see vips__token_get(). This
299  * is used to parse option strings for arguments.
300  *
301  * Left and right brackets can be any of (, {, [, <.
302  *
303  * Strings may be in double quotes, and may contain escaped quote characters,
304  * for example string, "string" and "str\"ing".
305  *
306  */
307 typedef enum {
308  	VIPS_TOKEN_LEFT = 1,
309 	VIPS_TOKEN_RIGHT,
310 	VIPS_TOKEN_STRING,
311 	VIPS_TOKEN_EQUALS,
312 	VIPS_TOKEN_COMMA
313 } VipsToken;
314 
315 const char *vips__token_get( const char *buffer,
316 	VipsToken *token, char *string, int size );
317 const char *vips__token_must( const char *buffer, VipsToken *token,
318 	char *string, int size );
319 const char *vips__token_need( const char *buffer, VipsToken need_token,
320 	char *string, int size );
321 const char *vips__token_segment( const char *p, VipsToken *token,
322 	char *string, int size );
323 const char *vips__token_segment_need( const char *p, VipsToken need_token,
324 	char *string, int size );
325 const char *vips__find_rightmost_brackets( const char *p );
326 void vips__filename_split8( const char *name,
327 	char *filename, char *option_string );
328 
329 int vips_ispoweroftwo( int p );
330 int vips_amiMSBfirst( void );
331 
332 char *vips__temp_name( const char *format );
333 
334 void vips__change_suffix( const char *name, char *out, int mx,
335         const char *new_suff, const char **olds, int nolds );
336 
337 char *vips_realpath( const char *path );
338 
339 guint32 vips__random( guint32 seed );
340 guint32 vips__random_add( guint32 seed, int value );
341 
342 const char *vips__icc_dir( void );
343 const char *vips__windows_prefix( void );
344 
345 char *vips__get_iso8601( void );
346 
347 int vips_strtod( const char *str, double *out );
348 
349 #ifdef __cplusplus
350 }
351 #endif /*__cplusplus*/
352 
353 #endif /*VIPS_UTIL_H*/
354