Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Ciego?

Iniciado por Warchief, 23 de Agosto de 2004, 07:03:57 PM

« anterior - próximo »

Warchief

 No debo de estar en mi sano juicio, pero estoy convencido de que la salida del programa deberia ser "14 14", y sin embargo es "14 16". ¿Alguien me explica donde esta el truco, por favor? Llevo muchisimo tiempo para encontrar que lo que me falla es el sizeof, pero no se por que falla, ¿donde pierdo 2 bytes?


typedef short int WORD;
typedef long  int DWORD;

// Cabecera archivo BMP
typedef struct {
WORD  bfType;  // Debe ser "BM"
DWORD bfSize;  // Tam fichero en bytes
WORD  bfReserved1; // Debe ser 0
WORD  bfReserved2; // Debe ser 0
DWORD bfOffBits;      // Offset inicio de datos (def 1078)
} bmpFileHeader;

int main (void);

int main(void) {
bmpFileHeader cabFile;
printf("%d\n",  sizeof(cabFile.bfType)+
    sizeof(cabFile.bfSize)+
    sizeof(cabFile.bfReserved1)+
    sizeof(cabFile.bfReserved2)+
    sizeof(cabFile.bfOffBits));
printf("%d\n", sizeof(bmpFileHeader));
return 0;
}

Zaelsius

 La estructura está alineada en regiones de 32 bits(4 bytes), de ahí que pierdas 2 bytes por el final (16bytes es múltiplo de 4 mientras que 14 no).

Internamente los DWORD's están alineados a 32bits por defecto. Si el compilador pusiese las variables en memoria una detrás de otra, el último DWORD estaría desalineado. La alineación permite al procesador leer/escribir las palabras más rápido que si no lo estuviesen.

Edit: Cutre-esquema, habia puesto una tabla en ascii pero se ve mal.. buscaré una imagen de algun lado.

Warchief

 Ahhhhm menos mal que has editado porque ya tenia preparada la siguiente, jasjajs ya que al hacer


void loadbmp_24bpp(char *filen){
bmpFileHeader cabFile;
bmpFileHeader cabFile2;
bmpInfoHeader cabInfo;
FILE *fd;
int sizeOfReal = sizeof(cabFile.bfType)+sizeof(cabFile.bfSize)+sizeof(cabFile.bfReserved1)+sizeof(cabFile.bfReserved2)+sizeof(cabFile.bfOffBits);

// Abrir el fichero
if ((fd = fopen(filen,"rb")) == NULL) {
 printf("Error al abrir el archivo '%s'\n",filen);
 return;
}

// Cargar cabecera de fichero
fread(&cabFile.bfType, sizeof(cabFile.bfType), 1, fd);
fread(&cabFile.bfSize, sizeof(cabFile.bfSize), 1, fd);
fread(&cabFile.bfReserved1, sizeof(cabFile.bfReserved1), 1, fd);
fread(&cabFile.bfReserved2, sizeof(cabFile.bfReserved2), 1, fd);
fread(&cabFile.bfOffBits, sizeof(cabFile.bfOffBits), 1, fd);

printf("*********\n%d (%d)\n%ld (%d)\n%d (%d)\n%d (%d)\n%ld (%d)\n*********\n",
 cabFile.bfType, sizeof(cabFile.bfType),
 cabFile.bfSize, sizeof(cabFile.bfSize),
 cabFile.bfReserved1, sizeof(cabFile.bfReserved1),
 cabFile.bfReserved2, sizeof(cabFile.bfReserved2),
 cabFile.bfOffBits, sizeof(cabFile.bfOffBits)
);

// Carga erroneo!!
fseek(fd,0, SEEK_SET);
fread(&cabFile2, sizeOfReal, 1, fd);

printf("*********\n%d (%d)\n%ld (%d)\n%d (%d)\n%d (%d)\n%ld (%d)\n*********\n",
 cabFile2.bfType, sizeof(cabFile2.bfType),
 cabFile2.bfSize, sizeof(cabFile2.bfSize),
 cabFile2.bfReserved1, sizeof(cabFile2.bfReserved1),
 cabFile2.bfReserved2, sizeof(cabFile2.bfReserved2),
 cabFile2.bfOffBits, sizeof(cabFile2.bfOffBits)
);

return 0;
}


Me salia mal el cabfile2 claramente.

Con "el editado" ha quedado tan claro como la falta que tengo de compiladores XDD

Gracias por la explicacion.


EDIT: No hace falta, el cutre-esquema era grandiosamente explicativo.

Gracias, gracias. Todo clarisimo.

gdl

 Si quieres deshabilitar el alineado en memoria o, mejor dicho, alinear a byte. Puedes probar algo como esto (o similar porque dependerá del compilador):

#pragma pack(1)

También suele haber algún procedimiento para recuperar el índice de alineación anterior (push/pop).

Esta directiva de compilación se suele usar para estructuras en ficheros (donde no hay alineación que valga).

¿Me he explicado bien? (Que estoy dormido)

Warchief

Cita de: "gdl"Si quieres deshabilitar el alineado en memoria o, mejor dicho, alinear a byte. Puedes probar algo como esto (o similar porque dependerá del compilador):

#pragma pack(1)

También suele haber algún procedimiento para recuperar el índice de alineación anterior (push/pop).

Esta directiva de compilación se suele usar para estructuras en ficheros (donde no hay alineación que valga).

¿Me he explicado bien? (Que estoy dormido)
Uhm si te has explicado. Mas que nada porque ahora entiendo el codigo que habia visto, en el que ponia:


#pragma pack( 1 )
typedef struct {

 char           Type[2];
 unsigned long  Size;
 long           Reserved;
 unsigned long  OffBits;
 unsigned long  InfoSize;
 long           Width;
 long           Height;
 short          Planes;
 short          BitCount;
 long           Compression;
 unsigned long  ImageSize;
 long           Fill[4];

} stBmpHeader;
#pragma pack( 4 )


Gracias por la indicacion.

Warchief

 No me deja editar mis mensajes, ¿por que?, ¿solo se puede editar 1 por hilo?

Solo para decir que ya use:


#pragma pack(1)
// Cabecera archivo BMP
typedef struct {
WORD  bfType;  // Debe ser "BM"
DWORD bfSize;  // Tam fichero en bytes
WORD  bfReserved1; // Debe ser 0
WORD  bfReserved2; // Debe ser 0
DWORD bfOffBits; // Offset inicio de datos (def 1078)
} bmpFileHeader;

// Cabecera informacion BMP
typedef struct {
...
} bmpInfoHeader;
#pragma pack(4)


y ya pude poner bien


// Cargar cabecera de fichero
fread(&cabFile, sizeof(bmpFileHeader), 1, fd);


Ademas me funciona tanto para windows como para linux.

Asi pues, gracias por los coments.

Edit: Uhm, este si le puedo editar.  No entiendo. ¿Sera por tiempo?  

BeRSeRKeR

 Mejor podrías utilizar lo que te ha dicho gdl para poder recuperar la alineación anterior:

#pragma pack(push, 1)

struct foo {
....
....
};

#pragma pack(pop)

Y cuando haces pop ya no hay stop :lol:

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

Warchief

 
Cita de: "BeRSeRKeR"Mejor podrías utilizar lo que te ha dicho gdl para poder recuperar la alineación anterior:

#pragma pack(push, 1)
struct foo {
....
};
#pragma pack(pop)

Y cuando haces pop ya no hay stop :lol:

Saludos.
Ok, no sabia bien como poner push y pop (por  "También suele haber algún procedimiento..").

Luego lo pruebo.  

Gracias.

----------------------------
EDIT:

Oppsss.


s@s:~$ gcc *.c -o run
In file included from bmplib.c:1:
bmplib.h:7: warning: malformed `#pragma pack'
bmplib.h:31: warning: malformed `#pragma pack'
In file included from conversionS.c:1:
bmplib.h:7: warning: malformed `#pragma pack'
bmplib.h:31: warning: malformed `#pragma pack'

s@s:~$ gcc --version
2.95.4

s@s:~$ ./run imagen24.bmp sal.bmp
BPP no valido (0 / 24)



Brr, me temo que no me sirve. En win va bien. Pero necesito que tire en linux.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.