[ Foro de C ]

Archivos GIF y números binarios (pág. 99)

04-Nov-2009 09:55
Jesús S.
12 Respuestas

¡Hola!

Por lo que he podido averiguar de los GIF, la cantidad de colores la indican en los 4 primeros bits del byte 10 del fichero.

Yo esperaba encontrar un número, que pensaba transformarlo en hexadecimal cuya cifra de la derecha me daría la clave para saber el número de colores (0--> 2 colores, 1--> 4 colores ..... 7-->256 colores). Pero el número del byte 10 me sale negativo (-43). ¿Qué puedo hacer? ¿Es correcto mi análisis de los archivos GIF?

Para el Profe: A mi modesto parecer, los archivos bin son un alivio en comparación con los txt.

Saludos.


05-Nov-2009 10:29
Jesús S.

¡Hola!

Ya he resuelto el problema, aunque he tenido que irme a las últimas páginas de los apuntes para estudiar el manejo de los bits.
Estoy tan entusiasmado por el programilla que lo cuelgo aquí por si a alguien le interesa.

Saludos


08-Nov-2009 22:35
Nacho Cabanes (+83)

Jesús, para hacer cambios como lo que comentas del número de colores de un fichero GIF (0--> 2 colores, 1--> 4 colores ..... 7-->256 colores) no necesitas manipular datos a nivel de bytes, aunque esta sería la solución más eficiente.

A nivel de principiante, sería más sencillo usar un bloque "switch..case".

Y tienes razón, el manejo de ficheros binarios de C "no da sustos", porque no tiene las incongruencias que hay en el manejo de ficheros de texto. Es sorprendente (al menos para mí) que ciertas manipulaciones de ficheros de texto resulten tan engorrosas en un lenguaje que se diseñó a la vez que el sistema operativo Unix y para ayudar en su desarrollo... y más cuando en los sistemas Unix (al menos actualmente) es enormemente frecuente que la configuración de casi cualquier cosa esté en ficheros de texto.

Yo, en mi práctica diaria, hacía dos cosas:

- Crearme mis propias funciones "corregidas", como un "nfgets" que era un "fgets mejorado".

- Usar otro lenguaje (típicamente Pascal, y en algunos casos C++) cuando la tarea a realizar era básicamente la manipulación de ficheros de texto, porque en estos lenguajes todo es mucho más "natural".


29-Dec-2011 20:03
bruno zelaia montero

Coincido contigo compañero de curso!
que bonito es en bin y que trauma pase con los txt...
cuando empecé con el tema 6, la primera ojeada por encima me dije a mí mismo, ya verás Bruno! los de txt tirao! pero los bin lloraras...cuando empecé con los txt se me hacía el mundo cuesta arriba y me decía a mi mismo, joooo****er y aun me faltan los BIN...y mira por donde ha sido al reves...que cosas tiene esto de hacerse prejuicios....un saludo tanto a tí como al profe! :)


29-Dec-2011 20:56
bruno zelaia montero

Por cierto Jesus, yo te agradecería enormemente si puedes poner tu programita aquí, quizás hice mal el mío o de donde saque los datos del GIF es erroneo pero en altura y colores me da unos datos rarunos...
en fín, a ver que ha sido, yo saque los datos de aqui:
GIF Header

Offset   Length   Contents
 0      3 bytes  "GIF"
 3      3 bytes  "87a" or "89a"
 6      2 bytes  <Logical Screen Width>
 8      2 bytes  <Logical Screen Height>
10      1 byte   bit 0:    Global Color Table Flag (GCTF)
                 bit 1..3: Color Resolution
                 bit 4:    Sort Flag to Global Color Table
                 bit 5..7: Size of Global Color Table: 2^(1+n)
11      1 byte   <Background Color Index>
12      1 byte   <Pixel Aspect Ratio>
13      ? bytes  <Global Color Table(0..255 x 3 bytes) if GCTF is one>
        ? bytes  <Blocks>
        1 bytes  <Trailer> (0x3b)
el enlace es http://www.onicos.com/staff/iz/formats/gif.html#ib


30-Dec-2011 14:07
Nacho Cabanes (+83)

Si miras con atención el mensaje anterior de Jesús, verás que tiene adjunto un fichero. Es su programita, para que puedas compararlo con el tuyo.


30-Dec-2011 14:31
bruno zelaia montero

Muchas gracias Nacho!
aprovecho para desearos a todos un buen año :D


03-Jan-2012 19:32
bruno zelaia montero

He mirado tu codigo que esta muy bien pero no encuentro como hayas el ancho y el alto...no se si es que de verdad falta o se me descarga mal, el caso es que llevo varios dias dandole vueltecicas(no muy a fondo la verdad, he ido avanzando en el otro libro) pero no me sale como quisiera, los datos que me dan son erroneos, os pongo los dos codigos que he hecho, a ver si alguien me ayuda a encontrar el fallo...


03-Jan-2012 20:58
bruno zelaia montero

Aqui adjunto codigo de un programa que comprueba
tamaño,alto, ancho y compresion de un fichero BMP y me funciona pero los que he hecho en GIF o PCX me da mal...mi no entender nada...mañana me volvere a pelear con ellos a ver que hago mal...


04-Jan-2012 22:58
Nacho Cabanes (+83)

No tengo claro que tu comprobador de GIF lea datos de donde debe:

Mira esta descripción

GIF format

Byte Order: Little-endian
GIF Header

Offset   Length   Contents
 0      3 bytes  "GIF"
 3      3 bytes  "87a" or "89a"
 6      2 bytes  <Logical Screen Width>
 8      2 bytes  <Logical Screen Height>
10      1 byte   bit 0:    Global Color Table Flag (GCTF)
                 bit 1..3: Color Resolution
                 bit 4:    Sort Flag to Global Color Table
                 bit 5..7: Size of Global Color Table: 2^(1+n)
11      1 byte   <Background Color Index>
12      1 byte   <Pixel Aspect Ratio>
13      ? bytes  <Global Color Table(0..255 x 3 bytes) if GCTF is one>
        ? bytes  <Blocks>
        1 bytes  <Trailer> (0x3b)
Image Block

Offset   Length   Contents
 0      1 byte   Image Separator (0x2c)
 1      2 bytes  Image Left Position
 3      2 bytes  Image Top Position
 5      2 bytes  Image Width
 7      2 bytes  Image Height
 8      1 byte   bit 0:    Local Color Table Flag (LCTF)
                 bit 1:    Interlace Flag
                 bit 2:    Sort Flag
                 bit 2..3: Reserved
                 bit 4..7: Size of Local Color Table: 2^(1+n)
        ? bytes  Local Color Table(0..255 x 3 bytes) if LCTF is one
        1 byte   LZW Minimum Code Size
[ // Blocks
        1 byte   Block Size (s)
       (s)bytes  Image Data
]*
        1 byte   Block Terminator(0x00)

Tomada de:
http://www.onicos.com/staff/iz/formats/gif.html

Y tu programa hace:

            printf ("Marca del fichero: %c%c%c \n",marca1,marca2,marca3);
            fread(&version,1,3,fichero);  /* la version viene en los 3 siguientes bytes del header GIF */
            fread(&ancho,1,2,fichero);    /* en los 2 siguientes bytes viene la info del ancho */
            fread(&alto,1,2,fichero);     /* en los 2 siguientes bytes viene la info de la altura */
            fread(&colores,1,1,fichero); /* En el siguiente byte viene la tabla de colores global */
            fclose (fichero);

Es decir, estás leyendo la "anchura lógica de pantalla", no la anchura de cada bloque de imagen. ¿Seguro que eso coincide con la anchura real de toda la imagen? Y en cualquier caso, son datos de 2 bytes (short), no de 4 bytes (int). Quizá con usar "short" (y leer 2 bytes) baste.


04-Jan-2012 23:07
Nacho Cabanes (+83)

He hecho una prueba rápida con un único fichero, y, efectivamente, con tu programa no me funcionaba correctamente, pero usando "short" sí.

El motivo es que un "int" ocupa 4 bytes (en un sistema operativo de 32 bits), no 2 bytes. Si no haces "ancho = 0;", la variable "ancho" contiene basura, y sólo estás leyendo de fichero datos como para llenar 2 de esos 4 bytes, de modo que los otros 2 bytes seguirán conteniendo basura.

Si da la casualidad de que esa basura son ceros, funcionará, pero sólo por casualidad.

La alternativa razonable es usar "short", y la segunda posibilidad, menos elegante pero que debería funcionar en procesadores Intel, es hacer "ancho=0" antes de leer de fichero.


05-Jan-2012 16:35
bruno zelaia montero

Ok, voy a retocar el código y lo pruebo, ante todo muchas gracias por tu atención y tu rapidez de respuesta y disculpa las molestias.


05-Jan-2012 16:56
bruno zelaia montero

Toda la razón del mundo profesor, por fin funciona! :D muchas gracias, lección aprendida...
ademas por partida doble, voy a ir más despacio y voy a tomármelo con más calma...revisando los foros he encontrado información interesante sobre fread,fseek,fwrite y ftell...creo que me lo voy a revisar a conciencia a ver, de nuevo una vez más agradecerte tu tiempo :)






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)