De BMP Windows a ICO Unix
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);
}
Bmp2Ico, Bmp2Bif código fuente completo y ejemplo de icono ICO