File indexing completed on 2024-04-28 15:10:12
0001 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0002 0003 This file is part of SEP 0004 0005 SPDX-FileCopyrightText: 2014 SEP developers 0006 SPDX-FileCopyrightText: 1993-2011 Emmanuel Bertin -- IAP /CNRS/UPMC 0007 SPDX-FileCopyrightText: 2014 SEP developers 0008 0009 All content except array comparison functions fqcmp() and fqmedian() is 0010 distributed under an MIT license. 0011 Array comparison functions fqcmp() and fqmedian() are distributed under an 0012 LGPL license: 0013 SPDX-License-Identifier: MIT AND LGPL-2.0-or-later 0014 0015 0016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 0017 0018 #include <math.h> 0019 #include <stdio.h> 0020 #include <stdlib.h> 0021 #include <string.h> 0022 #include "sep.h" 0023 #include "sepcore.h" 0024 0025 #define DETAILSIZE 512 0026 0027 char *sep_version_string = "0.6.0"; 0028 static char _errdetail_buffer[DETAILSIZE] = ""; 0029 0030 /****************************************************************************/ 0031 /* data type conversion mechanics for runtime type conversion */ 0032 0033 PIXTYPE convert_dbl(void *ptr) 0034 { 0035 return *(double *)ptr; 0036 } 0037 0038 PIXTYPE convert_flt(void *ptr) 0039 { 0040 return *(float *)ptr; 0041 } 0042 0043 PIXTYPE convert_int(void *ptr) 0044 { 0045 return *(int *)ptr; 0046 } 0047 0048 PIXTYPE convert_byt(void *ptr) 0049 { 0050 return *(BYTE *)ptr; 0051 } 0052 0053 /* return the correct converter depending on the datatype code */ 0054 int get_converter(int dtype, converter *f, int *size) 0055 { 0056 int status = RETURN_OK; 0057 0058 if (dtype == SEP_TFLOAT) 0059 { 0060 *f = convert_flt; 0061 *size = sizeof(float); 0062 } 0063 else if (dtype == SEP_TINT) 0064 { 0065 *f = convert_int; 0066 *size = sizeof(int); 0067 } 0068 else if (dtype == SEP_TDOUBLE) 0069 { 0070 *f = convert_dbl; 0071 *size = sizeof(double); 0072 } 0073 else if (dtype == SEP_TBYTE) 0074 { 0075 *f = convert_byt; 0076 *size = sizeof(BYTE); 0077 } 0078 else 0079 { 0080 *f = NULL; 0081 *size = 0; 0082 status = ILLEGAL_DTYPE; 0083 } 0084 return status; 0085 } 0086 0087 /* array conversions */ 0088 void convert_array_flt(void *ptr, int n, PIXTYPE *target) 0089 { 0090 float *source = (float *)ptr; 0091 int i; 0092 for (i=0; i<n; i++, source++) 0093 target[i] = *source; 0094 } 0095 0096 void convert_array_dbl(void *ptr, int n, PIXTYPE *target) 0097 { 0098 double *source = (double *)ptr; 0099 int i; 0100 for (i=0; i<n; i++, source++) 0101 target[i] = *source; 0102 } 0103 0104 void convert_array_int(void *ptr, int n, PIXTYPE *target) 0105 { 0106 int *source = (int *)ptr; 0107 int i; 0108 for (i=0; i<n; i++, source++) 0109 target[i] = *source; 0110 } 0111 0112 void convert_array_byt(void *ptr, int n, PIXTYPE *target) 0113 { 0114 BYTE *source = (BYTE *)ptr; 0115 int i; 0116 for (i=0; i<n; i++, source++) 0117 target[i] = *source; 0118 } 0119 0120 int get_array_converter(int dtype, array_converter *f, int *size) 0121 { 0122 int status = RETURN_OK; 0123 0124 if (dtype == SEP_TFLOAT) 0125 { 0126 *f = convert_array_flt; 0127 *size = sizeof(float); 0128 } 0129 else if (dtype == SEP_TBYTE) 0130 { 0131 *f = convert_array_byt; 0132 *size = sizeof(BYTE); 0133 } 0134 else if (dtype == SEP_TINT) 0135 { 0136 *f = convert_array_int; 0137 *size = sizeof(int); 0138 } 0139 else if (dtype == SEP_TDOUBLE) 0140 { 0141 *f = convert_array_dbl; 0142 *size = sizeof(double); 0143 } 0144 else 0145 { 0146 *f = NULL; 0147 *size = 0; 0148 status = ILLEGAL_DTYPE; 0149 } 0150 return status; 0151 } 0152 0153 0154 /****************************************************************************/ 0155 /* Copy a float array to various sorts of arrays */ 0156 0157 void write_array_dbl(float *ptr, int n, void *target) 0158 { 0159 double *t = (double *)target; 0160 int i; 0161 for (i=0; i<n; i++, ptr++) 0162 t[i] = (double)(*ptr); 0163 } 0164 0165 void write_array_int(float *ptr, int n, void *target) 0166 { 0167 int *t = (int *)target; 0168 int i; 0169 for (i=0; i<n; i++, ptr++) 0170 t[i] = (int)(*ptr+0.5); 0171 } 0172 0173 /* return the correct writer depending on the datatype code */ 0174 int get_array_writer(int dtype, array_writer *f, int *size) 0175 { 0176 int status = RETURN_OK; 0177 0178 if (dtype == SEP_TINT) 0179 { 0180 *f = write_array_int; 0181 *size = sizeof(int); 0182 } 0183 else if (dtype == SEP_TDOUBLE) 0184 { 0185 *f = write_array_dbl; 0186 *size = sizeof(double); 0187 } 0188 else 0189 { 0190 *f = NULL; 0191 *size = 0; 0192 status = ILLEGAL_DTYPE; 0193 } 0194 return status; 0195 } 0196 0197 /* subtract a float array from arrays of various types */ 0198 0199 void subtract_array_dbl(float *ptr, int n, void *target) 0200 { 0201 double *t = (double *)target; 0202 int i; 0203 for (i=0; i<n; i++, ptr++) 0204 t[i] -= (double)(*ptr); 0205 } 0206 0207 void subtract_array_flt(float *ptr, int n, void *target) 0208 { 0209 float *t = (float *)target; 0210 int i; 0211 for (i=0; i<n; i++, ptr++) 0212 t[i] -= *ptr; 0213 } 0214 0215 void subtract_array_int(float *ptr, int n, void *target) 0216 { 0217 int *t = (int *)target; 0218 int i; 0219 for (i=0; i<n; i++, ptr++) 0220 t[i] -= (int)(*ptr+0.5); 0221 } 0222 0223 /* return the correct subtractor depending on the datatype code */ 0224 int get_array_subtractor(int dtype, array_writer *f, int *size) 0225 { 0226 int status = RETURN_OK; 0227 char errtext[80]; 0228 0229 if (dtype == SEP_TFLOAT) 0230 { 0231 *f = subtract_array_flt; 0232 *size = sizeof(float); 0233 } 0234 else if (dtype == SEP_TINT) 0235 { 0236 *f = subtract_array_int; 0237 *size = sizeof(int); 0238 } 0239 else if (dtype == SEP_TDOUBLE) 0240 { 0241 *f = subtract_array_dbl; 0242 *size = sizeof(double); 0243 } 0244 else 0245 { 0246 *f = NULL; 0247 *size = 0; 0248 status = ILLEGAL_DTYPE; 0249 sprintf(errtext, "in get_array_subtractor(): %d", dtype); 0250 put_errdetail(errtext); 0251 } 0252 return status; 0253 } 0254 0255 /*****************************************************************************/ 0256 /* Error messaging */ 0257 0258 void sep_get_errmsg(int status, char *errtext) 0259 /* Return a short descriptive error message that corresponds to the input 0260 * error status value. The message may be up to 60 characters long, plus 0261 * the terminating null character. */ 0262 { 0263 errtext[0] = '\0'; 0264 switch (status) 0265 { 0266 case RETURN_OK: 0267 strcpy(errtext, "OK - no error"); 0268 break; 0269 case MEMORY_ALLOC_ERROR: 0270 strcpy(errtext, "memory allocation"); 0271 break; 0272 case PIXSTACK_FULL: 0273 strcpy(errtext, "internal pixel buffer full"); 0274 break; 0275 case DEBLEND_OVERFLOW: 0276 strcpy(errtext, "object deblending overflow"); 0277 break; 0278 case ILLEGAL_DTYPE: 0279 strcpy(errtext, "dtype not recognized/unsupported"); 0280 break; 0281 case ILLEGAL_SUBPIX: 0282 strcpy(errtext, "subpix value must be nonnegative"); 0283 break; 0284 case NON_ELLIPSE_PARAMS: 0285 strcpy(errtext, "parameters do not describe ellipse"); 0286 break; 0287 case ILLEGAL_APER_PARAMS: 0288 strcpy(errtext, "invalid aperture parameters"); 0289 break; 0290 case LINE_NOT_IN_BUF: 0291 strcpy(errtext, "array line out of buffer"); 0292 break; 0293 case RELTHRESH_NO_NOISE: 0294 strcpy(errtext, "relative threshold but image has noise_type of NONE"); 0295 break; 0296 case UNKNOWN_NOISE_TYPE: 0297 strcpy(errtext, "image has unknown noise_type"); 0298 break; 0299 default: 0300 strcpy(errtext, "unknown error status"); 0301 break; 0302 } 0303 } 0304 0305 void sep_get_errdetail(char *errtext) 0306 { 0307 strcpy(errtext, _errdetail_buffer); 0308 memset(_errdetail_buffer, 0, DETAILSIZE); 0309 } 0310 0311 void put_errdetail(char *errtext) 0312 { 0313 strcpy(_errdetail_buffer, errtext); 0314 0315 } 0316 0317 /*****************************************************************************/ 0318 /* Array median */ 0319 0320 static int fqcmp(const void *p1, const void *p2) 0321 /* Sorting function for floats, used in fqmedian() below. 0322 * Return value is 1 if *p1>*p2, 0 if *p1==*p2, -1 otherwise */ 0323 { 0324 double f1=*((float *)p1); 0325 double f2=*((float *)p2); 0326 return f1>f2? 1 : (f1<f2? -1 : 0); 0327 } 0328 0329 float fqmedian(float *ra, int n) 0330 /* Compute median of an array of floats. 0331 * 0332 * WARNING: input data are reordered! */ 0333 { 0334 int dqcmp(const void *p1, const void *p2); 0335 0336 qsort(ra, n, sizeof(float), fqcmp); 0337 if (n<2) 0338 return *ra; 0339 else 0340 return n&1? ra[n/2] : (ra[n/2-1]+ra[n/2])/2.0; 0341 }