Los esquemas de compresión de datos pueden clasificarse en dos categorías. Algunos de ellos son sin pérdidas, mientras que otros son con pérdidas. Los esquemas sin pérdidas son aquellos en los que no se pierde información durante el proceso de compresión. Los esquemas con pérdidas son esos otros que pueden llevar a la pérdida de una parte de la información. Las técnicas con pérdidas proporcionan a menudo un mayor grado de compresión que los que no tienen pérdidas y son, por tanto, bastante populares en aquellos entornos en los que pueden tolerarse los errores poco significativos, como es el caso de las imágenes y del audio.
En aquellos casos en los que los datos que se están comprimiendo están for- mados por largas secuencias del mismo valor, una técnica de compresión muy popular es la denominada codificación por longitud de secuencia, que es un método de compresión sin pérdidas. Dicha técnica es el proceso de sustituir las secuencias de elementos de datos con un código que indica el elemento repetido y el número de veces que ese elemento aparece dentro de la secuencia. Por ejemplo, esto permite reducir el espacio requerido para indicar que un patrón de bits está compuesto por 253 unos, seguidos de 118 ceros y seguidos de 87 unos. El número de bits almacenados con esta técnica de compresión será mucho menor que si enumeráramos los 458 bits que componen el patrón.
Otra técnica de compresión de datos sin pérdidas es la codificación dependiente de la frecuencia, un sistema en el que la longitud del patrón de bits utilizado para representar un elemento de datos es inversamente propor-
2. Codifique los siguiente valores en el formato de punto flotante explicado en el texto. Indique si se producen errores de truncamiento.
a. 23⁄
4 b. 51⁄4 c. 3⁄4 d. ⫺31⁄2 e. ⫺43⁄8
3. En términos del formato de punto flotante explicado en el texto, ¿cuál de los dos patrones 01001001 y 00111101 representa el valor mayor? Describa un procedimiento simple para determinar cuál de dos patrones cualesquiera representa el valor mayor.
4. Cuando utilizamos el formato de punto flotante explicado en el texto, ¿cuál es el mayor valor que se puede representar? ¿Cuál es el valor posi- tivo más pequeño que se puede representar?
69 1.8 Compresión de datos
cional a la frecuencia con que ese elemento aparece. Dichos códigos son un ejemplo de los denominados códigos de longitud variable, que son aquellos en los que los elementos se representan mediante patrones de diferentes longitu- des, por contraste con otros códigos tales como Unicode, en los que todos los símbolos se representan mediante 16 bits. Se atribuye a David Huffman el des- cubrimiento de un algoritmo que se utiliza de forma bastante común para el desarrollo de códigos dependientes de la frecuencia, por lo que los códigos desarrollados de esta manera suelen referirse con el nombre de códigos de Huffman. A su vez, la mayoría de los códigos dependientes de la frecuencia que se emplean actualmente son códigos de Huffman.
Como ejemplo de codificación dependiente de la frecuencia, consideremos la tarea de codificar un texto en inglés. En el idioma inglés, las letras e, t, a, e i se utilizan con más frecuencia que las letras z, q y x. Por tanto, a la hora de construir un código para un texto escrito en inglés, podemos ahorrar espacio utilizando patrones de bits cortos para representar el primer conjunto de letras y patrones más largos para representar el otro conjunto. El resultado será un código en el que cualquier texto escrito en inglés tendrá una representación más corta que la que se obtendría utilizando códigos de longitud uniforme.
En algunos casos, el flujo de datos que hay que comprimir está compuesto por unidades, cada una de las cuales solo difiere ligeramente de la anterior. Un ejemplo sería las imágenes consecutivas de una película. En estos casos, es útil emplear técnicas de codificación relativa, también conocidas como codifi- cación diferencial. Estas técnicas almacenan las diferencias entre unidades de datos consecutivas en lugar de almacenar las unidades completas; es decir, cada unidad se codifica en términos de su relación con la unidad anterior. La codificación relativa puede implementarse mediante técnicas de compresión sin pérdidas o con pérdidas, dependiendo de si las diferencias entre unidades de datos consecutivas están codificadas de forma precisa o aproximada.
Otro conjunto bastante popular de sistemas de compresión está basado en las técnicas de codificación por diccionario. En este caso, el término diccio-
nario hace referencia a una colección de bloques componentes a partir de los
cuales se construye el mensaje que se quiere comprimir, codificándose el propio mensaje mediante una serie de referencias al propio diccionario. Nor- malmente, consideramos los sistema de codificación por diccionario como sis- temas sin pérdidas, pero como veremos en nuestro análisis de las técnicas de compresión de imágenes, hay veces en las que las entradas del diccionario son solo aproximaciones de los elementos de datos correctos, por lo que se obtiene un sistema de compresión con pérdidas.
La codificación por diccionario puede ser utilizada por los procesadores de texto para comprimir documentos de texto, porque los diccionarios ya integra- dos en dichos procesadores para la corrección ortográfica proporcionan exce- lentes diccionarios de compresión. En particular, podemos codificar una palabra completa mediante una única referencia a dicho diccionario, en lugar de como una secuencia de caracteres individuales codificados utilizando un sistema tal como ASCII o Unicode. Un diccionario típico en un procesador de textos contiene aproximadamente 25.000 entradas, lo que quiere decir que cada entrada individual puede identificarse mediante un entero comprendido en el rango que va desde 0 a 24.999. Esto significa que cada entrada concreta del diccionario puede identificarse mediante un patrón de solo 15 bits. Por
contraste, si la palabra a la que se quiere hacer referencia está formada por seis letras, su codificación carácter a carácter requeriría 48 bits utilizando ASCII de 8 bits o 96 bits utilizando Unicode.
Una variante de la técnica de codificación por diccionario es la codifi- cación por diccionario adaptativa (también denominada codificación por diccionario dinámica). En un sistema de codificación por diccionario adapta- tiva, se permite que el diccionario varíe durante el proceso de codificación. Un ejemplo muy popular es la codificación de Lempel-Ziv-Welsh (LZW) (llamada así en honor de sus creadores, Abraham Lempel, Jacob Ziv y Terry Welsh). Para codificar un mensaje utilizando LZW, comenzamos con un dic- cionario que contiene los bloques componentes básicos a partir de los cuales se construye el mensaje, pero a medida que vamos encontrando unidades de mayor tamaño en el mensaje, se añaden esas unidades al diccionario, lo que implica que las futuras apariciones de esas unidades pueden codificarse mediante una única referencia al diccionario en lugar de mediante múltiples referencias. Por ejemplo, a la hora de codificar un texto escrito en inglés, podríamos comenzar con un diccionario que contuviera los caracteres indivi- duales, los dígitos y los signos de puntuación. Pero a medida que vamos iden- tificando palabras en el mensaje, se pueden ir añadiendo esas palabras al diccionario. De este modo, el diccionario crecería a medida que se codifica el mensaje y, según vaya creciendo el diccionario más palabras del mensaje (o patrones recurrentes de palabras) podremos codificar mediante una única refe- rencia al diccionario.
El resultado será un mensaje codificado en términos de un diccionario más bien grande, que será único para ese mensaje concreto. Pero este diccionario de gran tamaño no es necesario para decodificar el mensaje. Lo único que hace falta es disponer del pequeño diccionario original. Efectivamente, el proceso de decodificación comenzaría con el mismo pequeño diccionario con el que comenzó el proceso de codificación. Después, a medida que se desarrolla el proceso de decodificación, irá encontrando las mismas unidades que se hayan encontrado durante el proceso de codificación, por lo que se las podrá ir aña- diendo al diccionario para futura referencia exactamente igual que se hizo anteriormente al codificar el mensaje.
Para clarificar esta técnica, vamos a ver qué pasa cuando se aplica la codifi- cación LZW al mensaje
xyx xyx xyx xyx
partiendo de un diccionario en el que solo hay tres entradas, siendo la primera de ellas x, la segunda y y la tercera el carácter espacio. Comenzaríamos codifi- cando xyx mediante el valor 121, lo que quiere decir que el mensaje comienza con un patrón compuesto por la primera entrada del diccionario, seguida de la segunda y seguida de la primera. A continuación, codificamos el espacio para obtener el patrón 1213. Pero, habiendo llegado a un espacio, sabemos que la cadena anterior de caracteres forma una palabra, por lo que añadimos el patrón
xyx al diccionario como cuarta entrada. Continuando de esta manera, codifica-
ríamos todo el mensaje mediante el patrón 121343434.
Si ahora se nos pidiera decodificar este mensaje partiendo del diccionario original de tres entradas, comenzaríamos decodificando la cadena inicial 1213 como xyx seguido de un espacio. En este punto, nos daríamos cuenta de que la
71 1.8 Compresión de datos
cadena xyx forma una palabra y la añadiríamos al diccionario como cuarta entrada, exactamente igual que hicimos durante el proceso de codificación. Después, continuaríamos decodificando el mensaje, dándonos cuenta de que el 4 contenido en el mensaje hace referencia a esta cuarta entrada y decoficán- dolo como las palabra xyx, con lo que obtendríamos el patrón
xyx xyx
Continuando de esta forma terminaríamos decodificando la cadena 121343434 como
xyx xyx xyx xyx
que es el mensaje original.
Compresión de imágenes
En la Sección 1.4, hemos visto cómo se codifican las imágenes utilizando técnicas de mapa de bits. Lamentablemente, los mapas de bits producidos suelen ser de muy gran tamaño. Por ello, se han desarrollado numerosos esquemas de com- presión específicos para representar imágenes.
Un sistema, conocido con el nombre de GIF (Graphic Interchange Format, Formato de intercambio de gráficos) es un sistema de codificación por diccio- nario que fue desarrollado por CompuServe. Este sistema trata de resolver el problema de la compresión reduciendo a solo 256 el número de colores que pueden asignarse a un píxel. La combinación rojo-verde-azul (red-green-blue) para cada uno de estos colores se codifica utilizando tres bytes y estas 256 codi- ficaciones se almacenan en una tabla (un diccionario) que se denomina paleta. Después, cada píxel de una imagen puede representarse mediante un único byte, cuyo valor indica cuál de las 256 entradas de la paleta representa el color del píxel. (Recuerde que un único byte puede contener uno cualquiera de 256 patrones de bits diferentes.) Observe que GIF es un sistema de compresión con pérdidas cuando lo aplicamos a imágenes arbitrarias, porque los colores de la paleta pueden no ser iguales a los colores de la imagen original.
El sistema GIF puede incrementar el grado de compresión ampliando este sistema de diccionario simple a un sistema de diccionario adaptativo utilizando técnicas LZW. En particular, a medida que se encuentran patrones de píxeles durante el proceso de codificación, dichos patrones se añaden al diccionario para poder codificar de forma más eficiente las futuras apariciones de esos patrones. De ese modo, el diccionario final está compuesto por la paleta origi- nal y una colección de patrones de píxeles.
A uno de los colores de la paleta GIF se le asigna normalmente el valor “transparente”, lo que quiere decir que se permite que se vea el fondo a través de todas las regiones a las que se les haya asignado dicho “color”. Esta opción, combinada con la relativa simplicidad del sistema GIF, hace que GIF sea la opción preferida en las aplicaciones simples de animación, en las que es pre- ciso desplazar múltiples imágenes por la pantalla de la computadora. Por otro lado, su capacidad de codificar únicamente 256 colores hace que este sistema sea poco adecuado para aquellas aplicaciones en las que hace falta una mayor precisión, como sucede en el campo de la fotografía.
Otro sistema de compresión muy popular es el sistema JPEG. Es un están- dar desarrollado por el Joint Photographic Experts Group (Grupo conjunto
de expertos en fotografía), de aquí el nombre del estándar dentro de la organi- zación ISO. JPEG ha demostrado ser un estándar muy eficiente para la com- presión de fotografías en color y se utiliza ampliamente en el sector fotográfico, como lo indica el hecho de que la mayoría de las cámaras digitales emplean JPEG como técnica predeterminada de compresión.
En realidad, el estándar JPEG abarca diversos métodos de compresión de imágenes, cada uno con sus propios objetivos. En aquellas situaciones en las que se requiere una precisión máxima, JPEG proporciona un modo de compre- sión sin pérdidas. Sin embargo, el modo JPEG sin pérdidas no permite obtener un alto grado de compresión si lo comparamos con otras opciones JPEG. Además, hay otras opciones JPEG que han conseguido mucha mayor acepta- ción, por lo que el modo JPEG sin pérdidas raramente se emplea. En lugar de ello, el estándar preferido en muchas aplicaciones es la opción denominada estándar de línea base JPEG (también conocida con el nombre de modo secuencial con pérdidas de JPEG).
La compresión de imágenes utilizando el estándar de línea base JPEG requiere una secuencia de pasos, algunos de los cuales están diseñados para aprovecharse de las limitaciones del ojo humano. En particular, el ojo humano es más sensible a los cambios en el brillo que a los cambios de color. Por eso, si partimos de una imagen que esté codificada en función de sus componentes de luminancia y crominancia, el primer paso consiste en promediar los valores de crominancia en cuadrados de dos por dos píxeles. Esto reduce el tamaño de información de crominancia en un factor de cuatro, mientras que se conserva toda la información original de brillo. El resultado es un grado de compresión significativo sin una pérdida apreciable de calidad de la imagen.
El siguiente paso consiste en dividir la imagen en bloques de ocho por ocho píxeles y comprimir la información de cada bloque como una sola unidad. Esto se hace aplicando una técnica matemática conocida con el nombre de transfor- mada discreta de coseno, de cuyos detalles no nos tenemos que preocupar aquí. Lo importante es que dicha transformación convierte el bloque original de ocho por ocho píxeles en otro bloque, cuyas entradas reflejan el modo en que los píxeles del bloque original se relacionan entre sí en lugar de reflejar los valores reales de cada píxel. En este nuevo bloque, se sustituyen por cero los valores que se encuentran por debajo de un umbral predeterminado, para reflejar el hecho de que los cambios representados por dichos valores son demasiado sutiles como para poder ser detectados por el ojo humano. Por ejem- plo, si el bloque original contiene un patrón ajedrezado, el nuevo bloque podría reflejar la existencia de un color promedio uniforme. (Un bloque típico de ocho por ocho píxeles representaría un cuadrado muy pequeño dentro de la imagen, por lo que el ojo humano sería incapaz, de todos modos, de identificar la apa- riencia ajedrezada.)
Llegados a este punto, se aplican técnicas más tradicionales de codificación por longitud de secuencia, de codificación relativa y de codificación de longitud variable para obtener un grado de compresión adicional. En conjunto, el estándar de base de línea JPEG suele comprimir las imágenes en color según un factor de al menos 10, y a veces se puede alcanzar un factor de 30, sin una pérdida apre- ciable de calidad.
Otro sistema más de compresión de datos asociado con el tratamiento de imágenes es TIFF (Tagged Image File Format, Formato etiquetado de archivos
de imagen). Sin embargo, el uso más popular de TIFF no es como medio de comprimir los datos sino más bien como formato estandarizado para el almace- namiento de fotografías junto con información relacionada con ellas como la fecha, la hora y las opciones de la cámara. En este contexto, la propia imagen suele almacenarse mediante sus componentes roja, verde y azul de cada píxel, sin utilizar compresión.
El conjunto de estándares TIFF sí que incluye técnicas de compresión de datos, la mayoría de las cuales están diseñadas para comprimir imágenes de documentos de texto en aplicaciones de facsímil. Dichas técnicas emplean variantes de la codificación por longitud de secuencia para aprovechar el hecho de que los documentos de texto están compuestos por largas cadenas de píxeles en blanco. La opción de compresión de imágenes en color incluida en los están- dares TIFF está basada en técnicas similares a las utilizadas por GIF, por lo que se emplea ampliamente en el sector de la fotografía.