Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals

imadrawline.c

Go to the documentation of this file.
00001 /************************************************************************* 00002 * $Id: imadrawline.c,v 1.1 2005/09/09 08:22:47 bellet Exp $ 00003 ************************************************************************** 00004 This software is governed by the CeCILL license under French law and 00005 abiding by the rules of distribution of free software. You can use, 00006 modify and/ or redistribute the software under the terms of the CeCILL 00007 license as circulated by CEA, CNRS and INRIA at the following URL 00008 "http://www.cecill.info". 00009 00010 As a counterpart to the access to the source code and rights to copy, 00011 modify and redistribute granted by the license, users are provided only 00012 with a limited warranty and the software's author, the holder of the 00013 economic rights, and the successive licensors have only limited 00014 liability. 00015 00016 In this respect, the user's attention is drawn to the risks associated 00017 with loading, using, modifying and/or developing or reproducing the 00018 software by the user in light of its specific status of free software, 00019 that may mean that it is complicated to manipulate, and that also 00020 therefore means that it is reserved for developers and experienced 00021 professionals having in-depth computer knowledge. Users are therefore 00022 encouraged to load and test the software's suitability as regards their 00023 requirements in conditions enabling the security of their systems and/or 00024 data to be ensured and, more generally, to use and operate it in the 00025 same conditions as regards security. 00026 00027 The fact that you are presently reading this means that you have had 00028 knowledge of the CeCILL license and that you accept its terms. 00029 00030 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de 00031 l'Image). All rights reserved. See License.txt for details. 00032 00033 Version 1.0 05/09/2005 00034 *************************************************************************/ 00035 00036 /************************************************************************* 00037 * 00038 * Description : Trace de lignes dans une image. 00039 * 00040 **************************************************************************/ 00041 #include <string.h> // For memcpy 00042 #include <stdlib.h> 00043 #include "idcommon.h" 00044 #include "idima.h" 00045 #include "iderr.h" 00046 #include "idprint.h" 00047 #include "idcnt.h" 00048 00049 static int CalculVoxelDroite(int, int, int, int, int, int *, int *); 00050 00051 /* 00052 * ----------------------------------------------------- 00053 * 00054 * Cette fonction, statique, est prevue pour LE RESTER 00055 * Ne la recopiez pas chez vous ... 00056 * Il y a ds les fonctions sur les CNT tout ce qu'il faut pour travailler 00057 * Si vous trouvez qu'il en manque une, dites-le nous, nous la rajouterons... 00058 * Toutes les recopies 'non controlees' de cette fonction dans des directories 00059 * utilisateur ont ete jusqu'a present des erreures d'analyse ... 00060 * 00061 * ----------------------------------------------------- 00062 */ 00063 00064 static int 00065 CalculVoxelDroite(int premier, int ox, int oy, int fx, int fy, int *x, int *y) 00066 { 00067 00068 static int Dx; // Ecart en x entre debut et fin 00069 static int Dy; // " y " " " 00070 static short Incx; // Increment en x 00071 static short Incy; // Increment en y 00072 static int s; 00073 static int Dx2; // Double de Dx 00074 static int Dy2; // Double de Dy 00075 static int Dxy; // Double de |Dx-Dy| 00076 static int X; // coordonnee X courante 00077 static int Y; // coordonnee Y courante 00078 static int Voxel; // Compteur de voxel retourne 00079 00080 #define SIGN(x) ((x)<0?-1:((x)>0?1:0)) 00081 00082 Voxel++; 00083 /* 00084 * Initialisation du trace de droite 00085 */ 00086 if (premier) { 00087 X = ox; 00088 /* 00089 * Sens de variation de la droite suivant X 00090 */ 00091 Incx = SIGN(fx - X); 00092 /* 00093 * Variation totale suivant X 00094 */ 00095 Dx = ABS(fx - X); 00096 Dx2 = 2 * Dx; 00097 00098 Y = oy; 00099 /* 00100 * Sens de variation de la droite 00101 */ 00102 Incy = SIGN(fy - Y); 00103 /* 00104 * Variation totale suivant Y 00105 */ 00106 Dy = ABS(fy - Y); 00107 Dy2 = 2 * Dy; 00108 00109 /* 00110 * Servent a determiner si on va en diagonnale ou pas 00111 */ 00112 Dxy = SIGN(Dx - Dy) * (Dy2 - Dx2); 00113 if (Dx > Dy) 00114 s = Dy2 - Dx; 00115 else 00116 s = Dx2 - Dy; 00117 00118 Voxel = 0; 00119 /* 00120 * variation plus rapide suivant X 00121 */ 00122 } else if (Dx > Dy) { 00123 if (Voxel > Dx) 00124 /* 00125 * fin du trace 00126 */ 00127 return 0; 00128 if (s >= 0) { 00129 Y += Incy; 00130 s += Dxy; 00131 } else { 00132 s += Dy2; 00133 } 00134 X += Incx; 00135 /* 00136 * variation plus rapide suivant Y 00137 */ 00138 } else if (Dx < Dy) { 00139 if (Voxel > Dy) 00140 /* 00141 * fin du trace 00142 */ 00143 return 0; 00144 if (s >= 0) { 00145 X += Incx; 00146 s += Dxy; 00147 } else { 00148 s += Dx2; 00149 } 00150 Y += Incy; 00151 /* 00152 * variation égale suivant X et Y 00153 */ 00154 } else { 00155 if (Voxel > Dy) 00156 /* 00157 * fin du trace 00158 */ 00159 return 0; 00160 X += Incx; 00161 Y += Incy; 00162 } 00163 00164 *x = X; 00165 *y = Y; 00166 return 1; 00167 } 00168 00169 /* 00170 * FUNCTION DESCRIPTION ************************************************** 00171 * 00172 * IdImaDrawLine (fonction) 00173 * 00174 * RESUME: Trace une ligne dans une image UCHAR. 00175 * 00176 * DESCRIPTION: Trace une ligne dans une image UCHAR. 00177 * 00178 * SYNTAXE: PPIMAGE_UCHAR imSource = IdImaDrawLine ( PPIMAGE_UCHAR imSource, int value, int modeTrace, int ox, int oy, int fx, int fy); 00179 * 00180 * RETOUR: type : PPIMAGE_UCHAR 00181 * role : Pointeur vers l'image resultat. Zero si echec. 00182 * 00183 * PARAMETRES: nom : imSource 00184 * type : PPIMAGE_UCHAR 00185 * role : Pointeur vers l'image source 00186 * 00187 * nom : value 00188 * type : int 00189 * role : Valeur de trace. 00190 * 00191 * nom : modeTrace 00192 * type : int 00193 * role : Type de trace : 0 = trace direct 00194 * 1 = AND 00195 * 2 = OR 00196 * 3 = XOR 00197 * 00198 * nom : ox, oy, fx, fy 00199 * type : int 00200 * role : (ox, oy) et (fx,fy) correspondent aux points de debut 00201 * et de fin du segment a tracer. 00202 * 00203 * FICHIER: flignes.c 00204 * 00205 * EXEMPLE: if ( (imd=IdImaDrawLine(ims,255,0,0,3,0,5,4))==0 ) 00206 * IdErrPrintf("ERREUR: %s",IdErrMsg(IdErrno)); 00207 * Trace une ligne avec une valeur de 255, entre les points 00208 * (3,0) et (5,4). 00209 * 00210 * ******************************************************** END DESCRIPTION 00211 */ 00212 00213 PPIMAGE_UCHAR 00214 IdImaDrawLine(PPIMAGE_UCHAR ims, int value, int code, 00215 int ox, int oy, int fx, int fy) 00216 { 00217 int x, y; 00218 int init; 00219 /* 00220 * Controle de l'image * 00221 */ 00222 if (!ims || IdImaType(ims) != IMA_UCHAR) { 00223 IdErrno = IDERR_WRONG_TYPE; 00224 return 0; 00225 } 00226 00227 if ((ox < 0) || (ox >= IdImaDimX(ims)) 00228 || (fx < 0) || (fx >= IdImaDimX(ims)) 00229 || (oy < 0) || (oy >= IdImaDimY(ims)) 00230 || (fy < 0) || (fy >= IdImaDimY(ims)) 00231 || (code > 3) || (code < 0)) { 00232 IdErrno = IDERR_INVALID_NUMBER; 00233 return 0; 00234 } 00235 /* 00236 * Calcul du resultat **** 00237 */ 00238 switch (code) { 00239 00240 case 1:{ 00241 for (init = 00242 CalculVoxelDroite(1, ox, oy, fx, fy, &x, &y); 00243 init; 00244 init = 00245 CalculVoxelDroite(0, ox, oy, fx, fy, &x, &y)) { 00246 ims[y][x] &= value; 00247 } 00248 } 00249 break; 00250 00251 case 2:{ 00252 for (init = 00253 CalculVoxelDroite(1, ox, oy, fx, fy, &x, &y); 00254 init; 00255 init = 00256 CalculVoxelDroite(0, ox, oy, fx, fy, &x, &y)) { 00257 ims[y][x] |= value; 00258 } 00259 } 00260 break; 00261 00262 case 3:{ 00263 for (init = 00264 CalculVoxelDroite(1, ox, oy, fx, fy, &x, &y); 00265 init; 00266 init = 00267 CalculVoxelDroite(0, ox, oy, fx, fy, &x, &y)) { 00268 ims[y][x] ^= value; 00269 } 00270 } 00271 break; 00272 00273 case 0: 00274 default:{ 00275 for (init = 00276 CalculVoxelDroite(1, ox, oy, fx, fy, &x, &y); 00277 init; 00278 init = 00279 CalculVoxelDroite(0, ox, oy, fx, fy, &x, &y)) { 00280 ims[y][x] = value; 00281 } 00282 } 00283 } 00284 00285 return ims; 00286 00287 } 00288 00289 /* 00290 * FUNCTION DESCRIPTION ************************************************** 00291 * 00292 * IdImaDrawPolyLines (fonction) 00293 * 00294 * RESUME: Trace d'une suite de lignes dans une image UCHAR. 00295 * 00296 * DESCRIPTION: Trace d'une suite de lignes dans une image UCHAR. 00297 * 00298 * SYNTAXE: PPIMAGE_UCHAR imSource = IdImaDrawPolyLines ( PPIMAGE_UCHAR imSource, int value, int modeTrace, int ptx[],int pty[],int nb,int closepoly ); 00299 * 00300 * RETOUR: type : PPIMAGE_UCHAR 00301 * role : Pointeur vers l'image resultat. Zero si echec. 00302 * 00303 * PARAMETRES: nom : image 00304 * type : PPIMAGE_UCHAR 00305 * role : Pointeur vers l'image source 00306 * 00307 * nom : value 00308 * type : int 00309 * role : Valeur de trace. 00310 * 00311 * nom : modeTrace 00312 * type : int 00313 * role : Type de trace : 00314 * 0 = trace direct 00315 * 1 = AND 00316 * 2 = OR 00317 * 3 = XOR 00318 * 00319 * nom : ptx, pty 00320 * type : int * 00321 * role : Coordonnees des points decrivant les lignes 00322 * 00323 * nom : nb 00324 * type : int 00325 * role : nombre de pointsde la ligne 00326 * 00327 * nom : closepoly 00328 * type : int 00329 * role : Faut-il fermer le polygone ? 00330 * 0 = Non 00331 * 1 = Oui 00332 * FICHIER: flignes.c 00333 * 00334 * EXEMPLE: Trace d'un carre ferme entre les pts (50,50) et (100,100) : 00335 * static int ptx[]= {50,100,100,50}; 00336 * static int pty[]= {50,50,100,100}; 00337 * if ( IdImaDrawPolyLines(ims,255,0,0,ptx,pty,1) ==0 ) 00338 * IdErrPrintf("ERREUR: %s",IdErrMsg(IdErrno)); 00339 * 00340 * ******************************************************** END DESCRIPTION 00341 */ 00342 PPIMAGE_UCHAR 00343 IdImaDrawPolyLines(PPIMAGE_UCHAR imSource, int value, int modeTrace, 00344 int *ptx, int *pty, int nb, int closepoly) 00345 { 00346 int n; 00347 for (n = nb - 1; n > 0; n--) { 00348 imSource = IdImaDrawLine(imSource, value, modeTrace, 00349 ptx[n - 1], pty[n - 1], ptx[n], 00350 pty[n]); 00351 } 00352 if (closepoly) 00353 imSource = IdImaDrawLine(imSource, value, modeTrace, 00354 ptx[nb - 1], pty[nb - 1], ptx[0], 00355 pty[0]); 00356 00357 return imSource; 00358 } 00359 00360 /* 00361 * FUNCTION DESCRIPTION ************************************************** 00362 * 00363 * IdCntPointsOfSegment (fonction) 00364 * 00365 * RESUME: Renvoie les coordonnees des pixels sur un segment entre 2 points. 00366 * 00367 * DESCRIPTION: Renvoie les coordonnees des pixels sur un segment entre 2 points. 00368 * 00369 * SYNTAXE: PCONTOUR_USHORT cnt = IdCntPointsOfSegment ( int ox, int oy, int fx, int fy); 00370 * 00371 * RETOUR: type : PCONTOUR_USHORT 00372 * role : Pointeur vers le CONTOUR resultat. Zero si echec. 00373 * 00374 * PARAMETRES: 00375 * 00376 * nom : ox, oy, fx, fy 00377 * type : int 00378 * role : (ox, oy) et (fx,fy) correspondent aux points de debut 00379 * et de fin du segment. 00380 * 00381 * FICHIER: flignes.c 00382 * 00383 * EXEMPLE: if ( (cnt1=IdCntPointsOfSegment(3,0,5,4))==0 ) 00384 * IdErrPrintf("ERREUR: %s",IdErrMsg(IdErrno)); 00385 * Renvoie les coordonnees des pixels sur un segment entre les points 00386 * (3,0) et (5,4). 00387 * 00388 * ******************************************************** END DESCRIPTION 00389 */ 00390 00391 PCONTOUR_USHORT 00392 IdCntPointsOfSegment(int ox, int oy, int fx, int fy) 00393 { 00394 int x, y; 00395 int init; 00396 PCONTOUR_USHORT cnt; 00397 00398 if ((ox < 0) || (fx < 0) || (oy < 0) || (fy < 0)) { 00399 IdErrno = IDERR_INVALID_NUMBER; 00400 return 0; 00401 } 00402 00403 /* 00404 * Si pas suffisant, IdCntAddPoint rallonge 00405 */ 00406 cnt = (PCONTOUR_USHORT) IdCntAlloc(512, CNT_USHORT); 00407 00408 if (!cnt) { 00409 IdErrno = IDERR_ALLOC_CNT; 00410 IdErrPrintf("Echec Alloc Contour \n"); 00411 return 0; 00412 } 00413 /* 00414 * Calcul du resultat **** 00415 */ 00416 00417 for (init = CalculVoxelDroite(1, ox, oy, fx, fy, &x, &y); init; 00418 init = CalculVoxelDroite(0, ox, oy, fx, fy, &x, &y)) { 00419 IdCntAddPoint(cnt, x, y); 00420 } 00421 00422 return cnt; 00423 00424 } 00425 00426 /* 00427 * FUNCTION DESCRIPTION ************************************************** 00428 * 00429 * IdCntAddPointsOfSegment (Macro) 00430 * 00431 * RESUME: Rajoute a la fin d'un CNT les coordonnees des pixels sur un segment entre 2 points. 00432 * 00433 * DESCRIPTION: Rajoute a la fin d'un CNT les coordonnees des pixels sur un segment entre 2 points. 00434 * 00435 * SYNTAXE: int retCode = IdCntAddPointsOfSegment (PCONTOUR_USHORT cntSource int ox, int oy, int fx, int fy); 00436 * 00437 * RETOUR: type : int 00438 * role : code retour. Zero si echec, 1 si OK. 00439 * 00440 * PARAMETRES: 00441 * 00442 * nom : ox, oy, fx, fy 00443 * type : int 00444 * role : (ox, oy) et (fx,fy) correspondent aux points de debut 00445 * et de fin du segment. 00446 * 00447 * nom : cnt 00448 * type : PCONTOUR_USHORT 00449 * role : 00450 * 00451 * FICHIER: flignes.c 00452 * 00453 * EXEMPLE: if ( (cnt1=IdCntAddPointsOfSegment(cnt1,3,0,5,4))==0 ) 00454 * IdErrPrintf("ERREUR: %s",IdErrMsg(IdErrno)); 00455 * Renvoie les coordonnees des pixels sur un segment entre les points 00456 * (3,0) et (5,4). 00457 * 00458 * ******************************************************** END DESCRIPTION 00459 */ 00460 int 00461 _IdCntAddPointsOfSegment(PCONTOUR_USHORT *cnt, int ox, int oy, 00462 int fx, int fy) 00463 { 00464 int x, y; 00465 int init; 00466 00467 if ((ox < 0) || (fx < 0) || (oy < 0) || (fy < 0)) { 00468 IdErrno = IDERR_INVALID_NUMBER; 00469 return 0; 00470 } 00471 00472 if (!(*cnt)) { 00473 IdErrno = IDERR_POINTER_IS_NULL; 00474 IdErrPrintf("Contour non Alloue\n"); 00475 return 0; 00476 } 00477 /* 00478 * Calcul du resultat **** 00479 */ 00480 00481 for (init = CalculVoxelDroite(1, ox, oy, fx, fy, &x, &y); init; 00482 init = CalculVoxelDroite(0, ox, oy, fx, fy, &x, &y)) { 00483 IdCntAddPoint(*cnt, x, y); 00484 } 00485 00486 return 1; 00487 00488 } 00489 00490 /* 00491 * FUNCTION DESCRIPTION ************************************************** 00492 * 00493 * IdCntAppendPointsOfSegment (macro) 00494 * 00495 * RESUME: Rajoute a la fin d'un CNT les coordonnees des pixels sur un segment jusqu'a 1 point. 00496 * 00497 * DESCRIPTION: Rajoute a la fin d'un CNT les coordonnees des pixels sur un segment jusqu'a 1 point. 00498 * 00499 * SYNTAXE: int retCode = IdCntAppendPointsOfSegment (PCONTOUR_USHORT cntSource int x, int y); 00500 * 00501 * RETOUR: type : int 00502 * role : code retour. Zero si echec, 1 si OK. 00503 * 00504 * PARAMETRES: 00505 * nom : x, y 00506 * type : int 00507 * role : (x, y) correspondent a l'extremite du segment. 00508 * 00509 * nom : cnt 00510 * type : PCONTOUR_USHORT 00511 * role : 00512 * 00513 * FICHIER: flignes.c 00514 * 00515 * EXEMPLE: if ( (cnt1=IdCntAppendPointsOfSegment(cnt1,3,8))==0 ) 00516 * IdErrPrintf("ERREUR: %s",IdErrMsg(IdErrno)); 00517 * 00518 * ******************************************************** END DESCRIPTION 00519 */ 00520 00521 00522 00523 /* 00524 * FUNCTION DESCRIPTION ************************************************** 00525 * 00526 * IdCntInsertPointsOfSegment (macro) 00527 * 00528 * RESUME: Insere ds 1 CNT les coordonnees des pixels sur 1 segmt a partir d'1 point. 00529 * 00530 * DESCRIPTION: Insere ds 1 CNT les coordonnees des pixels sur 1 segmt a partir d'1 point. 00531 * 00532 * SYNTAXE: int retCode = IdCntInsertPointsOfSegment (PCONTOUR_USHORT cntSource ,int numPoint, int fx, int fy); 00533 * 00534 * RETOUR: type : int 00535 * role : code retour. Zero si echec, 1 si OK. 00536 * 00537 * PARAMETRES: 00538 * 00539 * nom : cnt 00540 * type : PCONTOUR_USHORT 00541 * role : 00542 * 00543 * nom : numPoint 00544 * type : int 00545 * role : indice du Point a partir duquel on insere 00546 * 00547 * nom : fx, fy 00548 * type : int 00549 * role : (fx,fy) correspondent aux points de fin du segment. 00550 * 00551 * FICHIER: cntutil.c 00552 * 00553 * EXEMPLE: 00554 * 00555 * ******************************************************** END DESCRIPTION 00556 */ 00557 00558 int 00559 _IdCntInsertPointsOfSegment(PCONTOUR_USHORT *cnt, 00560 int numPoint, int fx, int fy) 00561 { 00562 int x, y; 00563 int init, nbPtsAvLaFin, lgr, lgr2; 00564 char *zoneSecu = NULL; 00565 char *debut; 00566 00567 if ((fy < 0) || (fx < 0)) { 00568 IdErrno = IDERR_INVALID_NUMBER; 00569 return 0; 00570 } 00571 00572 if (!(*cnt)) { 00573 IdErrno = IDERR_POINTER_IS_NULL; 00574 IdErrPrintf("Contour non Alloue\n"); 00575 return 0; 00576 } 00577 00578 if (numPoint > IdCntUsedNbX(*cnt)) { 00579 IdErrno = IDERR_POINTER_IS_NULL; 00580 IdErrPrintf("numPoint > taille Cnt\n"); 00581 return 0; 00582 } 00583 00584 debut = (char *) *cnt + (numPoint + 1) * IdSizeOfType(*cnt); 00585 nbPtsAvLaFin = IdCntUsedNbX(*cnt) - numPoint - 1; 00586 lgr = IdSizeOfType(*cnt) * nbPtsAvLaFin; 00587 00588 zoneSecu = (char *) malloc(lgr); 00589 00590 memcpy(zoneSecu, debut, lgr); 00591 IdCntSetUsedNbX(*cnt, numPoint + 1); 00592 00593 /* 00594 * Calcul du resultat **** 00595 */ 00596 for (init = CalculVoxelDroite(1, IdCntGetX(*cnt, numPoint), 00597 IdCntGetY(*cnt, numPoint), 00598 fx, fy, &x, &y); 00599 init; 00600 init = CalculVoxelDroite(0, IdCntGetX(*cnt, numPoint), 00601 IdCntGetY(*cnt, numPoint), 00602 fx, fy, &x, &y)) { 00603 IdCntAddPoint(*cnt, x, y); 00604 } 00605 00606 lgr2 = (IdCntUsedNbX(*cnt) + nbPtsAvLaFin); 00607 00608 if (IdCntDimX(*cnt) < (IdCntUsedNbX(*cnt) + nbPtsAvLaFin)) { 00609 00610 /* 00611 * 20 % de + que necessaire pr eviter trop de realloc 00612 */ 00613 *cnt = (PCONTOUR_USHORT)IdCntModifLongueur( 00614 (PCONTOUR)*cnt, lgr2 * 1.2); 00615 } 00616 00617 memcpy((char *) *cnt + IdCntUsedNbX(*cnt) * IdSizeOfType(*cnt), 00618 zoneSecu, lgr); 00619 00620 IdCntSetUsedNbX(*cnt, IdCntUsedNbX(*cnt) + nbPtsAvLaFin); 00621 00622 return 1; 00623 00624 }

Generated on Wed Oct 19 09:28:33 2005 for SIMRI3D by doxygen 1.3.7