static int mget(union VALUETYPE* p, u_char *s, struct magic *m, int nbytes) { int32_t offset = m->offset; if (offset + sizeof(union VALUETYPE) <= nbytes) memcpy(p, s + offset, sizeof(*p)); else { /* * the usefulness of padding with zeroes eludes me, it * might even cause problems */ int32_t have = nbytes - offset; memset(p, 0, sizeof(*p)); if (have > 0) memcpy(p, s + offset, have); } if (!mconvert(p, m)) return (0); if (m->flag & INDIR) { switch (m->in.type) { case BYTE: offset = p->b + m->in.offset; break; case SHORT: offset = p->h + m->in.offset; break; case LONG: offset = p->l + m->in.offset; break; } if (offset + sizeof(*p) > nbytes) return (0); memcpy(p, s + offset, sizeof(*p)); if (!mconvert(p, m)) return (0); } return (1); }
int sep_windowed(sep_image *im, double x, double y, double sig, int subpix, short inflag, double *xout, double *yout, int *niter, short *flag) { PIXTYPE pix, varpix; double dx, dy, dx1, dy2, offset, scale, scale2, tmp, dxpos, dypos, weight; double maskarea, maskweight, maskdxpos, maskdypos; double r, tv, twv, sigtv, totarea, overlap, rpix2, invtwosig2; double wpix; int i, ix, iy, xmin, xmax, ymin, ymax, sx, sy, status, size, esize, msize; long pos; short errisarray, errisstd; BYTE *datat, *errort, *maskt; converter convert, econvert, mconvert; double r2, r_in2, r_out2; /* input checks */ if (sig < 0.0) return ILLEGAL_APER_PARAMS; if (subpix < 0) return ILLEGAL_SUBPIX; /* initializations */ size = esize = msize = 0; tv = sigtv = 0.0; overlap = totarea = maskweight = 0.0; datat = maskt = NULL; errort = im->noise; *flag = 0; varpix = 0.0; scale = 1.0/subpix; scale2 = scale*scale; offset = 0.5*(scale-1.0); invtwosig2 = 1.0/(2.0*sig*sig); errisarray = 0; errisstd = 0; /* Integration radius */ r = WINPOS_NSIG*sig; /* calculate oversampled annulus */ r2 = r*r; oversamp_ann_circle(r, &r_in2, &r_out2); /* get data converter(s) for input array(s) */ if ((status = get_converter(im->dtype, &convert, &size))) return status; if (im->mask && (status = get_converter(im->mdtype, &mconvert, &msize))) return status; /* get image noise */ if (im->noise_type != SEP_NOISE_NONE) { errisstd = (im->noise_type == SEP_NOISE_STDDEV); if (im->noise) { errisarray = 1; if ((status = get_converter(im->ndtype, &econvert, &esize))) return status; } else { varpix = (errisstd)? im->noiseval * im->noiseval: im->noiseval; } } /* iteration loop */ for (i=0; i<WINPOS_NITERMAX; i++) { /* get extent of box */ boxextent(x, y, r, r, im->w, im->h, &xmin, &xmax, &ymin, &ymax, flag); /* TODO: initialize values */ //mx2ph //my2ph // esum, emxy, emx2, emy2, mx2, my2, mxy tv = twv = sigtv = 0.0; overlap = totarea = maskarea = maskweight = 0.0; dxpos = dypos = 0.0; maskdxpos = maskdypos = 0.0; /* loop over rows in the box */ for (iy=ymin; iy<ymax; iy++) { /* set pointers to the start of this row */ pos = (iy % im->h) * im->w + xmin; datat = MSVC_VOID_CAST im->data + pos*size; if (errisarray) errort = MSVC_VOID_CAST im->noise + pos*esize; if (im->mask) maskt = MSVC_VOID_CAST im->mask + pos*msize; /* loop over pixels in this row */ for (ix=xmin; ix<xmax; ix++) { dx = ix - x; dy = iy - y; rpix2 = dx*dx + dy*dy; if (rpix2 < r_out2) { if (rpix2 > r_in2) /* might be partially in aperture */ { if (subpix == 0) overlap = circoverlap(dx-0.5, dy-0.5, dx+0.5, dy+0.5, r); else { dx += offset; dy += offset; overlap = 0.0; for (sy=subpix; sy--; dy+=scale) { dx1 = dx; dy2 = dy*dy; for (sx=subpix; sx--; dx1+=scale) if (dx1*dx1 + dy2 < r2) overlap += scale2; } } } else /* definitely fully in aperture */ overlap = 1.0; /* get pixel value and variance value */ pix = convert(datat); if (errisarray) { varpix = econvert(errort); if (errisstd) varpix *= varpix; } /* offset of this pixel from center */ dx = ix - x; dy = iy - y; /* weight by gaussian */ weight = exp(-rpix2*invtwosig2); if (im->mask && (mconvert(maskt) > im->maskthresh)) { *flag |= SEP_APER_HASMASKED; maskarea += overlap; maskweight += overlap * weight; maskdxpos += overlap * weight * dx; maskdypos += overlap * weight * dy; } else { tv += pix * overlap; wpix = pix * overlap * weight; twv += wpix; dxpos += wpix * dx; dypos += wpix * dy; } totarea += overlap; } /* closes "if pixel might be within aperture" */ /* increment pointers by one element */ datat += size; if (errisarray) errort += esize; maskt += msize; } /* closes loop over x */ } /* closes loop over y */ /* we're done looping over pixels for this iteration. * Our summary statistics are: * * tv : total value * twv : total weighted value * dxpos : weighted dx * dypos : weighted dy */ /* Correct for masked values: This effectively makes it as if * the masked pixels had the value of the average unmasked value * in the aperture. */ if (im->mask) { /* this option will probably not yield accurate values */ if (inflag & SEP_MASK_IGNORE) totarea -= maskarea; else { tmp = tv/(totarea-maskarea); /* avg unmasked pixel value */ twv += tmp * maskweight; dxpos += tmp * maskdxpos; dypos += tmp * maskdypos; } } /* update center */ if (twv>0.0) { x += (dxpos /= twv) * WINPOS_FAC; y += (dypos /= twv) * WINPOS_FAC; } else break; /* Stop here if position does not change */ if (dxpos*dxpos+dypos*dypos < WINPOS_STEPMIN*WINPOS_STEPMIN) break; } /* closes loop over interations */ /* assign output results */ *xout = x; *yout = y; *niter = i+1; return status; }
/* calculate Kron radius from pixels within an ellipse. */ int sep_kron_radius(sep_image *im, double x, double y, double cxx, double cyy, double cxy, double r, int id, double *kronrad, short *flag) { float pix; double r1, v1, r2, area, rpix2, dx, dy; int ix, iy, xmin, xmax, ymin, ymax, status, size, msize, ssize; long pos; int ismasked; BYTE *datat, *maskt, *segt; converter convert, mconvert, sconvert; r2 = r*r; r1 = v1 = 0.0; area = 0.0; *flag = 0; datat = maskt = segt = NULL; size = msize = ssize = 0; /* get data converter(s) for input array(s) */ if ((status = get_converter(im->dtype, &convert, &size))) return status; if (im->mask && (status = get_converter(im->mdtype, &mconvert, &msize))) return status; if (im->segmap && (status = get_converter(im->sdtype, &sconvert, &ssize))) return status; /* get extent of ellipse in x and y */ boxextent_ellipse(x, y, cxx, cyy, cxy, r, im->w, im->h, &xmin, &xmax, &ymin, &ymax, flag); /* loop over rows in the box */ for (iy=ymin; iy<ymax; iy++) { /* set pointers to the start of this row */ pos = (iy % im->h) * im->w + xmin; datat = MSVC_VOID_CAST im->data + pos*size; if (im->mask) maskt = MSVC_VOID_CAST im->mask + pos*msize; if (im->segmap) segt = MSVC_VOID_CAST im->segmap + pos*ssize; /* loop over pixels in this row */ for (ix=xmin; ix<xmax; ix++) { dx = ix - x; dy = iy - y; rpix2 = cxx*dx*dx + cyy*dy*dy + cxy*dx*dy; if (rpix2 <= r2) { pix = convert(datat); ismasked = 0; if ((pix < -BIG) || (im->mask && mconvert(maskt) > im->maskthresh)) ismasked = 1; /* Segmentation image: If `id` is negative, require segmented pixels within the aperture. If `id` is positive, mask pixels with nonzero segment ids not equal to `id`. */ if (im->segmap) { if (id > 0) { if ((sconvert(segt) > 0.) & (sconvert(segt) != id)) { ismasked = 1; } } else { if (sconvert(segt) != -1*id) { ismasked = 1; } } } if (ismasked > 0) { *flag |= SEP_APER_HASMASKED; } else { r1 += sqrt(rpix2)*pix; v1 += pix; area++; } } /* increment pointers by one element */ datat += size; maskt += msize; segt += ssize; } } if (area == 0) { *flag |= SEP_APER_ALLMASKED; *kronrad = 0.0; } else if (r1 <= 0.0 || v1 <= 0.0) { *flag |= SEP_APER_NONPOSITIVE; *kronrad = 0.0; } else { *kronrad = r1 / v1; } return RETURN_OK; }
/* * This is just different enough from the other aperture functions * that it doesn't quite make sense to use aperture.i. */ int sep_sum_circann_multi(sep_image *im, double x, double y, double rmax, int n, int id, int subpix, short inflag, double *sum, double *sumvar, double *area, double *maskarea, short *flag) { PIXTYPE pix, varpix; double dx, dy, dx1, dy2, offset, scale, scale2, tmp, rpix2; int ix, iy, xmin, xmax, ymin, ymax, sx, sy, status, size, esize, msize, ssize; long pos; short errisarray, errisstd; BYTE *datat, *errort, *maskt, *segt; converter convert, econvert, mconvert, sconvert; double rpix, r_out, r_out2, d, prevbinmargin, nextbinmargin, step, stepdens; int j, ismasked; /* input checks */ if (rmax < 0.0 || n < 1) return ILLEGAL_APER_PARAMS; if (subpix < 1) return ILLEGAL_SUBPIX; /* clear results arrays */ memset(sum, 0, (size_t)(n*sizeof(double))); memset(sumvar, 0, (size_t)(n*sizeof(double))); memset(area, 0, (size_t)(n*sizeof(double))); if (im->mask) memset(maskarea, 0, (size_t)(n*sizeof(double))); /* initializations */ size = esize = msize = 0; datat = maskt = segt = NULL; errort = im->noise; *flag = 0; varpix = 0.0; scale = 1.0/subpix; scale2 = scale*scale; offset = 0.5*(scale-1.0); r_out = rmax + 1.5; /* margin for interpolation */ r_out2 = r_out * r_out; step = rmax/n; stepdens = 1.0/step; prevbinmargin = 0.7072; nextbinmargin = step - 0.7072; j = 0; d = 0.; ismasked = 0; errisarray = 0; errisstd = 0; /* get data converter(s) for input array(s) */ if ((status = get_converter(im->dtype, &convert, &size))) return status; if (im->mask && (status = get_converter(im->mdtype, &mconvert, &msize))) return status; if (im->segmap && (status = get_converter(im->sdtype, &sconvert, &ssize))) return status; /* get image noise */ if (im->noise_type != SEP_NOISE_NONE) { errisstd = (im->noise_type == SEP_NOISE_STDDEV); if (im->noise) { errisarray = 1; if ((status = get_converter(im->ndtype, &econvert, &esize))) return status; } else { varpix = (errisstd)? im->noiseval * im->noiseval: im->noiseval; } } /* get extent of box */ boxextent(x, y, r_out, r_out, im->w, im->h, &xmin, &xmax, &ymin, &ymax, flag); /* loop over rows in the box */ for (iy=ymin; iy<ymax; iy++) { /* set pointers to the start of this row */ pos = (iy % im->h) * im->w + xmin; datat = MSVC_VOID_CAST im->data + pos*size; if (errisarray) errort = MSVC_VOID_CAST im->noise + pos*esize; if (im->mask) maskt = MSVC_VOID_CAST im->mask + pos*msize; if (im->segmap) segt = MSVC_VOID_CAST im->segmap + pos*ssize; /* loop over pixels in this row */ for (ix=xmin; ix<xmax; ix++) { dx = ix - x; dy = iy - y; rpix2 = dx*dx + dy*dy; if (rpix2 < r_out2) { /* get pixel values */ pix = convert(datat); if (errisarray) { varpix = econvert(errort); if (errisstd) varpix *= varpix; } ismasked = 0; if (im->mask) { if (mconvert(maskt) > im->maskthresh) { *flag |= SEP_APER_HASMASKED; ismasked = 1; } } /* Segmentation image: If `id` is negative, require segmented pixels within the aperture. If `id` is positive, mask pixels with nonzero segment ids not equal to `id`. */ if (im->segmap) { if (id > 0) { if ((sconvert(segt) > 0.) & (sconvert(segt) != id)) { *flag |= SEP_APER_HASMASKED; ismasked = 1; } } else { if (sconvert(segt) != -1*id) { *flag |= SEP_APER_HASMASKED; ismasked = 1; } } } /* check if oversampling is needed (close to bin boundary?) */ rpix = sqrt(rpix2); d = fmod(rpix, step); if (d < prevbinmargin || d > nextbinmargin) { dx += offset; dy += offset; for (sy=subpix; sy--; dy+=scale) { dx1 = dx; dy2 = dy*dy; for (sx=subpix; sx--; dx1+=scale) { j = (int)(sqrt(dx1*dx1+dy2)*stepdens); if (j < n) { if (ismasked) maskarea[j] += scale2; else { sum[j] += scale2*pix; sumvar[j] += scale2*varpix; } area[j] += scale2; } } } } else /* pixel not close to bin boundary */ { j = (int)(rpix*stepdens); if (j < n) { if (ismasked) maskarea[j] += 1.0; else { sum[j] += pix; sumvar[j] += varpix; } area[j] += 1.0; } } } /* closes "if pixel might be within aperture" */ /* increment pointers by one element */ datat += size; if (errisarray) errort += esize; maskt += msize; segt += ssize; } } /* correct for masked values */ if (im->mask) { if (inflag & SEP_MASK_IGNORE) for (j=n; j--;) area[j] -= maskarea[j]; else { for (j=n; j--;) { tmp = area[j] == maskarea[j]? 0.0: area[j]/(area[j]-maskarea[j]); sum[j] *= tmp; sumvar[j] *= tmp; } } } /* add poisson noise, only if gain > 0 */ if (im->gain > 0.0) for (j=n; j--;) if (sum[j] > 0.0) sumvar[j] += sum[j] / im->gain; return status; }