libtthimage/Lib/ptlist.c
2022-07-07 12:52:00 +02:00

273 lines
6.4 KiB
C
Raw Blame History

/*
ptlist.c
========
primitives for lists of picture points.
new 1999, 2001 ?
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../tthimage.h"
/*::------------------------------------------------------------------::*/
int Image_print_point(Image_Point *ppt)
{
printf(" xy %-4d %-4d c %-3d h %d\n", ppt->x, ppt->y, ppt->c, ppt->h);
return FUNC_IS_ALPHA;
}
/*::------------------------------------------------------------------::*/
int Image_ptl_dump(Image_PtList *pl, char *txt)
{
fprintf(stderr, "---+---------------\n");
fprintf(stderr, " | %s\n", txt);
fprintf(stderr, " | ptlist @ %p\n", pl);
fprintf(stderr, " | w %d h %d\n", pl->width, pl->height);
fprintf(stderr, " | name '%s'\n", pl->name);
fprintf(stderr, " | nbre %d alloc %d\n", pl->nbre, pl->alloc);
fprintf(stderr, "---+---------------\n");
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
Image_PtList * Image_ptl_alloc(int nbre, char *name)
{
Image_PtList *ptr;
#if DEBUG_LEVEL
fprintf(stderr, "Image PtList: alloc: %d '%s'\n", nbre, name);
#endif
if ( (ptr=malloc(sizeof(Image_PtList)))==NULL)
{
fprintf(stderr, "Image PtList: struct malloc failed\n");
#if FORCE_ABORT
abort();
#endif
return NULL;
}
ptr->control = 0xfde9601a; /* oh, a fucking magic number */
ptr->width = ptr->height = 0;
ptr->nbre = 0;
ptr->alloc = nbre;
if (strlen(name) < IMG_OBJNAME_LEN)
strcpy(ptr->name, name);
else
strcpy(ptr->name, "name too long");
if ( (ptr->points=malloc(sizeof(Image_Point)*nbre))==NULL)
{
fprintf(stderr, "Image PtList: array malloc failed\n");
#if FORCE_ABORT
abort();
#endif
return NULL;
}
return ptr;
}
/*::------------------------------------------------------------------::*/
int Image_ptl_add(Image_PtList *ptl, int x, int y, int h, int c)
{
Image_Point *ptrpt;
int newsize, idx;
#if DEBUG_LEVEL > 2
fprintf(stderr, "Image PtList: addpt to %p: %5d %5d %5d %5d\n",
ptl, x, y, h, c);
#endif
/* in first, we check if this is a valid point list */
if (ptl->control != 0xfde9601a)
{
fprintf(stderr, "ptl addpt: invalid point list %p\n", ptl);
#if FORCE_ABORT
abort();
#endif
return FULL_NUCKED;
}
/*
* in second, we check if we have room for the new point.
*/
if (ptl->nbre==ptl->alloc)
{
newsize = ptl->alloc + 200;
fprintf(stderr, "ptl: realloc array %d\n", newsize);
if ((ptrpt=realloc(ptl->points, sizeof(Image_Point)*newsize))==NULL)
{
fprintf(stderr, "%s: REALLOC FAIL\n", __func__);
exit(5);
}
ptl->points = ptrpt;
ptl->alloc = newsize;
}
idx = ptl->nbre;
ptl->points[idx].x = x;
ptl->points[idx].y = y;
ptl->points[idx].h = h;
ptl->points[idx].c = c;
ptl->nbre = idx + 1;
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
/*
* attention, il est _important_ de respecter le format d'<27>criture
* parce que les fichiers de liste de points sont parfois relus par
* des programmes FORTRAN, beaucoup plus pointilleux sur le
* formatage des donn<6E>es.
*/
int Image_ptl_write(char *filename, Image_PtList *ptl)
{
FILE *fp;
int foo;
if ( (fp=fopen(filename, "w"))==NULL )
{
fprintf(stderr, "Image PtList: write: fopen fail.\n");
return FILE_CREATE_ERR;
}
fprintf(fp, "%8d\n", ptl->nbre);
fprintf(fp, "%08d%08d\n", ptl->width, ptl->height);
fprintf(fp, "%08d%08d\n", 42, 42); /* reserved */
for (foo=0; foo<ptl->nbre; foo++)
{
fprintf(fp, "%8d%8d%8d%8d\n",
ptl->points[foo].x, ptl->points[foo].y,
ptl->points[foo].h, ptl->points[foo].c);
}
fclose(fp);
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
int Image_ptl_read(char *filename, Image_PtList *ptl)
{
FILE *fp;
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %p )\n", __func__, filename, ptl);
#endif
if (ptl->control != 0xfde9601a)
{
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
fprintf(stderr, " can't read '%s'\n", filename);
return 666;
}
/* doit-on utiliser un "must_open" ici ? */
return FULL_NUCKED;
}
/*::------------------------------------------------------------------::*/
/* destruction d'une liste de points */
int Image_ptl_kill(Image_PtList *ptl, char *msg)
{
#if DEBUG_LEVEL
fprintf(stderr, "Killing point list %p for '%s'\n", ptl, msg);
#endif
if (ptl->control != 0xfde9601a)
{
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
return 666;
}
if (NULL != msg) {
fprintf(stderr, "%s is killing %p because %s\n", __func__, ptl, msg);
}
/* killing the array */
free(ptl->points); ptl->points = NULL;
ptl->control = 0;
/* killing the struct */
free(ptl);
return FULL_NUCKED;
}
/*::------------------------------------------------------------------::*/
int
Image_ptl_get_size(Image_PtList *ptl, int *nbre, int *alloc)
{
if (ptl->control != 0xfde9601a)
{
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
return 666;
}
if (NULL != nbre) *nbre = ptl->nbre;
if (NULL != alloc) *alloc = ptl->alloc;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
int Image_ptl_get_point(Image_PtList *ptl, Image_Point *pt, int idx)
{
if (ptl->control != 0xfde9601a)
{
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
return 666;
}
if (idx < 0)
{
fprintf(stderr, "%s:%s point idx %d is negative, so bad !\n",
__FILE__, __func__, idx);
return FULL_NUCKED;
}
if (idx>ptl->nbre)
{
fprintf(stderr, "%s:%s point idx %d is too big, so bad !\n",
__FILE__, __func__, idx);
return FULL_NUCKED;
}
memcpy(pt, &(ptl->points[idx]), sizeof(Image_Point));
#if DEBUG_LEVEL > 3
fprintf(stderr, "%s: %p %d -> %d %d\n", __func__, ptl, idx, pt->x, pt->y);
#endif
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
int Image_ptl_boundingbox(Image_PtList *ptl, Image_Rect *box)
{
int xmin, ymin, xmax, ymax;
int foo;
if (ptl->control != 0xfde9601a)
{
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
return 666;
}
xmin = ymin = 999999999;
xmax = ymax = -999999999;
for (foo=0; foo<ptl->nbre; foo++)
{
if (ptl->points[foo].x < xmin) xmin = ptl->points[foo].x;
if (ptl->points[foo].x > xmax) xmax = ptl->points[foo].x;
if (ptl->points[foo].y < ymin) ymin = ptl->points[foo].y;
if (ptl->points[foo].y > ymax) ymax = ptl->points[foo].y;
}
box->x = xmin; box->y = ymin;
box->w = xmax - xmin; box->h = ymax - ymin;
#if DEBUG_LEVEL
Image_dump_rect(box, "calcul bounding box of a ptlist", 1);
#endif
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/