1

voila, je trouve mon code un peu lent, y a pas moyen de faire mieux ?
Cette routine effectue uniquement un etirement (agrandissement d'image)

[PRE]
#define PIXEL_IN_BYTE 8
#define BIT_OF_FIRST_PIXEL 0x80

void FN_Zoom(void)
{
short a, b, c, d, e, f, w, h, i, j, m, n, x, y, offset_left;
// x,y Zoom
a = ArgN[0] + Mode.OfstX;
b = ArgN[1] + Mode.OfstY;
if( !FindVarName(ArgS[0].str) ) return;
if( VatType!=PIC_TAG ) ERROR_SUB(err_nam);
// With, Height de l'image
e = *(short*)( FilePtr + 4 );
f = *(short*)( FilePtr + 2 );
//Controle etirement et mode
if( ArgN[2]<e || ArgN[3]<f || ArgN[4]<0 || ArgN[4]>2 || ArgN[5]<0 || ArgN[5]>3 ) ERROR_SUB(err_rng);
unsigned char *deb = (unsigned char *)FilePtr + 6;
// With, Height Zoom
w = ArgN[2];
h = ArgN[3];
// Xmax, Ymax
c = a + w;
d = b + h;
//Effacement de la zone de destination
if( ArgN[5] ) ScrRectFill ( &(SCR_RECT){{a, b, c, d}}, &Mode.clip ,ArgN[5] - 1 );

//Nombre de bytes(octets) par ligne
m = e / PIXEL_IN_BYTE + ( ( e % PIXEL_IN_BYTE )!=0 );
// Definition du Mode a appliquer aux pixels
SetCurAttr( ArgN[4] );
// Parcour des Pixel
for( i = 0; i<w; i++ ) {
// Rechercher abcisse Pixel correspondant dans l'image
x = ( i * e ) / w;
offset_left = x / PIXEL_IN_BYTE;
// Calcul du decallage
n = x % PIXEL_IN_BYTE;

// Parcour des Pixel
for( j = 0; j<h; j++ ) {
// Rechercher ordonnee Pixel correspondant dans l'image
y = ( j * f ) / h;
// Calcul du decallage
// Test etat Bit representant (x,y) dans l'image d'origine et affichage destination
if( (*(deb + y * m + offset_left)<<n ) & BIT_OF_FIRST_PIXEL ) DrawClipPix( a + i, b + j );
}
}
if( ArgS[1].str ) {
if( IsWindow( a, b, c, d ) ) SavePic(ArgS[1].str, a, b, c, d );
else ERROR_SET(err_rng);
}
}
[/PRE]
Extrait code source de ExtLiB

2

Edited_3598

3

Bresenhamise ton algo.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

4

merci, je vais faire un tour sur google pour me documenter sur tous vos conseils.

5

Hum, le precalcul des coef, j'ai essayer. Des resultats erronnes ca a donnees cyborg
Des entiers j'utilise, des coefs arrondis souvent nuls j'obtiens.
La methode j'avoue ne pas maitriser.

Ce site interressant j'ai trouve sur Bresenham
Interesser quelques uns cela pourrait.

6

Voila comment je comprends l'adaptation de Bresenham a mon probleme :
J'applique Bresenham a la portion de code charge de calculer la position des Pixels correspondant dans l'image Original.
[PRE]
// Rechercher de la position du Pixel correspondant dans l'image
x = ( i * e ) / w;
y = ( j * f ) / h;
[/PRE]
Le cas etudier correspondant a un etirement, Je dois determiner pour chaque pixel de l'image de destination, les coordonnees correspondant de l'image d'origine.
On Etire une image de dimensions(width, height) { e, f } en { w, h }

La portion de code ci-dessus, en l'occurence 2 equations de droites ( de type y=f(x) = a*x +b , b= 0 ) , determinent :
les coordonnees des points situes dans l'image d'origine (x, y) a partir
du parcours de toutes les coordonnees(i,j) de l'image de destination
[PRE]
1) Pour tout i E [ 0, w ] il existe x E [ 0, e ], x = f(i) = a0 * i avec w > e, a0 = e / w le coef directeur
2) Pour tout j E [ 0, h ] il existe y E [ 0, f ] , y = g(j) = a1 * j avec h > f, a1 = f / h le coef directeur
[/PRE]

Et la, j'ai plus qu'a appliquer Breseham sur chacune des fonctions.

si je prend le cas 1 :
[PRE]
Pour tout i E [ 0, w ] il existe x E [ 0, e ], x = f(i) = a0 * i avec w > e, a0 = e / w le coef directeur
Pour rendre les choses evidentes je choisis de faire coincider mes notations a celle de la doc sur Bresenham ; en remplacant :
- i par x
- x par y
Ce qui donne :
Pour tout x E [ 0, w ] il existe y E [ 0, e ], y = f(x) = a * x avec w > e, a = e / w le coef directeur

d_x = w - 0 = w
d_y = e - 0 = e


[/PRE]

7

Je suis largue quelque part dans la section portant ce titre: Bresenham pour le tracé de segments

Je pige ceci :

- La variable cumul represente l'accroissement
- comme x s'accroit de 1, le coef directeur 'a' depend uniquement de d_y
ce qui entraine que cumul s'accroit toujours de d_y
lorsque l'effet d_y l'emporte sur d_x dans le cumul, on fait progresser le y de 1 et l'on reduit le cumul de d_x pour en tenir compte ( reste que je me pose la question d'ou est tire cette astuce )

Je pige pas ceci :
- pourquoi l'initialisation suivante cumul = d_x/2. D'apres la doc

On utilise une variable cumul pour stocker la différence entre l'ordonnée entière et l'ordonnée réelle.

Cela suppose qu'au point de depart de l'algo on considere que d_y = 2 ( m'enfin , je suis perdu )

8

J'ai trouver une autre doc de Bresenham qui presente les chose simplement en disant que l'on peut calcule les ordonnees y successive de facon incrementale, en ajoutant a chaque iteration le coef directeur. C'est une approche plus etape par etape que dans la doc d'en haut.
Cela va surement m'aider a y voir plus clair

9

Voici le code que j'obtiens apres Bresehamisation de l'algo :
mais j'ai un bug d'affichage des dernieres lignes/colonnes que j'arrive pas a voir


[PRE]
void FN_Zoom(void)
{
short a, b, c, d;
unsigned short byte_in_row, left_shift, offset_x, i, j, e, f, h, w, x, y;
// x,y Zoom
a = ArgN[0] + Mode.OfstX;
b = ArgN[1] + Mode.OfstY;
if( !FindVarName(ArgS[0].str) ) return;
if( VatType!=PIC_TAG ) ERROR_SUB(err_nam);
// With, Height de l'image
e = *(unsigned short*)( FilePtr + 4 );
f = *(unsigned short*)( FilePtr + 2 );
//Controle etirement et mode
if( ArgN[2]<(short)e || ArgN[3]<(short)f || ArgN[4]<0 || ArgN[4]>2 || ArgN[5]<0 || ArgN[5]>3 ) ERROR_SUB(err_rng);
// Pointeur sur le 1er byte dans l'Image
unsigned char *deb = (unsigned char *)FilePtr + 6;
// With, Height Zoom
w = ArgN[2];
h = ArgN[3];
// Xmax, Ymax
c = a + w;
d = b + h;
//Effacement de la zone de destination
if( ArgN[5] ) ScrRectFill ( &(SCR_RECT){{a, b, c, d}}, &Mode.clip ,ArgN[5] - 1 );

// Definition du Mode a appliquer aux pixels
SetCurAttr( ArgN[4] );

//Nombre de bytes(octets) par ligne
byte_in_row = e / PIXEL_IN_BYTE + ( ( e % PIXEL_IN_BYTE )!=0 );

// Variables Bresenham
unsigned short dx1, dx2, dy1, dy2;
short e1, e2, h1, h2, d1, d2;
// Bresenham X
dx1 = w;
dy1 = e;
h1 = 2 * dy1;
d1 = 2 * ( dy1 - dx1 );
e1 = 2 * dy1 - dx1;

// Bresenham Y
dx2 = h;
dy2 = f;
h2 = 2 * dy2;
d2 = 2 * ( dy2 - dx2 );

// Initialisation parametre X
x = 0;
offset_x = 0;
left_shift = 0;

// Parcour des Pixel X
for( i = 0; i<w; i++ ) {

// Initialisation parametre Y
y = 0;
e2 = 2 * dy2 - dx2;
//sprintf( Buffer1, "COLUMN n = %i, x=%i y=%i", i, x, y );
//ST_helpMsg( Buffer1 );

// Parcour des Pixel Y
for( j = 0; j<h; j++ ) {

// Test de l'etat du Bit representant le couple (x,y) dans l'image d'origine
if( (*(deb + y * byte_in_row + offset_x )<< left_shift ) & BIT_OF_FIRST_PIXEL ) DrawClipPix( a + i, b + j );

// Calcul Y a partir de Bresenham
if( e2 > 0 ) {
y++;
e2 += d2;
}
else e2 += h2;

}

// Calcul X a partir de Bresenham
if( e1 > 0 ) {
x++;
e1 += d1;
}
else e1 += h1;

// Calcul de l'offset du a l'abcisse X dans le fichier Image
offset_x = x / PIXEL_IN_BYTE;
// Calcul decallage binaire a effectuer pour lire l'etat du bit(X, Y) dans un byte
left_shift = x % PIXEL_IN_BYTE;

//Wait( 10 );
}

if( ArgS[1].len ) {
if( IsWindow( a, b, c, d ) ) SavePic(ArgS[1].str, a, b, c, d );
else ERROR_SET(err_rng);
}

}

[/PRE]
Extrait code source de ExtLiB


Il ne me reste plus qu'a trouver un moyen d'eliminer la division et le modulo lors du calcul des decallage:
[PRE]
// Calcul decallage du a l'abcisse X dans le fichier Image
offset_x = x / PIXEL_IN_BYTE;
// Calcul decallage pour lire l'etat a la position ( X, Y)
n = x % PIXEL_IN_BYTE;

[/PRE]

10

Lol ton sextuple post grin
Bon pour ton truc, (x/8) => (x>>3) et (x%8) => (x&7) pour x >= 0.
Ces deux opérations sont aussi rapides qu'une addition wink
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

11

Sauf que pour sa constante s'il fait une division y'a pas de raison qu'il écrive un décalage. La division est plus explicite et tout aussi rapide, seule la notation change. Idem pour le modulo.

12

Ok. Je peux pas tester, j'ai pas le compilo sur la main, mais j'ai dit ça parce que je sais que sur PC par exemple le compilo n'optimise les divisions en décalage que si les opérandes sont non signées vu que le résultat n'est pas le même: (-3)>>1 = -2 mais (-3)/2 = -1.
Maintenant sur TI c'est peut-être équivalent...
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

13

Oué mais je suis persuadé qu'il peut travailler avec des nombres non signés.

14

surement que ca doit se faire sans probleme

15

Dans mon code apres Bresehamisation base sur l'algo de la fin du document sur Bresenham:

J'ai un bug d'affichage des dernieres lignes/colonnes sur lequel j'arrive pas a mettre la main.
index.php?f=7219E25C

Un peu d'aide serait bienvenu.

Il me semble que ce sont la 1ere ligne et la 1ere colonne de l'image a zoomer qui sont mal lue.

J'ai pourtant suvi l'algo a la lettre.
En comparant les valeur de X, Y avec les 2 algo, a partir d'un moment, les coordonnees different. Mais j'ai beau chercher je trouve pas mon erreur

16

L'impression que ça donne, c'est que tu débordes à droite et en bas.
Regarde : le trait parasite à droite correspond au trait de gauche, mais un pixel plus haut.
La ligne du bas serait donc lue depuis une donnée quelconque suivant ton image en mémoire.