1 2/* is_colour_space str: is a string one of nip's colour space names 3 */ 4is_colour_space str = Image_type.colour_spaces.present 0 str; 5 6/* is_colour_type n: is a number one of VIPS's colour spaces 7 */ 8is_colour_type n = Image_type.colour_spaces.present 1 n; 9 10/* is_number: is a real or a complex number. 11 */ 12is_number a = is_real a || is_complex a; 13 14/* is_int: is an integer 15 */ 16is_int a = is_real a && a == (int) a; 17 18/* is_uint: is an unsigned integer 19 */ 20is_uint a = is_int a && a >= 0; 21 22/* is_pint: is a positive integer 23 */ 24is_pint a = is_int a && a > 0; 25 26/* is_preal: is a positive real 27 */ 28is_preal a = is_real a && a > 0; 29 30/* is_ureal: is an unsigned real 31 */ 32is_ureal a = is_real a && a >= 0; 33 34/* is_letter c: true of character c is an ASCII letter 35 * 36 * is_letter :: char -> bool 37 */ 38is_letter c = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); 39 40/* is_digit c: true if character c is an ASCII digit 41 * 42 * is_digit :: char->bool 43 */ 44is_digit x = '0' <= x && x <= '9'; 45 46/* A whitespace character. 47 * 48 * is_space :: char->bool 49 */ 50is_space = member " \n\t"; 51 52/* is_listof p s: true if finite list with p true for every element. 53 */ 54is_listof p l = is_list l && land (map p l); 55 56/* is_string s: true if finite list of char. 57 */ 58is_string s = is_listof is_char s; 59 60/* is_real_list l: is l a list of real numbers ... test each element, 61 * so no infinite lists pls. 62 */ 63is_real_list l = is_listof is_real l; 64 65/* is_string_list l: is l a finite list of finite strings. 66 */ 67is_string_list l = is_listof is_string l; 68 69/* is_rectangular l: is l a rectangular data structure 70 */ 71is_rectangular l 72 = true, !is_list l 73 = true, land (map is_obj l) 74 = true, land (map is_list l) && 75 land (map (not @ is_obj) l) && 76 land (map is_rectangular l) && 77 len l > 0 && 78 land (map (equal (hd lengths)) (tl lengths)) 79 = false 80{ 81 // treat strings as a base type, not [char] 82 is_obj x = !is_list x || is_string x; 83 lengths = map len l; 84} 85 86/* is_matrix l: is l a list of lists of real numbers, all the same length 87 */ 88is_matrix l = is_listof is_real_list l && is_rectangular l; 89 90/* is_square_matrix l: is l a matrix with width == height 91 */ 92is_square_matrix l 93 = true, l == [] 94 = is_matrix l && len l == len (hd l); 95 96/* is_oddmatrix l: is l a matrix with odd-length sides 97 */ 98is_oddmatrix l 99 = true, l == [] 100 = is_matrix l && (len l) % 2 == 1 && (len (l?0)) % 2 == 1; 101 102/* is_odd_square_matrix l: is l a square_matrix with odd-length sides 103 */ 104is_odd_square_matrix l = is_square_matrix l && (len l) % 2 == 1; 105 106/* Is an item in a column of a table? 107 */ 108is_incolumn n table x = member (map (extract n) table) x; 109 110/* Is HGuide or VGuide. 111 */ 112is_HGuide x = is_instanceof "HGuide" x; 113 114is_VGuide x = is_instanceof "VGuide" x; 115 116is_Guide x = is_HGuide x || is_VGuide x; 117 118is_Mark x = is_instanceof "Mark" x; 119 120is_Group x = is_instanceof "Group" x; 121 122is_Image x = is_instanceof "Image" x; 123 124is_Region x = is_instanceof "Region" x; 125 126is_Real x = is_instanceof "Real" x; 127 128is_Matrix x = is_instanceof "Matrix_base" x; 129 130is_Vector x = is_instanceof "Vector" x; 131 132is_Colour x = is_instanceof "Colour" x; 133 134is_Arrow x = is_instanceof "Arrow" x; 135 136is_Bool x = is_instanceof "Bool" x; 137 138is_Slider x = is_instanceof "Scale" x; 139 140is_Rect x = is_instanceof "Rect" x; 141 142is_Number x = is_instanceof "Number" x; 143 144is_Expression x = is_instanceof "Expression" x; 145 146is_String x = is_instanceof "String" x; 147 148/* A list of the form [[1,2],[3,4],[5,6]...] 149 */ 150is_xy_list l 151 = is_list l && land (map xy l) 152{ 153 xy l = is_real_list l && len l == 2; 154} 155 156/* Does an object have a sensible VIPS type? 157 */ 158has_type x = is_image x || is_Image x || is_Arrow x || is_Colour x; 159 160/* Try to get a VIPS image type from an object. 161 */ 162get_type x 163 = get_type_im x, is_image x 164 = get_type_im x.value, is_Image x 165 = get_type_im x.image.value, is_Arrow x 166 = Image_type.colour_spaces.lookup 0 1 x.colour_space, is_Colour x 167 // slightly odd ... but our display is always 0-255, so it makes sense for 168 // a plain number to be in the same range 169 = Image_type.sRGB, is_real x 170 = error ("get_type: unable to get type from " ++ print x) 171{ 172 // get the type from a VIPS image ... but only if it makes sense with 173 // the rest of the image 174 175 // we often have Type set wrong, hence the ugly guessing :-( 176 get_type_im im 177 = Image_type.LABQ, coding == Image_coding.LABPACK 178 = Image_type.B_W, bands == 1 179 = type, bands == 3 && is_colorimetric 180 = Image_type.sRGB, bands == 3 && !is_colorimetric 181 = Image_type.MULTIBAND, bands != 3 && !is_colorimetric 182 = type 183 { 184 type = im_header_int "Type" im; 185 coding = im_header_int "Coding" im; 186 bands = im_header_int "Bands" im; 187 188 // 3-band colorimetric types we allow ... the things which the 189 // Colour/Convert To menu can make, excluding mono. 190 ok_types = [ 191 Image_type.sRGB, 192 Image_type.LAB, 193 Image_type.LABQ, 194 Image_type.LABS, 195 Image_type.LCH, 196 Image_type.XYZ, 197 Image_type.YXY, 198 Image_type.UCS 199 ]; 200 is_colorimetric = member ok_types type; 201 } 202} 203 204has_format x = has_member "format" x || is_Arrow x || is_image x; 205 206get_format x 207 = x.format, has_member "format" x 208 = x.image.format, is_Arrow x 209 = im_header_int "BandFmt" x, is_image x 210 = error ("get_format: unable to get format from " ++ print x); 211 212has_bits x = has_member "bits" x || is_Arrow x || is_image x; 213 214get_bits x 215 = x.bits, has_member "bits" x 216 = x.image.bits, is_Arrow x 217 = im_header_int "Bbits" x, is_image x 218 = error ("get_bits: unable to get bits from " ++ print x); 219 220has_bands x = is_image x || has_member "bands" x || is_Arrow x; 221 222get_bands x 223 = x.bands, has_member "bands" x 224 = x.image.bands, is_Arrow x 225 = im_header_int "Bands" x, is_image x 226 = 1, is_real x 227 = len x, is_real_list x 228 = error ("get_bands: unable to get bands from " ++ print x); 229 230has_coding x = has_member "coding" x || is_Arrow x || is_image x; 231 232get_coding x 233 = x.coding, has_member "coding" x 234 = x.image.coding, is_Arrow x 235 = im_header_int "Coding" x, is_image x 236 = Image_coding.NOCODING, is_real x 237 = error ("get_coding: unable to get coding from " ++ print x); 238 239has_xres x = has_member "xres" x || is_Arrow x || is_image x; 240 241get_xres x 242 = x.xres, has_member "xres" x 243 = x.image.xres, is_Arrow x 244 = im_header_int "Xres" x, is_image x 245 = error ("get_xres: unable to get xres from " ++ print x); 246 247has_yres x = has_member "yres" x || is_Arrow x || is_image x; 248 249get_yres x 250 = x.yres, has_member "yres" x 251 = x.image.yres, is_Arrow x 252 = im_header_int "Yres" x, is_image x 253 = error ("get_yres: unable to get yres from " ++ print x); 254 255has_xoffset x = has_member "xoffset" x || is_Arrow x || is_image x; 256 257get_xoffset x 258 = x.xoffset, has_member "xoffset" x 259 = x.image.xoffset, is_Arrow x 260 = im_header_int "Xoffset" x, is_image x 261 = error ("get_xoffset: unable to get xoffset from " ++ print x); 262 263has_yoffset x = has_member "yoffset" x || is_Arrow x || is_image x; 264 265get_yoffset x 266 = x.yoffset, has_member "yoffset" x 267 = x.image.yoffset, is_Arrow x 268 = im_header_int "Yoffset" x, is_image x 269 = error ("get_yoffset: unable to get yoffset from " ++ print x); 270 271has_value = has_member "value"; 272 273get_value x = x.value; 274 275has_image x = is_image x || is_Image x || is_Arrow x; 276 277get_image x 278 = x.value, is_Image x 279 = x.image.value, is_Arrow x 280 = x, is_image x 281 = error ("get_image: unable to get image from " ++ print x); 282 283has_number x = is_number x || is_Real x; 284 285get_number x 286 = x.value, is_Real x 287 = x, is_number x 288 = error ("get_number: unable to get number from " ++ print x); 289 290has_real x = is_real x || is_Real x; 291 292get_real x 293 = x.value, is_Real x 294 = x, is_real x 295 = error ("get_real: unable to get real from " ++ print x); 296 297has_width x = has_member "width" x || is_image x; 298 299get_width x 300 = x.width, has_member "width" x 301 = im_header_int "Xsize" x, is_image x 302 = error ("get_width: unable to get width from " ++ print x); 303 304has_height x = has_member "height" x || is_image x; 305 306get_height x 307 = x.height, has_member "height" x 308 = im_header_int "Ysize" x, is_image x 309 = error ("get_height: unable to get height from " ++ print x); 310 311has_left x = has_member "left" x; 312 313get_left x 314 = x.left, has_member "left" x 315 = error ("get_left: unable to get left from " ++ print x); 316 317has_top x = has_member "top" x; 318 319get_top x 320 = x.top, has_member "top" x 321 = error ("get_top: unable to get top from " ++ print x); 322 323// like has/get member,but first in a lst of objects 324has_member_list has objects 325 = filter has objects != []; 326 327// get a member from the first of a list of objects to have it 328get_member_list has get objects 329 = hd members, members != [] 330 = error "unable to get property" 331{ 332 members = map get (filter has objects); 333} 334 335is_hist x 336 = has_image x && (h == 1 || w == 1 || t == Image_type.HISTOGRAM) 337{ 338 im = get_image x; 339 w = get_width im; 340 h = get_height im; 341 t = get_type im; 342} 343