Suivez-nous sur Mastodon

|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Dossier : Le format et la structure des icônes Amiga
(Article écrit par Grzegorz Kraszewski et extrait de krashan.ppa.pl - janvier 2012)
|
|
Un guide non officiel pour décoder les images d'icônes Amiga classiques
1. Introduction
Les icônes dans AmigaOS et ses dérivés (MorphOS, AROS) sont fondamentalement les mêmes que sur les autres
systèmes d'exploitation : de petites images identifiant des fichiers, des répertoires, des disques, etc.
À l'exception des données d'image, les icônes Amiga contiennent des informations supplémentaires. Les
icônes de fichier peuvent contenir un chemin vers une application utilisée pour ouvrir le fichier de projet
lorsqu'on double-clique dessus (l'outil par défaut). Elles peuvent également contenir ce que l'on appelle
des "types d'outils", qui ne sont que des chaînes utilisées comme paramètres de programme. Les icônes de
dossier (tiroir) et de disque contiennent la position, la taille et le mode d'affichage d'une fenêtre
ouverte sur le bureau après avoir cliqué sur l'icône. Toutes les icônes peuvent stocker leur position dans
la fenêtre parente du tiroir (ou du bureau).
J'ai voulu écrire ce guide non officiel car je n'en ai trouvé aucun sur Internet. Bien que les icônes Amiga
ne soient pas très populaires, AmigaOS lui-même étant plutôt un système d'exploitation de niche et de loisir,
quelqu'un pourrait trouver cet article utile. Notez qu'il existe plusieurs types d'icônes Amiga. Cet article
décrit un ancien format basé sur le plan de bits ("bitplane"). Les icônes NewIcons et PNG ultérieures (telles
qu'utilisées dans AmigaOS 4, MorphOS et AROS) ne sont pas décrites ici.
2. Icônes réelles et par défaut
Les icônes dans AmigaOS sont des fichiers séparés, portant le même nom que le fichier "principal"
et l'extension ".info" à la fin. Notez que si un fichier possède une extension propre (par exemple "archive.lha"),
l'extension ".info" ne remplace pas l'extension du fichier, mais est ajoutée à la fin, donc une icône pour
"archive.lha" porte le nom "archive.lha.info". Cela peut paraître étrange pour un utilisateur Windows,
mais cela vient du fait que le système Amiga n'utilise pas du tout d'extensions pour la reconnaissance du
type de fichier. Un fichier exécutable sans ".exe" est parfaitement reconnu comme tel, par exemple. Pour en
dire plus, les fichiers exécutables sur Amiga n'ont généralement aucune extension.
Lorsqu'un fichier n'a pas d'icône associée, il est invisible dans la fenêtre Workbench jusqu'à ce que le
mode d'affichage "Afficher tous les fichiers" soit sélectionné. Une icône par défaut pour le fichier est
alors utilisée. Les anciennes versions d'AmigaOS stockaient les icônes par défaut dans "ENVARC:sys/def_xxxx.info",
où "xxxx" est un "tiroir", un "projet", un "outil" ou un "disque". Certaines extensions de ce système ont
été développées, ce qui permet d'utiliser des icônes différentes pour différents types de fichiers. Ce qui
est important ici, c'est que les icônes par défaut ont le même format de fichier que les vraies. On peut
facilement créer une vraie icône à partir d'une icône par défaut, en utilisant les outils système, ou simplement
en copiant l'icône et en changeant son nom.
3. Structure des icônes Amiga
Le fichier d'icônes est composé directement de certaines structures système. Il présente l'avantage de
charger et d'afficher rapidement les icônes, le fichier est simplement chargé en mémoire, les adresses des
structures sont extraites et peuvent être transmises directement à Intuition, la bibliothèque d'interface
utilisateur principale d'Amiga. D'un autre côté, de nombreux champs de ces structures système sont inutilisés
ou redondants, ce qui rend le fichier d'icônes plus volumineux. Certaines données de ces structures sont
référencées via des pointeurs en mémoire, dans un fichier d'icônes, les données sont stockées après les
structures dans un ordre défini.
L'état sélectionné d'une icône Amiga n'est pas généré par programmation, mais est spécifié dans l'icône
elle-même. Souvent, l'état sélectionné est une seconde image distincte, parfois il est spécifié sous forme
d'échange d'entrées de palette.
3.1. Aperçu du format
Le fichier d'icône commence par une structure DiskObject, qui intègre la structure Gadget. Il peut ensuite
y avoir une structure DrawerData, suivie d'une ou deux structures Image. Après elles, les données d'image
raster pour Image(s) suivent. Il y a ensuite une chaîne d'outils par défaut et des chaînes de types d'outils.
DrawerData contient une structure NewWindow. Voici un schéma fonctionnel d'une icône Amiga :
| DiskObject |
DrawerData |
Image 1 |
Donnée raster pour image 1 |
Image 2 |
Donnée raster pour image 2 |
Outil par défaut |
Type d'outils |
Fig. 1. Un schéma fonctionnel de la structure du fichier d'icônes Amiga (les éléments en bleu clair
sont facultatifs)
Remarque : tous les champs multi-octets d'une icône Amiga sont de type gros-boutiste. Les programmeurs
x86 doivent échanger les octets.
3.2. Structure DiskObject
| 0000 |
uint16 |
do_Magic |
Un identifiant de fichier. Toutes les icônes ont ici 0xE310 |
| 0002 |
uint16 |
do_Version |
Version icône. La version actuelle est la 1 |
| 0004 |
uint32 |
do_Gadget NextGadget |
Non utilisé. Contient généralement 0 |
| 0008 |
int16 |
do_Gadget.LeftEdeg |
Position horizontale du bord gauche de l'icône par rapport au bord gauche de la fenêtre parente.
Ce champ n'est utilisé que lorsqu'une icône est chargée en mémoire |
| 0010 |
int16 |
do_Gadget.TopEdge |
Position verticale du bord supérieur de l'icône par rapport au bord supérieur de la fenêtre parente.
Ce champ n'est utilisé que lorsqu'une icône est chargée en mémoire |
| 0012 |
uint16 |
do_Gadget.Width |
Largeur de l'icône en pixels |
| 0014 |
uint16 |
do_Gadget.Height |
Hauteur de l'icône en pixels |
| 0016 |
uint16 |
do_Gadget.Flags |
Drapeaux de gadget. Utilisé uniquement par Intuition, lorsque l'icône est chargée en mémoire.
Généralement défini sur 5
|
| 0018 |
uint16 |
do_Gadget.Activation |
Drapeaux d'activation des gadgets. La valeur habituelle est ici 3 (les méthodes d'activation "immediate"
et "relverify" sont définies) |
| 0020 |
uint16 |
do_Gadget.GadgetType |
Type de gadget. La valeur habituelle ici est 1 (ce qui signifie gadget booléen) |
| 0022 |
uint32 |
do_Gadget.GadgetRender |
En mémoire, un pointeur vers la première image, utilisé pour l'état non sélectionné. Dans le
fichier, il doit s'agir d'une valeur différente de zéro. Zéro ici ne devrait pas se produire |
| 0026 |
uint32 |
do_Gadget.SelectRender |
En mémoire, un pointeur vers la deuxième image, utilisé pour l'état sélectionné. Dans le fichier,
une valeur différente de zéro signifie que l'icône contient la deuxième image et les données raster |
| 0030 |
uint32 |
do_Gadget.GadgetText |
Non utilisé. Habituellement 0 |
| 0034 |
uint32 |
do_Gadget.MutualExclude |
Non utilisé. Habituellement 0 |
| 0038 |
uint32 |
do_Gadget.SpecialInfo |
Non utilisé. Habituellement 0 |
| 0042 |
uint16 |
do_Gadget.GadgetID |
Non utilisé. Habituellement 0 |
| 0044 |
uint32 |
do_Gadget.UserData |
Utilisé pour la révision des icônes. 0 pour les icônes AmigaOS 1.x. 1 pour les icônes AmigaOS 2.x/3.x |
| 0048 |
uint8 |
do_Type |
Un type d'icône :
- 1 - disque ou volume
- 2 - tiroir (dossier)
- 3 - outil (exécutable)
- 4 - projet (fichier de données)
- 5 - poubelle
- 6 - périphérique logique
- 7 - Image ROM Kickstart
- 8 - une icône d'application (placée sur le bureau par l'application)
|
| 0049 |
uint8 |
padding |
Juste un octet de remplissage |
| 0050 |
uint32 |
do_DefaultTool |
En mémoire, un pointeur vers une chaîne de chemin d'outil par défaut. Dans le fichier, il doit être
interprété comme un champ booléen indiquant la présence d'un outil par défaut |
| 0054 |
uint32 |
do_ToolTypes |
En mémoire, un pointeur vers une table contenant des pointeurs vers des chaînes de types d'outils.
Dans le fichier, il doit être interprété comme un champ booléen indiquant la présence de la table des
types d'outils |
| 0058 |
int32 |
do_CurrentX |
Position horizontale virtuelle de l'icône dans la fenêtre du tiroir |
| 0062 |
int32 |
do_CurrentY |
Position verticale virtuelle de l'icône dans la fenêtre du tiroir |
| 0066 |
uint32 |
do_DrawerData |
En mémoire, un pointeur vers la structure DrawerData. Dans le fichier, il doit être interprété comme
un champ booléen indiquant la présence de DrawerData |
| 0070 |
uint32 |
do_ToolWindow |
Inutilisé |
| 0074 |
uint32 |
do_StackSize |
Taille de la pile de tâches pour une application (dans le cas d'un fichier projet, cette taille est
celle de l'application d'outil par défaut) |
| Taille totale : 78 octets |
3.3. Structure DrawerData
La structure démarre à partir d'une structure NewWindow. Notez que DrawerData peut être simplement ignoré
lorsque seule l'image de l'icône doit être décodée. J'ai mis les informations ici juste pour être complet.
| 0000 |
int16 |
dd_NewWindow.LeftEdge |
Bord gauche de la fenêtre du tiroir par rapport à l'écran du Workbench |
| 0002 |
int16 |
dd_NewWindow.TopEdge |
Bord supérieur de la fenêtre du tiroir par rapport à l'écran du Workbench |
| 0004 |
int16 |
dd_NewWindow.Width |
Largeur de la fenêtre du tiroir |
| 0006 |
int32 |
dd_NewWindow.Height |
Hauteur de la fenêtre du tiroir |
| 0008 |
uint8 |
dd_NewWindow.DetailPen |
Nombre de stylos graphiques utilisés pour restituer les détails de la fenêtre |
| 0009 |
uint8 |
dd_NewWindow.BlockPen |
Nombre de stylos graphiques utilisés pour restituer l'arrière-plan du cadre de la fenêtre |
| 0010 |
uint32 |
dd_NewWindow.IDCMPFlags |
Types d'événements IDCMP (GUI -> application) demandés |
| 0014 |
uint32 |
dd_NewWindow.Flags |
Différents drapeaux de fenêtre (bordures, gadgets système, etc.) |
| 0018 |
uint32 |
dd_NewWindow.FirstGadget |
En mémoire, un pointeur vers le premier gadget de fenêtre dans une liste chaînée. Inutilisé dans un fichier d'icône |
| 0022 |
uint32 |
dd_NewWindow.CheckMark |
En mémoire, un pointeur pour cocher les images de la fenêtre. Inutilisé dans un fichier d'icône |
| 0026 |
uint32 |
dd_NewWindow.Title |
En mémoire, un pointeur vers la chaîne du titre de la fenêtre. Inutilisé dans un fichier d'icône |
| 0030 |
uint32 |
dd_NewWindow.Screen |
En mémoire, un pointeur vers l'écran système sur lequel une fenêtre doit être ouverte. Non utilisé dans
un fichier d'icône |
| 0034 |
uint32 |
dd_NewWindow.BitMap |
En mémoire, pointe vers un BitMap système pour la fenêtre. Inutilisé dans un fichier d'icône |
| 0038 |
int16 |
dd_NewWindow.MinWidth |
Largeur minimale de la fenêtre |
| 0040 |
int16 |
dd_NewWindow.MinHeight |
Hauteur minimale de la fenêtre |
| 0042 |
uint16 |
dd_NewWindow.MaxWidth |
Largeur maximale de la fenêtre |
| 0044 |
uint16 |
dd_NewWindow.MaxHeight |
Hauteur maximale de la fenêtre |
| 0046 |
uint16 |
dd_NewWindow.Type |
Type de fenêtre (écran public/personnalisé) |
| 0048 |
int32 |
dd_CurrentX |
Position horizontale de l'icône d'origine |
| 0052 |
int32 |
dd_CurrentY |
Position verticale de l'icône d'origine |
| Taille totale : 56 octets |
3.4. Structure de l'image
| 0000 |
int16 |
LeftEdge |
Position du bord gauche de l'image par rapport au bord gauche de l'icône. Le découpage de l'image doit
être effectué pour les valeurs négatives |
| 0002 |
int16 |
TopEdge |
Position du bord supérieur de l'image par rapport au bord supérieur de l'icône. Le découpage de l'image doit
être effectué pour les valeurs négatives |
| 0004 |
uint16 |
Width |
Largeur de l'image en pixels. Peut être inférieure à la largeur de l'icône (stockée dans DiskObject.Gadget),
les colonnes manquantes utilisent la couleur 0. Si elle est supérieure à la largeur de l'icône, je recommande
de couper l'image |
| 0006 |
uint16 |
Height |
Hauteur de l'image en pixels. Peut être inférieure à la hauteur de l'icône (stockée dans DiskObject.Gadget),
les lignes manquantes utilisent la couleur 0. Si elle est supérieure à la hauteur de l'icône, je recommande de
couper l'image |
| 0008 |
uint16 |
Depth |
Nombre de plans de bits de l'image (voir chapitre 3.5) |
| 0010 |
uint32 |
ImageData |
En mémoire, il s'agit d'un pointeur vers des plans de bits ; dans le fichier, il doit être traité comme
une valeur booléenne (si elle n'est pas nulle, les données du plan de bits sont stockées comme indiqué sur
la fig. 1) |
| 0014 |
uint8 |
PlanePick |
Un champ de bits contrôlant quel plan de bits d'image est copié sur quel plan de bits d'écran. Utilisé
uniquement par les jeux de composants graphiques de l'Amiga Classic. N'a aucune signification dans un fichier,
car il est interprété dans le contexte du jeu de composants Amiga affichant un écran particulier |
| 0015 |
uint8 |
PlaneOnOff |
Un champ de bits contrôlant les plans de bits de l'écran non alimentés par des données d'icône. Ils peuvent
être remplis soit par des zéros, soit par des uns. Utilisé uniquement par les jeux de composants graphiques de l'Amiga
Classic. N'a aucune signification dans un fichier, car il est interprété dans le contexte du jeu de composants
Amiga affichant un écran particulier |
| 0016 |
uint32 |
NextImage |
Non utilisé. Habituellement 0 |
| Taille totale : 20 octets |
3.5. Données d'image et palette
Les données d'image d'icône sont stockées sous forme de plans de bits. Bien qu'un peu encombrant pour les
dispositifs d'affichage actuels, ce format est natif pour les jeux de composants graphiques Amiga. Ensuite,
les données d'image, une fois chargées dans la mémoire graphique ("Chip"), peuvent être directement transférées
sur un écran. Sur les plans de bits, chaque pixel occupe un bit, quel que soit le nombre de couleurs de la
palette. La taille de la palette est déterminée par un nombre de plans de bits, pour N plans de bits, il y a
2N couleurs disponibles. Pour déterminer une couleur de pixel, il faut rassembler ces bits de pixel
de tous les plans de bits (le plan de bits 0, qui vient en premier dans les données, est le plus significatif)
comme indiqué sur la figure 2, former un nombre et l'utiliser comme index de la table de palettes.
Fig. 2. Données d'image en plan de bits
Les plans de bits des icônes Amiga ne sont pas entrelacés, les plans complets sont stockés un par un.
L'ordre de balayage des pixels est généralement de gauche à droite et de haut en bas. Les rangées de plans
sont complétées par des mots de 16 bits, il n'y a pas de remplissage vertical.
Bien que les données d'image soient basées sur des palettes, aucune palette n'est stockée dans l'icône,
seule une palette standard est supposée. Malheureusement, quelques palettes "standard" sont utilisées :
- Palette standard AmigaOS 1.x, 4 couleurs
- couleur 0, R=85, V=170, B=255 (0x55AAFF)
- couleur 1, R=255, V=255, B=255 (0xFFFFFF)
- couleur 2, R=0, V=0, B=0 (0x000000)
- couleur 3, R=255, V=136, B=0 (0xFF8800)
- Palette standard AmigaOS 2.x, 4 couleurs
- couleur 0, R=149, V=149, B=149 (0x959595)
- couleur 1, R=0, V=0, B=0 (0x000000)
- couleur 2, R=255, V=255, B=255 (0xFFFFFF)
- couleur 3, R=59, V=103, B=162 (0x3B67A2)
- Palette MagicWB, 8 couleurs. Elle étend la palette AmigaOS 2.x avec 4 couleurs supplémentaires
- couleur 4, R=123, V=123, B=123 (0x7B7B7B)
- couleur 5, R=175, V=175, B=175 (0xAFAFAF)
- couleur 6, R=170, V=144, B=124 (0xAA907C)
- couleur 7, R=255, V=169, B=151 (0xFFA997)
D'autres palettes ont été proposées, généralement pour étendre MagicWB avec plus de couleurs, mais elles
n'ont pas gagné en popularité. Le format NewIcons a finalement résolu le problème en stockant une palette
à l'intérieur d'une icône. Quelle palette faut-il utiliser pour convertir l'image de l'icône en espace
colorimétrique RVB ? Si nous limitons les possibilités aux palettes présentées ci-dessus, la révision de
l'icône permet de choisir entre la palette AmigaOS 1.x et AmigaOS 2.x. Alors si la révision est 1 et le
nombre de plans de bits est 3, l'icône est celle de MagicWB.
4. Décoder les images des icônes
En général, vous ne vous intéresserez qu'à l'extraction d'images à partir d'une icône et à leur conversion
dans l'espace colorimétrique RVB (à moins que vous n'écriviez un remplacement du Workbench Amiga...). Voici
un petit guide pour savoir comment procéder :
- Gardez à l'esprit que la plupart des informations de l'icône ne sont pas utilisées. Tous les champs des
structures DiskObject et Image réellement nécessaires au décodage des images sont marqués dans les cases des
tableaux en bleu clair. Les entrées en blanc peuvent être ignorées. Si vous utilisez une plate-forme x86 ou
une autre plate-forme petit-boutiste, n'oubliez pas l'échange d'octets.
- Commencez par charger une structure DiskObject de taille fixe. Vérifiez do_Magic et do_Version.
Vérifiez ensuite la présence de DrawerData. Un do_DrawerData non nul est l'indicateur principal, un do_Type
de 1, 2 ou 5 est l'indicateur secondaire. Vérifiez la présence de la première image (do_Gadget.GadgetRender).
Le deuxième indicateur principal d'image est do_Gadget.SelectRender, le secondaire est que les bits de
surbrillance du gadget sont définis sur 2 (do_Gadget.Flags & 0x0003 == 0x0002).
- Si DrawerData est présent, ignorez-le.
- Lire la première structure d'image. Extraire les décalages, la largeur, la hauteur et le nombre de
plans de bits. Calculer la largeur du plan de bits en octets en tenant compte du remplissage horizontal.
Elle peut être calculée comme ((Largeur + 15) >> 4) << 1.
- Vérifiez la présence d'ImageData. Si la valeur est 0, cela peut signifier que l'image est vide ou que
le fichier est endommagé. Dans le cas contraire, chargez les plans de bits en mémoire.
- Si vous avez détecté la deuxième image, répétez les étapes 4 et 5. Soyez prêt pour des décalages et des
dimensions différents (cela peut arriver souvent) ou un nombre de plans de bits différent (très peu probable,
mais qui sait).
- Sélectionnez la palette pour chaque image, en fonction de la révision de l'icône et du nombre de plans
de bits. Convertissez les plans de bits en une carte de pixels RVB, en utilisant la palette sélectionnée.
Notez que les bits de remplissage doivent être ignorés même s'ils ne sont pas nuls.
- Créez un rectangle vide de la taille d'une icône (do_Gadget.Width × do_Gadget_Height).
Remplissez-le avec la couleur de palette 0. Ensuite, imposez-lui l'image normale ou sélectionnée en
utilisant Image LeftEdge et TopEdge comme décalages. Effectuez un découpage si nécessaire.
|