dev.gamez.lv Forum Index dev.gamez.lv
Latvian Game Developers Community
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups 

c++ tga file loader!

 
dev.gamez.lv Forum Index -> Programmēšana
View previous topic :: View next topic  
Author Message
coderpp



Joined: 20 Aug 2005
Posts: 167
Location: Rīga, Koknese, Gajiena

PostPosted: Tue Aug 07, 2007 1:08 pm    Post subject: c++ tga file loader!

Izdomāju uzrakstīt tga faila ielādētāju. Palasīju faila dokomentāciju un man radās daži jautājumi.

* Citāts no tga faila dokomentācijas:
Quote:
Byte Ordering!
TGA files are stored using the Intel byte ordering convention (least significant byte first, most significant byte last). For this reason, applications running on Motorola-based systems will need to invert the ordering of bytes for short and long values after a file has been read.

Vai man šī baitu kārtošana jāņem vērā rakstot faila ielādētāju? Vai kāds mani varētu apgaismot par šo baitu kartošanu latviešu mēlē?

* Šajā dokomentācijā ir minēts gan vecais tga formāts (kas satur divus laukus: header, image/color map data), gan jaunais(kas satur piecus laukus: header, image/color map data, developer area (var nebūt), extension area (var nebūt) un footer). Vai tagad vēl tiek lietots vecais tga formāts?

* Es faila header daļu nolasu šādi:
Code:

unsigned char * Header = new unsigned char[18];
int ImageWidth;

TgaFile.read((char*)Header, 18);
if (Header == NULL){
   return false;
}
...
memcpy(&ImageWidth, &HeaderData[12], 2);
...

Rezultātā iegūstu bildes platuma izmēru pikseļos.

Meklējot internetā atradu, ka bildes platumu iegūst savādāk:
Code:

int width = hdr[TGAHDR_WIDTH + 1] * 256 + hdr[TGAHDR_WIDTH];

Kāpēc tur bildes platums tiek iegūts kautko reizinot un saskaitot?[/quote]
Back to top
View user's profile Send e-mail
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Tue Aug 07, 2007 2:11 pm    Post subject: Re: c++ tga file loader!

coderpp wrote:
Vai man šī baitu kārtošana jāņem vērā rakstot faila ielādētāju? Vai kāds mani varētu apgaismot par šo baitu kartošanu latviešu mēlē?

Jā, ja gribi lai kods strādā uz PPC makinošiem, vai arī citām ne-Intel sistēmām.
Pēc būtības tas nozīmē, ka tu nedrīksti kastot integeru/short un char* (baitu masīvu) un operēta ar individuālajiem baitiem. Tas ir tieši tas, ko tu dari zemāk: TgaFile.read((char*)Header, 18); Šāds kods nestrādās uz big-endian sistēmām.

Quote:
* Šajā dokomentācijā ir minēts gan vecais tga formāts (kas satur divus laukus: header, image/color map data), gan jaunais(kas satur piecus laukus: header, image/color map data, developer area (var nebūt), extension area (var nebūt) un footer). Vai tagad vēl tiek lietots vecais tga formāts?

hvz. Es parasti tga lasu šādi - headeris, developer area (kuru izlaižu) un image. color-map (paletizētos) formātus nemaz netaisos lasīt. Man pilnīgi pietiek ar RGB/RGBA formātiem (tb 24/32-bit). Tagad ir 21. gadsimts kā nekā. Vajag vienkārši atbalstīt konkrēta tipa headerus, kurus tikai gribi un viss. Pārējiem mest kļūdu.

Quote:
Kāpēc tur bildes platums tiek iegūts kautko reizinot un saskaitot?

Tāpēc ka tāds kods ir endianess-neatkarīgs, jo tajā netiek kāstots integers uz atsevišķiem baitiem, bet gan baiti tiek pareizā kārtībā salikti integerā. Tas strādās gan uz little-endian, gan big-endian arhitektūrām.

Varu pastāstīt sīkāk - width ir 2 baitu integers.
Pa bitiem: 01234567 01234567, kur katrs no šiem ir viens baits.
Ja tev headerī ir divi baiti A un B, kuri nosaka width, bet tu tos gribi vienā veselā integerī dabūt, tad ko jādara? Pēc Little-endian sistēmas (jo tga specifikācijā teikts ka headeris ir little-endian formātā) A jāliek zemākajā baitā, bet B augstākajā - BBBBBBBB AAAAAAAA (pa bitiem). Kā to dabūt gatavu? Vajag zināt, ka reizināšana ar 2-nieka pakāpi nozīmē bitu pabīdīšanu par pakāpes vērtību, tātad lai BBBBBBBB dabūtu par BBBBBBBB 00000000 vajag B pabīdīt pa kreisi par 8 bitiem - tātad reizināt ar 2^8 = 256. Rezultātā atliek tikai pieskaitīt A: width = B*256 + A.
To pašu var vispārināt arī uz 4-baitu integeriem, tikai tur veseli četri baiti ir jābīda un jāskaita kopā.

Un piekasīšos sourcei:
Code:
unsigned char * Header = new unsigned char[18];

Kāpēc tu dinamiski izdali atmiņu konstanta izmēra masīvam?
Ja izmērs ir konstants, tad vajag lietot parastu masīvu:
Code:
unsigned char Header[18];

Gan ātrāk kods darbosies, gan mazāk iespēju tev pašam nokļūdīties.
Back to top
View user's profile Send e-mail
coderpp



Joined: 20 Aug 2005
Posts: 167
Location: Rīga, Koknese, Gajiena

PostPosted: Mon Aug 27, 2007 9:17 pm    Post subject:

bubu wrote:
Pēc būtības tas nozīmē, ka tu nedrīksti kastot integeru/short un char* (baitu masīvu) un operēta ar individuālajiem baitiem. Tas ir tieši tas, ko tu dari zemāk: TgaFile.read((char*)Header, 1Cool; Šāds kods nestrādās uz big-endian sistēmām.

Kā nestrādās? Vispār nenolasīs? Internetā atradu veidu kā uzzināt endian sistēmu.
Code:

enum EndianType{
   BIG      = 0,   // Big-endian
   LITTLE   = 1      // Little-endian
};

EndianType GetEndian(){
   short word = 0x0001;
   char *byte = (char *) &word;
   
   if (byte[0] == 1){
      return LITTLE;
   }else{
      return BIG;
   }
}

Vai var vienkārši nolasīt, tā kā es to darīju un tad, ja sistēma ir big-endian, tad vienkārši samainīt baitus?
Code:

piemēram:
ImageWidth = SwapTwoBytes(ImageWidth);

Un īsti nesapratu, kas ir Image Descriptor? Tas ir alpha kanāls?
Back to top
View user's profile Send e-mail
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Mon Aug 27, 2007 10:53 pm    Post subject:

coderpp wrote:
Kā nestrādās? Vispār nenolasīs?

Nolasīs, bet visu, kas >baitu, to nolasīs otrādi. Piemēram skaitli 512 lasot kā word, nolasīs par skaitli 2 ( 0x0200 <-> 0x0002)

Quote:
Vai var vienkārši nolasīt, tā kā es to darīju un tad, ja sistēma ir big-endian, tad vienkārši samainīt baitus?
Code:

piemēram:
ImageWidth = SwapTwoBytes(ImageWidth);

Jā, var.
Back to top
View user's profile Send e-mail
Display posts from previous:   
dev.gamez.lv Forum Index -> Programmēšana All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group