Quadra-comp est une solution de compression/décompression qui décompose n'importe quelle image en rectangles dont les coordonnées sont stoquées dans la matrice P et peut la recomposer en un temps variable qui va de 3 secondes à 2 minutes.
La picture 1 est réquisitionnée pour la procédure.
-------------
Versions
-------------
Version 1.10:
------------------
-Programme de navigation plus complet
-Obligation d'entrer son identifiant (3 lettres) avant chaque compression afin d'identifier l'auteur de la compression et/ou picture
-sauvegarde et chargement assistés.
-Plus aucune picture n'est réquisitionnée et il est possible de compresser l'image courante.
Version 1.30:
---------------
-Il est possible de choisir de nettoyer l'écran avant une décompression.
-Suppression optimisation inutile dans le décompresseur
-Ajout d'un programme de dessin sommaire
-Ajout d'une visionneuse de pictures
-Ajouts d'une image d'exemple à compresser et d'une matrice d'exemple à décompresser.
o) " QDR.CMP1 " correspond à la boucle principale qui va balayer l'intégralité de l'image
(ou de la fenêtre) en testant l'état de chacun des pixels. Si il rencontre un pixel allumé, il
stoquera ses coordonnées puis lancera le programme " QDR.CMP2 "
o) " QDR.CMP2 " contient l'algorythme de compression, c'est à dire le coeur de l'ensemble.
A partir du pixel de base, il essayer de trouver à partir de lui le plus grand rectangle qu'il
soit possible de faire. Une fois ce rectangle trouvé, les coordonées de son point supérieur
gauche et inférieur droit sont stoqués puis le programme " QDR.CMP3 " se lance.
o) " QDR.CMP3 " est un programme dédié au remplissage "intelligent" de la matrice P.
Celle-ci en effet ne pèse que 10 octets au démarrage puis croît de taille au fur et à mesure
que les rectangles de l'image sont stoqués. Si la matrice P est déja occupée, ce programme
se contentera de stoquer les coordonnées à la suite des valeurs déja contenues, sans les
effacer (cependant, il ne conservera que la première colonne en effacant les éventuelles
autres). Si il détecte que la matrice P n'a plus la place suffisante pour contenir la
compression, il sauvegardera ses données dans la matrice Q avant de réinistialiser la
matrice P en y conservant tout de même votre identifiant dans la première case. Il faut noter
que les matrices ne se connecteront pas automatiquement lorsque vous les décompresserez.
Si votre image est morcelée dans plusieurs matrices, il faudra les charger une par une et les
décompresser chacun leur tour.
A noter que si la matrice P se remplit une deuxième fois, la matrice Q sera une nouvelle
fois mise utilisée et les données précédentes seront perdues.
Une fois que les coordonées du rectangles sont stoquées, celles-ci sont passées au
programme " QDR.CMP4 "
o) " QDR.CMP4 " ne fait rien d'autre que d'effacer les pixels du rectangle mis en mémoire.
Si cela n'était pas fait, le rectangle serait stoqué plusieurs fois de suite, car à chaque
balayage de colonne, le programme CMP1 tomberait sur un pixel allumé et relancerait le
processus.
------8<------8<------8<
Précisions sur le programme QDR.CMP2 :
Voici le premier pour voir à quoi correspondent les variables:
QDR.CMP1:
For P->A To R
For Q->B To S
PxlTest B,A
Ans=>Prog "QDR.CMP2"
Next
Next
QDR.CMP2 :
A->C
B->D
Do
C=R=>Goto A
PxlTest D,C+1
Not Ans=>Break
C+1->C
LpWhile 1
Lbl A
C->Z
A->C
B->D
Do
A->C
D=S=>Break
PxlTest D+1,C
Not Ans=>Break
C+1->C
WhileEnd
Lbl B
C<Z=>Break
D+1->D
LpWhile 1
Lbl C
Z->C
Prog "QDR.CMP3"
Return
Premièrement on passe les coordonnées du début à d'autres variables: à savoir C et D.
Ensuite, entrée dans une boucle
Si on trouve que la coordonnées X est au même niveau que Xmax (la variable R), on saute le test pour ne pas produire un Arg Error.
Ensuite, on effectue le test de présence de pixel allumé en X+1 jusqu'à ce qu'on tombe sur un pixel éteint. Cela enclenche un break qui sort de cette boucle.
On donne la dernière valeur du X avant de tmber sur un pixel éteint à la variable Z puis on réinitiallise les variables C et D pour réenclencher une boucle
Pour faire simple, on essaye d'agrandir le rectangle vers le bas au maximum. La croissance du rectangle s'arrête lorsque le pxltest tombe sur un pixel éteint avant la valeur de X stoquée dans Z. On prend alors la valeur Y-1 comme valeur de la hauteur en pixels du rectangle
Une fois le rectangle trouvé, QDR.CMP3 se lance. Il ne fait qu'agrandir la matrice P d'une case puis de rajouter les coordonnées du dernier rectangle trouvé dans la case crée.
Pour la décompression ensuite :
QDR.VIS
CoordOff:GridOff:AxesOff:LabelOff:BG-None:S-WindMan
ClrText:ClrGraph
ViewWindow 1,127,0,1,63,0
S-Gph1 DrawOn,xyLine,List1,List2,1,Dot
S-Gph2 DrawOff
S-Gph3 DrawOff
Cls
Dim Mat P
For 2->Z To List Ans[1]
Mat P[Z,1]
100Frac (Ans/100)->D
Int (Ans/100)
1000Frac (Ans/1000)->C
Int (Ans/1000)
100Frac (Ans/100)->B
Int (Ans/100)->A
2+2*(D-B)->Dim List 1
List 1->List 2
1->L
For B->G To D
A->List 1[L]
64-G->List 2[L]
C=/=A=>Isz L
C->List 1[L]
64-G->List 2[L]
Isz L
Next
DrawStat
Next
Premièrement la définition de la fenêtre graphique.
On voit que ce seront la liste 1 et 2 qui seront utilisées pour le drawstat.
On nettoye l'écran, on vérifie les dimensions de la matrice P. On récupère la valeur Y en utilisant l'argument List Ans[1]
Le For commence à la valeur 2 car la première case de la matrice P contient l'identifiant de la compression, ce qui aboutirait à une erreur grahique.
Chaque case de la matrice P contient les coordonés d'un rectangle.
On peut la découper ainsi:
X1-X1-X1-/-Y1-Y1-/-X2-X2-X2-/-Y2-Y2
L'assemblage de Int( et de Frac( est une technique connue pour repêcher des valeurs dans une suite de chiffres donc je ne m'étendrais pas là dessus.
2+2*(D-B)->Dim List 1
Sert à prédéfinir la taille de la liste qu'il sera nécessaire pour le drawstat. D c'est X2, c'est à dire la valeur absolue (par rapport à l'écran) de la limite inférieure du rectangle. B c'est la limite supérieure. La soustraction de ces deux termes donne la hauteur du rectangle. On multiplie par 2 car chaque ligne du recangle nécessite deux cases dans la liste, et on rajoute 2 car D-B (on aurait pu faire 2*(D-B+1) mais bon...) ne prend pas en compte la dernière ligne.
For B->G To D
A->List 1[L]
64-G->List 2[L]
C=/=A=>Isz L
C->List 1[L]
64-G->List 2[L]
Isz L
Next
On charge deux listes pour lancer un drawstat. La liste 1 pour les coordonnées X des points à tracer et la liste 2 pour les coordonnées Y.
Le balayage de B à D descend le long du rectangle. A chaque nouvelle ligne descendue, on recharge toujours la même variable dans la liste 1 (le bord gauche du rectangle se trouve toujours sur la même colonne). Pour la valeur Y, on utilise la valeur de G qu'on transforme pour respecter le viewwindow.
Ensuite, si C n'est pas différent de A, on n'incrémente pas le pointeur qui sert à remplir les cases pour ne pas utiliser 4 cases de la liste là où il n'en faut (faudrait? A vérifier) que 2.
Ensuite, on charge dans la liste 1 la valeur du bord droit du rectangle et la valeur en Y qui lui correspond.
Le drawstat se lance et les listes sont réinitialisées.
Comme ça on aime pas la couleur ? Je note.
Tu aurais pu me le dire !
De toute façon maitenant je fais aussi sur 85 donc c'est dispo en monochrome...
Sinon ton programme de compression est bien puissant mais il bug, il me fait des lignes droites en étoile parfos du bord inférieur gauche de la calto à un des points de la picture...
et elle est beaucoup beaucoup plus évoluée au niveau de l'interface (l'algorithme de compression n'a subi presque aucune modification)
Je pense qu'il n'y a que celui-ci qui pose problème.
Copié depuis le manuel:
------8<------8<------8<------
o) " QDR.CMP1 " correspond à la boucle principale qui va balayer l'intégralité de l'image
(ou de la fenêtre) en testant l'état de chacun des pixels. Si il rencontre un pixel allumé, il
stoquera ses coordonnées puis lancera le programme " QDR.CMP2 "
o) " QDR.CMP2 " contient l'algorythme de compression, c'est à dire le coeur de l'ensemble.
A partir du pixel de base, il essayer de trouver à partir de lui le plus grand rectangle qu'il
soit possible de faire. Une fois ce rectangle trouvé, les coordonées de son point supérieur
gauche et inférieur droit sont stoqués puis le programme " QDR.CMP3 " se lance.
o) " QDR.CMP3 " est un programme dédié au remplissage "intelligent" de la matrice P.
Celle-ci en effet ne pèse que 10 octets au démarrage puis croît de taille au fur et à mesure
que les rectangles de l'image sont stoqués. Si la matrice P est déja occupée, ce programme
se contentera de stoquer les coordonnées à la suite des valeurs déja contenues, sans les
effacer (cependant, il ne conservera que la première colonne en effacant les éventuelles
autres). Si il détecte que la matrice P n'a plus la place suffisante pour contenir la
compression, il sauvegardera ses données dans la matrice Q avant de réinistialiser la
matrice P en y conservant tout de même votre identifiant dans la première case. Il faut noter
que les matrices ne se connecteront pas automatiquement lorsque vous les décompresserez.
Si votre image est morcelée dans plusieurs matrices, il faudra les charger une par une et les
décompresser chacun leur tour.
A noter que si la matrice P se remplit une deuxième fois, la matrice Q sera une nouvelle
fois mise à contribution et les données précédentes seront perdues.
Une fois que les coordonées du rectangles sont stoquées, celles-ci sont passées au
programme " QDR.CMP4 "
o) " QDR.CMP4 " ne fait rien d'autre que d'effacer les pixels du rectangle mis en mémoire.
Si cela n'était pas fait, le rectangle serait stoqué plusieurs fois de suite, car à chaque
balayage de colonne, le programme CMP1 tomberait sur un pixel allumé et relancera le
processus.
------8<------8<------8<
Le programme QDR.CMP2 nécessite peut être d'avantage de précisions:
Donc déja le premier pour voir à quoi correspondent les variables:
QDR.CMP1:
For P->A To R
For Q->B To S
PxlTest B,A
Ans=>Prog "QDR.CMP2"
Next
Next
QDR.CMP2 :
A->C
B->D
Do
C=R=>Goto A
PxlTest D,C+1
Not Ans=>Break
C+1->C
LpWhile 1
Lbl A
C->Z
A->C
B->D
Do
A->C
D=S=>Break
PxlTest D+1,C
Not Ans=>Break
C+1->C
WhileEnd
Lbl B
C<Z=>Break
D+1->D
LpWhile 1
Lbl C
Z->C
Prog "QDR.CMP3"
Return
Donc déja on passe les coordonnées du début à d'autres variables: à savoir C et D.
Ensuite, entrée dans une boucle
Si on trouve que la coordonnées X est au même niveau que Xmax (la variable R), on saute le test pour ne pas produire un Arg Error.
Ensuite, on effectue le test de présence de pixel allumé en X+1 jusqu'à ce qu'on tombe sur un pixel éteint. Cela enclenche un break qui sort de cette boucle.
On donne la dernière valeur du X avant de tmber sur un pixel éteint à la variable Z puis on réinitiallise les variables C et D pour réenclencher une boucle
Pour faire simple, on essaye d'agrandir le rectangle vers le bas au maximum. La croissance du rectangle s'arrête lorsque le pxltest tombe sur un pixel éteint avant la valeur de X stoquée dans Z. On prend alors la valeur Y-1 comme valeur de la hauteur en pixels du rectangle
Une fois le rectangle trouvé, QDR.CMP3 se lance. Il ne fait qu'agrandir la matrice P d'une case puis de rajouter les coordonnées du dernier rectangle trouvé dans la case crée.
Pour la décompression ensuite (ce qui semble poser problème)
QDR.VIS
CoordOff:GridOff:AxesOff:LabelOff:BG-None:S-WindMan
ClrText:ClrGraph
ViewWindow 1,127,0,1,63,0
S-Gph1 DrawOn,xyLine,List1,List2,1,Dot
S-Gph2 DrawOff
S-Gph3 DrawOff
Cls
Dim Mat P
For 2->Z To List Ans[1]
Mat P[Z,1]
100Frac (Ans/100)->D
Int (Ans/100)
1000Frac (Ans/1000)->C
Int (Ans/1000)
100Frac (Ans/100)->B
Int (Ans/100)->A
2+2*(D-B)->Dim List 1
List 1->List 2
1->L
For B->G To D
A->List 1[L]
64-G->List 2[L]
C=/=A=>Isz L
C->List 1[L]
64-G->List 2[L]
Isz L
Next
DrawStat
Next
Premièrement la définition de la fenêtre graphique (peut être l'erreur se trouve-elle ici).
On voit que ce seront la liste 1 et 2 qui seront utulisées pour le drawstat.
On nettoye l'écran, on vérifie les dimensions de la matrice P. On récupère la valeur Y en utilisant l'argument List Ans[1]
Le For commence à la valeur 2 car la première case de la matrice P contient l'identifiant de la compression, ce qui aboutirait à une erreur grahique.
Chaque case de la matrice P contient les coordonés d'un rectangle.
On peut la découper ainsi:
X1-X1-X1-/-Y1-Y1-/-X2-X2-X2-/-Y2-Y2
Les Int et les Frac sont une technique connue pour repêcher des valeurs dans une suite de chiffres donc je ne m'étendrais pas là dessus.
2+2*(D-B)->Dim List 1
Sert à prédéfinir la taille de la liste qu'il sera nécessaire pour le drawstat. D c'est X2, c'est à dire la valeur absolue (par rapport à l'écran) de la limite inférieure du rectangle. B c'est la limite supérieure. La soustraction de ces deux termes donne la hauteur du rectangle. On multiplie par 2 car chaque ligne du recangle nécessite deux cases dans la liste, et on rajoute 2 car D-B (on aurait pu faire 2*(D-B+1) mais bon...) ne prend pas en compte la dernière ligne.
For B->G To D
A->List 1[L]
64-G->List 2[L]
C=/=A=>Isz L
C->List 1[L]
64-G->List 2[L]
Isz L
Next
Ici, il convient de savoir parfaitement ce à quoi correspond chaque variable, et de ne pas oublier qu'on et en train de charger deux listes pour lancer un drawstat. La liste 1 pour les coordonnées X des points à tracer et la liste 2 pour les coordonnées Y.
Le balayage de B à D descend le long du rectangle. A chaque nouvelle ligne descendue, on recharge toujours la même variable dans la liste 1 (le bord gauche du rectangle se trouve toujours sur la même colonne). Pour la valeur Y, on utilise la valeur de G qu'on transforme pour respecter le viewwindow.
Ensuite, si C n'est pas différent de A, on n'incrémente pas le pointeur qui sert à remplir les cases pour ne pas utiliser 4 cases de la liste là où il n'en faut (faudrait? A vérifier) que 2.
Ensuite, on charge dans la liste 1 la valeur du bord droit du rectangle et la valeur en Y qui lui correspond.
Le drawstat se lance et les listes sont réinitialisées.
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd