2022-06-26 11:06:35 +02:00
|
|
|
|
/*
|
|
|
|
|
ptlist.c
|
|
|
|
|
========
|
|
|
|
|
primitives for lists of picture points.
|
|
|
|
|
new 1999, 2001 ?
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
2022-06-27 02:19:31 +02:00
|
|
|
|
#include "../tthimage.h"
|
2022-06-26 11:06:35 +02:00
|
|
|
|
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-07-07 12:52:00 +02:00
|
|
|
|
int Image_print_point(Image_Point *ppt)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
printf(" xy %-4d %-4d c %-3d h %d\n", ppt->x, ppt->y, ppt->c, ppt->h);
|
|
|
|
|
return FUNC_IS_ALPHA;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-07-07 12:52:00 +02:00
|
|
|
|
int Image_ptl_dump(Image_PtList *pl, char *txt)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-07-07 12:52:00 +02:00
|
|
|
|
Image_PtList * Image_ptl_alloc(int nbre, char *name)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
Image_PtList *ptr;
|
|
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
2023-11-18 19:56:25 +01:00
|
|
|
|
fprintf(stderr, ">>> %s ( %d '%s' )\n", __func__, nbre, name);
|
2022-06-26 11:06:35 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if ( (ptr=malloc(sizeof(Image_PtList)))==NULL) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
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");
|
|
|
|
|
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if ( (ptr->points=malloc(sizeof(Image_Point)*nbre))==NULL) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "Image PtList: array malloc failed\n");
|
|
|
|
|
#if FORCE_ABORT
|
|
|
|
|
abort();
|
|
|
|
|
#endif
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-07-07 12:52:00 +02:00
|
|
|
|
int Image_ptl_add(Image_PtList *ptl, int x, int y, int h, int c)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
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 */
|
|
|
|
|
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (ptl->control != 0xfde9601a) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
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.
|
|
|
|
|
*/
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (ptl->nbre==ptl->alloc) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
newsize = ptl->alloc + 200;
|
|
|
|
|
fprintf(stderr, "ptl: realloc array %d\n", newsize);
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if ((ptrpt=realloc(ptl->points, sizeof(Image_Point)*newsize))==NULL) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
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'<EFBFBD>criture
|
|
|
|
|
* parce que les fichiers de liste de points sont parfois relus par
|
2023-11-18 19:56:25 +01:00
|
|
|
|
* des programmes FORTRAN 77, beaucoup plus pointilleux sur le
|
2022-06-26 11:06:35 +02:00
|
|
|
|
* formatage des donn<EFBFBD>es.
|
|
|
|
|
*/
|
2022-07-07 12:52:00 +02:00
|
|
|
|
int Image_ptl_write(char *filename, Image_PtList *ptl)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
FILE *fp;
|
|
|
|
|
int foo;
|
|
|
|
|
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if ( (fp=fopen(filename, "w"))==NULL ) {
|
|
|
|
|
fprintf(stderr, "%s: write %s fopen fail.\n", __func__, filename);
|
2022-06-26 11:06:35 +02:00
|
|
|
|
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 */
|
2023-11-18 19:56:25 +01:00
|
|
|
|
for (foo=0; foo<ptl->nbre; foo++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-07-07 12:52:00 +02:00
|
|
|
|
int Image_ptl_read(char *filename, Image_PtList *ptl)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
FILE *fp;
|
|
|
|
|
int foo;
|
|
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
2022-07-07 12:52:00 +02:00
|
|
|
|
fprintf(stderr, ">>> %s ( '%s' %p )\n", __func__, filename, ptl);
|
2022-06-26 11:06:35 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (ptl->control != 0xfde9601a) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
|
2022-07-07 12:52:00 +02:00
|
|
|
|
fprintf(stderr, " can't read '%s'\n", filename);
|
2022-06-26 11:06:35 +02:00
|
|
|
|
return 666;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* doit-on utiliser un "must_open" ici ? */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return FULL_NUCKED;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
|
/* destruction d'une liste de points */
|
2022-07-07 12:52:00 +02:00
|
|
|
|
int Image_ptl_kill(Image_PtList *ptl, char *msg)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
|
fprintf(stderr, "Killing point list %p for '%s'\n", ptl, msg);
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (ptl->control != 0xfde9601a) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
|
|
|
|
|
return 666;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-07 12:52:00 +02:00
|
|
|
|
if (NULL != msg) {
|
|
|
|
|
fprintf(stderr, "%s is killing %p because %s\n", __func__, ptl, msg);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-26 11:06:35 +02:00
|
|
|
|
/* 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)
|
|
|
|
|
{
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (ptl->control != 0xfde9601a) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-07-07 12:52:00 +02:00
|
|
|
|
int Image_ptl_get_point(Image_PtList *ptl, Image_Point *pt, int idx)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (ptl->control != 0xfde9601a) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
|
|
|
|
|
return 666;
|
|
|
|
|
}
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (idx < 0) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "%s:%s point idx %d is negative, so bad !\n",
|
|
|
|
|
__FILE__, __func__, idx);
|
|
|
|
|
return FULL_NUCKED;
|
|
|
|
|
}
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (idx>ptl->nbre) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-07-07 12:52:00 +02:00
|
|
|
|
int Image_ptl_boundingbox(Image_PtList *ptl, Image_Rect *box)
|
2022-06-26 11:06:35 +02:00
|
|
|
|
{
|
|
|
|
|
int xmin, ymin, xmax, ymax;
|
|
|
|
|
int foo;
|
|
|
|
|
|
2023-11-18 19:56:25 +01:00
|
|
|
|
if (ptl->control != 0xfde9601a) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
fprintf(stderr, "%s: no deadbeef in %p\n", __func__, ptl);
|
|
|
|
|
return 666;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xmin = ymin = 999999999;
|
|
|
|
|
xmax = ymax = -999999999;
|
|
|
|
|
|
2023-11-18 19:56:25 +01:00
|
|
|
|
for (foo=0; foo<ptl->nbre; foo++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|