LBMLIB.CPP 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. // lbmlib.c
  19. #include "stdafx.h"
  20. #include "cmdlib.h"
  21. #include "lbmlib.h"
  22. #include "bmp.h"
  23. #include "pakstuff.h"
  24. #include "jpeglib.h"
  25. /*
  26. ============================================================================
  27. LBM STUFF
  28. ============================================================================
  29. */
  30. typedef unsigned char UBYTE;
  31. //conflicts with windows typedef short WORD;
  32. typedef unsigned short UWORD;
  33. typedef long LONG;
  34. typedef enum
  35. {
  36. ms_none,
  37. ms_mask,
  38. ms_transcolor,
  39. ms_lasso
  40. } mask_t;
  41. typedef enum
  42. {
  43. cm_none,
  44. cm_rle1
  45. } compress_t;
  46. typedef struct
  47. {
  48. UWORD w,h;
  49. short x,y;
  50. UBYTE nPlanes;
  51. UBYTE masking;
  52. UBYTE compression;
  53. UBYTE pad1;
  54. UWORD transparentColor;
  55. UBYTE xAspect,yAspect;
  56. short pageWidth,pageHeight;
  57. } bmhd_t;
  58. extern bmhd_t bmhd; // will be in native byte order
  59. #define FORMID ('F'+('O'<<8)+((int)'R'<<16)+((int)'M'<<24))
  60. #define ILBMID ('I'+('L'<<8)+((int)'B'<<16)+((int)'M'<<24))
  61. #define PBMID ('P'+('B'<<8)+((int)'M'<<16)+((int)' '<<24))
  62. #define BMHDID ('B'+('M'<<8)+((int)'H'<<16)+((int)'D'<<24))
  63. #define BODYID ('B'+('O'<<8)+((int)'D'<<16)+((int)'Y'<<24))
  64. #define CMAPID ('C'+('M'<<8)+((int)'A'<<16)+((int)'P'<<24))
  65. bmhd_t bmhd;
  66. int Align (int l)
  67. {
  68. if (l&1)
  69. return l+1;
  70. return l;
  71. }
  72. /*
  73. ================
  74. LBMRLEdecompress
  75. Source must be evenly aligned!
  76. ================
  77. */
  78. byte *LBMRLEDecompress (byte *source,byte *unpacked, int bpwidth)
  79. {
  80. int count;
  81. byte b,rept;
  82. count = 0;
  83. do
  84. {
  85. rept = *source++;
  86. if (rept > 0x80)
  87. {
  88. rept = (rept^0xff)+2;
  89. b = *source++;
  90. memset(unpacked,b,rept);
  91. unpacked += rept;
  92. }
  93. else if (rept < 0x80)
  94. {
  95. rept++;
  96. memcpy(unpacked,source,rept);
  97. unpacked += rept;
  98. source += rept;
  99. }
  100. else
  101. rept = 0; // rept of 0x80 is NOP
  102. count += rept;
  103. } while (count<bpwidth);
  104. if (count>bpwidth)
  105. Error ("Decompression exceeded width!\n");
  106. return source;
  107. }
  108. /*
  109. =================
  110. LoadLBM
  111. =================
  112. */
  113. void LoadLBM (char *filename, byte **picture, byte **palette)
  114. {
  115. byte *LBMbuffer, *picbuffer, *cmapbuffer;
  116. int y;
  117. byte *LBM_P, *LBMEND_P;
  118. byte *pic_p;
  119. byte *body_p;
  120. int formtype,formlength;
  121. int chunktype,chunklength;
  122. // qiet compiler warnings
  123. picbuffer = NULL;
  124. cmapbuffer = NULL;
  125. //
  126. // load the LBM
  127. //
  128. LoadFile (filename, (void **)&LBMbuffer);
  129. if (LBMbuffer == NULL)
  130. {
  131. return;
  132. }
  133. //
  134. // parse the LBM header
  135. //
  136. LBM_P = LBMbuffer;
  137. if ( *(int *)LBMbuffer != LittleLong(FORMID) )
  138. Error ("No FORM ID at start of file!\n");
  139. LBM_P += 4;
  140. formlength = BigLong( *(int *)LBM_P );
  141. LBM_P += 4;
  142. LBMEND_P = LBM_P + Align(formlength);
  143. formtype = LittleLong(*(int *)LBM_P);
  144. if (formtype != ILBMID && formtype != PBMID)
  145. Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff
  146. ,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff);
  147. LBM_P += 4;
  148. //
  149. // parse chunks
  150. //
  151. while (LBM_P < LBMEND_P)
  152. {
  153. chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24);
  154. LBM_P += 4;
  155. chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24);
  156. LBM_P += 4;
  157. switch ( chunktype )
  158. {
  159. case BMHDID:
  160. memcpy (&bmhd,LBM_P,sizeof(bmhd));
  161. bmhd.w = BigShort(bmhd.w);
  162. bmhd.h = BigShort(bmhd.h);
  163. bmhd.x = BigShort(bmhd.x);
  164. bmhd.y = BigShort(bmhd.y);
  165. bmhd.pageWidth = BigShort(bmhd.pageWidth);
  166. bmhd.pageHeight = BigShort(bmhd.pageHeight);
  167. break;
  168. case CMAPID:
  169. cmapbuffer = (unsigned char*)malloc (768);
  170. memset (cmapbuffer, 0, 768);
  171. memcpy (cmapbuffer, LBM_P, chunklength);
  172. break;
  173. case BODYID:
  174. body_p = LBM_P;
  175. pic_p = picbuffer = (unsigned char*)malloc (bmhd.w*bmhd.h);
  176. if (formtype == PBMID)
  177. {
  178. //
  179. // unpack PBM
  180. //
  181. for (y=0 ; y<bmhd.h ; y++, pic_p += bmhd.w)
  182. {
  183. if (bmhd.compression == cm_rle1)
  184. body_p = LBMRLEDecompress ((byte *)body_p
  185. , pic_p , bmhd.w);
  186. else if (bmhd.compression == cm_none)
  187. {
  188. memcpy (pic_p,body_p,bmhd.w);
  189. body_p += Align(bmhd.w);
  190. }
  191. }
  192. }
  193. else
  194. {
  195. //
  196. // unpack ILBM
  197. //
  198. Error ("%s is an interlaced LBM, not packed", filename);
  199. }
  200. break;
  201. }
  202. LBM_P += Align(chunklength);
  203. }
  204. free (LBMbuffer);
  205. *picture = picbuffer;
  206. if (palette)
  207. *palette = cmapbuffer;
  208. }
  209. /*
  210. ============================================================================
  211. WRITE LBM
  212. ============================================================================
  213. */
  214. /*
  215. ==============
  216. WriteLBMfile
  217. ==============
  218. */
  219. void WriteLBMfile (char *filename, byte *data,
  220. int width, int height, byte *palette)
  221. {
  222. byte *lbm, *lbmptr;
  223. int *formlength, *bmhdlength, *cmaplength, *bodylength;
  224. int length;
  225. bmhd_t basebmhd;
  226. lbm = lbmptr = (unsigned char*)malloc (width*height+1000);
  227. //
  228. // start FORM
  229. //
  230. *lbmptr++ = 'F';
  231. *lbmptr++ = 'O';
  232. *lbmptr++ = 'R';
  233. *lbmptr++ = 'M';
  234. formlength = (int*)lbmptr;
  235. lbmptr+=4; // leave space for length
  236. *lbmptr++ = 'P';
  237. *lbmptr++ = 'B';
  238. *lbmptr++ = 'M';
  239. *lbmptr++ = ' ';
  240. //
  241. // write BMHD
  242. //
  243. *lbmptr++ = 'B';
  244. *lbmptr++ = 'M';
  245. *lbmptr++ = 'H';
  246. *lbmptr++ = 'D';
  247. bmhdlength = (int *)lbmptr;
  248. lbmptr+=4; // leave space for length
  249. memset (&basebmhd,0,sizeof(basebmhd));
  250. basebmhd.w = BigShort((short)width);
  251. basebmhd.h = BigShort((short)height);
  252. basebmhd.nPlanes = 8;
  253. basebmhd.xAspect = 5;
  254. basebmhd.yAspect = 6;
  255. basebmhd.pageWidth = BigShort((short)width);
  256. basebmhd.pageHeight = BigShort((short)height);
  257. memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
  258. lbmptr += sizeof(basebmhd);
  259. length = lbmptr-(byte *)bmhdlength-4;
  260. *bmhdlength = BigLong(length);
  261. if (length&1)
  262. *lbmptr++ = 0; // pad chunk to even offset
  263. //
  264. // write CMAP
  265. //
  266. *lbmptr++ = 'C';
  267. *lbmptr++ = 'M';
  268. *lbmptr++ = 'A';
  269. *lbmptr++ = 'P';
  270. cmaplength = (int *)lbmptr;
  271. lbmptr+=4; // leave space for length
  272. memcpy (lbmptr,palette,768);
  273. lbmptr += 768;
  274. length = lbmptr-(byte *)cmaplength-4;
  275. *cmaplength = BigLong(length);
  276. if (length&1)
  277. *lbmptr++ = 0; // pad chunk to even offset
  278. //
  279. // write BODY
  280. //
  281. *lbmptr++ = 'B';
  282. *lbmptr++ = 'O';
  283. *lbmptr++ = 'D';
  284. *lbmptr++ = 'Y';
  285. bodylength = (int *)lbmptr;
  286. lbmptr+=4; // leave space for length
  287. memcpy (lbmptr,data,width*height);
  288. lbmptr += width*height;
  289. length = lbmptr-(byte *)bodylength-4;
  290. *bodylength = BigLong(length);
  291. if (length&1)
  292. *lbmptr++ = 0; // pad chunk to even offset
  293. //
  294. // done
  295. //
  296. length = lbmptr-(byte *)formlength-4;
  297. *formlength = BigLong(length);
  298. if (length&1)
  299. *lbmptr++ = 0; // pad chunk to even offset
  300. //
  301. // write output file
  302. //
  303. SaveFile (filename, lbm, lbmptr-lbm);
  304. free (lbm);
  305. }
  306. /*
  307. ============================================================================
  308. LOAD PCX
  309. ============================================================================
  310. */
  311. typedef struct
  312. {
  313. char manufacturer;
  314. char version;
  315. char encoding;
  316. char bits_per_pixel;
  317. unsigned short xmin,ymin,xmax,ymax;
  318. unsigned short hres,vres;
  319. unsigned char palette[48];
  320. char reserved;
  321. char color_planes;
  322. unsigned short bytes_per_line;
  323. unsigned short palette_type;
  324. char filler[58];
  325. unsigned char data; // unbounded
  326. } pcx_t;
  327. /*
  328. ==============
  329. LoadPCX
  330. ==============
  331. */
  332. void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
  333. {
  334. byte *raw = 0;
  335. pcx_t *pcx;
  336. int x, y;
  337. int len;
  338. int dataByte, runLength;
  339. byte *out, *pix;
  340. if (pic)
  341. *pic = NULL;
  342. if (palette)
  343. *palette = NULL;
  344. if (width)
  345. *width = 0;
  346. if (height)
  347. *height = 0;
  348. //
  349. // load the file
  350. //
  351. len = LoadFile (filename, (void **)&raw);
  352. if (len == -1)
  353. return;
  354. //
  355. // parse the PCX file
  356. //
  357. pcx = (pcx_t *)raw;
  358. raw = &pcx->data;
  359. pcx->xmin = LittleShort(pcx->xmin);
  360. pcx->ymin = LittleShort(pcx->ymin);
  361. pcx->xmax = LittleShort(pcx->xmax);
  362. pcx->ymax = LittleShort(pcx->ymax);
  363. pcx->hres = LittleShort(pcx->hres);
  364. pcx->vres = LittleShort(pcx->vres);
  365. pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
  366. pcx->palette_type = LittleShort(pcx->palette_type);
  367. if (pcx->manufacturer != 0x0a
  368. || pcx->version != 5
  369. || pcx->encoding != 1
  370. || pcx->bits_per_pixel != 8
  371. || pcx->xmax >= 640
  372. || pcx->ymax >= 480)
  373. Error ("Bad pcx file %s", filename);
  374. if (palette)
  375. {
  376. *palette = (unsigned char*)malloc(768);
  377. memcpy (*palette, (byte *)pcx + len - 768, 768);
  378. }
  379. if (width)
  380. *width = pcx->xmax+1;
  381. if (height)
  382. *height = pcx->ymax+1;
  383. if (!pic)
  384. {
  385. free(pcx);
  386. return;
  387. }
  388. out = (unsigned char*)malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
  389. if (!out)
  390. Error ("Skin_Cache: couldn't allocate");
  391. *pic = out;
  392. pix = out;
  393. for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
  394. {
  395. for (x=0 ; x<=pcx->xmax ; )
  396. {
  397. dataByte = *raw++;
  398. if((dataByte & 0xC0) == 0xC0)
  399. {
  400. runLength = dataByte & 0x3F;
  401. dataByte = *raw++;
  402. }
  403. else
  404. runLength = 1;
  405. while(runLength-- > 0)
  406. pix[x++] = dataByte;
  407. }
  408. }
  409. if ( raw - (byte *)pcx > len)
  410. Error ("PCX file %s was malformed", filename);
  411. free (pcx);
  412. }
  413. /*
  414. ==============
  415. WritePCXfile
  416. ==============
  417. */
  418. void WritePCXfile (char *filename, byte *data,
  419. int width, int height, byte *palette)
  420. {
  421. int i, j, length;
  422. pcx_t *pcx;
  423. byte *pack;
  424. pcx = (pcx_t*)malloc (width*height*2+1000);
  425. memset (pcx, 0, sizeof(*pcx));
  426. pcx->manufacturer = 0x0a; // PCX id
  427. pcx->version = 5; // 256 color
  428. pcx->encoding = 1; // uncompressed
  429. pcx->bits_per_pixel = 8; // 256 color
  430. pcx->xmin = 0;
  431. pcx->ymin = 0;
  432. pcx->xmax = LittleShort((short)(width-1));
  433. pcx->ymax = LittleShort((short)(height-1));
  434. pcx->hres = LittleShort((short)width);
  435. pcx->vres = LittleShort((short)height);
  436. pcx->color_planes = 1; // chunky image
  437. pcx->bytes_per_line = LittleShort((short)width);
  438. pcx->palette_type = LittleShort(2); // not a grey scale
  439. // pack the image
  440. pack = &pcx->data;
  441. for (i=0 ; i<height ; i++)
  442. {
  443. for (j=0 ; j<width ; j++)
  444. {
  445. if ( (*data & 0xc0) != 0xc0)
  446. *pack++ = *data++;
  447. else
  448. {
  449. *pack++ = 0xc1;
  450. *pack++ = *data++;
  451. }
  452. }
  453. }
  454. // write the palette
  455. *pack++ = 0x0c; // palette ID byte
  456. for (i=0 ; i<768 ; i++)
  457. *pack++ = *palette++;
  458. // write output file
  459. length = pack - (byte *)pcx;
  460. SaveFile (filename, pcx, length);
  461. free (pcx);
  462. }
  463. /*
  464. ============================================================================
  465. LOAD IMAGE
  466. ============================================================================
  467. */
  468. /*
  469. ==============
  470. Load256Image
  471. Will load either an lbm or pcx, depending on extension.
  472. Any of the return pointers can be NULL if you don't want them.
  473. ==============
  474. */
  475. void Load256Image (char *name, byte **pixels, byte **palette,
  476. int *width, int *height)
  477. {
  478. char ext[128];
  479. bitmap_t bmp;
  480. ExtractFileExtension (name, ext);
  481. if (stricmp(ext, "lbm"))
  482. {
  483. LoadLBM (name, pixels, palette);
  484. if (width)
  485. *width = bmhd.w;
  486. if (height)
  487. *height = bmhd.h;
  488. }
  489. else if (stricmp (ext, "pcx"))
  490. {
  491. LoadPCX (name, pixels, palette, width, height);
  492. }
  493. else if (stricmp (ext, "bmp"))
  494. {
  495. LoadBMP (name, &bmp);
  496. if (bmp.palette)
  497. {
  498. *palette = (unsigned char*)malloc (768);
  499. memcpy (*palette, bmp.palette, 768);
  500. }
  501. FreeBMP (&bmp);
  502. }
  503. else
  504. Error ("%s doesn't have a known image extension", name);
  505. }
  506. /*
  507. ==============
  508. Save256Image
  509. Will save either an lbm or pcx, depending on extension.
  510. ==============
  511. */
  512. void Save256Image (char *name, byte *pixels, byte *palette,
  513. int width, int height)
  514. {
  515. char ext[128];
  516. ExtractFileExtension (name, ext);
  517. if (!strcmp (ext, "lbm"))
  518. {
  519. WriteLBMfile (name, pixels, width, height, palette);
  520. }
  521. else if (!stricmp (ext, "pcx"))
  522. {
  523. WritePCXfile (name, pixels, width, height, palette);
  524. }
  525. else
  526. Error ("%s doesn't have a known image extension", name);
  527. }
  528. /*
  529. ============================================================================
  530. TARGA IMAGE
  531. ============================================================================
  532. */
  533. typedef struct _TargaHeader {
  534. unsigned char id_length, colormap_type, image_type;
  535. unsigned short colormap_index, colormap_length;
  536. unsigned char colormap_size;
  537. unsigned short x_origin, y_origin, width, height;
  538. unsigned char pixel_size, attributes;
  539. } TargaHeader;
  540. int fgetLittleShort (FILE *f)
  541. {
  542. byte b1, b2;
  543. b1 = fgetc(f);
  544. b2 = fgetc(f);
  545. return (short)(b1 + b2*256);
  546. }
  547. int getLittleShort (byte*& p)
  548. {
  549. byte b1, b2;
  550. b1 = *p++;
  551. b2 = *p++;
  552. return (short)(b1 + b2*256);
  553. }
  554. int getLittleLong (byte*& p)
  555. {
  556. byte b1, b2, b3, b4;
  557. b1 = *p++;
  558. b2 = *p++;
  559. b3 = *p++;
  560. b4 = *p++;
  561. return b1 + (b2<<8) + (b3<<16) + (b4<<24);
  562. }
  563. char getc(byte*& p)
  564. {
  565. return *p++;
  566. }
  567. /*
  568. =========================================================
  569. BMP LOADING
  570. =========================================================
  571. */
  572. typedef struct
  573. {
  574. char id[2];
  575. unsigned long fileSize;
  576. unsigned long reserved0;
  577. unsigned long bitmapDataOffset;
  578. unsigned long bitmapHeaderSize;
  579. unsigned long width;
  580. unsigned long height;
  581. unsigned short planes;
  582. unsigned short bitsPerPixel;
  583. unsigned long compression;
  584. unsigned long bitmapDataSize;
  585. unsigned long hRes;
  586. unsigned long vRes;
  587. unsigned long colors;
  588. unsigned long importantColors;
  589. unsigned char palette[256][4];
  590. } BMPHeader_t;
  591. static void LoadBMP( const char *name, byte **pic, int *width, int *height )
  592. {
  593. int columns, rows, numPixels;
  594. byte *pixbuf;
  595. int row, column;
  596. byte *buf_p;
  597. byte *buffer;
  598. unsigned int length;
  599. BMPHeader_t bmpHeader;
  600. byte *bmpRGBA;
  601. *pic = NULL;
  602. //
  603. // load the file
  604. //
  605. length = LoadFile( ( char * ) name, (void **)&buffer);
  606. if (length == -1)
  607. {
  608. length = PakLoadAnyFile( (char*)name, (void**)&buffer);
  609. if (length == -1)
  610. {
  611. return;
  612. }
  613. }
  614. buf_p = buffer;
  615. bmpHeader.id[0] = *buf_p++;
  616. bmpHeader.id[1] = *buf_p++;
  617. bmpHeader.fileSize = LittleLong( * ( long * ) buf_p );
  618. buf_p += 4;
  619. bmpHeader.reserved0 = LittleLong( * ( long * ) buf_p );
  620. buf_p += 4;
  621. bmpHeader.bitmapDataOffset = LittleLong( * ( long * ) buf_p );
  622. buf_p += 4;
  623. bmpHeader.bitmapHeaderSize = LittleLong( * ( long * ) buf_p );
  624. buf_p += 4;
  625. bmpHeader.width = LittleLong( * ( long * ) buf_p );
  626. buf_p += 4;
  627. bmpHeader.height = LittleLong( * ( long * ) buf_p );
  628. buf_p += 4;
  629. bmpHeader.planes = LittleShort( * ( short * ) buf_p );
  630. buf_p += 2;
  631. bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p );
  632. buf_p += 2;
  633. bmpHeader.compression = LittleLong( * ( long * ) buf_p );
  634. buf_p += 4;
  635. bmpHeader.bitmapDataSize = LittleLong( * ( long * ) buf_p );
  636. buf_p += 4;
  637. bmpHeader.hRes = LittleLong( * ( long * ) buf_p );
  638. buf_p += 4;
  639. bmpHeader.vRes = LittleLong( * ( long * ) buf_p );
  640. buf_p += 4;
  641. bmpHeader.colors = LittleLong( * ( long * ) buf_p );
  642. buf_p += 4;
  643. bmpHeader.importantColors = LittleLong( * ( long * ) buf_p );
  644. buf_p += 4;
  645. memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) );
  646. if ( bmpHeader.bitsPerPixel == 8 )
  647. buf_p += 1024;
  648. if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' )
  649. {
  650. Sys_Printf("LoadBMP: only Windows-style BMP files supported (%s)\n", name );
  651. }
  652. if ( bmpHeader.fileSize != length )
  653. {
  654. Sys_Printf("LoadBMP: header size does not match file size (%d vs. %d) (%s)\n", bmpHeader.fileSize, length, name );
  655. }
  656. if ( bmpHeader.compression != 0 )
  657. {
  658. Sys_Printf("LoadBMP: only uncompressed BMP files supported (%s)\n", name );
  659. }
  660. if ( bmpHeader.bitsPerPixel < 8 )
  661. {
  662. Sys_Printf("LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name );
  663. }
  664. columns = bmpHeader.width;
  665. rows = bmpHeader.height;
  666. if ( rows < 0 )
  667. rows = -rows;
  668. numPixels = columns * rows;
  669. if ( width )
  670. *width = columns;
  671. if ( height )
  672. *height = rows;
  673. bmpRGBA = reinterpret_cast<unsigned char*>(malloc( numPixels * 4 ));
  674. *pic = bmpRGBA;
  675. for ( row = rows-1; row >= 0; row-- )
  676. {
  677. pixbuf = bmpRGBA + row*columns*4;
  678. for ( column = 0; column < columns; column++ )
  679. {
  680. unsigned char red, green, blue, alpha;
  681. int palIndex;
  682. unsigned short shortPixel;
  683. switch ( bmpHeader.bitsPerPixel )
  684. {
  685. case 8:
  686. palIndex = *buf_p++;
  687. *pixbuf++ = bmpHeader.palette[palIndex][2];
  688. *pixbuf++ = bmpHeader.palette[palIndex][1];
  689. *pixbuf++ = bmpHeader.palette[palIndex][0];
  690. *pixbuf++ = 0xff;
  691. break;
  692. case 16:
  693. shortPixel = * ( unsigned short * ) pixbuf;
  694. pixbuf += 2;
  695. *pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7;
  696. *pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2;
  697. *pixbuf++ = ( shortPixel & ( 31 ) ) << 3;
  698. *pixbuf++ = 0xff;
  699. break;
  700. case 24:
  701. blue = *buf_p++;
  702. green = *buf_p++;
  703. red = *buf_p++;
  704. *pixbuf++ = red;
  705. *pixbuf++ = green;
  706. *pixbuf++ = blue;
  707. *pixbuf++ = 255;
  708. break;
  709. case 32:
  710. blue = *buf_p++;
  711. green = *buf_p++;
  712. red = *buf_p++;
  713. alpha = *buf_p++;
  714. *pixbuf++ = red;
  715. *pixbuf++ = green;
  716. *pixbuf++ = blue;
  717. *pixbuf++ = alpha;
  718. break;
  719. default:
  720. Sys_Printf("LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name );
  721. break;
  722. }
  723. }
  724. }
  725. free( buffer );
  726. }
  727. /*
  728. =================================================================
  729. PCX LOADING
  730. =================================================================
  731. */
  732. /*
  733. ==============
  734. LoadPCX
  735. ==============
  736. */
  737. static void LoadPCX ( const char *filename, byte **pic, byte **palette, int *width, int *height)
  738. {
  739. byte *raw;
  740. pcx_t *pcx;
  741. int x, y;
  742. int len;
  743. int dataByte, runLength;
  744. byte *out, *pix;
  745. int xmax, ymax;
  746. *pic = NULL;
  747. *palette = NULL;
  748. //
  749. // load the file
  750. //
  751. len = LoadFile( ( char * ) filename, (void **)&raw);
  752. if (len == -1)
  753. {
  754. len = PakLoadAnyFile( (char*)filename, (void**)&raw);
  755. if (len == -1)
  756. {
  757. return;
  758. }
  759. }
  760. //
  761. // parse the PCX file
  762. //
  763. pcx = (pcx_t *)raw;
  764. raw = &pcx->data;
  765. xmax = LittleShort(pcx->xmax);
  766. ymax = LittleShort(pcx->ymax);
  767. if (pcx->manufacturer != 0x0a
  768. || pcx->version != 5
  769. || pcx->encoding != 1
  770. || pcx->bits_per_pixel != 8
  771. || xmax >= 1024
  772. || ymax >= 1024)
  773. {
  774. Sys_Printf ("Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax);
  775. return;
  776. }
  777. out = reinterpret_cast<unsigned char*>(malloc ( (ymax+1) * (xmax+1) ));
  778. *pic = out;
  779. pix = out;
  780. if (palette)
  781. {
  782. *palette = reinterpret_cast<unsigned char*>(malloc(768));
  783. memcpy (*palette, (byte *)pcx + len - 768, 768);
  784. }
  785. if (width)
  786. *width = xmax+1;
  787. if (height)
  788. *height = ymax+1;
  789. // FIXME: use bytes_per_line here?
  790. for (y=0 ; y<=ymax ; y++, pix += xmax+1)
  791. {
  792. for (x=0 ; x<=xmax ; )
  793. {
  794. dataByte = *raw++;
  795. if((dataByte & 0xC0) == 0xC0)
  796. {
  797. runLength = dataByte & 0x3F;
  798. dataByte = *raw++;
  799. }
  800. else
  801. runLength = 1;
  802. while(runLength-- > 0)
  803. pix[x++] = dataByte;
  804. }
  805. }
  806. if ( raw - (byte *)pcx > len)
  807. {
  808. Sys_Printf ("PCX file %s was malformed", filename);
  809. free (*pic);
  810. *pic = NULL;
  811. }
  812. free(pcx);
  813. }
  814. /*
  815. ==============
  816. LoadPCX32
  817. ==============
  818. */
  819. static void LoadPCX32 ( const char *filename, byte **pic, int *width, int *height) {
  820. byte *palette;
  821. byte *pic8;
  822. int i, c, p;
  823. byte *pic32;
  824. LoadPCX (filename, &pic8, &palette, width, height);
  825. if (!pic8) {
  826. *pic = NULL;
  827. return;
  828. }
  829. c = (*width) * (*height);
  830. pic32 = *pic = reinterpret_cast<unsigned char*>(malloc(4 * c ));
  831. for (i = 0 ; i < c ; i++) {
  832. p = pic8[i];
  833. pic32[0] = palette[p*3];
  834. pic32[1] = palette[p*3 + 1];
  835. pic32[2] = palette[p*3 + 2];
  836. pic32[3] = 255;
  837. pic32 += 4;
  838. }
  839. free (pic8);
  840. free (palette);
  841. }
  842. /*
  843. =========================================================
  844. TARGA LOADING
  845. =========================================================
  846. */
  847. /*
  848. =============
  849. LoadTGA
  850. =============
  851. */
  852. void LoadTGA ( const char *name, byte **pic, int *width, int *height)
  853. {
  854. int columns, rows, numPixels;
  855. byte *pixbuf;
  856. int row, column;
  857. byte *buf_p;
  858. byte *buffer;
  859. TargaHeader targa_header;
  860. byte *targa_rgba;
  861. *pic = NULL;
  862. //
  863. // load the file
  864. //
  865. int nLen = LoadFile ( ( char * ) name, (void **)&buffer);
  866. if (nLen == -1)
  867. {
  868. nLen = PakLoadAnyFile((char*)name, (void**)&buffer);
  869. if (nLen == -1)
  870. {
  871. return;
  872. }
  873. }
  874. buf_p = buffer;
  875. targa_header.id_length = *buf_p++;
  876. targa_header.colormap_type = *buf_p++;
  877. targa_header.image_type = *buf_p++;
  878. targa_header.colormap_index = LittleShort ( *(short *)buf_p );
  879. buf_p += 2;
  880. targa_header.colormap_length = LittleShort ( *(short *)buf_p );
  881. buf_p += 2;
  882. targa_header.colormap_size = *buf_p++;
  883. targa_header.x_origin = LittleShort ( *(short *)buf_p );
  884. buf_p += 2;
  885. targa_header.y_origin = LittleShort ( *(short *)buf_p );
  886. buf_p += 2;
  887. targa_header.width = LittleShort ( *(short *)buf_p );
  888. buf_p += 2;
  889. targa_header.height = LittleShort ( *(short *)buf_p );
  890. buf_p += 2;
  891. targa_header.pixel_size = *buf_p++;
  892. targa_header.attributes = *buf_p++;
  893. //++timo debug
  894. if (targa_header.pixel_size == 32)
  895. Sys_Printf("%s is 32bit\n", name);
  896. bool bAlphaOK = false;
  897. if (targa_header.image_type!=2
  898. && targa_header.image_type!=10
  899. && targa_header.image_type != 3 )
  900. {
  901. Sys_Printf("LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n");
  902. }
  903. if ( targa_header.colormap_type != 0 )
  904. {
  905. Sys_Printf("LoadTGA: colormaps not supported\n" );
  906. }
  907. if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
  908. {
  909. Sys_Printf("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  910. }
  911. columns = targa_header.width;
  912. rows = targa_header.height;
  913. numPixels = columns * rows;
  914. if (width)
  915. *width = columns;
  916. if (height)
  917. *height = rows;
  918. targa_rgba = reinterpret_cast<unsigned char*>(malloc (numPixels*4));
  919. *pic = targa_rgba;
  920. if (targa_header.id_length != 0)
  921. buf_p += targa_header.id_length; // skip TARGA image comment
  922. if ( targa_header.image_type==2 || targa_header.image_type == 3 )
  923. {
  924. // Uncompressed RGB or gray scale image
  925. for(row=rows-1; row>=0; row--)
  926. {
  927. pixbuf = targa_rgba + row*columns*4;
  928. for(column=0; column<columns; column++)
  929. {
  930. unsigned char red,green,blue,alphabyte;
  931. switch (targa_header.pixel_size)
  932. {
  933. case 8:
  934. blue = *buf_p++;
  935. green = blue;
  936. red = blue;
  937. *pixbuf++ = red;
  938. *pixbuf++ = green;
  939. *pixbuf++ = blue;
  940. *pixbuf++ = 255;
  941. break;
  942. case 24:
  943. blue = *buf_p++;
  944. green = *buf_p++;
  945. red = *buf_p++;
  946. *pixbuf++ = red;
  947. *pixbuf++ = green;
  948. *pixbuf++ = blue;
  949. *pixbuf++ = 255;
  950. break;
  951. case 32:
  952. blue = *buf_p++;
  953. green = *buf_p++;
  954. red = *buf_p++;
  955. alphabyte = *buf_p++;
  956. //++timo debug: detect if the whole alpha channel is 0
  957. if (alphabyte != 0)
  958. bAlphaOK = true;
  959. *pixbuf++ = red;
  960. *pixbuf++ = green;
  961. *pixbuf++ = blue;
  962. *pixbuf++ = alphabyte;
  963. break;
  964. default:
  965. Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  966. break;
  967. }
  968. }
  969. }
  970. //++timo debug
  971. if (bAlphaOK)
  972. Sys_Printf("alpha channel OK");
  973. else
  974. Sys_Printf("empty alpha channel!");
  975. }
  976. else if (targa_header.image_type==10) { // Runlength encoded RGB images
  977. //++timo debug
  978. Sys_Printf("runlength encode RGB image");
  979. unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  980. red = 0;
  981. green = 0;
  982. blue = 0;
  983. alphabyte = 0xff;
  984. for(row=rows-1; row>=0; row--) {
  985. pixbuf = targa_rgba + row*columns*4;
  986. for(column=0; column<columns; ) {
  987. packetHeader= *buf_p++;
  988. packetSize = 1 + (packetHeader & 0x7f);
  989. if (packetHeader & 0x80) { // run-length packet
  990. switch (targa_header.pixel_size) {
  991. case 24:
  992. blue = *buf_p++;
  993. green = *buf_p++;
  994. red = *buf_p++;
  995. alphabyte = 255;
  996. break;
  997. case 32:
  998. blue = *buf_p++;
  999. green = *buf_p++;
  1000. red = *buf_p++;
  1001. alphabyte = *buf_p++;
  1002. break;
  1003. default:
  1004. Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  1005. break;
  1006. }
  1007. for(j=0;j<packetSize;j++) {
  1008. *pixbuf++=red;
  1009. *pixbuf++=green;
  1010. *pixbuf++=blue;
  1011. *pixbuf++=alphabyte;
  1012. column++;
  1013. if (column==columns) { // run spans across rows
  1014. column=0;
  1015. if (row>0)
  1016. row--;
  1017. else
  1018. goto breakOut;
  1019. pixbuf = targa_rgba + row*columns*4;
  1020. }
  1021. }
  1022. }
  1023. else { // non run-length packet
  1024. for(j=0;j<packetSize;j++) {
  1025. switch (targa_header.pixel_size) {
  1026. case 24:
  1027. blue = *buf_p++;
  1028. green = *buf_p++;
  1029. red = *buf_p++;
  1030. *pixbuf++ = red;
  1031. *pixbuf++ = green;
  1032. *pixbuf++ = blue;
  1033. *pixbuf++ = 255;
  1034. break;
  1035. case 32:
  1036. blue = *buf_p++;
  1037. green = *buf_p++;
  1038. red = *buf_p++;
  1039. alphabyte = *buf_p++;
  1040. *pixbuf++ = red;
  1041. *pixbuf++ = green;
  1042. *pixbuf++ = blue;
  1043. *pixbuf++ = alphabyte;
  1044. break;
  1045. default:
  1046. Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  1047. break;
  1048. }
  1049. column++;
  1050. if (column==columns) { // pixel packet run spans across rows
  1051. column=0;
  1052. if (row>0)
  1053. row--;
  1054. else
  1055. goto breakOut;
  1056. pixbuf = targa_rgba + row*columns*4;
  1057. }
  1058. }
  1059. }
  1060. }
  1061. breakOut:;
  1062. }
  1063. }
  1064. free(buffer);
  1065. }
  1066. void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height )
  1067. {
  1068. byte *fbuffer = NULL;
  1069. int nLen = LoadFile( ( char * ) filename, (void **)&fbuffer);
  1070. if (nLen == -1)
  1071. {
  1072. nLen = PakLoadAnyFile((char*)filename, (void**)&fbuffer);
  1073. if (nLen == -1)
  1074. {
  1075. return;
  1076. }
  1077. }
  1078. LoadJPGBuff(fbuffer, pic, width, height);
  1079. free(fbuffer);
  1080. }
  1081. //===================================================================
  1082. /*
  1083. =================
  1084. LoadImage
  1085. Loads any of the supported image types into a cannonical
  1086. 32 bit format.
  1087. =================
  1088. */
  1089. void LoadImage( const char *name, byte **pic, int *width, int *height )
  1090. {
  1091. int len;
  1092. *pic = NULL;
  1093. *width = 0;
  1094. *height = 0;
  1095. len = strlen(name);
  1096. if (len<5)
  1097. {
  1098. return;
  1099. }
  1100. if ( !stricmp( name+len-4, ".tga" ) )
  1101. {
  1102. LoadTGA( name, pic, width, height );
  1103. }
  1104. else if ( !stricmp(name+len-4, ".pcx") )
  1105. {
  1106. LoadPCX32( name, pic, width, height );
  1107. }
  1108. else if ( !stricmp( name+len-4, ".bmp" ) )
  1109. {
  1110. LoadBMP( name, pic, width, height );
  1111. }
  1112. else if ( !stricmp( name+len-4, ".jpg" ) )
  1113. {
  1114. LoadJPG( name, pic, width, height );
  1115. }
  1116. }