Toto vlákno bylo označeno za vyřešené.
oxidián 0
Grafoman
Načetl jsem 4 bajty z binárního souboru: "\000\000\000\020" string reprezentuje číslo (pozici v souboru).
Jak převést n na uint32_t abych dostal offset?
uint32_t header_offset;
....
char n[4];
size_t in;
in = fread(n, 4, 1, fp);
if (!in)
return -2;
header_offset = (uint32_t ) n; // get 4 bytes string to integer
KIIV ~ Moderátor
+43
God of flame
no jelikoz to vypada na big endian, tak prinejmensim header_offset = ntohl(*((uint32_t *)n));
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián 0
Grafoman
A ve standardním C něco není? Já jen že to asi nemám na počítači píse mi to undefined reference to `ntohl'|
KIIV ~ Moderátor
+43
God of flame
no musis se mrknout na google, v jakem hlavickovem souboru to je a pripadne jaka je nahrada pro tvuj prohlizec...
urcite to neni v zakladu, je to zavisly na procesoru a tak
nebo to holt prohazet - na netu jsou ukazky, jak se da vymenit byte order - nicmene ntohl to muze i nechat tak jak to je, pokud je procesor big endian
Program vždy dělá to co naprogramujete, ne to co chcete...
BDS +3
Věrný člen
#3 oxidián
můžeš to udělat sám:
unsigned int SwapUINT(unsigned int v)
{
unsigned int i,r;
for (i=0; i<4; i++) *((unsigned char *)&r + i) = *((unsigned char *)&v + (3 - i));
return r;
}
KIIV ~ Moderátor
+43
God of flame
#5 BDS
no to uz by lip vypadalo:
#define BSWAP32(n) ((n) >> 24) | (((n) << 8) & 0x00FF0000L) | (((n) >> 8) & 0x0000FF00L) | ((n) << 24)
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián 0
Grafoman
BDS: ale nefunguje mi to správně. Dostal jsem číslo 2969117184 a to je příliš vysoké. Očekávám že offset by mohl být několik desítek bytů.
oxidián 0
Grafoman
Něco mi uniká. Proč nemohu zkopírovat kód ze stránky jako normální člověk?
Nemohl bys to poslat na externí link?
Tohle se fakt číst nedá:
#define BSWAP32(n) ((n) >> 24) | (((n) << 8) & 0x00FF0000L) | (((n) >> 8) & 0x0000FF00L) | ((n) << 24)
Tak jestli jsem do dopře opsal tak mi to hlásí:
#define BSWAP32(n) ((n) << 24) | (((n) >> 8) & 0x00FF0000L) | (((n) >> 8) & 0x0000FF00L) | ((n) << 24)header_offset = SwapUINT(n); // get 4 bytes string to integer
header_offset = SwapUINT(n);
header_offset = BSWAP32(n);
warning: passing argument 1 of 'SwapUINT' makes integer from pointer without a cast
note: expected 'unsigned int' but argument is of type 'char *'|
invalid operands to binary << (have 'char *' and 'int')|
BDS +3
Věrný člen
#8 oxidián
určitě ta funkce funguje správně
samozřejmě taky můžeš použít makro od KIIV, nebo taky:
unsigned int SwapUINTfromChars(unsigned char n[])
{
return(
n[0] * 0x01000000 +
n[1] * 0x010000 +
n[2] * 0x0100 +
n[3]);
}
BDS +3
Věrný člen
#9 oxidián
asi nepoužíváš prohlížeč jako normální člověk :D
oxidián 0
Grafoman
Hodnotu char[4] jsem posílal: je "\000\000\000\020" bez uvozovek
BDS +3
Věrný člen
#9 oxidián
'unsigned int' but argument is of type 'char *'|
nemůžeš měnit char* na int
BDS +3
Věrný člen
uint32_t header_offset;
....
//char n[4];
unsigned int val;
fread(&val, 4, 1, fp);
...
header_offset = BSWAP32(val);
oxidián 0
Grafoman
Poslední funkce funguje skvěle (SwapUINTFromChar ), dík.
PS: Používám Firefox v32.0.1
BDS +3
Věrný člen
#15 oxidián
funguje, protože očekává pole charů, ne int. Ty předešlé fungují taky, ale předával si jim nesprávný parametr!
oxidián 0
Grafoman
Já? Spíš ty, ne? Já to pouze opsal jak si to udělal ty.
BDS +3
Věrný člen
#17 oxidián
kdyby si to opsal tak si to měl udělat takto:
uint32_t header_offset;
....
char n[4];
size_t in;
in = fread(n, 4, 1, fp);
if (!in)
return -2;
header_offset = BSWAP32(*(unsigned int*)n);
nebo ještě lépe jak jsem napsal v #14:
unsigned int val;
fread(&val, 4, 1, fp); //(načítat přímo do intu)
...
header_offset = BSWAP32(val);
oxidián 0
Grafoman
Teď jsem zjistil, že ta hlavička je v little-endian. Mění se tím něco?
BDS +3
Věrný člen
#19 oxidián
tak to nemusíš přehazovat na big
oxidián 0
Grafoman
Já nevím, já tomu vůbec nerozumím. Snažím se přečíst data z hlavičky BMP souboru, ale nevyznám se ani v té tabulce* bytů natož kde má být správná pozice. Takže z toho co ste mi tu napsali nemám nic protože nevím co je správný výsledek.
Poznámka: nesedí mi to co čtu v té tabulce s tím co čtu v souboru bmp v hex editoru.
Soubor mi začíná dvěma byty BM identifikující soubor BMP: 424D Pak tam má být velikost hlavičky 4 byty je tam napsáno 3600 0003 když to převedu na kalkulačce z HEX do DEC tak výjde číslo přes 900 Megabyte, což je nesmysl, soubor rgb 4096x4096 má zabírat kolem 49 megabyte.
edit:
A offset má v souboru: 0000 3600
ještě jednou to opíšu celé:
424D 3600 0003 0000 0000 3600 0000
oxidián 0
Grafoman
Tak mi to nesedí. Zase mi vychází to číslo 905969664 nevím proč. A to čtu správně pozici header_offset od 10 bytu (správná hodnota by měla být "6\000\000" ).
KIIV ~ Moderátor
+43
God of flame
nicmene 0x03000036 dava 50331702 coz uz tech 49MB bude.. kazdopadne to uz vypada na little endian a bude ti stacit nacist to rovnou jako uint
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián 0
Grafoman
Nevím ale kde bereš těch 0x030000 36 Takové číslo tam není. Jestli myslíš 03 0000 0000 36 tak to je omyl - velikost souboru má být podle dokumentace na wiki 3600 0003 - tedy byty 02-05 by měli dávat velikost souboru. Další 4 byty jsou vyhrazeny pro aplikaci (to jsou ty podtržené) a poslední 4 mají být header_offset
Lépe přiložím odkaz:
http://oi62.tinypic.com/2rcopoo.jpg
Připojen obrázek.
oxidián 0
Grafoman
Počkat, když upravím příkaz fseek na pozici +1: tak mi to dá zajimavý výsledek:
fseek (fp, result->header_offset_position+1, SEEK_SET);
"\000\000\000("
Což je header_offset 40 a to by už bylo v pořádku. Takže problém byl asi v tom, že offset je kde končí předchozí sekce (na 10 bytu), ale následující sekce je offset +1
(11 byte čili 11,12,13,14 je ten header_offset).
BDS +3
Věrný člen
#24 oxidián
0x03000036 je na offset pozici 2 ve formátu 0x36000003
oxidián 0
Grafoman
Aha, takže vy ti čísla čtete pozpátku! Snad už vás chápu.
KIIV ~ Moderátor
+43
God of flame
precti si pojem little a big endian..
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků
Přidej příspěvek
Uživatelé prohlížející si toto vlákno Uživatelé on-line: 0 registrovaných, 42 hostů