El formato de imagen PCX

pcarballosa

1er Lugar
Mensajes
1,096
Oro
229,825
En un tiempo se utilizó mucho un formato de imagen conocido como PCX (.pcx) diseñado en la empresa ZSoft; era la época cuando reinaba en las PC de IBM el Windows 3.1, el cual venía con un programa de nombre Paintbrush para editar esa clase de archivos de imagen.

De hecho, el formato de los archivos comentados llegó a ser tan popular que muchos diseñadores de videojuegos lo usaban (en su variante para imágenes de 256 colores) para elaborar los gráficos de su producto, en tanto, en otros productos de la misma índole, entre ellos el conocido videojuego de estrategia en tiempo real Starcraft, también sirvió para guardar las capturas de pantalla.

En cambio en la actualidad, a diferencia de lo comentado antes, las imágenes ".pcx" casi no son utilizadas como resultado de las limitaciones de su formato, causadas estas en parte a su vez por todas las limitaciones tecnológicas de la época cuando fue elaborado.

En todo caso, y a pesar de lo dicho, estudiar los PCX puede resultar interesante, puesto incluso cuando su uso no es ahora tan extendido como en su época de gloria, pueden seguir siendo útiles en muchas ocasiones. En primer lugar podría mencionar una situación como la propia de cuando se desarrolla un sistema operativo y se necesita mostrar una imagen de bienvenida en pantalla en tanto se está llevando a cabo la carga del sistema en segundo plano; y en una situación similar, u otras parecidas, una imagen ".pcx" con los símbolos de las distintas letras del alfabeto podría ser usada como si se tratara de una fuente, para poner texto en pantalla en modo gráfico. Pero según mi punto de vista, lo más conveniente de estudiar el formato de los PCX es su simplicidad, lo cual lo hace ideal para comenzar a introducirse en este mundo de las imágenes en la computadora, y a su vez propicia su utilidad en las situaciones mencionadas, y en otras parecidas, por posibilitar la interpretación y puesta en pantalla de imágenes con sólo unas pocas líneas de código de programa.

Por todo esto, en este corto texto vamos a estudiar todo lo referente a la organización interna o formato de los archivos PCX, o por lo menos de la forma más somera posible, mas suficiente para entender cómo fue diseñado dicho formato; y también ofreceré, como demostración más práctica de lo explicado en la parte teórica, una implementación del código necesario para colocar un PCX centrado en la pantalla de la computadora.

El código mencionado estará escrito en la variante del lenguaje BASIC usada por QuickBASIC para facilitar la comprensión del programa, aun cuando en última instancia el entorno utilizado para la compilación fue QB64 (una implementación más moderna de QuickBASIC). En este caso debí hacerlo así para posibilitar que el programa creado se pudiera correr directamente sobre los Windows de 64 bits más modernos, los cuales son incapaces de correr programas de MSDOS de 16 bits como los generados por QuickBASIC, a no ser se use para eso un emulador de MSDOS como DOSBox. Pero lo dicho no significa que cada cual no podrá usar su lenguaje preferido si desea interpretar un archivo ".pcx" por su cuenta, porque por lo menos en cuanto a la información necesaria para hacerlo, tendrá lo necesario, y todo lo demás dependerá más bien sólo de su deseo de llevar a cabo esa tarea.

En resumen, primero vamos a estudiar lo referente a la estructura interna de un PCX, y después los interesados podrán descargarse la implementación mencionada si les sirve de algo; aun cuando debo especificar dicha implementación estará limitada a las imágenes ".pcx" de 16 colores debido a los motivos comentados más adelante.

Nota: En caso de descargar la implementación podrán notar una pobre calidad de las imágenes a ser mostradas, esto no se debe ni a la implementación ni a las imágenes en sí mismas, sino a la pérdida de calidad en ellas cuando se las convierte desde color verdadero (como eran en principio) a sólo 16 colores, debido a no disponer de imágenes originales de 16 colores.

En fin, para no darle más vueltas, comencemos, y lo haremos conociendo como las imágenes en formato PCX son imágenes de mapa de bits cual las imágenes BMP, JPEG, GIF, PNG, mas como comenté un poco antes, con una organización interna mucho más simple en comparación con esos otros formatos de imagen mencionados. En ellas por lo común se utiliza una paleta de colores para la representación de estos, como sucede con los GIF, y esta es la causa de la limitación de la cantidad de colores disponible con ese formato, por lo común no más de 256 a la vez. En general la cantidad de colores varía según la profundidad de color soportada por cada variante de formato, y existen varias variantes de los archivos “.pcx” para 1, 2, 4, y 8 bits por pixel (BPP), esto es, para 2, 4, 16, y 256 colores respectivamente. Pero además es necesario mencionar como entre todas las distintas variantes del formato PCX también podemos encontrarnos con una no indexada de 24 bits de profundidad de color, o sea, una variante donde no se utilizó una paleta de colores para representarlos, y por esto con ella se puede disponer de imágenes en color verdadero.

Nota: Las imágenes de mapa de bit guardan la información como una matriz de puntos de colores individuales conocidos como píxeles, los cuales, cuando son vistos en pantalla en sus posiciones relativas, nos permiten reconocer la forma representada en ellas; pero también existen los gráficos vectoriales, en los cuales a diferencia de en las imágenes de mapa de bits, se conforma la imagen por medio de una serie de cálculos matemáticos, y del llamado a las primitivas gráficas, primitivas estas casi siempre dependientes del sistema en donde se los ha creado.

En adición a lo dicho, por lo común el mapa de bit o zona de datos de los PCX está comprimida usando el algoritmo RLE (Run Length Encoding por sus siglas en inglés), lo cual se utiliza para la reducción de su tamaño en disco como mismo se lo hace en las imágenes en formato BMP de los Windows más modernos, y por eso mismo estudiar los PCX nos da la oportunidad de ir viendo cómo es ese procedimiento de compresión, y después estar más preparados cuando estudiemos un formato de imagen diferente en donde también se lo utilice.

En mi caso particular, como comenté, me concentré en la variante o versión de 16 colores de los archivos ".pcx", y lo hice por lo menos por tres motivos distintos (el último no es tan relevante):​

  1. La documentación para la versión de los PCX de 256 colores está mucho más extendida debido a lo comentado sobre su uso pasado en la realización de videojuegos.​
  2. La variante de formato de 4 bits de profundidad de color o 16 colores, se interpreta casi del mismo modo en comparación con la de 256 colores, aun cuando presenta un poco más de complicaciones durante ese proceso.​
  3. El entorno Microsoft QuickBASIC usado sólo dispone de una resolución de 320x200 píxeles en modo 13 (único con soporte para los 256 colores), en cambio tiene una resolución de 640x480 en modo 12 (donde los colores se ven limitados a 16), y por eso podemos disponer de más resolución con imágenes de 16 colores.​
En cuanto a su organización interna, un archivo ".pcx" consiste de forma general en una cabecera con la información necesaria para su decodificación, el mencionado mapa de bits o zona de datos donde se guarda la información de la imagen propiamente dicha, y una paleta de colores para 256 colores, todo esto en ese mismo orden dentro del archivo.

Nota: Las imágenes en formato PCX de 24 bits o color verdadero también existen, como he dicho en otra parte, y se representan como imágenes de 8 bits con planos de color diferentes para cada componente de los colores básicos.

Todo lo anterior, en unión a la posibilidad de usar o no la compresión (RLE), provoca todas esas variaciones del formato de archivo y por tanto las particularidades en cuanto a los pasos necesarios para interpretar la información de una imagen PCX, porque como es fácil suponer e insinué antes, no es exactamente lo mismo interpretar una imagen en un formato de 16 o de 256 colores, y esto se complica por lo mencionado sobre la compresión, haciendo necesario tener presente además si para la elaboración de la imagen se la usó (lo más común), o por el contrario no se la utilizó para nada.

Pero de todas formas las variaciones debidas a las distintas características de los archivos ".pcx" no son tan grandes, y por eso el procedimiento no cambia tanto como lo haría si se tratara de la interpretación de formatos de imagen diferentes.

En la paleta de colores en particular se almacenan los colores divididos en sus componentes RGB, sin embargo, no es así como se guardan los píxeles de la imagen en la zona de datos del archivo (salvo cuando se trata de una imagen en color verdadero), puesto en este caso se almacenan más bien los atributos de color o índices de la paleta de colores en la zona de datos, en vez de tener en ella las componentes de los colores primarios propiamente dichos.

En resumen, y para decirlo con más exactitud, los archivos de imagen “.pcx” están compuestos por una cabecera de 128 bytes, un área con un mapa de bits en donde se encuentran los atributos de color de cada pixel de la imagen (o las componentes de color en una imagen de 24 bits), región a la cual he llamado también zona de datos, y por último la paleta de colores para las tarjetas VGA comunes y corrientes en su época de gloria con las componentes RGB del color de cada atributo.

Nota: La paleta de colores del final del archivo sólo es usada para las imágenes de 8 bits o 256 colores, puesto las de 4 bits o 16 colores utilizan la paleta situada en la propia cabecera de éste, e ignoran por completo la colocada en la parte final en caso de estar incluida, lo cual no es lo más común.

La cabecera de 128 bytes es una estructura donde podremos encontrar toda la información de la imagen contenida en el archivo, salvo por la usada para representar la imagen como tal sobre la pantalla (puede variar un poco según la versión del PCX, aun cuando nada más su parte final), y sus componentes se muestran en la Tabla 1.​

Tabla 1: El formato de la cabecera de un archivo de imagen en formato PCX.
PosiciónLongitud (Bytes)SignificadoValor más común
01Identificador de archivo de imagen “.pcx”0A (10 en decimal)
11Versión05 (Paintbrush y Paintbrush+ versión 3.0, puede incluir una imagen de 24 bits)
21Codificado con RLE (1 = Sí)01
31Bits por pixel (BPP)04 (08 para 256 colores, etc.)
42XMin0000
62YMin0000
82XMax (Anchura – 1)El ancho de la imagen (pixeles)
102YMax (Altura – 1)La altura de la imagen (pixeles)
122Resolución horizontalPixeles por pulgada (DPI)
142Resolución verticalPixeles por pulgada (DPI)
1648Paleta de colores EGA/VGA 16 coloresNo se utiliza con 256 colores
641Sin uso00
651Planos de color01
662Bytes por líneaEl valor depende del ancho de la imagen y de la profundidad de color usada.
682Tipo de paleta (1 = Color/BN, 2 = Escala de grises)01
7058Sin uso00

Nota: Los valores con una longitud de 2 bytes son números enteros sin signo, y se almacenan en memoria con el formato conocido como punta delgada (Little Endian), un formato común en las microcomputadoras de IBM por sus procesadores Intel, lo cual significa en castellano primero viene el byte de menor peso, y después se coloca el de mayor peso; así, un número de 16 bits en hexadecimal como el 20F4, se almacenaría en la memoria como F420 (cada dígito en hexadecimal se corresponde con 4 bits en binario), lo cual es una información importante si leemos la cabecera con un arreglo de 128 bytes individuales (como lo hice) en vez de hacerlo con una estructura, aun cuando no es necesario tenerlo en cuenta si esos números se leen como enteros con o sin signo, como se hace con una estructura (a pesar de no ser recomendable leerlos como enteros con signo puesto en algún momento podrían producirse errores de interpretación).

La información del mapa de bits de la imagen PCX como tal, o como la he llamado antes, la zona de datos, se sitúa inmediatamente detrás de la cabecera del archivo antes comentada, por lo tanto, comienza a partir del byte 129 del “.pcx”, y se extiende hasta donde está colocado un código 0x0C (número 12 en notación decimal), después del cual se encuentra la paleta de colores VGA (en las imágenes de 4 bits o de 16 colores, y también en las de color verdadero, no se encuentra colocado este código, como también he dicho por lo común tampoco se encontrará la paleta de 256 colores del final del archivo).

Nota: El símbolo “0x” es utilizado en lenguaje C para denotar un número en sistema hexadecimal; en BASIC por el contrario el código antes mencionado se denotaría como &H0C.

De todas formas, el tamaño del mapa de bits se puede calcular usando los valores correspondientes situados en la cabecera del archivo de la imagen, sin necesidad de tener en cuenta el código 0x0C, dispuesto nada más para más seguridad.

En nuestro caso, con una imagen con una profundidad de color de 4 bits, cada byte de atributo de color contendrá los atributos de color de 2 pixeles consecutivos en pantalla, en lugar de sólo uno, como sucede con las imágenes de 8 bits; pero por lo general esta parte del archivo está comprimida utilizando el algoritmo de compresión RLE mencionado antes, y por eso debemos tener ese dato en cuenta para poder interpretar correctamente cada byte del mapa de bits de la imagen.

Por último, después de la información de la imagen como tal, se coloca la paleta de colores VGA de un tamaño de 256 colores, y como cada color es guardado con sus componentes RGB, dicha paleta tendrá 768 bytes de información; es decir, si comenzamos a leer bytes desde el principio de la paleta, el primer bytes será el componente rojo, el segundo el componente verde, y el tercero el componente azul del primer atributo de color de la paleta de colores (índice 0); y en lo adelante sucederá lo mismo, y nos encontraremos los tres bytes consecutivos de las componentes RGB del segundo atributo de color de la paleta (índice 1), hasta completar los 256 atributos (índice 255) o 768 bytes de las componentes de color de la paleta.

Nota: La información contenida en cada byte de las componentes de color RGB está desplazada en 2 posiciones a la izquierda, por lo cual sus valores deben desplazarse 2 posiciones a la derecha antes de usarlos o cargar la paleta en la tarjeta de video; en este caso también podemos dividir los valores entre 4 si no disponemos de los operadores de desplazamiento a nivel de bits, como por cierto sucede en QuickBASIC y otros BASIC, puesto esa operación es igual a desplazar los bits de los valores en 2 posiciones a la derecha.

En cuanto al algoritmo de compresión RLE usado para reducir el tamaño del mapa de bits dentro del archivo de imagen PCX, en lo fundamental consiste en colocar la cantidad de veces en que se repiten los píxeles consecutivos de un mismo color delante del atributo de dicho color, en vez de repetir el atributo en cuestión muchas veces, o en guardar nada más el atributo de color del pixel a colocar en pantalla si dicho color no se repite de modo consecutivo.

Por lo anterior, para interpretar el mapa de bits o la zona de datos de la imagen PCX comprimida, será necesario distinguir dichos valores numéricos para la repetición de un atributo de color del pixel en pantalla, de los valores del atributo de color del pixel propiamente dicho. En imágenes de 16 y de 256 colores (4 y 8 bits) el proceso de descompresión de los datos se hace del mismo modo, y consiste en comparar el valor leído del mapa de bits con el número 192 (este valor viene del método usado para distinguir un atributo de color de un número de repetición; en estos últimos, los 2 bits de mayor peso se establecen en 1, y debido a eso siempre son mayores a 192). En caso de ser el byte leído un número superior a 192, se trata de un valor de repetición de un color y no de un atributo, y se deben tomar sus seis bits de menor peso (bits desde 0 a 5), y repetir el byte siguiente colocado en el mapa de bits como píxeles de color en pantalla tantas veces como el valor obtenido. En cambio, si el byte leído no es mayor de 192, el valor de repetición se asumirá como de 1, y el byte leído se corresponderá con el atributo de color como tal, por lo cual debe ponerse sólo 1 pixel de dicho color en la pantalla.

La relación de compresión conseguida con el método descrito puede llegar a ser de 3:2, o sea, el archivo comprimido tendría nada más un 66% del tamaño original.

Por supuesto, como comenté el proceso a seguir es un poco más complicado en una imagen de 16 colores por causa de contener los bytes de los atributos de color 2 colores de 2 píxeles en vez de uno como sucede en las de 256 colores, y debido a eso es también levemente diferente una vez se ha identificado si un byte leído del mapa de bit del archivo es un atributo de color; sin embargo, como implementé esto en el código de demostración descargable de este tutorial, no comentaré el procedimiento a seguir con más extensión en este punto del texto, puesto todos podrán ver los detalles directamente en dicho código del programa fuente en caso de tener interés en estudiarlo, y en caso de necesidad o duda también podrán hacer una pregunta.

Por eso terminaré con la explicación para no extenderme mucho más, dado toda la información pertinente sobre el formato de los archivos ".pcx" ha sido expuesta en detalle, y para mostrar uno en pantalla sólo nos faltaría llevar todo lo comentado a código en un lenguaje capaz de ser corrido por una computadora, como lo hice en mi caso para la variante de 16 colores con compresión.

Los interesados en ver la implementación en QuickBASIC para mostrar un PCX de 16 colores y utilizando compresión RLE centrado en la pantalla pueden descargar el código con este enlace: PCX4BPP.zip.

Por último me despido esperando este contenido pueda ser de utilidad a alguno, y sería bueno si también pudieran comentar su parecer sobre lo tratado, o tal vez dar más información o indicar a los posibles lectores (dudo sean muchos) dónde pueden encontrar más contenido de esta índole.​
 
Atrás
Arriba