258 lines
6.4 KiB
C
258 lines
6.4 KiB
C
/*
|
||
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, ">>> %s ( %d '%s' )\n", __func__, 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 77, 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, "%s: write %s fopen fail.\n", __func__, filename);
|
||
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;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|