Newer
Older
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Emmanuel Bertin
committed
* Copyright: (C) 1993-2013 Emmanuel Bertin -- IAP/CNRS/UPMC
*
* License: GNU General Public License
*
* SExtractor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* SExtractor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with SExtractor. If not, see <http://www.gnu.org/licenses/>.
*
Emmanuel Bertin
committed
* Last modified: 23/09/2013
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "fits/fitscat.h"
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "check.h"
/********************************* addcheck **********************************/
/*
Add a PSF to a CHECK-image (with a multiplicative factor).
Outside boundaries are taken into account.
*/
void addcheck(checkstruct *check, float *psf,
int w,int h, int ix,int iy, float amplitude)
{
PIXTYPE *pix;
int x,y, xmin,xmax,ymin,ymax,w2, dwpsf;
/* Set the image boundaries */
w2 = w;
ymin = iy-h/2;
ymax = ymin + h;
if (ymin<0)
{
psf -= ymin*w;
ymin = 0;
}
if (ymax>check->height)
ymax = check->height;
xmin = ix-w/2;
xmax = xmin + w;
if (xmax>check->width)
{
w2 -= xmax-check->width;
xmax = check->width;
}
if (xmin<0)
{
xmin = 0;
}
dwpsf = w-w2;
/* Subtract the right pixels to the destination */
for (y=ymin; y<ymax; y++, psf += dwpsf)
{
pix = (float *)check->pix+y*check->width+xmin;
for (x=w2; x--;)
*(pix++) += amplitude**(psf++);
}
return;
}
Emmanuel Bertin
committed
/****** addcheck_resample *****************************************************
PROTO void addcheck_resample(checkstruct *check, float *thumb, int w, int h,
int ix,int iy, float zoom, float amplitude)
PURPOSE Add a resampled thumbnail to a check image (with a multiplicative
factor).
INPUT Pointer to the check-image,
pointer to the thumbnail,
thumbnail width,
thumbnail height,
thumbnail center x coordinate,
thumbnail center y coordinate,
Emmanuel Bertin
committed
inverse zoom factor,
Emmanuel Bertin
committed
flux scaling factor.
OUTPUT -.
NOTES Outside boundaries are taken into account.
AUTHOR E. Bertin (IAP)
Emmanuel Bertin
committed
VERSION 23/09/2013
Emmanuel Bertin
committed
***/
void addcheck_resample(checkstruct *check, float *thumb, int w, int h,
Emmanuel Bertin
committed
int ix, int iy, float step1, float amplitude)
Emmanuel Bertin
committed
{
float interpm[CHECKINTERPW*CHECKINTERPW],
*pix2, *mask,*maskt,*pix12, *pixin,*pixin0, *pixout,*pixout0,
Emmanuel Bertin
committed
xs1,ys1, x1,y1, x,y, dxm,dym, val, norm, step2;
Emmanuel Bertin
committed
int i,j,k,n,t, *start,*startt, *nmask,*nmaskt,
ixs2,iys2, ix2,iy2, dix2,diy2, nx2,ny2, iys1a, ny1, hmw,hmh,
ixs,iys, ix1,iy1, w2,h2;
Emmanuel Bertin
committed
step2 = 1.0/step1;
Emmanuel Bertin
committed
pix2 = check->pix;
w2 = check->width;
h2 = check->height;
Emmanuel Bertin
committed
xs1 = -0.5 - ((float)ix - (int)(w*step1)/2 - 0.5)*step2; /* Im1 start coord */
Emmanuel Bertin
committed
if ((int)xs1 >= w)
return;
ixs2 = 0; /* Int part of Im2 start x-coord */
if (xs1<0.0)
{
Emmanuel Bertin
committed
dix2 = (int)(1-xs1*step1);
Emmanuel Bertin
committed
/*-- Simply leave here if the images do not overlap in x */
if (dix2 >= w2)
return;
ixs2 += dix2;
xs1 += dix2*step2;
}
Emmanuel Bertin
committed
nx2 = (int)((w-1-xs1)*step1+1);/* nb of interpolated Im2 pixels along x */
Emmanuel Bertin
committed
if (nx2>(ix2=w2-ixs2))
nx2 = ix2;
if (nx2<=0)
return;
Emmanuel Bertin
committed
ys1 = -0.5 - ((float)iy - (int)(h*step1)/2 - 0.5)*step2; /* Im1 start coord */
Emmanuel Bertin
committed
if ((int)ys1 >= h)
return;
iys2 = 0; /* Int part of Im2 start y-coord */
if (ys1<0.0)
{
Emmanuel Bertin
committed
diy2 = (int)(1-ys1*step1);
Emmanuel Bertin
committed
/*-- Simply leave here if the images do not overlap in y */
if (diy2 >= h2)
return;
iys2 += diy2;
ys1 += diy2*step2;
}
Emmanuel Bertin
committed
ny2 = (int)((h-1-ys1)*step1+1);/* nb of interpolated Im2 pixels along y */
Emmanuel Bertin
committed
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
if (ny2>(iy2=h2-iys2))
ny2 = iy2;
if (ny2<=0)
return;
/* Set the yrange for the x-resampling with some margin for interpolation */
iys1a = (int)ys1; /* Int part of Im1 start y-coord with margin */
hmh = CHECKINTERPW/2 - 1; /* Interpolant start */
if (iys1a<0 || ((iys1a -= hmh)< 0))
iys1a = 0;
ny1 = (int)(ys1+ny2*step2)+CHECKINTERPW-hmh; /* Interpolated Im1 y size */
if (ny1>h) /* with margin */
ny1 = h;
/* Express everything relative to the effective Im1 start (with margin) */
ny1 -= iys1a;
ys1 -= (float)iys1a;
/* Allocate interpolant stuff for the x direction */
QMALLOC(mask, float, nx2*CHECKINTERPW); /* Interpolation masks */
QMALLOC(nmask, int, nx2); /* Interpolation mask sizes */
QMALLOC(start, int, nx2); /* Int part of Im1 conv starts */
/* Compute the local interpolant and data starting points in x */
hmw = CHECKINTERPW/2 - 1;
x1 = xs1;
maskt = mask;
nmaskt = nmask;
startt = start;
for (j=nx2; j--; x1+=step2)
{
ixs = (ix1=(int)x1) - hmw;
dxm = ix1 - x1 - hmw; /* starting point in the interpolation func */
if (ixs < 0)
{
n = CHECKINTERPW+ixs;
dxm -= (float)ixs;
ixs = 0;
}
else
n = CHECKINTERPW;
if (n>(t=w-ixs))
n=t;
*(startt++) = ixs;
*(nmaskt++) = n;
norm = 0.0;
for (x=dxm, i=n; i--; x+=1.0)
norm += (*(maskt++) = CHECKINTERPF(x));
norm = norm>0.0? 1.0/norm : 1.0;
maskt -= n;
for (i=n; i--;)
*(maskt++) *= norm;
}
QCALLOC(pix12, float, nx2*ny1); /* Intermediary frame-buffer */
/* Make the interpolation in x (this includes transposition) */
pixin0 = thumb+iys1a*w;
pixout0 = pix12;
for (k=ny1; k--; pixin0+=w, pixout0++)
{
maskt = mask;
nmaskt = nmask;
startt = start;
pixout = pixout0;
for (j=nx2; j--; pixout+=ny1)
{
pixin = pixin0+*(startt++);
val = 0.0;
for (i=*(nmaskt++); i--;)
val += *(maskt++)**(pixin++);
*pixout = val;
}
}
/* Reallocate interpolant stuff for the y direction */
QREALLOC(mask, float, ny2*CHECKINTERPW); /* Interpolation masks */
QREALLOC(nmask, int, ny2); /* Interpolation mask sizes */
QREALLOC(start, int, ny2); /* Int part of Im1 conv starts */
/* Compute the local interpolant and data starting points in y */
hmh = CHECKINTERPW/2 - 1;
y1 = ys1;
maskt = mask;
nmaskt = nmask;
startt = start;
for (j=ny2; j--; y1+=step2)
{
iys = (iy1=(int)y1) - hmh;
dym = iy1 - y1 - hmh; /* starting point in the interpolation func */
if (iys < 0)
{
n = CHECKINTERPW+iys;
dym -= (float)iys;
iys = 0;
}
else
n = CHECKINTERPW;
if (n>(t=ny1-iys))
n=t;
*(startt++) = iys;
*(nmaskt++) = n;
norm = 0.0;
for (y=dym, i=n; i--; y+=1.0)
norm += (*(maskt++) = CHECKINTERPF(y));
norm = norm>0.0? 1.0/norm : 1.0;
maskt -= n;
for (i=n; i--;)
*(maskt++) *= norm;
}
/* Make the interpolation in y and transpose once again */
pixin0 = pix12;
pixout0 = pix2+ixs2+iys2*w2;
for (k=nx2; k--; pixin0+=ny1, pixout0++)
{
maskt = mask;
nmaskt = nmask;
startt = start;
pixout = pixout0;
for (j=ny2; j--; pixout+=w2)
{
pixin = pixin0+*(startt++);
val = 0.0;
for (i=*(nmaskt++); i--;)
val += *(maskt++)**(pixin++);
*pixout += amplitude*val;
}
}
/* Free memory */
free(pix12);
free(mask);
free(nmask);
free(start);
return;
}
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
/********************************* blankcheck *******************************/
/*
Blank a part of the CHECK-image according to a mask.
*/
void blankcheck(checkstruct *check, PIXTYPE *mask, int w,int h,
int xmin,int ymin, PIXTYPE val)
{
PIXTYPE *pixt;
int x,y, xmax,ymax,w2,wc;
/* Don't go further if out of frame!! */
if (xmin+w<0 || xmin>=check->width
|| ymin+h<0 || ymin>=check->height)
return;
/* Set the image boundaries */
w2 = w;
ymax = ymin + h;
if (ymin<0)
{
mask -= ymin*w;
ymin = 0;
}
if (ymax>check->height)
ymax = check->height;
xmax = xmin + w;
if (xmax>check->width)
{
w2 -= xmax - check->width;
xmax = check->width;
}
if (xmin<0)
{
mask += -xmin;
w2 -= -xmin;
xmin = 0;
}
w -= w2;
wc = check->width;
ymin = ymin*wc+xmin;
ymax = ymax*wc+xmin;
/* Blank the right pixels in the image */
for (y=ymin; y<ymax; y+=wc, mask += w)
{
pixt = (float *)check->pix + y;
for (x=w2; x--; pixt++)
if (*(mask++) > -BIG)
*pixt = val;
}
return;
}
/******************************** initcheck **********************************/
/*
initialize check-image.
*/
checkstruct *initcheck(char *filename, checkenum check_type, int next)
{
Emmanuel Bertin
committed
catstruct *cat;
checkstruct *check;
QCALLOC(check, checkstruct, 1);
check->type = check_type;
Emmanuel Bertin
committed
check->next = next;
cat = check->cat = new_cat(1);
strcpy(cat->filename, filename);
if (next>1)
/*-- Create a "pure" primary HDU */
{
Emmanuel Bertin
committed
init_cat(cat);
addkeywordto_head(cat->tab, "NEXTEND ", "Number of extensions");
fitswrite(cat->tab->headbuf, "NEXTEND ", &next, H_INT, T_LONG);
if (open_cat(cat, WRITE_ONLY) != RETURN_OK)
error(EXIT_FAILURE,"*Error*: cannot open for writing ", filename);
Emmanuel Bertin
committed
save_head(cat, cat->tab);
remove_tabs(cat);
Emmanuel Bertin
committed
open_cat(cat, WRITE_ONLY);
return check;
}
/******************************** reinitcheck ********************************/
/*
initialize check-image (for subsequent writing).
*/
void reinitcheck(picstruct *field, checkstruct *check)
{
Emmanuel Bertin
committed
catstruct *cat;
tabstruct *tab;
Emmanuel Bertin
committed
char *fitshead;
Emmanuel Bertin
committed
double dval;
int i;
Emmanuel Bertin
committed
cat = check->cat;
Emmanuel Bertin
committed
remove_tabs(cat);
copy_tab_fromptr(field->tab, cat, 0);
tab = cat->tab;
tab->cat = cat;
if (check->next<=1)
prim_head(tab);
Emmanuel Bertin
committed
fitshead = tab->headbuf;
/* Neutralize possible scaling factors */
Emmanuel Bertin
committed
tab->bscale = 1.0;
tab->bzero = 0.0;
fitswrite(fitshead, "BSCALE ", &tab->bscale, H_FLOAT, T_DOUBLE);
fitswrite(fitshead, "BZERO ", &tab->bzero, H_FLOAT, T_DOUBLE);
fitswrite(fitshead, "BITSGN ", &tab->bitsgn, H_INT, T_LONG);
if (tab->compress_type != COMPRESS_NONE)
{
tab->compress_type = COMPRESS_NONE;
fitswrite(fitshead, "IMAGECOD", "NONE", H_STRING, T_STRING);
}
fitswrite(fitshead, "ORIGIN ", BANNER, H_STRING, T_STRING);
switch(check->type)
{
case CHECK_IDENTICAL:
case CHECK_BACKGROUND:
case CHECK_FILTERED:
case CHECK_SUBTRACTED:
tab->bitpix = BP_FLOAT;
tab->bytepix = 4;
Emmanuel Bertin
committed
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
check->npix = field->npix;
QMALLOC(ptrf, PIXTYPE, check->width);
check->pix = (void *)ptrf;
Emmanuel Bertin
committed
save_head(cat, cat->tab);
break;
case CHECK_BACKRMS:
case CHECK_SUBOBJECTS:
tab->bitpix = BP_FLOAT;
tab->bytepix = 4;
Emmanuel Bertin
committed
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin
committed
QMALLOC(check->pix, PIXTYPE, check->width);
save_head(cat, cat->tab);
/*---- Allocate memory for replacing the blanked pixels by 0 */
if (!check->line)
QMALLOC(check->line, PIXTYPE, field->width);
break;
case CHECK_OBJECTS:
case CHECK_APERTURES:
case CHECK_PSFPROTOS:
case CHECK_SUBPSFPROTOS:
case CHECK_SUBPCPROTOS:
case CHECK_SUBPROFILES:
case CHECK_SPHEROIDS:
case CHECK_SUBSPHEROIDS:
case CHECK_DISKS:
case CHECK_SUBDISKS:
Emmanuel Bertin
committed
tab->bitpix = -32;
Emmanuel Bertin
committed
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
check->npix = field->npix;
check->overlay = 30*field->backsig;
Emmanuel Bertin
committed
QCALLOC(check->pix, PIXTYPE, check->npix);
save_head(cat, cat->tab);
tab->bitpix = BP_LONG;
tab->bytepix = 4;
Emmanuel Bertin
committed
tab->bitsgn = 1;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin
committed
QCALLOC(check->pix, ULONG, check->npix);
save_head(cat, cat->tab);
case CHECK_MASK:
case CHECK_SUBMASK:
tab->bitpix = BP_BYTE;
tab->bytepix = 1;
tab->bitsgn = 1;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
check->npix = field->npix;
save_head(cat, cat->tab);
/*---- Allocate memory */
if (!check->line)
QMALLOC(check->line, FLAGTYPE, check->width);
break;
tab->bitpix = BP_FLOAT;
tab->bytepix = 4;
Emmanuel Bertin
committed
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin
committed
QMALLOC(check->pix, PIXTYPE, check->npix);
/*---- Initialize the pixmap to IEEE NaN */
Emmanuel Bertin
committed
memset(check->pix, 0xFF, check->npix*sizeof(LONG));
save_head(cat, cat->tab);
break;
case CHECK_MINIBACKGROUND:
case CHECK_MINIBACKRMS:
tab->bitpix = BP_FLOAT;
tab->bytepix = 4;
Emmanuel Bertin
committed
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->nbackx;
tab->naxisn[1] = check->height = field->nbacky;
/*---- Scale the WCS information if present */
Emmanuel Bertin
committed
fitswrite(fitshead, "CDELT1 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CDELT2 ", &dval, H_EXPO, T_DOUBLE);
dval = (wcs->crpix[0]-0.5)/field->backw + 0.5;
Emmanuel Bertin
committed
fitswrite(fitshead, "CRPIX1 ", &dval, H_EXPO, T_DOUBLE);
dval = (wcs->crpix[1]-0.5)/field->backh + 0.5;
Emmanuel Bertin
committed
fitswrite(fitshead, "CRPIX2 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CD1_1 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CD1_2 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CD2_1 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CD2_2 ", &dval, H_EXPO, T_DOUBLE);
}
check->npix = check->width*check->height;
Emmanuel Bertin
committed
QMALLOC(check->pix, PIXTYPE, check->npix);
if (check->type==CHECK_MINIBACKRMS)
memcpy(check->pix, field->sigma, check->npix*sizeof(float));
else
memcpy(check->pix, field->back, check->npix*sizeof(float));
Emmanuel Bertin
committed
save_head(cat, cat->tab);
write_body(cat->tab, check->pix, check->npix);
free(check->pix);
break;
case CHECK_MAPSOM:
tab->bitpix = BP_FLOAT;
tab->bytepix = 4;
Emmanuel Bertin
committed
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
check->npix = field->npix;
QMALLOC(ptrf, PIXTYPE, check->npix);
check->pix = (void *)ptrf;
for (i=check->npix; i--;)
*(ptrf++) = -10.0;
Emmanuel Bertin
committed
save_head(cat, cat->tab);
tab->bitpix = BP_FLOAT;
tab->bytepix = 4;
Emmanuel Bertin
committed
tab->bitsgn = 0;
Emmanuel Bertin
committed
tab->naxisn[0] = check->width;
tab->naxisn[1] = check->height;
check->npix = check->width*check->height;
Emmanuel Bertin
committed
QCALLOC(check->pix, PIXTYPE, check->npix);
save_head(cat, cat->tab);
error(EXIT_FAILURE, "*Internal Error* in ", "reinitcheck()!");
}
return;
}
/******************************** writecheck *********************************/
/*
Write ONE line of npix pixels of a check-image.
*/
void writecheck(checkstruct *check, PIXTYPE *data, int w)
{
if (check->type == CHECK_APERTURES || check->type == CHECK_SUBPSFPROTOS
|| check->type == CHECK_SUBPCPROTOS || check->type == CHECK_PCOPROTOS
|| check->type == CHECK_SUBPROFILES || check->type == CHECK_SUBSPHEROIDS
|| check->type == CHECK_SUBDISKS || check->type == CHECK_OTHER)
{
memcpy((PIXTYPE *)check->pix + w*(check->y++), data, w*sizeof(PIXTYPE));
return;
}
else if (check->type == CHECK_SUBOBJECTS)
{
int i;
PIXTYPE *pixt;
pixt = (PIXTYPE *)check->line;
for (i=w; i--; data++)
*(pixt++) = (*data>-BIG)? *data:0.0;
write_body(check->cat->tab, (PIXTYPE *)check->line, w);
}
else if (check->type == CHECK_MASK)
{
int i;
FLAGTYPE *pixt;
pixt = (FLAGTYPE *)check->line;
for (i=w; i--;)
*(pixt++) = (*(data++)>-BIG)?0:1;
write_ibody(check->cat->tab, (FLAGTYPE *)check->line, w);
else if (check->type == CHECK_SUBMASK)
{
int i;
FLAGTYPE *pixt;
pixt = (FLAGTYPE *)check->line;
for (i=w; i--;)
*(pixt++) = (*(data++)>-BIG)?1:0;
write_ibody(check->cat->tab, (FLAGTYPE *)check->line, w);
}
else
write_body(check->cat->tab, data, w);
return;
}
/********************************* reendcheck ********************************/
/*
Finish current check-image.
*/
void reendcheck(picstruct *field, checkstruct *check)
{
Emmanuel Bertin
committed
catstruct *cat;
Emmanuel Bertin
committed
cat = check->cat;
switch(check->type)
{
case CHECK_MINIBACKGROUND:
case CHECK_MINIBACKRMS:
Emmanuel Bertin
committed
break;
case CHECK_IDENTICAL:
case CHECK_BACKGROUND:
case CHECK_BACKRMS:
case CHECK_FILTERED:
case CHECK_SUBTRACTED:
free(check->pix);
free(check->line);
check->line = NULL;
break;
case CHECK_OBJECTS:
case CHECK_APERTURES:
case CHECK_PSFPROTOS:
case CHECK_SUBPSFPROTOS:
case CHECK_SUBPCPROTOS:
case CHECK_SUBPROFILES:
case CHECK_SPHEROIDS:
case CHECK_SUBSPHEROIDS:
case CHECK_DISKS:
case CHECK_SUBDISKS:
case CHECK_MAPSOM:
case CHECK_OTHER:
Emmanuel Bertin
committed
write_body(cat->tab, check->pix, check->npix);
free(check->pix);
break;
case CHECK_SEGMENTATION:
Emmanuel Bertin
committed
write_ibody(cat->tab, check->pix, check->npix);
case CHECK_MASK:
case CHECK_SUBMASK:
{
int y;
for (y=field->ymin; y<field->ymax; y++)
writecheck(check, &PIX(field, 0, y), field->width);
free(check->line);
check->line = NULL;
break;
}
case CHECK_SUBOBJECTS:
{
int y;
for (y=field->ymin; y<field->ymax; y++)
writecheck(check, &PIX(field, 0, y), field->width);
free(check->pix);
free(check->line);
check->line = NULL;
break;
}
default:
error(EXIT_FAILURE, "*Internal Error* in ", "endcheck()!");
}
Emmanuel Bertin
committed
pad_tab(cat, check->npix*sizeof(PIXTYPE));
return;
}
/********************************* endcheck **********************************/
/*
close check-image.
*/
void endcheck(checkstruct *check)
{
Emmanuel Bertin
committed
free_cat(&check->cat,1);