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