/*************************************************************************************************************************************/ /* */ /* 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