El programa de conversión de Bitmaps (BMP) de 16 bits de Windows
al formato ICO (de icono) de Unix
lo comenzó a desarrollar Juan Ramón Miraz, al comienzo de los noventa,
y la versión final que se adjunta en este post la terminé yo.
El formato ICO de Unix especifica un mapa de bits como una matriz de
caracteres ASCII,
donde cada letra se asocia con el color del pixel de su misma fila y columna.
Hubo una época que los bitmaps de los botones de los interfaces de usuario
yo lo pintaba así,
utilizando el editor vi de Unix y letra a letra.
Por ejemplo, asociaba
la v al verde, la b al blanco, la r al rojo, etc.,
para que me fuera más fácil,
e iba poniendo letras, una a una, hasta que el botón quedaba bien.
Para mi era una gratificante labor artesanal.
A partir de este programa también desarrollé el que convierte del formato
BMP al formato BIF, que era un formato propio mio, que
utilizaba en combinación con Clipper.
Aunque ahora se podrían recompilar estos dos códigos fuente
para las versiones de Windows de 64 bits,
sigo utilizando los ejecutables originales de 16 bits.
Antes estos ejecutables de 16 bits podían correr mediante emulación
en Windows de 32 bits,
pero ahora el Windows de 64 bits ya no emula al de 16 bits.
Para poder seguir ejecutando estas pequeñas joyas históricas,
sin necesidad de recompilarlas
(y más aun en aquellos casos en el que el compilador es también de 16 bits)
utilizo el emulador de x86 con DOS de
DOSBox
que se publica con licencia GNU GPL y aceptan donaciones
(yo se la di).
Aunque adjunto en PDF el código fuente completo de
los 2 programas de conversión y
un ejemplo del formato ICO generado con mi logotipo personal,
pongo a continuación el ciclo fundamental de extracción de pixels de
un Bitmap (BMP) de 16 colores.
Como curiosidad, en esta época,
por razones de normalización con el equipo de software con el que trabajaba,
los corchetes { } están en la vertical del bloque de código y
no dos caracteres antes como es mi costumbre habitual:
for (Y=0, YMax=Bmih.biHeight; Y < YMax; Y++)
{
fseek(Bmp, RowStart, SEEK_SET);
for (X=0, XMax=Bmih.biWidth; X < XMax; X++)
{
Arg = fgetc(Bmp);
H = (Arg >> 4) & 0x0F; H = Color[H];
L = Arg & 0x0F; L = Color[L];
X++;
fprintf(Pix,"%c%c",(char)H,(char)L);
}
RowStart -= RowBytes;
fprintf(Pix,"\n");
fputc('.',stdout); fflush(stdout);
}