budowa pliku bmp, dlaczego czyta od tyłu?

0

O formatach plików itd nie mam praktycznie pojęcia stąd też ten topic.

Po kolei...
Na dysku mam obrazek w formacie *.BMP, szerokość obrazka to: 639 pixeli.

Wg wikipedii, cztery bajty licząc od 18-ego bajta od początku pliku, zawierają informację o szerokości obrazka. Ok, to 4 bajty od 18-ego = szerokość. W HEX edytorze te bajty wyglądają tak (po kolei, od osiemnastego):
7F
02
00
00

Czyli 7F02? No to zamieniam hex na dec i mam wynik: 32514, a przecież szerokość obrazka to 639 pixeli, coś jest nie tak.
No to od tyłu czytam bajty, czyli nie od osiemnastego po kolei, tylko od 21-ego bajta do 18-ego.
Czyli 7F02 to będzie 027F i teraz zamieniam to na dec i wynik to: 639. Wow, zgadza się.

I teraz pytanie do was - dlaczego bajty czyta się od tyłu w plikach BMP? w plikach np. mp3 czyta się po kolei (przynajmniej tam gdzie są tagi, informacje o wykonawcy piosenki itd, czyli chyba wielkość pliku - 127 bajtów (nie pamiętam) i lecą tam bajty ładnie po kolei, od lewej do prawej i ładnie czyta się ascii. Skąd program wie jak to czytać? Czy może wszędzie tak jest, a tylko tagi itd w pliku mp3 (czyli końcówka pliku) to celowa zagrywka, by było wygodnie?

A tak na marginesie, lamerski kod w delphi:

var
  Buffer: array[1..4] of Char;
  F: File;
begin
  AssignFile(F, 'd:\test.bmp');
  Reset(F, 1);
  Seek(F, 18);
  BlockRead(F, Buffer, 4);
  CloseFile(F);

  Form1.Caption:= IntToStr(Ord(Buffer[1]));
end;

Ktoś mi powie, czy w ogóle tak kod na odczytanie szerokości powinien wyglądać? czy inaczej? Działać, działa, bo odczytuje szerokość obrazka. Chciałbym też prosić o wyjaśnienie kodu, jako, że ja laik w delphi. Sam z siebie powiem co rozumiem dobrze, bądź źle. Skomentowany kod:

var
  Buffer: array[1..4] of Char; {deklaracja tablicy, jako, że 4 bajty chcę odczytać to 1..4, a typ Char, bo tak se wylosowałem, zakres 0-255}
  F: File; //to wiadomo, plik
begin
  AssignFile(F, 'd:\test.bmp'); //skojarzenie
  Reset(F, 1); //otworzenie pliku
  Seek(F, 18); //przesunięcie pliku, "kursora" na 18 bajt
  BlockRead(F, Buffer, 4); {odczytanie 4 bajtów do tablicy Buffer, w debuggerze odczyta mi jakieś krzaki przez to "char", nawet jak HEXy to 00 na trzecim i czwartym bajcie, to widzę tam krzaki, na dodatek różnią się, choć hexy te same, dopiero jak zmienię typ tablicy z char na byte to mam normalne liczby, czyli tablica ma wtedy elementy: 127, 2, 0, 0 (czyli hexy 7F, 02, 00, 00)}
  CloseFile(F);

  Form1.Caption:= IntToStr(Ord(Buffer[1])); {dałem Ord na chara, wyszedł int, to na Stringa przerobiłem i tyle. A to w klamrze [1], to co to jest? że Ord(Buffer[1]) to znaczy, że chcę pobrać kod ascii pierwszego znaku z tablicy? jeśli tak, to czemu program daje mi Orda wszystkich znaków, tzn. sam czyta 4 elementy tablicy od tyłu zamiast tylko pierwszy element, który dałby wynik 127 (bo 7F)}
end;

Zatem, jeśli ma ktoś z was cierpliwość, to proszę o wyjaśnienie mi tych spraw. Dziękuję.

1

Specyfikacja formatu BMP mówi, że wartości liczbowe są zapisane w formie little-endian, tzn. że najmniej znaczące bajty liczby będą na początku. Jeżeli użyłbyś czegoś, co ci przeczyta całą liczbę (wszystkie 4 bajty na raz) to prawdopodobnie uzyskałbyś normalną wartość.

http://pl.wikipedia.org/wiki/Kolejno%C5%9B%C4%87_bajt%C3%B3w

1

daj

    var szerokosc:longword;
    BlockRead(F, szerokosc, 4);

i powinno działać.

Poza tym jak już robisz bufory, to byte a nie char.

0
Azarien napisał(a)

daj

    var szerokosc:longword;
    BlockRead(F, szerokosc, 4);

i powinno działać.

Poza tym jak już robisz bufory, to byte a nie char.

przecież pisałem, że tamten kod z tablicą Char działa ;) (a swoją drogą, jak zamiast tablicy zrobię tę twoją zmienną longword, to też działa, dzięki, przyda się ta wiedza (a z tablicą Byte miałem problem, coś źle robiłem i robię)). Bardziej chciałbym wiedzieć o co chodzi z Form1.Caption:= IntToStr(Ord(Buffer**[1]**));

a co do odpowiedzi poprzedniego użytkownika, też mu dziękuję, ale trochę czuję niedosyt heh

0

przecież pisałem, że tamten kod z tablicą Char działa
a w Delphi 2009 działać przestanie. char w delphi to nie bajt! char to znak. litera. nie ładuj inta do charów.
zresztą ty w ogóle nie potrzebujesz tablicy, tylko całą liczbę.

o co chodzi z Form1.Caption:= IntToStr(Ord(Buffer[1]));
o wyświetlenie pierwszego bajta tego inta. jeśli int wynosi 255 lub mniej, będzie to wartośc tego inta. jeśli szerokość obrazka jest 256 lub więcej, dostaniesz bzdury.

0
Azarien napisał(a)

a w Delphi 2009 działać przestanie. char w delphi to nie bajt! char to znak. litera. nie ładuj inta do charów.
zresztą ty w ogóle nie potrzebujesz tablicy, tylko całą liczbę.

w 2010 działa z tablicą char, ale skoro to jest złe, to będę ładował do zmiennej //i w sumie racja z tym charem, ale dałem go jak mi z Byte coś kod nie wyszedł

o wyświetlenie pierwszego bajta tego inta. jeśli int wynosi 255 lub mniej, będzie to wartośc tego inta. jeśli szerokość obrazka jest 256 lub więcej, dostaniesz bzdury.

inta? tam jeszcze był kod do tablicy typu char więc chyba do pierwszego elementu tej tablicy powinien wyświetlić info nie? ale o dziwo wyczytał z tego elementu tablicy char liczbę 639 (czyli taką jaką ma szerokość obrazka i dlatego mnie to trochę zdziwiło, że w klamrach jest [1], a czyta całość) to tyle
Tobie także dziękuję za posta, wszystkie są użyteczne :)

1

2010 działa z tablicą char
w D2010 char ma dwa bajty. działa - bo rezerwujesz dwa razy większy obszar niż potrzeba. ale to źle.

ale o dziwo wyczytał z tego elementu tablicy char liczbę 639 (czyli taką jaką ma szerokość obrazka i dlatego mnie to trochę zdziwiło, że w klamrach jest [1], a czyta całość) t
no to się wyjaśnia, przypadkiem działa właśnie ze względu, że char nie jest jednym bajtem tylko dwoma. ale to jeszcze gorzej – dwa błędy nakładając się przypadkowo dały dobry wynik.

0

właśnie ze względu, że char nie jest jednym bajtem

to teraz rozumiem skąd ten wynik :), myślałem, że char mi tylko zmieści np. FF, a nie FFFF (a te rozmiary obrazka i tak były w 2 bajtach, reszta puste stąd dobry wynik), dzięki wielkie za wyjaśnienie, jak to dobrze, że są fora :]

1 użytkowników online, w tym zalogowanych: 0, gości: 1