/*************************************************************************************************************************************/
/* */
/* F A C T O R I S A T I O N D ' U N E D I M E N S I O N D ' I M A G E : */
/* */
/* */
/* Definition : */
/* */
/* Cette commande (inspiree du programme */
/* 'v $xtc/f_tailleI.02$c') factorise, lorsque */
/* cela est possible, un nombre entier en deux */
/* facteurs... */
/* */
/* */
/* Author of '$xcg/dimX_dimY$vv$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 20090504090957). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* I N T E R F A C E ' listG ' : */
/* */
/* */
/* :Debut_listG: */
/* :Fin_listG: */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F I C H I E R S D ' I N C L U D E S : */
/* */
/*************************************************************************************************************************************/
#include INCLUDES_MINI
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
#define DIMENSION_A_FACTORISER \
MILLION \
/* Dimension a factoriser en 'dimX.dimY'. */
#define FACTEUR_DE_BALAYAGE \
GRO3(FRA2(FU)) \
/* Facteur dans permettant de calculer {dim?min,dim?max}. */
#define RAPPORT_dimensionX_SUR_dimensionY_OPTIMAL \
GRO3(FRA2(FU)) \
/* Valeur optimale de 'dimX/dimY' resultat de la factorisation. */
#define EDITER_TOUS_LES_COUPLES_TROUVES_ET_D_AUTRES_INFORMATIONS \
FAUX \
/* Faut-il ('VRAI') ou pas ('FAUX') editer tous les couples {dimX,dimY} trouves plus */ \
/* d'autres choses introduites le 20090504173827... */
#define SIMPLIFIER_L_EDITION_DU_COUPLE_OPTIMAL \
VRAI \
/* Faut-il ('VRAI') ou pas ('FAUX') simplifier l'edition du couple {dimX,dimY} optimal ? */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F A C T O R I S A T I O N D ' U N E D I M E N S I O N D ' I M A G E : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Int,INIT(dimension_a_factoriser,DIMENSION_A_FACTORISER));
/* Dimension a factoriser en 'dimX.dimY'. On notera que celle-ci ne peut pas etre un */
/* 'Positive' a cause d'une part du 'GET_ARGUMENT_I(...)' dont elle fait l'objet (on */
/* pourrait introduire une valeur negative...) et d'autre part du test 'Test(IZGT(...))' */
/* ci-apres qui ne detecterait alors que les valeurs nulles... */
DEFV(Float,INIT(facteur_de_balayage,FACTEUR_DE_BALAYAGE));
/* Facteur dans [permettant de calculer {dim?min,dim?max}. */
DEFV(Float,INIT(rapport_dimensionX_sur_dimensionY_optimal,RAPPORT_dimensionX_SUR_dimensionY_OPTIMAL));
/* Valeur optimale de 'dimX/dimY' resultat de la factorisation. */
DEFV(Logical,INIT(editer_tous_les_couples_trouves_et_d_autres_informations
,EDITER_TOUS_LES_COUPLES_TROUVES_ET_D_AUTRES_INFORMATIONS
)
);
/* Faut-il ('VRAI') ou pas ('FAUX') editer tous les couples {dimX,dimY} trouves plus */
/* d'autres choses introduites le 20090504173827... */
DEFV(Logical,INIT(simplifier_l_edition_du_couple_optimal,SIMPLIFIER_L_EDITION_DU_COUPLE_OPTIMAL));
/* Faut-il ('VRAI') ou pas ('FAUX') simplifier l'edition du couple {dimX,dimY} optimal ? */
/*..............................................................................................................................*/
GET_ARGUMENTS_(nombre_d_arguments
,BLOC(GET_ARGUMENT_I("dimension=""d=""dXdY=""XY=",dimension_a_factoriser);
GET_ARGUMENT_F("facteur_balayage=""facteur=""f=",facteur_de_balayage);
GET_ARGUMENT_F("rapport_dimensionXsY=""rapport=""r=""dXsdY=",rapport_dimensionX_sur_dimensionY_optimal);
GET_ARGUMENT_L("tout_editer=""editer=""e=",editer_tous_les_couples_trouves_et_d_autres_informations);
GET_ARGUMENT_L("simplifier=""s=",simplifier_l_edition_du_couple_optimal);
)
);
Test(IZGT(dimension_a_factoriser))
Bblock
DEFV(Logical,INIT(la_factorisation_est_possible,FAUX));
/* A priori, la factorisation est impossible... */
DEFV(Float,INIT(valeur_moyenne_de_dimensionX_et_de_dimensionY,FLOT__UNDEF));
DEFV(Int,INIT(valeur_inferieure_de_dimensionX_et_de_dimensionY,UNDEF));
DEFV(Int,INIT(valeur_superieure_de_dimensionX_et_de_dimensionY,UNDEF));
/* Afin de definir les intervalles de balayage de 'dimX' et de 'dimY'. */
DEFV(Int,INIT(dimensionX,UNDEF));
DEFV(Int,INIT(dimensionY,UNDEF));
/* Facteurs courants de 'dimension_a_factoriser'. */
DEFV(Int,INIT(meilleure_dimensionX,UNDEF));
DEFV(Int,INIT(meilleure_dimensionY,UNDEF));
DEFV(Float,INIT(minimum_de_dimensionX_sur_dimensionY_relatif,F_INFINI));
/* Meilleur couple {dimX,dimY} factorisant 'dimension_a_factoriser' et "outil" permettant */
/* de le determiner... */
EGAL(valeur_moyenne_de_dimensionX_et_de_dimensionY
,RACX(dimension_a_factoriser)
);
Test(IFEXof(facteur_de_balayage,FZERO,valeur_moyenne_de_dimensionX_et_de_dimensionY))
/* Validation introduite le 20090504173827... */
Bblock
PRINT_ERREUR("le facteur de balayage est incorrect");
CAL1(Prer2("(il vaut %f et n'est donc pas dans ]0,%f])\n"
,facteur_de_balayage
,valeur_moyenne_de_dimensionX_et_de_dimensionY
)
);
Eblock
ATes
Bblock
EGAL(valeur_inferieure_de_dimensionX_et_de_dimensionY
,INTE(DIVI(FLOT(valeur_moyenne_de_dimensionX_et_de_dimensionY),facteur_de_balayage))
);
EGAL(valeur_superieure_de_dimensionX_et_de_dimensionY
,INTE(MUL2(FLOT(valeur_moyenne_de_dimensionX_et_de_dimensionY),facteur_de_balayage))
);
/* Definition des intervalles de balayage de 'dimX' et de 'dimY'. */
/* */
/* On notera les valeurs extremales du facteur 'f' ('facteur_de_balayage') : */
/* */
/* f=0 ==> dim? E [m,m] ([inf,sup]=[m,m]) */
/* f=m ==> dim? E [1,d] ([inf,sup]=[1,d]) */
/* */
/* ou 'm' et 'd' designent respectivement 'valeur_moyenne_de_dimensionX_et_de_dimensionY' */
/* et 'dimension_a_factoriser', en rappelant que : */
/* */
/* 2 */
/* d = m */
/* */
/* On peut ainsi (pour 'f=m') balayer tous le segment [1,d], mais au prix d'un temps */
/* de calcul en general redhibitoire... */
/* */
/* On notera de plus que ('inf' et 'sup' etant respectivement les 'valeur_inferieure_...' */
/* et les 'valeur_superieure_' calculees ci-dessus) : */
/* */
/* m */
/* inf = --- */
/* f */
/* */
/* et que : */
/* */
/* sup = m.f */
/* */
/* donc : */
/* */
/* 2 */
/* inf.sup = m = d */
/* */
/* Ainsi, 'm' est la moyenne geometrique 'MOYG(...)' de 'inf' et 'sup'. */
Test(IL_FAUT(editer_tous_les_couples_trouves_et_d_autres_informations))
Bblock
CAL2(Prin3("Segment de recherche pour les dimensions en 'X' et en 'Y' : [%d,%d] 'centre' en %d\n"
,valeur_inferieure_de_dimensionX_et_de_dimensionY
,valeur_superieure_de_dimensionX_et_de_dimensionY
,INTE(valeur_moyenne_de_dimensionX_et_de_dimensionY)
)
);
Eblock
ATes
Bblock
Eblock
ETes
DoIn(dimensionY
,valeur_inferieure_de_dimensionX_et_de_dimensionY
,valeur_superieure_de_dimensionX_et_de_dimensionY
,I
)
/* L'ordre de balayage ('dimY' a l'exterieur et 'dimX' a l'interieur) est le meme que celui */
/* de 'v $xiii/begin_end$DEF Gbegin_imageQ', mais cela est arbitraire et le resultat final */
/* ne depend evidemment pas de lui... */
Bblock
DoIn(dimensionX
,valeur_inferieure_de_dimensionX_et_de_dimensionY
,valeur_superieure_de_dimensionX_et_de_dimensionY
,I
)
Bblock
Test(IFEQ(MUL2(FLOT(dimensionX),FLOT(dimensionY)),FLOT(dimension_a_factoriser)))
/* L'introduction des 'FLOT(...)'s le 20090504113818 est destine a eviter des debordements */
/* dans le produit de 'dimensionX' par 'dimensionY' qui peuvent apparaitre des que le */
/* facteur 'facteur_de_balayage' est un peu grand. Cela s'est vu a cette date avec : */
/* */
/* facteur_de_balayage = 28 */
/* dimension_a_factoriser = 12345678 */
/* */
/* la valeur de 'valeur_superieure_de_dimensionX_et_de_dimensionY' etant alors 98364, dont */
/* le carre 9675476496 deborde, ce qui est donc aussi le cas de nombreux produits de */
/* 'dimensionX' par 'dimensionY' dans les deux boucles 'DoIn(...)'s ci-dessus... */
Bblock
DEFV(Float,INIT(dimensionX_sur_dimensionY,DIVI(FLOT(dimensionX),FLOT(dimensionY))));
DEFV(Float,INIT(dimensionX_sur_dimensionY_relatif,FLOT__UNDEF));
EGAL(la_factorisation_est_possible,VRAI);
/* On a trouve au moins une factorisation... */
Test(IL_FAUT(editer_tous_les_couples_trouves_et_d_autres_informations))
Bblock
CAL2(Prin6("Factorisation : %d=%dx%d (%d/%d=%f)\n"
,dimension_a_factoriser
,dimensionX
,dimensionY
,dimensionX
,dimensionY
,dimensionX_sur_dimensionY
)
);
/* Malheureusement bien souvent la factorisation d'une "dimension" n'est pas unique. */
/* C'est ainsi le cas en format 'Pal' qui donne alors : */
/* */
/* dimX=975 dimY=460 */
/* dimX=897 dimY=500 */
/* dimX=780 dimY=575 */
/* dimX=750 dimY=598 */
/* dimX=690 dimY=650 */
/* dimX=650 dimY=690 */
/* dimX=598 dimY=750 */
/* dimX=575 dimY=780 */
/* dimX=500 dimY=897 */
/* dimX=975 dimY=460 */
/* */
/* pour 'facteur_de_balayage=1.5'. */
/* */
/* Cela rend ce processus non utilisable lors du redimensionnement automatique des images */
/* dans 'v $xiii/files$FON CHoi.taille_de_imageR.' lorsqu'aucun des formats de base des */
/* images n'a ete reconnu... */
/* */
/* Cela est vrai aussi de formats plus "exotiques". Ainsi '999x999' donne : */
/* */
/* dimX=1369 dimY=729 */
/* dimX=999 dimY=999 */
/* dimX=729 dimY=1369 */
/* */
/* alors que '1000x1000' donne : */
/* */
/* dimX=1250 dimY=800 */
/* dimX=1000 dimY=1000 */
/* dimX=800 dimY=1250 */
/* */
/* Il y a donc en general ambiguite... */
Eblock
ATes
Bblock
Eblock
ETes
EGAL(dimensionX_sur_dimensionY_relatif
,ABSO(SOUS(dimensionX_sur_dimensionY,rapport_dimensionX_sur_dimensionY_optimal))
);
Test(IFLT(dimensionX_sur_dimensionY_relatif,minimum_de_dimensionX_sur_dimensionY_relatif));
Bblock
EGAL(meilleure_dimensionX,dimensionX);
EGAL(meilleure_dimensionY,dimensionY);
EGAL(minimum_de_dimensionX_sur_dimensionY_relatif,dimensionX_sur_dimensionY_relatif);
/* Un couple {dimX,dimY} dont le rapport est plus proche de l'optimal vient d'etre trouve. */
/* On le memorise donc... */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
EDoI
Eblock
EDoI
Test(EST_VRAI(la_factorisation_est_possible))
Bblock
Test(IFET(IL_FAUT(simplifier_l_edition_du_couple_optimal)
,IL_NE_FAUT_PAS(editer_tous_les_couples_trouves_et_d_autres_informations)
)
)
Bblock
CAL2(Prin2("%d %d\n",meilleure_dimensionX,meilleure_dimensionY));
Eblock
ATes
Bblock
CAL2(Prin5("La meilleure factorisation est : %d=%dx%d (de rapport egal a %f, proche de %f).\n"
,dimension_a_factoriser
,meilleure_dimensionX,meilleure_dimensionY
,DIVI(FLOT(meilleure_dimensionX),FLOT(meilleure_dimensionY))
,rapport_dimensionX_sur_dimensionY_optimal
)
);
Eblock
ETes
Eblock
ATes
Bblock
CAL2(Prin1("La factorisation de %d est impossible.\n",dimension_a_factoriser));
Eblock
ETes
Eblock
ETes
Eblock
ATes
Bblock
PRINT_ERREUR("la dimension a factoriser est negative ou nulle");
Eblock
ETes
RETU_Commande;
Eblock
ECommande