Mostrar/Ocultar TOC

Tabla de Contenidos del Libro
Prefacio
Capítulo 1: Introducción
Capítulo 2: Fundamentos
Capítulo 3: Mapas de Bits
Capítulo 4: Archivos Vectoriales
Capítulo 5: Metaarchivos
Capítulo 6: Dependencias de Plataforma
Capítulo 7: Conversión de Formatos
Capítulo 8: Trabajando con Archivos Gráficos  
Capítulo 9: Compresión
Capítulo 10: Multimedia
Formato: Adobe Illustrator
Formato: Adobe Photoshop
Formato: Atari ST
Formato: AutoCAD DXF
Formato: Autodesk 3D Studio
Formato: BDF
Formato: BRL-CAD
Formato: BUFR
Formato: CALS Raster
Formato: CGM
Formato: CMU
Formato: DKB
Formato: Dore Raster
Formato: DPX
Formato: Dr. Halo
Formato: DVM Movie
Formato: PostScript Encapsulado
Formato: FaceSaver
Formato: FAX
Formato: FITS
Formato: FLI
Formato: GEM Raster
Formato: GEM VDI
Formato: GIF
Texto en Inglés del Capítulo 8
Imagen del CD-ROM de la 2° Edición
Imagen del CD-ROM de la 1° Edición (Torrent y HTTPS)
Versión Hipertexto del CD-ROM de la 2° Edición (En Inglés)
Versión Hipertexto del CD-ROM de la 2° Edición (En Ruso)

Capítulo 8 — Trabajando con Archivos Gráficos

Capítulo 8 — Trabajando con Archivos Gráficos

Este capítulo ofrece una buena cantidad de información de cierta forma escuetamente conectada sobre archivos gráficos, formatos de archivo, y especificaciones de formatos de archivo. Discutimos los problemas que confrontarás cuando intentes leer y escribir archivos gráficos (incluyendo ejemplos de código que puedes usar en tus propios programas). También describimos el uso de archivos de prueba, la corrupción y encriptación de archivos gráficos, el potencial para la infección de virus en estos archivos, y los problemas involucrados en el desarrollo de tu propio formato de archivo y en escribir la especificación para ese formato, incluyendo maneras de aplicar derechos de autor y de otra manera, proteger tus archivos y formatos de archivo.



Leyendo Datos Gráficos

Un lector de archivos de formato gráfico es responsable de abrir y leer un archivo, determinar su validez, e interpretar la información contenida en este. Un lector puede tomar, como su entrada, datos fuente de imagen ya sea de un archivo o de un flujo de datos de un dispositivo de entrada, tal como un escáner o frame buffer.

Existen dos tipos de diseños de lectores en uso común. El primero es el filtro. Un filtro lee una fuente de datos un carácter a la vez, y recolecta esos datos mientras estén disponibles desde el dispositivo de entrada o archivo. El segundo tipo es el escáner (también llamado un parser, o analizador). Los escáneres son capaces de acceder aleatoriamente a través de todos los datos de la fuente. A diferencia de los filtros, los cuales no pueden retroceder o adelantarse para leer información, los escáneres pueden leer y releer datos en cualquier lugar dentro del archivo. La diferencia principal entre filtros y escáneres es la cantidad de memoria que usan. Si bien los filtros están limitados en la manera en la que leen los datos, estos requieren solo una cantidad pequeña de memoria sobre la cual efectuar su función. Los escáneres, por otra parte, no están limitados en la manera en la que leen los datos, pero como compensación pueden requerir una cantidad grande de memoria o espacio en disco en el cual almacenar los datos.

Ya que la mayoría de archivos de imagen son muy grandes, asegúrate de que tus lectores estén altamente optimizados para leer la información de archivo tan rápidamente como sea posible. Las aplicaciones gráficas y de imagen a menudo son severamente juzgadas por los usuarios basándose en la cantidad de tiempo que les toma leer y desplegar un archivo de imagen. Una curiosidad de la tradición de las interfaces de usuario declara que una aplicación que renderiza una imagen en un dispositivo de salida un scan line a la vez será percibida como más lenta que una aplicación que espera a dibujar la pantalla hasta que la imagen completa ha sido ensamblada, aun cuando en realidad ambas aplicaciones puedan llevarse el mismo tiempo.

Lectores Binarios Versus ASCII

Los lectores de imagen binria deben leer datos binarios escritos en tamaños de palabra de 1, 2 y 4 bytes y en uno de varios esquemas de órdenes de bytes. Los datos de mapa de bits deberían leerse en porciones grandes y ponerse en búferes de memoria para un rendimiento más rápido, al contrario de leer un pixel o scan line a la vez.

Los lectores de imagen en formato ASCII requieren funciones de lectura y análisis de cadena altamente optimizadas, capaces de encontrar rápidamente y extraer información pertinente a partir de una cadena de caracteres y de convertir cadenas ASCII en valores numéricos.


Leyendo la Cabecera de un Archivo Gráfico

El tipo de código que usas para implementar un lector variará grandemente, dependiendo de cómo se almacenan los datos en un archivo gráfico. Por ejemplo, los archivos PCX contienen solo datos binarios Little Endian; los archivos Encapsulated PostScript contienen tanto datos binarios como ASCII; los archivos TIFF contienen datos binarios que pueden almacenarse ya sea en el orden de datos Big Endian o Little Endian; y los archivos AutoCAD DXF contienen solamente datos ASCII.

Muchos archivos gráficos que contienen solo datos ASCII pueden analizarse un carácter a la vez. Usualmente, se usa un bucle y un conjunto de declaraciones de caso condicional anidadas bastante elaboradas para leer el archivo e identificar los diferentes tokens de palabras clave y valores. El diseño e implementación de dicho analizador de texto no tiene demasiados obstáculos en el camino.

Detalles a Tener en Cuenta (Gotchas)

En donde podrás encontrar algunos problemas verdaderos es en el trabajo con archivos gráficos que contienen datos binarios, tales como los contenidos de la mayoría de archivos de mapa de bits. Unas cuantas palabras de consejo son apropiadas, para que cuando comiences a escribir tus propios lectores y escritores de archivos gráficos, no enfrentes demasiados problemas (y sin darte cuenta dañes tus puños con el teclado).

Cuando lees la mayoría de archivos de mapa de bits, encontrarás que la cebecera s la primer porción de datos almacenados en el archivo. Las cabeceras almacenan atributos de los datos gráficos que pueden cambiar entre un archivo y otro, tales como la altura y anchura de la imagen y el número de colores que contiene. Si un formato siempre almacenara imágenes del mismo tamaño, tipo, y número de colores, una cabecera no sería necesaria. Los valores para ese formato simplemente estarían codificados de forma estática en el lector.

Tal como son, los formatos de archivos de mapa de bits tienen cabeceras, y tu lector debe conocer la estructura interna de la cabecera de cada formato que ha de leer. Un programa que lee un único formato de mapa de bits puede lograr su trabajo al moverse a una ubicación de offset conocida y leer solo unos pocos campos de datos. Sin embargo, formatos más sofisticados que contienen muchos campos de información requieren que leas la cabecera entera.

Usando el lenguaje C, podrías verte tentado a leer una cabecera desde un archivo usando el siguiente código:

typedef struct _Header
{
	DWORD FileId;
	BYTE  Type;
	WORD  Height;
	WORD  Width;
	WORD  Depth;
	CHAR  FileName[81];
	DWORD Flags;
	BYTE  Filler[32];
} HEADER;

HEADER header;
FILE *fp = fopen("MYFORMAT.FOR", "rb");
if (fp)
	fread(&header, sizeof(HEADER), 1, fp);

Aquí vemos una cabecera típica de un archivo en formato de mapa de bits definida como una estructura en el lenguaje C. Los campos en la cabecera contienen información sobre el tamaño, color, tipo de imagen, banderas de atributo, y nombre de la imagen misma. Los campos en la cabecera varían desde 1 a 80 byte en tamaño, y la estructura entera está rellenada hacia una longitud total de 128 bytes.

El primer problema potencial puede ocurrir incluso antes de que leas el archivo. Se queda esperando en la función fopen(). Si no indicas que estás abriendo el archivo gráfico como un archivo binario (al especificar "rb" en el segundo argumento de la lista de parámetros de fopen()), puedes encontrar que aparecen retornos de carro o inicios de línea adicionales en tus datos en memoria los cuales no están en el archivo gráfico. Esto es porque fopen() abre archivos en modo de texto por defecto.

En C++, necesitas aplicar OR al valor ios::binary en los argumentos de modo del constructor fstream o istream:

fstream *fs = new fstream ("MYFORMAT.FOR", ios::in|ios::binary);

Después de que has abierto exitosamente el archivo gráfico, el siguiente paso es leer la cabecera. El código que elegimos para leer la cabecera en este ejemplo es la función fread(), la cual es la más comúnmente usada para leer porciones de datos desde un flujo de archivo. Usando fread(), puedes leer la cabecera entera con una única llamada de función. Una buena idea, excepto que al usar fread() sea probable que encuentres problemas. Lo adivinaste, ¡el segundo problema a tener en cuenta!

Un problema común que puedes encontrar cuando lees datos y los pones una estructura es la alineación del final de los elementos en la estructura. En la mayoría de máquinas, usualmente es más eficiente alinear cada elemento de la estructura para que comience en un límite de 2, 4, 8 o 16 bytes. Ya que alinear los elementos de la estructura es el trabajo del compilador, y no del programador, los efectos de dichos alineamientos no siempre son obvios.

El compilador alinea en límites de palabra los elementos de la estructura en la misma manera. Al agregar relleno, hemos aumentado la longitud de la cabecera así para que esta termine en una frontera de 128 bytes. Tal como agregamos relleno al final de la cabecera, los compiladores agregan relleno invisible a las estructuras para hacer lo siguiente:

El tamaño ocupa la forma de elementos invisibles que están insertados entre los elementos visibles que el programador define en la estructura. Aunque este relleno invisible no es directamente accesible, integra parte de la estructura tanto como cualquier elemento visible en la estructura. Por ejemplo, la siguiente estructura tendrá 5, 6 u 8 bytes de tamaño si se compila usando una alineación de palabra de 1, 2 o 4 bytes:

typedef struct _test
{
	BYTE  A;    /* Un byte */
	DWORD B;    /* Cuatro bytes */
} TEST;

Con alineación de 1 byte, no hay relleno y la estructura tiene 5 bytes de tamaño, con el elemento B comenzando en un límite de byte impar. Con alineación de 2 bytes, se inserta 1 byte entre los elementos A y B para permitir que el elemento B comience en la siguiente frontera de byte par. Con alineación de 4 bytes, se insertan 3 bytes de relleno entre A y B, permitiendo que el elemento B comience en la siguiente frontera de palabra par.

Determinando el Tamaño de una Estructura

En tiempo de ejecución, puedes usar el operador sizeof() para determinar el tamaño de una estructura:

typedef struct _test
{
 BYTE  A;
 DWORD B;
} TEST;
printf("TEST tiene %u bytes de tamaño\n", sizeof(TEST));

Ya que la mayoría de compiladores ANSI C no permiten el uso de sizeof() en una declaración de preprocesador, puedes verificar la longitud de la estructura en tiempo de compilación usando una pieza de código ligeramente más ingeniosa:

/*
** Verificar si el tamaño de TEST es de 5 bytes o no. Sino, el arreglo
** SizeTest[] estará declarado para tener cero elementos, y se generará
** un error en tiempo de compilación en todos los compiladores ANSI C.
** Nota que el uso de un typedef no provoca que se reserve memoria
** si la prueba de sizeof() es true. Y por favor, documenta este tipo
** de pruebas en tu código para que otros programadores sepan qué
** se supone que es lo que estás tratando de hacer.
*/
typedef char CHECKSIZEOFTEST[sizeof(TEST) == 5];

El problema aquí es que la función fread() escribirá datos en el relleno cuando tú esperabas que se escribieran en un elemento. Si usaste fread() para leer datos de un 5 bytes desde un archivo en nuestra estructura TEST, alineada a 4 bytes, encontrarás que el primer byte está correctamente en el elemento A, pero que los bytes 2, 3 y 4 se almacenaron en el relleno y no en el elemento B como habías esperado. En lugar de eso, el elemento B solo almacena el byte 5 y los últimos 3 bytes de B contendrán basura.

Hay varios pasos involucrados en resolver este problema.

Primero intenta diseñar una estructura para que cada campo comience naturalmente en un límite de 2 bytes (para máquinas de 16 bits) o de 4 bytes (para máquinas de 32 bits). Ahora sin importar si la bandera del compilador esté activada o desactivada, no ocurrirá ningún cambio en la estructura.

Cuando definas elementos dentro de una estructura, también desearás evitar usar el tipo de datos INT. Un INT tiene 2 bytes en algunas máquinas y 4 bytes en otras. Si usas INTs, encontrarás que el tamaño de una estructura cambiará entre máquinas de 16 y 32 bits aun cuando el compilador no esté efectuando ninguna alineación en la estructura. Siempre usa SHORT para definir un elemento entero de 2 bytes y LONG para especificar un elemento entero de 4 bytes, o usa WORD y DWORD para especificar sus equivalentes sin signo.

Cuando lees una cabecera de archivo de imagen, típicamente no puedes darte el lujo de ser el diseñador de la estructura de la cabecera de archivo. Tu estructura debe encajar exactamente con el formato de la cabecera en el archivo gráfico. Si el diseñador del formato de archivo gráfico no pensó en alinear los campos en la cabecera, entonces no estás de suerte.

En segundo lugar, compila el módulo de código fuente que contiene la estructura, con una bandera que indique que los elementos de la estructura no deberían estar alineados (/Zp1 para Microsoft C++ y -a1 para Borland C++). Opcionalmente, puedes colocar la directiva #pragma para esta opción del compilador alrededor de la estructura; el resultado es que solo la estructura es afectada por la restricción de alineación y no el resto del módulo.

Esta, sin embargo, no es una solución terriblemente buena. Como hemos notado, al alinear todos los campos de la estructura en el límite de 1 byte, el CPU accederá los datos de la estructura de forma mucho menos eficiente. Si estás leyendo y escribiendo la estructura solo una o dos veces, como es el caso con muchos lectores de formato, puede no interesarte cuán rápido se leen los datos.

También debes asegurarte de que siempre que alguien compile tu código fuente, usen la bandera de compilador para la alineación a 1 byte para las estructuras. Dependiendo en qué máquina esté ejecutando tu código, el fallar en usar esta bandera puede causar problemas al leer archivos de imagen. Las convenciones de nombrado también pueden diferir para las directivas #pragma entre vendedores de compiladores; en algunos compiladores, las directivas #pragma de alineación de bytes pueden no soportarse en absoluto.

Finalmente, debemos enfrentar el tercer problema insidioso — el orden nativo del CPU. Si intentas usar fread() para una cabecera de archivo gráfico que contiene datos escritos en el orden Little Endian en una máquina Big Endian (o viceversa), no obtendrás nada sino basura. La función fread() no puede efectuar las operaciones de conversión necesarias para leer los datos correctamente, porque solo puede leer datos usando el orden nativo de bytes del CPU.

En este punto, si estás pensando, "¡Pero si no voy a leer cada campo de cabecera separadamente!", te espera un cambio bastante rudo de tu paradigma de implementación.

Leer cada campo de una cabecera de un archivo gráfico en los elementos de una estructura, y efectuar las conversiones necesarias del orden de los bytes, es la forma correcta de hacer esto. Si estás preocupado por la eficiencia, solo recuerda que una cabecera usualmente se lee desde un archivo y es puesta en memoria solo una vez, y típicamente etás leyendo menos de 512 bytes de datos — de hecho, típicamente mucho menos que eso. Dudamos que el medidor de despeño en tu profiler de código fuente muestre un descenso muy grande.

Así que, ¿cómo leemos los campos de la cabecera, un elemento a la vez? Podríamos volver a nuestro viejo amigo fread():

HEADER header;
fread(&header.FileId,   sizeof(header.FileId),   1, fp);
fread(&header.Height,   sizeof(header.Height),   1, fp);
fread(&header.Width,    sizeof(header.Width),    1, fp);
fread(&header.Depth,    sizeof(header.Depth),    1, fp);
fread(&header.Type,     sizeof(header.Type),     1, fp);
fread(&header.FileName, sizeof(header.FileName), 1, fp);
fread(&header.Flags,    sizeof(header.Flags),    1, fp);
fread(&header.Filler,   sizeof(header.Filler),   1, fp);

Si bien este código lee los datos de cabecera y los almacena en la estructura correctamente (sin importar el tipo de relleno), fread() usualmente lee los datos en el orden de datos nativo a la máquina en la que se está ejecutando. Esto está bien si estás leyendo datos Big Endian en una máquina Big Endian, o datos Little Endian en una máquina Little Endian, pero no si el orden de los bytes de la máquina es diferente del orden de los datos que se están leyendo. Parece que lo que necesitamos es un filtro que pueda convertir los datos a un orden de bytes diferente.

Si alguna vez has escrito código que confundiera el orden de los bytes de datos, entonces probablemente has escrito un conjunto de funciones IntercambiarBytes que intercambian la posición de los bytes de una palabra de datos. Tus funciones probablemente se miraban como algo como esto:

/*
** Swap the bytes within a 16-bit WORD.
*/
WORD IntercambiarDosBytes(WORD w)
{
	register WORD tmp;
	tmp =  (w & 0x00FF);
	tmp = ((w & 0xFF00) >> 0x08) | (tmp << 0x08);
	return(tmp);
}
/*
** Intercambiar los bytes dentro de una palabra (DWORD) de 32 bits.
*/
DWORD IntercambiarCuatroBytes(DWORD w)
{
	register DWORD tmp;
	tmp =  (w & 0x000000FF);
	tmp = ((w & 0x0000FF00) >> 0x08) | (tmp << 0x08);
	tmp = ((w & 0x00FF0000) >> 0x10) | (tmp << 0x08);
	tmp = ((w & 0xFF000000) >> 0x18) | (tmp << 0x08);
	return(tmp);
}

Ya que las palabras vienen en dos tamaños, necesitas dos funciones, IntercambiarDosBytes() e IntercambiarCuatroBytes()—para aquellos de ustedes en el mundo C++, simplemente escribirías dos funciones sobrecargadas, o una plantilla de función, llamada IntercambiarBytes(). Por supuesto, puedes intercambiar valores con signo de forma igualmente fácil al escribir dos funciones más que sustituyen los tipos de datos SHORT y LONG por WORD y DWORD.

Usando nuestras funciones IntercambiarBytes(), ahora podemos leer la cabecera de la siguiente manera:

HEADER header;
fread(&header.FileId,   sizeof(header.FileId),   1, fp);
header.FileId = IntercambiarCuatroBytes(header.FileId);
fread(&header.Height,   sizeof(header.Height),   1, fp);
header.Height = IntercambiarDosBytes(header.Height);
fread(&header.Width,    sizeof(header.Width),    1, fp);
header.Width = IntercambiarDosBytes(header.Width);
fread(&header.Depth,    sizeof(header.Depth),    1, fp);
header.Depth = IntercambiarDosBytes(header.Depth);
fread(&header.Type,     sizeof(header.Type),     1, fp);
fread(&header.FileName, sizeof(header.FileName), 1, fp);
fread(&header.Flags,    sizeof(header.Flags),    1, fp);
header.Flags = IntercambiarCuatroBytes(header.Flags);
fread(&header.Filler,   sizeof(header.Filler),   1, fp);

Podemos leer los datos usando fread() y podemos reordenar los bytes de los campos de tamaño WORD y DWORD usando las funciones IntercambiarBytes. Esto es genial si el orden de bytes de los datos no concuerda con el orden de los datos del CPU pero, ¿qué tal si concuerda? ¿Necesitamos dos versiones separadas para leer la cabecera, una con las funciones IntercambiarBytes() y una sin esta, para asegurar que nuestro código funcionará en la mayoría de máquinas? Y, ¿cómo sabemos en tiempo de ejecución cuál es el orden de los bytes de una máquina? Dale un vistazo a este ejemplo:

#define LSB_FIRST        0
#define MSB_FIRST        1
/*
** Verificar el orden de los bytes del CPU.
*/
int VerificarOrdenBytes(void)
{
	SHORT  w = 0x0001;
	CHAR  *b = (CHAR *) &w;
	return(b[0] ? LSB_FIRST : MSB_FIRST);
}

La función VerificarOrdenBytes() devuelve el valor LSB_FIRST si la máquina es Little Endian (el final pequeño viene primero) a MSB_FIRST si la máquina es Big Endian (el final grande viene primero). Esta función funcionará correctamente en todas las máquinas Big y Little Endian. Su valor de retorno es indefinido para máquinas Middle Endian (como la PDP-11).

Asumamos que el formato de los datos de nuestro archivo gráfico es Little Endian. Podemos verificar el orden de los bytes de la máquina que ejecuta nuestro código y podemos llamar la función de lectura apropiada, como se muestra a continuación:

int byteorder = VerificarOrdenBytes();
if (byteorder == LSB_FIRST)
	LeerCabeceraComoLittleEndian();
else
	LeerCabeceraComoBigEndian();

La función LeerCabeceraComoLittleEndian() contendría solamente las funciones fread(), y LeerCabeceraComoBigEndian() contendría las funciones fread() e IntercambiarBytes().

Pero esto no es muy elegante. Lo que realmente necesitamos es un reemplazo tanto para las funciones fread() e IntercambiarBytes() que puedan leer WORDs y DWORDs desde un archivo de datos, asegurándose de que los datos devueltos estén en el orden de bytes que especificamos. Considera las siguientes funciones:

/*
** Obtener una palabra de 16 bits ya sea en orden Big o Little Endian.
*/
WORD GetWord(char byteorder, FILE *fp)
{
	register WORD w;
	if (byteorder == MSB_FIRST)
	{
		w =  (WORD) (fgetc(fp) & 0xFF);
		w = ((WORD) (fgetc(fp) & 0xFF)) | (w << 0x08);
	}
	else          /* LSB_FIRST */
	{
		w  =  (WORD) (fgetc(fp) & 0xFF);
		w |= ((WORD) (fgetc(fp) & 0xFF) << 0x08);
	}
	 return(w);
}

/*
** Obtener una palabra de 32 bits ya sea en orden Big Endian o Little Endian.
*/
DWORD GetDword(char byteorder, FILE *fp)
{
	register DWORD w;

	if (byteorder == MSB_FIRST)
	{
		w =  (DWORD) (fgetc(fp) & 0xFF);
		w = ((DWORD) (fgetc(fp) & 0xFF)) | (w << 0x08);
		w = ((DWORD) (fgetc(fp) & 0xFF)) | (w << 0x08);
		w = ((DWORD) (fgetc(fp) & 0xFF)) | (w << 0x08);
	}
	else          /* LSB_FIRST */
	{
		w |=   (DWORD) (fgetc(fp) & 0xFF);
		w |= (((DWORD) (fgetc(fp) & 0xFF)) << 0x08);
		w |= (((DWORD) (fgetc(fp) & 0xFF)) << 0x10);
		w |= (((DWORD) (fgetc(fp) & 0xFF)) << 0x18);
	}
	return(w);
}

Las funciones GetWord() y GetDword() leerán una palabra de datos desde un flujo de datos en cualquier orden de bytes (especificado en su primer argumento). Los valores válidos son LSB_FIRST y MSB_FIRST.

Ahora veamos cómo sería leer una cabecera usando las funciones GetWord() y GetDword(). Nota que ahora leemos el campo de 1 byte llamado Type usando fgetc() y que fread() todavía es la mejor manera de leer bloques de datos alineados a bytes:

HEADER header;
int byteorder = VerificarOrdenBytes();
header.FileId   = GetDword(byteorder, fp);
header.Height   = GetWord(byteorder, fp);
header.Width    = GetWord(byteorder, fp);
header.Depth    = GetWord(byteorder, fp);
header.Type     = fgetc(fp);
fread(&header.FileName, sizeof(header.FileName), 1, fp);
header.Flags    = GetDword(byteorder, fp);
fread(&header.Filler, sizeof(header.Filler), 1, fp);

Todo lo que necesitamos ahora es pasar el orden de los bytes de datos que se leen, a las funciones GetWord() y GetDword(). Los datos son leídos entonces correctamente sin importar el orden de los bytes de la máquina en las que las funciones se están ejecutando.

Las técnicas que hemos explorado para leer la cabecera de un archivo gráfico pueden usarse también para leer otras estructuras de datos en un archivo gráfico, tales como mapas de color, tablas de páginas, tablas de scan lines, etiquetas, pies, e incluso los valores de pixeles mismos.

Leyendo Datos de Imagen

En la mayoría de casos, no encontrarás ninguna sorpresa cuando leas datos de imagen de un archivo gráfico. Los datos de imagen comprimida normalmente están alineados a bytes y simplemente se leen un byte a la vez desde el archivo y puestos en la memoria antes de descomprimirse. Los datos de imagen descomprimidos a menudo se almacenan solo como bytes, incluso cuando los pixeles tienen dos, tres o cuatro bytes de tamaño.

También usarás usualmente fread(), para leer un bloque de datos comprimidos en un búfer de memoria que típicamente tiene de 8K a 32K de tamaño. Los datos comprimidos se leen desde la memoria un byte individual a la vez, se descomprimen, y los datos crudos se escriben ya sea a la memoria de video para desplegarse, o a un arreglo de mapa de bits para procesamiento y análisis.

Muchos formatos de imagen de mapa de bits especifican que scan lines (o azulejos) de datos de imagen de 1 bit deberían rellenarse hacia el límite del siguiente byte. Esto significa que si la anchura de una imagen no es un múltiplo de ocho, entonces probablemente tienes unos pocos bits extra puestos a cero rellenando el final de cada scan line (o el final y/o parte inferior de cada azulejo). Por ejemplo, una imagen de 1 bit con una anchura de 28 pixeles, contendrá 28 bits de datos de scan line seguidos por 4 bits de relleno, creando un scan line de 32 bits de longitud. El relleno permite que la siguiente scan line comience en un límite de byte, en lugar de a la mitad de un byte.

Debes determinar si los datos de imagen sin comprimir contienen relleno de scan line. La especificación del formato de archivo te dirá si dicho relleno existe. Usualmente, el relleno es cargado en la memoria de video junto con los datos de imagen, pero el tamaño de la ventana en pantalla (la parte de la memoria de video de hecho visible en la pantalla) debe ajustarse para que los datos de relleno no sean mostrados.

Para Mayor Información Sobre la Lectura de Datos Gráficos

Un excelente artículo sobre la solución de los problemas de conversión del orden de los bytes apareció en la ahora extinta revista, C Gazette. Fue escrita por un compallero llamado, ¡James D. Murray!

Murray, James D., "Which Endian is Up?" C Gazette, Summer, 1990.



Escribiendo Datos Gráficos

Como puede que hayas adivinado, escribir un archivo gráfico es básicamente lo opuesto a leer uno. Los escritores pueden enviar datos directamente a un dispositivo de lalida, tal como una impresora, o puede que creen archivos de imagen y almacenen datos en ellos.

Escribiendo una Cabecera de Archivo Gráfico

Cuando escribes una cabecera de archivo gráfico, debes tener cuidado de inicializar todos los campos en la cabecera con los datos correctos. Inicializa los campos reservados usados para relleno con el valor 00h, a menos que la especificación del formato especifique otra cosa. También debes escribir los datos de cabecera a los archivos gráficos usando el orden de bytes correcto para el formato de archivo.

Ya que las funciones GetWord() y GetDword() fueron tan útiles para leer correctamente una cabecera, sus hermanos PutWord() y PutDword() deben ser igualmente útiles para escribir una:

/*
** Colocar una palabra de 16 bits en orden Big Endian o Little Endian.
*/
void PutWord(char byteorder, FILE *fp, WORD w)
{
	if (byteorder == MSB_FIRST)
	{
		fputc((w >> 0x08) & 0xFF, fp);
		fputc( w          & 0xFF, fp);
	}
	else          /* LSB_FIRST */
	{
		fputc( w          & 0xFF, fp);
		fputc((w >> 0x08) & 0xFF, fp);
	}
}
/*
** Colocar una palabra de 32 bits en orden Big Endian o Little Endian.
*/
void PutDword(char byteorder, FILE *fp, DWORD w)
{
	if (byteorder == MSB_FIRST)
	{
		fputc((w >> 0x18) & 0xFF, fp);
		fputc((w >> 0x10) & 0xFF, fp);
		fputc((w >> 0x08) & 0xFF, fp);
		fputc( w          & 0xFF, fp);
	}
	else          /* LSB_FIRST */
	{
		fputc( w          & 0xFF, fp);
		fputc((w >> 0x08) & 0xFF, fp);
		fputc((w >> 0x10) & 0xFF, fp);
		fputc((w >> 0x18) & 0xFF, fp);
	}
}

En el siguiente ejemplo, usamos fwrite(), PutWord() y PutDword() para escribir nuestra estructura de cabecera. Nota que el argumento byteorder en PutWord() y PutDword() indica el orden de los bytes del archivo que estamos escribiendo (en este caso, Little Endian), y no el orden de los bytes de la máquina en la que las funciones se están ejecutando. También, indicamos en fopen() que el archivo de salida está siendo abierto para escribirse en modo binario (wb):

typedef struct _Header
{
	DWORD FileId;
	BYTE  Type;
	WORD  Height;
	WORD  Width;
	WORD  Depth;
	CHAR  FileName[81];
	DWORD Flags;
	BYTE  Filler[32];
} HEADER;

int EscribirCabecera()
{
	HEADER header;
	FILE *fp = fopen("MYFORMAT.FOR", "wb");

	if (fp)
	{
		header.FileId   = 0x91827364;
		header.Type     = 3;
		header.Depth    = 8;
		header.Height   = 512;
		header.Width    = 512;
		strncpy((char *)header.FileName, "MYFORMAT.FOR",
	sizeof(header.FileName));
		header.Flags    = 0x04008001;
		memset(&header.Filler, 0, sizeof(header.Filler));

		PutDword(MSB_FIRST, fp, header.FileId);
		fputc(header.Type, fp);
		PutWord(MSB_FIRST, fp, header.Height);
		PutWord(MSB_FIRST, fp, header.Width);
		PutWord(MSB_FIRST, fp, header.Depth);
		fwrite(&header.FileName, sizeof(header.FileName), 1, fp);
		PutDword(MSB_FIRST, fp, header.Flags);
		fwrite(&header.Filler, sizeof(header.Filler), 1, fp);

		fclose(fp);
		return(0);
	}
	return(1);
}

Escribiendo Datos de Imagen

Escribir datos binarios puede ser un poco más complejo que simplemente asegurarte de que estás escribiendo datos en el orden correcto de bytes. Muchos formatos especifican que cada scan line ha de ser rellenada para terminar en un límite de byte o palabra si no lo hace naturalmente. Cuando se leen los datos de scan line del archivo, este relleno (usualmente una serie de valores de bits a cero) se descarta, pero debe agregarse nuevamente si los datos se escriben a un archivo.

Los datos de imagen que se escriben sin comprimir a un archivo, pueden requerir una conversión antes de escribirse. Si los datos se están escribiendo directamente desde la memoria de video, puede ser necesario convertir la orientación de los datos desde pixeles a planos, o desde planos a pixeles, antes de escribir los datos.

Si los datos han de almacenarse en un formato descomprimido, el enfoque más rápido es comprimir los datos de imagen en memoria y usar fwrite() para escribir los datos de imagen al archivo gráfico. Si no tienes mucha memoria para usar, entonces escribe los datos de imagen tal como están codificados, usualmente un scan line a la vez.



Archivos de Prueba

¿Cómo puedes asegurarte de que tu aplicación soporta un formato de archivo particular? Prueba, prueba, prueba...

Los archivos que se adhieren a la especificación escrita del formato, y las aplicaciones de software que trabajan con estas, son llamadas plenamente conformes, o simplemente conformes. El software plenamente conforme siempre debería hacer la elección conservadora si hay cualquier ambigüedad en la especifiación del formato. Por supuesto, no siempre es claro saber qué significa conservador en cualquier contexto específico, pero el punto es no extender el formato si se da la oportunidad, sin importar lo tentadora que sea la oportunidad. En cualquier caso, si escribes software que manipule archivos gráficos, necesitarás algún tipo de archivos plenamente conformes para probar el código.

Si el caso es que estás trabajando con archivos TIFF, GIF o PCS en los archivos en estos formatos a menudo los separa solo una llamada por teléfono, pero ten cuidado. Los archivos no necesariamente son plenamente conformes, y no hay registro central de archivos conformes. En algunos casos, se ha hecho el esfuerzo de crear conjuntos de archivos de prueba canónicos; por ejemplo, algunos están distribuidos en la distribución TIFF.

El truco es conseguir un espectro amplio de archivos desde un número de fuentes y llevar a cabo pruebas extensivas en todo lo que encuentres — cada tamaño, resolución y variante que pueda encontrarse. Otra estragegia es adquirir archivos creados por aplicaciones mayores y probar la compatibilidad. Por ejemplo, los archivos de Aldus PageMaker a menudo se usan para probar el software de manipulación TIFF. Desafortunadamente, PageMaker ha sido la fuente de revisiones TIFF no documentadas de facto, y probar la compatibilidad con archivos TIFF producidos con PageMaker no produce resultados del todo precisos.

Existe un número de programas de conversión de archivos gráficos que pueden hacer capturas de imagen, convertir archivos, y desplegar gráficos e imágenes en muchos formatos diferentes. Como hemos dicho antes, estás a la merced de la diligencia del autor de la aplicación.

Recuerda, también, que es tu responsabilidad localizar las revisiones más recientes del formato. Todavía vemos lectores nuevos, por ejemplo, en todas las plataformas, que fallan en dar soporte a la última especificación. Si simplemente no puedes localizar un ejemplo del formato que necesitas, tu última alternativa será siempre el creador del formato o curador. Si bien este enfoque ha de ser usado con discreción, y de ninguna manera está garantizado, a veces es tu única opción, particularmente si el formato es muy nuevo.

En cualquier caso, no dejes de programar y probar simplemente porque una variación de un formato de archivo de imagen puede leerse y convertirse exitosamente por tu aplicación. Prueba tu aplicación usando tantas variaciones del formato, y de tantas fuentes diferentes, como sea posible. Haz que tu aplicación haga su mejor esfuerzo por soportar el formato de imagen completamente.



Corrupción de Archivos Gráficos

¿Qué es un archivo gráfico corrupto?

Imagina cada imagen que has visto desplegada de mala manera por un programa de visualización de gráficos — imágenes desplazadas incompletas, áreas grandes de patrones nevados o de mosaico, colores que solo aparecen en serio en pinturas de Andy Warhol, o simplemente ninguna imagen en absoluto. ¿Por qué pasa esto?

Causas de Corrupción

Cuando una imagen falla en desplegarse apropiadamente, la(s) causa(s) pueden ser algunas o todas las siguientes:

Problemas con el entorno de display

La mayoría de problemas de despliegue pueden corregirse al ajustar uno o más aspectos del entorno de despliegue. Por ejemplo, si intentas desplegar una imagen de color verdadero usando una tarjeta gráfica o controlador de software que no soporta la profundidad de bits o resolución completa de la imagen, el programa de visualización ya sea reducirá el número de colores en la imagen desplegada, o simplemente se negará por completo a desplegar la imagen. En cualquier caso, los resultados probablemente no se verán como esperabas.

Instalar el controlador de software apropiado para la tarjeta gráfica, resolución y número de colores deseados puede solucionar el problema de despliegue. Actualizar tu programa de visualización a una versión más reciente o usar un programa diferente es también una opción. Y, por supuesto, ¿quién podría no usar una tarjeta gráfica más rápida con más dinero, y un monitor más grande y de mayor resolución también?

A veces el problema reside en el lector del archivo. Un programa de visualización debería hacer todo esfuerzo para verificar que entiende el formato de los datos que está leyendo. Por ejemplo, leer un archivo JPEG como un archivo GIF puede provocar que un programa de visualización produzca resultados inesperados.

Muchos formatos de archivo tienen muchas variaciones internas dependiendo del nivel de revisión del formato y el tipo de datos que los archivos almacenan. La mayoría de formatos (por ejemplo TIFF y TGA) facilitan determinar el tipo de los datos almacenados en el archivo al inspecionar la información de la cabecera, y otros (por ejemplo PCX) lo hacen un poco más difícil. Algunos formatos (por ejemplo Amiga IFF) usan una extensión de archivo diferente para cada tipo de datos que almacenan, y otros (XBM) almacenan solo un tipo de datos.

Estás buscando problemas si asumes a partir de la extensión de un archivo que el archivo tiene un formato específico. A más de un archivo se le ha dado una extensión de archivo inapropiada. Y si el programa de visualización está aceptando entradas directamente desde un flujo de datos, no habrá una extensión de archivo que leer en todo caso.

Con la mayoría de formatos, la extensión de archivo no cambia para reflejar el nivel de revisión del formato de archivo, o el tipo de datos almacenados en el archivo. Esta carencia de reconocimiento legible por el humano probablemente le ha hecho daño al formato TIFF sobre todo. Un archivo TIFF puede almacener cualquier tipo de datos de imagen que van desde monocromático hasta color verdadero, y puede comprimirlos usando cualquiera de más de media docena o más métodos de codificación.

Muchos visores TIFF soportan imágenes monocromáticas comprimidas con RLE o descomprimidas, pero no imágenes que usan codificación CCITT G3 y G4. Otros visores TIFF soportan escala de grises e imágenes con color de paleta, pero no imágenes de color verdadero. Algunos visores soportan el despliegue de imágenes comprimidas usando los algoritmos JPEG o TIFF-LZW, y (la mayoría de) otros no lo hacen.

Como puedes ver, pueden almacenarse muchos tipos diferentes de imágenes en un archivo TIFF — y todos ellos tendrán la extensión ".TIF". No sorprende que los usuarios se frustren cuando algunos archivos TIFF se muestran y otros no; después de todo, en un listado de directorios todos los archivos se "ven" igual. Asegúrate de que no todos los archivos se vean iguales para tu lector de archivo.

Problemas con el código del programa

Hemos discutido el hecho de que una imagen puede fallar en desplegarse apropiadamente porque el programa que lo lee carece de las características para desplegar los datos de imagen. También es muy posible que una imagen pueda fallar en desplegarse a causa de errores en el código del programa de visualización. Tales errores usualmente resultan del hecho de que el programador interpreta equivocadamente la especificación del formato de archivo, o que este no entiende por completo el lenguaje de programación que está usando, o que incluya código con errores de otro programador en su propio código. Probar el programa en una amplia variedad de archivos de imagen revelará tales problemas.

Problemas con los datos

¿Qué tal el archivo gráfico? ¿Puede el archivo mismo ser la fuente del problem?

Un archivo gráfico no es diferente de cualquier otro tipo de archivo de datos en tu sistema. Tal como otros archivos, los datos que un archivo gráfico contiene pueden estar construidos incorrectamente (datos malos) o dañados (datos corruptos). Los archivos malos o corrompidos ocurren como consecuencia de uno o más de los siguientes problemas:

Los datos malos pueden resultar de un escritor de formato pobremente diseñado. Calcular valores de cabecera inapropiadamente (por ejemplo número de colores, resolución, tamaño de archivo, etc.) o escribir los datos en un orden de bytes incorrecto hará que un lector de formato interprete incorrectamente los datos de imagen del archivo. Los códecs con errores (codificadores/decodificadores) pueden producir datos erróneamente codificados que pueden parecer estar haciendo su trabajo pero que de hecho violan el algoritmo de compresión. (Por ejemplo, la especificación TIFF implementa el algoritmo LZW de una manera equivocada.)

Los archivos pueden corromperse en una variedad de maneras. Por ejemplo:

Detectando la Corrupción de Archivos

Los lectores de formatos de archivo deben ser capaces de detectar rápidamente que los datos de un archivo son incorrectos o inesperados, o que de alguna manera violan la especificación del formato de archivo o algoritmo de compresión de datos. La detección temprana le permite al lector responder con un mensaje de error al usuario, y evita que el programa se cierre en un mal momento al leer datos malos. Un análisis preciso del problema por parte del lector de archivo y un mensaje de error detallado mostrado al usuario del programa son también requeridos.

¿Cómo puedes saber si un archivo está corrompido? Describimos varios indicadores a continuación:

Marcador EOF

El marcador de fin de archivo (end of file, o EOF) que sirve como marcador de un flujo de archivo, es un buen indicador. A menudo, los archivos gráficos se truncan a través de errores en la transmisión o por una operación de escritura en disco fallida. En tales casos, cuando se lee el archivo, el EOF ocurrirá mucho más pronto de lo que un lector de formato de archivo habría esperado, y puede que se asuma la corrupción del archivo. Las operaciones de lectura también fallarán si hay un error real en el sistema de archivos o el disco. Siempre verifica el valor de retorno de tus operaciones de lectura. Un EOF inesperado, o cualquier error de flujo de datos, es una señal segura de que algo está mal.

Caracteres Inesperados

Datos perdidos o excesivos pueden provocar una alineación inapropiada de las estructuras internas de un formato de archivo. Las estructuras de datos en memoria a menudo contienen relleno invisible para lograr alineación de 2 o 4 bytes entre los elementos de las estructuras que pueden ser escritos a un archivo de forma no intencional. Los datos escritos a un archivo abierto en modo de texto, en lugar de modo binario, pueden contener caracteres de retorno de carro o de nueva línea anidados y por lo tanto pueden crear datos malos.

Errores de Valores Mágicos

Los formatos orientados a flujos dividen los datos almacenados en secciones individuales llamadas segmentos (bloques, porciones, etc.), cada uno de los cuales comienza con un valor de identificación específico o valor "mágico" seguido por la longitud de los datos en el segmento. Si un lector de formato lee un segmento entero y descubre que el siguiente dato en el archivo no es el valor mágico esperado del siguiente segmento (o el marcador de flujo de fin de archivo), entonces el lector asume que los datos están malos o corrompidos.

Valores de Offsets Fuera de Rango

Los formatos orientados a archivos típicamente usan estructuras de datos de tamaño fijo, y valores de offset absolutos para localizar los datos. Un valor de offset que apunta fuera del espacio del archivo es una indicación segura de que el valor de offset es erróneo, o que el archivo ha sido truncado.

Ideas para Diseñar Lectores y Escritores de Archivo

¿Qué debería hacer un lector de formato de archivo en caso de datos perdidos o excesivos? Eso depende del formato de archivo y los datos mismos. Si la información mala es trivial (por ejemplo, un comentario de texto o una imagen en miniatura), el lector puede elegir ignorar los datos malos y seguir leyendo el archivo. Si la información es crítica (por ejemplo, la cabecera), el lector simplemente debería rendirse.

Sin importar la acción que tome, un lector de archivo debería desplegar una advertencia, error o mensaje de diagnóstico para indicar que ha ocurrido algo inesperado. Mensajes tales como "Formato de archivo desconocido", "Tipo de compresión desconocido", "Resolución no soportada", o "Datos corrompidos" por lo menos le dará al usuario una pista sobre qué está mal.

Aquí hay algunos tips para diseñar un lector de formato de archivo capaz de detectar errores:

Aquí hay algunos tips para diseñar un lector de formato de archivo:

La mayoría de formatos de archivo no tienen mecanismos integrados para detectar errores. En lugar de eso, nosotros dependemos de la cabecera del archivo para reconocer datos malos o corrompidos. Algunos formatos almacenan el tamaño de los datos gráficos, o incluso el tamaño del archivo entero, en sus cabeceras. Otros formatos contienen estructuras de datos de tamaño fijo que solo cambian entre revisiones del formato. Estas características no están diseñadas específicamente para detectar o corregir errores de archivo o datos, pero estos pueden usarse de esa manera y son mejor que no tener nada.

Al menos un formato, PNG, incluye un mecanismo activo de verificación de errores. PNG es un formato de flujo de datos que comprende una pequeña firma de valores de bytes seguidos por tres o más porciones de datos. Cada una de estas porciones puede que almacene valores CRC-32 de 4 bytes calculados a partir de los datos en la porción. Si los valores no concuerdan, el lector puede asumir que los datos en esa porción están corrompidos.

La firma PNG también es única en que contiene varios caracteres usados para detectar si el archivo fue procesado inapropiadamente por un canal de datos de 7 bits o filtro de procesamiento de texto. (Mira el artículo sobre PNG para mayor información.)

Para los formatos que no proveen ninguna verificación real de errores, podrías considerar almacenar los archivos usando un programa de compresión de archivos que ofrezca la verificación de errores entre sus características. Muchos compresores, tales como pkzip y zoo, efectúan un cálculo de CRC en cada archivo que almacenan. Cuando el archivo se elimina del comprimido, el valor es recalculado y comparado con el valor almacenado. Si concuerdan, entonces sabes que el archivo no se ha corrompido. Comprimir tus archivos gráficos es especialmente recomendable si los estás enviando a través de una red de comunicación, tal como la Internet.

Otro tipo de mecanismo externo de detección de errores es una firma digital. Este es un método para detectar si han ocurrido cambios dentro de un bloque de información. Discutimos las firmas digitales en el contexto de la encriptación de archivos gráficos en la sección que sigue.



Encriptación de Archivos Gráficos

La criptografía es la tecnología de mantener la información secreta. En este contexto, definimos secreto como "estar protegido de acceso no autorizado y ataques". Aunque puede que no pienses que tus archivos gráficos o sus contenidos estarán alguna vez bajo ataque, puedes desear evitar que la información contenida en estos archivos sea copiada o vista por gente no autorizada o computadoras. Si hay copias de los archivos disponibles libremente, la única manera de mantener los archivos secretos es encriptarlos.

La criptografía puede parecer un arte oscuro que requiere matemática extremadamente compleja y acceso a supercomputadoras. Este puede ser el caso para el criptanálisis profesional (codebreakers). Pero para la gente ordinaria que necesita proteger datos, la criptografía puede ser una herramienta fuerte, a menudo fácil de usar, y a veces fácilmente disponible.

Esta sección no trata de explicar la criptografía, ni los detalles de un criptosistema particular. (Refiérete a los libros en la sección "Para Mayor Información" para información básica en esta área.) En lugar de eso, veremos por qué tú, como un autor, archivador, transportador, o usuario de archivos gráficos, puede necesitar encriptar archivos gráficos.

Primero, miremos al problema general de proteger archivos gráficos.

Protegiendo Archivos Gráficos

Muchos negocios y organizaciones, tales como aquellos asociados con imágenes y documentos médicos, se preocupan de que los usuarios (la mayoría de otros programadores) encuentren maneras de alterar los contenidos de sus archivos gráficos y de imagen. Tales alteraciones pueden usarse para cambiar una fotografía de rayos X, descubrir un número de tarjeta de débito, o falsificar una firma en el mapa de bits de un cheque. Además de las consecuencias humanas, tales acciones pueden resultar en demandas legales contra la compañía cuyo proceso o equipo originalmente creó el archivo gráfico — un prospecto nada agradable para una corporación.

¿Cómo puedes protegerte en contra de alteraciones de este tipo?

Protección Física

La defensa inicial contra alteraciones no autorizadas es negar el acceso físico a tus archivos gráficos. ¿Cómo harías esto? Cuando una imagen se guarda, almacénala en un archivo que esté físicamente y directamente inaccesible al usuario. Cuando se necesita una imagen, desencríptala (y posiblemente descomprímela), luego despliégala o imprímela, pero nunca hagas que el archivo sea directamente accesible.

Desafortunadamente, este enfoque no es posible para operaciones que requieren que los datos de imagen sean transmitidos a través de canales inseguros, o posiblemente almacenados en un sistema no asegurado. En tales casos, en lugar de eso debemos encontrar una manera de hacer que el contenido de nuestros archivos gráficos esté seguro a la vez que permitamos que los archivos se almacenen en cualquier sistema de computadora, incluso uno que no es seguro.

Formatos de archivo propietarios

Los archivos pueden ser difíciles sino imposibles de leer si no conoces el formato en el que los datos del archivo están almacenados. Si usamos un formato de archivo gráfico bien publicado para almacenar nuestros datos, un programador podría escribir trivialmente un programa que haga uso no autorizado de nuestros datos. Así que, parecería que crear un formato de archivo gráfico propietario, uno cuyos detalles internos se mantienen secretos, lograría mucho en proteger nuestros datos. El problema con este método es que la habilidad y determinación de la gente que desea ver y alterar tus archivos gráficos pueden ser mucho mayor que las tuyas.

Incluso información general puede ser suficiente sobre la cual basar un ataque. Por ejemplo, alguien que sepa que tu archivo es un mapa de bits también sabrá que la vasta mayoría de archivos de mapa de bits contienen una cabecera de tamaño fijo seguida por los datos de imagen. Todas las cabeceras de mapa de bits contienen información típica, tal como el tamaño de los mapas de bits y el número de bits por pixel. Inventar una cabecera desde cero (o peor, basar tu nuevo formato en un formato ya bien conocido) y seguirla con datos codificados usando un esquema de compresión convencional (o peor, ninguna compresión en absoluto) no frenará un cracker de formatos de archivo con determinación por mucho tiempo. El crackeo del formato Kodak Photo CD, por ejemplo, surgió a través de la explotación de unos pocos bits de información general.

Podemos asumir que la mayoría de contenidos útiles o incluso una cabecera de archivo gráfico desconocida pueden deducirse. ¿Qué hay de los datos de imagen en cuestión? Los datos de mapa de bits usualmente se almacenan como pixeles que tienen 1, 8 o 24 bits de tamaño. Los valores de pixel se indexan típicamente usando una tabla de color, o se almacena directamente usando un modelo de tres colores, tal como RGB o CMY. Solo unos pocos formatos almacenan datos de mapa de bits de otra manera, así que descubrir el formato del mapa de bits puede ser tan simple como deducir los contenidos de la cabecera.

Métodos de compresión propietarios

¿Qué tal usar compresión como un medio de oscurecer los datos? Un mapa de bits ciertamente puede estar comprimido, y la compresión oscurece el formato aparente del mapa de bits. Pero una vez que el byte inicial del mapa de bits es identificado, es una simple cuestíón de intentar cualquiera de una docena aproximadamente de algoritmos comunes para descomprimir los datos. Puede incluso ser posible identificar el tipo de método de compresión usado al mirar los contenidos hexadecimales de una sección del mapa de bits que tiene un único color. Y, aunque los scan lines del mapa de bits puedan no almacenarse en orden secuencial (tal como en los archivos GIF entrelazados), eso no evitará que el método de compresión sea descubierto.

Una manera de solucionar esto es usar un método de compresión que un cracker de formatos de archivo no tendrá en su caja de herramientas. Desafortunadamente, los algoritmos de compresión de datos están diseñados solo para hacer tus datos físicamente más pequeños, y no para asegurar tus datos de vistas curiosas (o emuladores en implementados en un circuito). Por supuesto, unos pocos métodos propietarios no publicados de compresión, tales como la compresión fractal, son también considerados formas de encriptación de datos porque los detalles se mantienen en secteto. Sin embargo, estos métodos derivan su seguridad a partir de su complejidad, no del uso de un algoritmo complejo. Es solo cuestión de tiempo antes de que sean crackeados. También, nota que estos son algoritmos de codificación extremadamente complejos; si no sabes cómo descomprimir los datos, ciertamente no puedes usarlos de forma práctica.

Es dudoso que la empresa promedio —o incluso el programador arriba del promedio— tenga los recursos para inventar un método de compresión ue sea radicalmente diferente de, y aún así tan bueno como, JPEG, LZW o CCITT Grupo 4. Puedes alterar un algoritmo de compresión existente publicado para "romperlo" de una forma no documentada, y de ahí haciendo que sea indecodificable por medios convencionales. Sin embargo, hacer eso arriesga el disminuir la eficiencia del método de compresión y dejar tus archivos más grandes en tamaño, y posiblemente más lentos de descomprimir, de lo que serían de otra manera. También arriesgas darte un falso sentido de seguridad.

En resumen, formatos de archivo propietarios y métodos de compresión bizarros no son métodos seguros de proteger tus datos. Recomendamos que consideres la encriptación en su lugar.

¿Por Qué Encriptar Archivos Gráficos?

Hay un número de razones posibles por las que podrías desear encriptar tus archivos gráficos:

Pros y Contras de la Criptografía

Antes de ver en más detalle qué es la criptografía, discutamos lo que no es.

Conceptos erróneos sobre la criptografía

La criptografía no es una forma de compresión de datos. Muchos sistemas criptográficos usan algoritmos de compresión de datos para comprimir tus datos antes de encriptarlos. Sin embargo, este paso a menudo se efectúa no solo para reducir el tamaño físico de los datos, sino también para eliminar redundancias en los datos las cuales podrían hacer que los archivos sean fáciles de crackear. Esta es la razón por la que muchos archivos encriptados son físicamente pequeños que los archivos originales no encriptados.

La criptografía no es protección contra copia. Los archivos encriptados pueden copiarse a CD-ROMs, floppies y discos duros, tan fácilmente como cualquier otro archivo. Los esquemas de protección contra copia usualmente alteran el medio físicamente en el que los archivos están almacenados, o formatean el medio en alguna manera no estándar (tal como el formato de disco DMF de Microsoft). Y si bien algunos esquemas de protección contra copia pueden hacer uso de encriptación, no es la encriptación en sí la que evita que los archivos sean copiados. En este caso, la encriptación solo puede asegurar que si un archivo es copiado, el archivo sería inutilizable.

Beneficios de la criptografía

¿Cuáles son los beneficios de usar criptografía?

Todas estas son razones muy buenas para usar tecnología criptográfica para asegurar tus datos. ¿Hay alguna razón para no usar encriptación? ¿Qué problemas podría haber al encriptar tus archivos gráficos? Para responder esto tenemos que mirar brevemente a dos sistemas básicos de criptografía llamados criptografía de clave privada y criptografía de clave pública.

Criptografía de clave privada y pública

Si alguna vez has usado una contraseña secreta para entrar en un sistema de computadora o red, sacar dinero de un cajero automático, o entrar en una reunión secreta, probablemente has usado un sistema criptográfico de clave privada.

Los sistemas de clave privada usan una única contraseña o frase clave para encriptar y desencriptar una pieza de información. Ambas personas que encriptan la información y toda la gente autorizada para desencriptar la información deben tener la clave. Si una persona no autorizada adquiere tanto la información encriptada como la clave, y si conocen el algoritmo de encriptación que está siendo usado, ellos pueden acceder fácilmente tu información.

Los sistemas de clave pública usan un algoritmo para generar dos claves matemáticamente relacionadas. Los datos encriptados con una clave (la clave pública) pueden desencriptarse solamente con la otra clave (la clave secreta) y la frase clave secreta. Los datos están seguros si nadie más tiene una copia de tu clave secreta y conoce la frase clave de tu clave (y si no dejas copias desencriptadas esparcidas de tus archivos).

Los sistemas de clave pública tienen algunas ventajas tremendas sobre los sistemas de clave privada. Supón que transmites algunos archivos encriptados con clave privada a una amiga a través del país. Tu amiga no puede desencriptar estos archivos hasta que también le des la misma contraseña que usaste para desencriptarlos. Pero, ¿cómo le dices de manera segura cuál es la contraseña? Si la contraseña es interceptada junto con tus archivos, tus datos estarán en manos no autorizadas.

Si, por otro lado, usas un sistema de clave pública, solamente necesitas la clave pública de tu amiga, libremente disponible, para encriptar los archivos. Una vez que tu amiga recibe los archivos, ella usa su propia clave secreta y la frase secreta de su clave para desencriptarlos. No se necesita enviar la frase clave con los archivos. Además, la clave pública de tu amiga (y ciertamente la tuya propia) no necesitan estar ocultas. De hecho, ¡quieres que tanta gente como sea posible tenga tu clave pública para que puedan enviarte archivos encriptados!

Riesgos de la criptografía

La criptografía no está libre de tener sus riesgos y problemas:

Asumiendo que puedes vivir con estas limitantes de los sistemas de encriptación (o tal vez simplemente quieres jugar un poco con esta tecnología), ¿cómo puedes de hecho encriptar tus archivos? Un archivo que es fácil de obtener y usar es PGP (Pretty Good Privacy).

Usando PGP para Encriptar Archivos Gráficos

PGP es un sistema robusto de clave pública, inventado por Phil Zimmermann, que se usa para encriptar y desencriptar de forma segura los archivos. PGP también es una herramienta de software personalizable que es capaz de crear y administrar claves públicas y privadas, crear firmas digitales, e integrarse en los programas de software, tales como editores de texto y gráficos y aplicaciones de email. PGP también está libremente disponible para uso no comercial.

¿Cómo usarías PGP para encriptar un archivo gráfico? Esto depende de si deseas que los datos encriptados resultantes estén almacenados como datos binarios o ASCII. Usando el siguiente comando, PGP almacenará los datos encriptados a un archivo como datos binarios:

   unix% pgp -c private.gif

Este comando provoca que PGP lea el archivo private.gif y cree un nuevo archivo llamado private.pgp. El contenido de private.pgp son datos binarios que son una representación encriptada de los datos de private.gif. Si miras a private.pgp en un editor de texto, verás datos binarios ininteligibles.

Si prefieres que los datos encriptados estén almacenados en formato de caracteres ASCII, PGP puede producir el archivo encriptado usando datos de caracteres ASCII:

   unix% pgp -ca private.gif

Ahora PGP crea un archivo llamado private.asc. Este archivo contiene una versión encriptada de private.gif usando solo caracteres ASCII. Si miras private.asc con un editor de texto, verás algo que se mira así:

-----BEGIN PGP MESSAGE-----
Version: 2.6
pgAAAm5mv5vjsqw+3E+nZvfweBVh8+h4xueb3LnyKgyDjReGzxdvfZcyPQQCXrb9
yegMQoPL9yprzA0cKq0REhlWsE1tq02bFZXDTNjEfDZ5X/ucTutFS4M6fQJFCMWA
R3RC2HwdW8KUZ8/qRK6sf1hisx/HBOuddcjiI+5gj7GFitoXYIu5f/i9wfQlXiqy
Z9NLaPmcROjS9p695s1nkVVA1Z97Dy8f/gswsmg82cQ2RJ51KzHJaINWMOvZWHkz
epnn
=jE5E
-----END PGP MESSAGE-----

En lugar de basura binaria, verás tu archivo encriptado codificado como datos ASCII sando el algoritmo de codificación de binario a ASCII, radix-64 (Base64). Usando este algoritmo, un archivo encriptado almacenado en formato ASCII es un tercio más grande que el mismo archivo encriptado y almacenado usando el formato binario. Esto es porque radix-64 codifica cada tres caracteres binarios como cuatro caracteres ASCII. Este resultado es bien conocido para cualquiera que ha usado el programa uuencode nativo a UNIX.

¿Qué significa esto para ti? Puedes almacenar tus archivos gráficos como datos binarios o datos ASCII. El contenido de los archivos estará oculto. De hecho, cualquiera que mire los datos encriptados no podrá saber qué tipo de archivos son. Si los archivos son alterados o se corrompen de cualquier manera, no se decodificarán correctamente. Y sin la clave secreta y frase clave que le corresponden, los contenidos del archivo no pueden desencriptarse con éxito.

De esta manera, puedes evitar que la gente descubra los contenidos de un archivo, detectar si un archivo encriptado ha sido cambiado, e incluso ocultar el tipo de los datos que contiene un archivo. ¿Pero cómo usas PGP para verificar quién creó el archivo? PGP hace esto usando una firma digital.

Una firma digital es un valor numérico creado usando un algoritmo conocido como función de resumen de mensaje (message digest algorithm). Esta función lee los datos de tu archivo como la entrada, y genera un valor que es único a los datos en el archivo. Cambiar tan poco como un único bit en el archivo, provocará que la firma digital sea diferente.

Las firmas digitales típicamente se usan para autenticar el remitente de un mensaje de correo. Una firma digital única se crea a partir de los datos del archivo, encriptados con la clave privada del remitente, y se adjunta al mensaje. El receptor del mensaje entonces obtiene la clave pública del remitente, desencripta la firma digital, y calcula la firma digital del mensaje. Si la firma digital calculada concuerda con la firma incluida en el mensaje, el receptor puede asumir con seguridad que el mensaje fue enviado por el propietario de la clave pública.

Puedes tomar cualquier archivo gráfico y firmarlo usando PGP. La firma puede usarse para verificar el creador (humano o computadora) del archivo, y los contenidos del archivo no necesitan estar encriptados. Aquí está cómo harías esto usando PGP:

   unix% pgp -s private.gif

Este comando firma el archivo private.gif usando tu clave privada y frase clave. La firma encriptada se adjunta a los datos y se almacena en el archivo private.pgp. Los datos del archivo no están encriptados. Si deseas que los datos del archivo estén encriptados, usa el siguiente comando en su lugar:

   unix% pgp -se private.gif

Este comando desencripta los datos del archivo, firma los contenidos del archivo, y también coloca los datos en el archivo private.pgp. La firma es un valor binario por defecto. Si deseas una firma ASCII, especifica:

unix% pgp -sea private.gif

Este comando crea un archivo llamado private.asc, el cual contiene los datos encriptados y una firma ASCII adjunta. Si el archivo de entrada texto en lugar de datos binarios, agregas otra bandera más:

   unix% pgp -seat private.dxf

NOTA

PGP es un programa de software autocontenido que ha sido porteado a muchas computadoras diferentes y sistemas operativos. PGP es usado típicamente desde la línea de comandos. Una aplicación de software que usa la versión PGP 2.x podría usar también PGP como un programa ejecutable separado. La versión PGP 3.0 promete una librería API de herramientas que pueden ser enlazadas directamente a las aplicaciones de software.

Para Mayor Información Sobre Encriptación

Internet rebosa de información sobre encriptación de datos. Una búsqueda web sobre las palabras "encriptación" y "criptografía" devolverá cientos de resultados.

Dos fuentes mayores de información y referencias son los grupos de noticias de USENET, alt.security.pgp y sci.crypt y sus FAQs asociadas.

Además, mira las siguientes referencias sobre información de encriptación:

Garfinkel, Simson, PGP: Pretty Good Privacy, O'Reilly & Associates, Sebastopol, CA, 1995.

Schneier, Bruce, Applied Cryptography: Protocols, Algorithms, and Source Code in C, John Wiley & Sons, New York, NY, 1994.

Schneier, Bruce, Practical Cryptography, John Wiley & Sons, New York, NY, 1994.

Schneier, Bruce, "Untangling Public Key Cryptography," Dr. Dobb's Journal, May 1992, pp. 16-28.

Schneier, Bruce, "The IDEA Encryption Algorithm," Dr. Dobb's Journal, December 1993, pp. 50-56.

Stevens, A., "Hacks, Spooks and Data Encryption," Dr. Dobb's Journal, September 1990, pp. 127-134, 147-149.




Virus en Archivos Gráficos

“Evitar la detección y evadir la selección.”

—Lo que Charles Darwin pudo haber dicho si se le hubiera preguntado sobre el comportamiento fundamental de los virus de computadora.

Todos los usuarios de computadora se preocupan por los virus de computadora. Estos a menudo y a veces casi indetectables programas son el tema de mucha literatura del consumidor y de folklore urbano.

Es difícil generalizar sobre los virus de computadora, pero típicamente no son muy complejos. En la mayoría de casos, un virus es simplemente un programa que está escrito para replicarse a sí mismo, evitar la detección tanto por el usuario de la computadora como del entorno operativo, y tal vez hacer unas pocas otras cosas en su camino. Algunos virus tienen la intención de causar daño (por ejemplo, destruir archivos y degradar gradualmente el rendimiento de redes), por supuesto, pero otros solo son peligrosos sin advertirlo debido a errores de lógica en su propio código o a causa de incompatibilidades entre el código y el sistema en el que está corriendo. Todavía otros virus están programados meramente para ser molestos; en algunos casos, fastidian a su víctima, la cual se da cuenta de forma desalentadora que algo extraño tiene control al menos parcial de su computadora.

¿Por qué usar el término virus de computadora? Al principio, el término pudo parecer simplemente un juego con la bien conocida frase error de software (software bug). Pero hay más sobre este tema que solo eso. Las características operacionales de los virus de computadora poseen una semejanza sorprendente con los virus biológicos. La meta primaria de un virus biológico es reproducirse. Un virus es solo un fragmento de RNA o DNA, y por lo tanto no constituye lo que la mayoría de gente considera un organimso vivo. Ya que no puede reproducirse por su cuenta, un virus biológico debe infectar un anfitrión vivo en el cual reproducirse — un proceso que puede resultar en la enfermedad o la muerte del anfitrión.

Cuando un programa anfitrión infectado se ejecuta por el sistema operativo, este ejecuta sin saberlo el código viral también. El código viral ejecutado está diseñado para buscar otros programas anfitriones compatibles y adjuntar copias de sí mismo en ellos también. Cuando el código de un virus infecta otro programa, se dice que el virus se ha reproducido. La mayoría de programas ejecutables, tales como archivos .COM y .EXE en sistemas MS-DOS, contienen código de máquina y se ejecutan directamente por un sistema operativo. Un virus solo puede infectar archivos para los que etá diseñado para infectar.

Algunos virus están diseñados para que puedan adjuntarse a sí mismos a archivos por ejecución de lotes (.BAT), scripts de consola shell, los sectores de boot de los discos duros y floppies, e incluso macros de hoja de cálculo y de procesador de palabras. Si es código que puede ejecutarse por un programa, es posible que sea destino para la infección de un virus.

¿Qué hay de los archivos gráficos? ¿Pueden infectarse con un virus? ¿Está tu sistema en peligro alguno por archivos gráficos infectados?

Los archivos gráficos generalmente son colecciones de datos y como tales no se ejecutan por un sistema operativo. Los programas que usan archivos gráficos, tales como programas de visualización y de edición, simplemente leen los datos de un archivo gráfico a la memoria, y luego lo modifican para renderizarlo a un dispositivo de salida. Los archivos gráficos que consisten de datos no pueden infectarse por un virus porque el código no se ejecuta. Los archivos gráficos estáticos (es decir, aquellos que no contienen código) están seguros contra una infección.

Algunos archivos gráficos, tales como aquellos usados en aplicaciones multimedia, tienen la capacidad de almacenar instrucciones que pueden ejecutarse por aplicaciones específicas de software. Tales instrucciones pueden desplegar texto, crear sonido, menús emergentes, y leer datos de otros archivos. Los archivos orientados a objetos que contienen datos y el código necesario para renderizar los datos también están en esta categoría. Estos tipos de archivos teóricamente son susceptibles a la infección de un virus. Sin embargo, en este punto ninguno ha sido atacado por los virus. Esto puede cambiar, sin embargo, a medida que las secuencias de instrucciones necesarias para la renderización correcta de un archivo particular se vuelvan más complejas. Sin embargo, ninguno de los formatos de archivo en uso común soportan este nivel de complejidad.

NOTA

¿Qué hay de los lenguajes de descripción de páginas (PDLs) tales como PostScript y lenguajes de hipertexto como HTML? Dichos lenguajes no son realmente archivos de formato gráfico, sino que colecciones de declaraciones interpretadas que pueden contener o referenciar datos gráficos. Aunque los datos gráficos mismos no son un objetivo para los virus, el código del lenguaje interpretado puede ser alterado, y se pueden explotar agujeros de seguridad conocidos en el lenguaje de programación.



En resumen, es muy improbable que archivos gráficos sean candidatos para una infección de virus. De hecho, la mayoría de programas de detección de virus ni siquiera se molestarán en escanear archivos gráficos a menos que se les ordene explícitamente. Por supuesto, un virus aún podría hacerle cosas malas a un archivo gráfico, tal como podría hacérselas a cualquier otro tipo de archivo — por ejemplo, podría copiar, mover, alterar, corromper, o eliminar un archivo gráfico, o podría adjuntar datos al archivo, provocando que su tamaño aumente.Pero un virus de computadora no puede usar un archivo gráfico que solo contiene datos —ni ningún archivo de datos, hablando en términos generales— para reproducirse.

Diseñando Tu Propio Formato

Encontramos difícil de imaginar por qué alguien pensaría que el mundo necesita otro formato de archivo gráfico. Y, de hecho, no queremos dar la impresión de que estamos animando tal comportamiento. Pero dado el hecho de que la gente puede y de hecho creará nuevos formatos, nos gustaría dejarte algunas indicaciones.

¿Por Qué Considerarlo Siquiera?

La verdad es que este libro ni siquiera comienza a incluir todos los cientos de formatos más oscuros, algunos de los cuales solo se usan de forma privada y permanecen dentro de las paredes de la compañía. Las compañías que desean que la salida de sus productos permanezca propietaria, siempre encontrarán una manera de lograrlo y por lo tanto seguirán desarrollando nuevos formatos.

Diseñar tu propio formato también te ayudará a evitar problemas en caso de que el uso del formato de alguien más fuera restringido algún día a través de acciones legales. El uso del formato GIF recientemente ha entrado en restricciones de licencia que requieren el pago de regalías por el software que lea o escriba el formato GIF. El pago de esta cuota ha sido activamente impuesto a través de la amenaza de acciones legales tanto de los propietarios del formato GIF como de los propietarios del formato de compresión Lempel-Ziv-Welch (LZW) usado por los GIF. Recuerda que aun cuando muchos formatos parezcan estar gratuita y públicamente disponibles, muy pocos realmente lo son.

Pero Si Debes Hacerlo...

Dicho esto, considera los siguientes lineamientos si persistes en tu idea de diseñar el tuyo propio:

Una Última Palabra

Recuerda que mucho código ya existe allá afuera y hay muchas librerías disponibles en forma de código fuente que puede que supla tus necesidades. Considera esta declaración de la FAQ (lista de Preguntas Frecuentes) del grupo de noticias comp.graphics.misc en Internet:

Los documentos para los formatos TIFF, IFF, BIFF, NFF, OFF, FITS, etc., casi seguramente no necesitan esto. Lee la sección sobre software de manipulación de imagen gratuita. Obtén uno o más de estos paquetes y revísalos por separado. Hay excelentes probabilidades de que el convertidor de imagen que ibas a escribir ya esté ahí.




Escribiendo una Especificación de Formato de Archivo

Si vas a escribir una especificación de formato de archivo, lo primero que debes hacer es escribir una lista de los tipos de información que vas a almacenar. Entonces haz una segunda lista, de todos los datos que un programa necesitará para renderizar los datos que escribiste en la primera lista. ¿Entiendes? Al compilar la segunda lista, casi seguramente encontrarás que olvidaste algo en la primera — y viceversa.

Lo siguiente que necesitas hacer es mirar todas las especificaciones de formato que son como la tuya y ver dónde se extraviaron los escritores. Ahora regresa y arregla tu lista. Ahora repite el proceso. Este es un ejercicio en honestidad, inteligencia y diligencia. Nadie —y lo que queremos decir es nadie— ha hecho esto correctamente todavía. Tal vez tú serás el primero.

Sugerencias para Escribir Especificaciones

Cuando leas a través de tus especificaciones de formato apiladas, encontrarás que no hay dos iguales (a menos que estén escritas por el gobierno o los militares — en ese caso todas ellas son iguales). Y descubrirás que la mayoría están pobremente escritas y son muy complejas también. ¿Cómo puedes evitar cometer el mismo error? Aquí hay unas cuantas sugerencias:

Ejemplos de algunas especificaciones de formato bien escritas que hemos encontrado incluyen TGA, TIFF, PNG, EPSF, y PostScript.

Hemos encontrado que algunas especificaciones están bien escritas, pero contienen tanta información extraña que son excesivamente complejas y demasiado tediosas de leer. La mayoría de formatos del gobierno y militares están en este grupo, ya que son aquellos creados por comités; ejemplos en esta categoría son CALS, NITF, NAPLPS, IGES, GKS, y CGM.

Y finalmente, especificaciones de formato tales como PCX, GIF, JFIF y Sun Raster, definitivamente caen en la categoría de "no dejes que esto te pase".

Sugerencias para una Buena Escritura Técnica

Aquí hay unas pocas pautas más generales para una buena escritura técnica:

Marcas Registradas, Patentes y Derechos de Autor

Probablemente piensas en una marca registrada, ya sea que esté en un logo de Microsoft Windows, una máquina Xerox, o una caja de Keenex, como una marca de identificación de producto. Puede que pienses en una patente como una declaración de propiedad sobre una invención extraña o proceso químico. Y cuando piensas en un derecho de autor, puede que visualices un libro, un artículo de revista, o una pieza de música marcada con un nombre y fecha reclamando propiedad de ese trabajo.

¿Dónde están los formatos de archivo gráficos en este esquema? Empecemos a responder esta pregunta al examinar las marcas registradas, luego las patentes, y finalmente los derechos de autor.

NOTA

Los autores no son abogados, y esta información no debería interpretarse como asesoría legal. Te aconsejamos que contactes a un abogado de propiedad intelectual si tienes necesidad de información absolutamente precisa y actualizada.

Marcas Registradas

Estas son palabras, nombres, o símbolos usados para identificar un producto o servicio. Ser el dueño de una marca registrada no significa que posees las palabras en cuestión asociadas con el reclamo de marca registrada (aunque Eastman Kodak y la Corporación Xerox podrían no estar de acuerdo). La marca registrada solo otorga propiedad de una palabra o frase dentro de un cierto contexto, tal como la palabra windows dentro del contexto de la industria de las computadoras.

Las marcas registradasson importantes en el mundo de formatos de archivo gráficos. CompuServe posee la marca registrada "GIF"; Adobe (y anteriormente Aldus) poseen la marca registrada "TIFF"; y Microsoft posee la marca registrada "RIFF". Entiendes a lo que me refiero.

Los logos gráficos también pueden estar sujetos a marcas registradas. Los logos de Apple Computer y Microsoft Windows son marcas registradas que pertenecen a estas corporaciones. El arte original usado como una marca registrada puede, a diferencia de las palabras, ser propiedad del titular de la marca registrada. Una pieza original de arte se considera como un "trabajo de autoría", mientras que unas pocas palabras de Inglés (u otro lenguaje) puestas juntas de una forma astuta no.

En resumen, no puedes aplicar una marca registrada a un archivo gráfico o su formato, pero ciertamente puedes registrar la marca de su nombre y logo.

Patentes

¿Qué hay de las patentes? ¿Puede un formato gráfico de archivo, los contenidos de dicho archivo, o el formato en cuestión ser patentado?

Una patente es un reclamo de la autoría de una invención, proceso, o diseño que es "nuevo, útil y no obvio". Las invenciones que son mecánicas, químicas, eléctricas o electrónicas en naturaleza se cubren por las "patantes de utilidad". Los diseños funcionales y artísticos se cubren por las "patentes de diseño". ¿Qué patente aplicarías a un formato de archivo?

Recuerda que los formatos de archivo y de datos son solo arreglos específicos de información presente en algunos tipos de medios físico o digitales. No son la información del medio en cuestión.

Una patente de utilidad aplicaría a la invención de almacenar información en un dispositivo de disco duro, o el texto en las páginas de un libro, incluso el concepto del libro mismo. Pero no apliaría al formato o la información, a menos que el formato fuera una parte necesaria de la invención misma.

Un formato de archivo es más un diseño funcional que la forma de un aeroplano o un tubo de rayos catódicos, en lugar de un diseño artístico, tal como el patrón en una pieza de tela. ¿Significa esto que puedes crear un nuevo formato de archivo gráfico y patentar su diseño?

Para que una patente se otorgue, las invenciones y diseños deben ser nuevos, útiles, y no deben estar derivados de trabajo preexistente. Aunque los formatos de archivo existen en muchas formas diferentes, estos efectúan el mismo trabajo: almacenar datos gráficos en un medio analógico o digital. Es probable que intentar obtener una patente de diseño para un nuevo formato de archivo sea negado basado en la existencia de arte previo.

Derechos de Autor

¿Puede un archivo gráfico tener derechos de autor?

Un archivo gráfico en cuestión normalmente no puede estar bajo derechos de autor bajo las leyes de derechos de autor de Estados Unidos (aunque las sentencias de algunos jueces pueden discrepar). La especificación de un formato y los "contenidos" de un archivo gráfico, sin embargo, están sujetos a derechos de autor. En otras palabras, tu salsa secreta de barbacoa, o su receta, pueden ganar un listón azul en la feria del condado pero no el jarrón en el que pones la salda, o el papel en el que escribiste la receta.

Para que cualquier cosa pueda tener derechos de autor, esta debe ser:

La descripción de un formato gráfico no cumple estos dos criterios si está tanto fijada en un medio (impreso en papel o almacenado en un disco) y es un trabajo de autoría (no se ha copiado de un trabajo preexistente). Cualquier especificación de formatos de archivo que cumple estos dos requerimientos está protegida bajo leyes de derechos de autor.

Un archivo gráfico creado usando una descripción de formato, sin embargo, cumple el segundo criterio pero no el primero. Es decir, el archivo mismo no se considera un trabajo de autoría. En su lugar, el archivo en cuestión se considera como una idea o un sistema y por lo tanto no está protegido por leyes de derechos de autor.

Así que la descripcíon de un formato de archivo puede estar bajo derechos de autor, pero el formato tal como existe en el medio no. ¿Qué tal los datos gráficos que contiene el archivo?

Si los datos gráficos escritos a un archivo gráfico también cumplen los dos criterios anteriores, también está protegido por las leyes de derechos de autor como propiedad intelectual. No estarás renunciando a tu protección de derechos de autor al almacenar cualquier información original usando un formato de archivo gráfico.

Derechos de autor explícitos versus implícitos

¿Como pones bajo derechos de autor los contenidos de un archivo gráfico o la especificación de un formato de archivo? Hay varios niveles de derechos de autor: formal, explícito, e implícito.

Puedes registrar formalmente los derechos de autor de tu trabajo para establecer prioridad como el creador del trabajo. Esta acción te da protección extra si piensas vender o de otra manera asignar tus derechos de autor, o si necesitas defenderte en el evento de que la propiedad de tu trabajo sea disputada en una corten legal. Para la información más reciente sobre el registro de los derechos de autor, consulta la Oficina de Copyright de los Estados Unidos (o la oficina apropiada en tu propio país) o un abodado de propiedad intelectual.

La mayoría de gente pone bajo derechos de autor su trabajo explícitamente, pero informalmente, al adjuntar una noticia de derechos de autor del trabajo. (Describiremos cómo hacer esto en las secciones que siguen.) Sin embargo, ni el registro formal ni tampoco el adjuntar una noticia explícita de derechos de autor se necesita para establecer derechos de autor. Gracias a las Convenciones de Berne sobre derechos de autor, los contenidos de cualquier archivo gráfico creados después de Marzo 1 de 1989, están automáticamente e implícitamente bajo derechos de autor y protegidos, sin importar si una noticia de copyright está de hecho presente en el archivo. De hecho, incluso todos los mensajes en USENET y todos los emails enviados a través del Internet están automáticamente bajo derechos de autor por estas leyes internacionales.

Trabajo por Contrato

En muchos casos, los derechos de autor no son automáticamente asignados, tales como con los trabajos por contrato. Si eres remunerado por alguien para crear un trabajo elegible para derechos de autor, el derecho de autor le pertenece a tu empleador y no a ti.



Desafortunadamente, mucha gente no se da cuenta de que aun cuando no ven una noticia de derechos de autor explícita en un archivo, la información en ese archivo todavía está sujeta a protección bajo las leyes de derechos de autor. Te recomendamos que incluyas una noticia de derechos de autor visible en tu archivo. Hacer esto dejará claro que el contenido de tus archivos gráficos están al menos en algunas maneras, protegidas por leyes de derechos de autor.

Una noticia mínima de derechos de autor se mira así:

   Copyright fecha(s) por autor(es)

Esta noticia establece visualmente el hecho de que los contenidos de tu archivo están bajo derechos de autor en año(s) dado(s) e indica quién es el titular del derecho de autor. Por ejemplo:

   Copyright 1995-96 por James D. Murray

Puede que hagas más completas tus noticias de derechos de autor al declarar:

   Copyright (C) 1995-96 por James D. Murray. Todos los derechos reservados.

La (C) es un intento en ASCII de reprecentar el símbolo de derecho de autor de la "c en un círculo" (©). Nota que debes incluir ya sea la palabra Copyright o el símbolo de copyright en tu declaración. Esto es redundante, pero inocuo, incluir ambos. Nota también que el carácter (C) que la gente pone en los archivos ASCII aún no ha sido aceptado como un símbolo válido de derechos de autor por ninguna corte legal.

La frase Todos los derechos reservados era un requisito de varios países hace muchos años para considerar válida una noticia de copyright. Bajo las leyes internacionales actuales de derechos de autor, esta frase ya no es requerida, pero mucha gente aún la usa.

Derechos de autor del código objeto

Una noticia de derechos de autor en el código objeto es una noticia legible por el humano que ha sido integrada en el código objeto de un módulo de librería o archivo ejecutable. Esta noticia le permite a cualquiera que efectúe una búsqueda de cadena en un archivo objeto, ver que los contenidos intelectuales del archivo están protegidos por derechos de autor.

En ANSI C, podrías usar la siguiente línea de código para anidar una cadena de derechos de autor en un archivo objeto:

   static const char * const Copyright = "Copyright 1996 por James D. Murray";

Este código crea una constante estática llamada Copyright, que contiene tu cadena de copyright. Esta es también la cadena que debería mostrarse al usuario con otra información sobre el programa.

Dominio público

No todos sienten la necesidad de poner bajo derechos de autor su trabajo. Algunas personas explícitamente desean compartir los frutos de sus labores. En lugar de incluir una noticia de derechos de autor en tu archivo, puedes elegir poner los contenidos de tu formato de archivo en el dominio público. Hacer esto le permite a cualquiera hacer lo que deseen con tu trabajo. Al poner tu trabajo en el dominio público, estás, en efecto, haciendo una contribución "sin límites" a la base de conocimiento libremente accesible del género humano.

Para poner el contenido de tus archivos gráficos en el dominio público, incluye una declaración en tu trabajo tal como:

   Yo tunombreaqui concedo este nombredetutrabajoaqui al dominio público.

Esta declaración es una noticia legal de que tu trabajo puede usarse libremente y distribuirse por cualquiera de la manera en la que él o ella mejor le parezca.

Noticia de licencia

¿Qué tal si no deseas evitar que la gente use o distribuya tus gráficos al renunciar a tus derechos de autor, pero no quieres liberar tu trabajo en el dominio público solo para que algunos impostores reclamen tu trabajo como suyo? Para una posible respuesta, veamos la noticia de derechos de autor en la lista de la FAQ de los Formatos de Archivo Gráficos que circula en USENET:

Esta FAQ es Copyright 1994-96 por James D. Murray. Este trabajo puede ser
reproducido, en todo o en parte, usando cualquier medio, incluyendo pero sin
limitarse a, transmisión electrónica, CD-ROM, publicado en impresión, bajo la
condición de que esta noticia de copyright se mantenga intacta.

Esta noticia de derechos de autor incluye una declarción, llamada licencia de noticia, que declara cómo espera el autor que la información en la lista sea usada. Y, como puedes leer, el autor le permite a cualquiera hacer prácticamente todo lo que él o ella desee con la información en la lista, siempre y cuando al autor se le dé crédito apropiado como el creador y quien mantiene la lista.

Lo que tenemos aquí es una noticia de derechos de autor que establecen propiedad de un trabajo el cual incluye una declaración escrita de lo que el propietario del trabajo considera "uso justo" del material con derechos de autor. En este caso, el autor ha hecho todo excepto colocar la información original en la FAQ de Formatos de Archivo Gráficos en el dominio público; todo lo que pide es ser reconocido por sus esfuerzos si la información contenida en la FAQ es usada alguna vez. ¡Qué tipo tan bueno!

Derechos de propiedad

Nota que tú debes ser el propietario del trabajo para explícitamente ponerlo bajo derechos de autor o ponerlo en el dominio público. Usar o distribuir intencional o sin saberlo un trabajo con derechos de autor sin permiso del titular de los derechos de autor, por remuneración o gratuitamente, es una violación clara y perseguible bajo las leyes de derechos de autor. Tu ofensa es incluso peor si tu "uso" del material ha dañado el valor comercial de la propiedad en cuestión.

El propietario de un derecho de autor tiene varios derechos exclusivos sobre su trabjo con derechos. Cuatro de estos archivos que aplican directamente a los contenidos de los archivos gráficos incluyen:

¿Puedes estar en problemas al distribuir al distribuir archivos gráficos que tú no posees? Puedes apostar que sí. Violar el derecho exclusivo de un titular de derechos de autor te otorgará el título exclusivo de "infractor de derechos de autor" en la mayoría de países de la Tierra.

Digamos que te encuentras con una bonita fotografía o pieza de arte en una revista o videocinta, y decides escanearla o capturarla, guardarla a disco usando un formato de gráficos popular, borrar una parte de la imagen y tal vez agregar un borde, y subirla a una BBS o enviarla a USENET u otro servicio de información. Al hacer esto tú has infringido los derechos de reproducción del titular de los derechos de autor (escanear o capturar el trabajo y guardrlo), los derechos de modificación (alterar el trabajo usando un editor gráfico), y los derechos de distribución (subir el archivo y su trabajo reproducido).

Una corte legal puede imponerte daños de hecho y estatutarios por tales infracciones, que varían potencialmente desde decenas de miles a millones de dólares.

Para mantenerse lejos de los problemas, debes asumir que no tienes permiso de copiar, modificar o distribuir ningún archivo gráfico a menos que tengas permiso explícito para hacerlo por parte de los propietarios de los contenidos del archivo. Escanear una página de una revista y almacenar la imagen en un archivo no te da propiedad de la imagen, sino solo propiedad sobre el archivo. Los contenidos del archivo todavía pertenecen al titular del derecho de autor del texto, fotografía, o trabajo artístico que escaneaste.

Recuerda, la propiedad del archivo gráfico en cuestión no es el problema. Siempre debes estar consciente de a quién pertenece y tiene los derechos de los contenidos del archivo gráfico.

Noticias de derechos de autor en archivos gráficos

En este punto probablemente te estés preguntando cómo puedes incluir una noticia de derechos de autor en un archivo gráfico. Algunos formatos de archivo tienen un campo de texto, a menudo en la cabecera, específicamente reservada para una noticia de derechos de autor; por ejemplo, TIFF, SPIFF, DPX y PNG soportan dicho campo. Muchos formatos soportan el almacenamiento de comentarios de texto en un campo de datos definido por el usuario; por ejemplo, GIF, IFF, y TGA permiten comentarios de texto. Tales comentarios se usan para describir cualquier cosa que el escritor desee, lo cual usualmente es el contenido de un archivo, el nombre del autor, y la noticia de derechos de autor.

En formatos que carecen de campos de comentarios o de derechos de autor (por ejemplo, PCX y BMP), las noticias de derechos de autor pueden encontrar su lugar en áreas del archivo reservadas para expansión futura, o pueden simplemente adjuntarse al final del archivo mismo. Ninguno de estos métodos es recomendable, porque seguramente provocarán que algunos lectores del formato de archivo reporten un error —o simplemente exploten— cuando lean tales archivos gráficos con una añadidura de derechos de autor.

Si no puedes usar un formato que soporte apropiadamente el almacenamiento de una noticia de derechos de autor, deberías incluir un archivo externo que contenga tu noticia de derechos de autor y los términos de uso y listar los nombres y descripciones de todos los archivos con derechos de autor que estás distribuyendo. Este método tiene la ventaja de hacer que tu noticia de derechos de autor sea humanamente legible, lo cual es útil porque muy pocos visores de archivos gráficos son capaces de desplegar comentarios de texto contenidos en un archivo gráfico.

Resumen

Para resumir los hechos de las marcas registradas, patentes y derechos de autor aplicados a los archivos gráficos, recuerda que una especificación de formato de archivo gráfico, y los contenidos de un archivo gráfico, pueden estar protegidos por un derecho de autor, pero los archivos gráficos en cuestión no pueden. Y, hasta que las cortes federales den un veredicto diferente, los formatos de archivo —o más precisamente, sus contenidos— pueden estar sujetos a derechos de autor pero no a marcas registradas o patentes.

Para Mayor Información sobre Derechos de Autor y Patentes

Para mayor información sobre derechos de autor, por favor refiérete a las FAQs de Copyrights, encontradas en los grupos de noticias misc.legal, misc.legal.computing, misc.int.property, y comp.patents, así como a los sitios FTP:

ftp://rtfm.mit.edu/pub/usenet/news.answers/law/Copyright-FAQ/
ftp://rtfm.mit.edu/pub/usenet/news.answers/law/Copyright-FAQ/myths/



Varias discusiones de derechos de autor ocurren también en los grupos de noticias comp.infosystems.www.*.

Para mayor información sobre la lista de correo del Internet Patents News Service, envía un email a patents@world.std.com.

La información sobre patentes, copyrights, y propiedad intelectual también puede encontrarse en:

http://www.questel.orbit.com/patents/readings.html
    Información de patentes, marcas registradas, científica, química, de negocios, y noticias.

http://www.uspto.gov
    U.S. Patent and Trademark Office

http://www.spi.org
    Software Patent Institute

ftp://comments.uspto.gov/pub/software_hearings
    Transcripción de audiencias sobre patentes de software

ftp://marvel.loc.gov/pub/copyright
    Formularios e información de la Oficina de Copyright de Estados Unidos

http://www.eff.org/pub/CAF/law/ip-primer
    Ensayo de ley de propiedad intelectual para desarrolladores multimedia

http://www.eff.org/pub/CAF/law/multimedia-copyright
http://www.eff.org/pub/CAF/law/multimedia-handbook

    Información de derechos de autor para desarrolladores multimedia


__________________
*(EL libro PGP: Pretty Good Privacy de Simson Garfinkel, referenciado en "Para Mayor Información", contiene una discusión completa de los problemas de patentes y de exportación.)

 n0HCo(-JT' &N5i5詗7c'wOưQ|c!@|%A"@[0d1̖Y'zb,5͔Ow( 2+FcI`Fqlzv(7LX rfYvNzzYOA#.E-94Zn!S 52@K9my;.}U݀r&jn2WWHJ`Q}u_tro {rWL;=_ؼ