File indexing completed on 2024-04-28 03:43:55

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 }