imagelib.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165
  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. // imagelib.c
  19. #include "cmdlib.h"
  20. #include "imagelib.h"
  21. int fgetLittleShort (FILE *f)
  22. {
  23. byte b1, b2;
  24. b1 = fgetc(f);
  25. b2 = fgetc(f);
  26. return (short)(b1 + b2*256);
  27. }
  28. int fgetLittleLong (FILE *f)
  29. {
  30. byte b1, b2, b3, b4;
  31. b1 = fgetc(f);
  32. b2 = fgetc(f);
  33. b3 = fgetc(f);
  34. b4 = fgetc(f);
  35. return b1 + (b2<<8) + (b3<<16) + (b4<<24);
  36. }
  37. /*
  38. ============================================================================
  39. LBM STUFF
  40. ============================================================================
  41. */
  42. typedef unsigned char UBYTE;
  43. //conflicts with windows typedef short WORD;
  44. typedef unsigned short UWORD;
  45. typedef long LONG;
  46. typedef enum
  47. {
  48. ms_none,
  49. ms_mask,
  50. ms_transcolor,
  51. ms_lasso
  52. } mask_t;
  53. typedef enum
  54. {
  55. cm_none,
  56. cm_rle1
  57. } compress_t;
  58. typedef struct
  59. {
  60. UWORD w,h;
  61. short x,y;
  62. UBYTE nPlanes;
  63. UBYTE masking;
  64. UBYTE compression;
  65. UBYTE pad1;
  66. UWORD transparentColor;
  67. UBYTE xAspect,yAspect;
  68. short pageWidth,pageHeight;
  69. } bmhd_t;
  70. extern bmhd_t bmhd; // will be in native byte order
  71. #define FORMID ('F'+('O'<<8)+((int)'R'<<16)+((int)'M'<<24))
  72. #define ILBMID ('I'+('L'<<8)+((int)'B'<<16)+((int)'M'<<24))
  73. #define PBMID ('P'+('B'<<8)+((int)'M'<<16)+((int)' '<<24))
  74. #define BMHDID ('B'+('M'<<8)+((int)'H'<<16)+((int)'D'<<24))
  75. #define BODYID ('B'+('O'<<8)+((int)'D'<<16)+((int)'Y'<<24))
  76. #define CMAPID ('C'+('M'<<8)+((int)'A'<<16)+((int)'P'<<24))
  77. bmhd_t bmhd;
  78. int Align (int l)
  79. {
  80. if (l&1)
  81. return l+1;
  82. return l;
  83. }
  84. /*
  85. ================
  86. LBMRLEdecompress
  87. Source must be evenly aligned!
  88. ================
  89. */
  90. byte *LBMRLEDecompress (byte *source,byte *unpacked, int bpwidth)
  91. {
  92. int count;
  93. byte b,rept;
  94. count = 0;
  95. do
  96. {
  97. rept = *source++;
  98. if (rept > 0x80)
  99. {
  100. rept = (rept^0xff)+2;
  101. b = *source++;
  102. memset(unpacked,b,rept);
  103. unpacked += rept;
  104. }
  105. else if (rept < 0x80)
  106. {
  107. rept++;
  108. memcpy(unpacked,source,rept);
  109. unpacked += rept;
  110. source += rept;
  111. }
  112. else
  113. rept = 0; // rept of 0x80 is NOP
  114. count += rept;
  115. } while (count<bpwidth);
  116. if (count>bpwidth)
  117. Error ("Decompression exceeded width!\n");
  118. return source;
  119. }
  120. /*
  121. =================
  122. LoadLBM
  123. =================
  124. */
  125. void LoadLBM (const char *filename, byte **picture, byte **palette)
  126. {
  127. byte *LBMbuffer, *picbuffer, *cmapbuffer;
  128. int y;
  129. byte *LBM_P, *LBMEND_P;
  130. byte *pic_p;
  131. byte *body_p;
  132. int formtype,formlength;
  133. int chunktype,chunklength;
  134. // qiet compiler warnings
  135. picbuffer = NULL;
  136. cmapbuffer = NULL;
  137. //
  138. // load the LBM
  139. //
  140. LoadFile (filename, (void **)&LBMbuffer);
  141. //
  142. // parse the LBM header
  143. //
  144. LBM_P = LBMbuffer;
  145. if ( *(int *)LBMbuffer != LittleLong(FORMID) )
  146. Error ("No FORM ID at start of file!\n");
  147. LBM_P += 4;
  148. formlength = BigLong( *(int *)LBM_P );
  149. LBM_P += 4;
  150. LBMEND_P = LBM_P + Align(formlength);
  151. formtype = LittleLong(*(int *)LBM_P);
  152. if (formtype != ILBMID && formtype != PBMID)
  153. Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff
  154. ,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff);
  155. LBM_P += 4;
  156. //
  157. // parse chunks
  158. //
  159. while (LBM_P < LBMEND_P)
  160. {
  161. chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24);
  162. LBM_P += 4;
  163. chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24);
  164. LBM_P += 4;
  165. switch ( chunktype )
  166. {
  167. case BMHDID:
  168. memcpy (&bmhd,LBM_P,sizeof(bmhd));
  169. bmhd.w = BigShort(bmhd.w);
  170. bmhd.h = BigShort(bmhd.h);
  171. bmhd.x = BigShort(bmhd.x);
  172. bmhd.y = BigShort(bmhd.y);
  173. bmhd.pageWidth = BigShort(bmhd.pageWidth);
  174. bmhd.pageHeight = BigShort(bmhd.pageHeight);
  175. break;
  176. case CMAPID:
  177. cmapbuffer = malloc (768);
  178. memset (cmapbuffer, 0, 768);
  179. memcpy (cmapbuffer, LBM_P, chunklength);
  180. break;
  181. case BODYID:
  182. body_p = LBM_P;
  183. pic_p = picbuffer = malloc (bmhd.w*bmhd.h);
  184. if (formtype == PBMID)
  185. {
  186. //
  187. // unpack PBM
  188. //
  189. for (y=0 ; y<bmhd.h ; y++, pic_p += bmhd.w)
  190. {
  191. if (bmhd.compression == cm_rle1)
  192. body_p = LBMRLEDecompress ((byte *)body_p
  193. , pic_p , bmhd.w);
  194. else if (bmhd.compression == cm_none)
  195. {
  196. memcpy (pic_p,body_p,bmhd.w);
  197. body_p += Align(bmhd.w);
  198. }
  199. }
  200. }
  201. else
  202. {
  203. //
  204. // unpack ILBM
  205. //
  206. Error ("%s is an interlaced LBM, not packed", filename);
  207. }
  208. break;
  209. }
  210. LBM_P += Align(chunklength);
  211. }
  212. free (LBMbuffer);
  213. *picture = picbuffer;
  214. if (palette)
  215. *palette = cmapbuffer;
  216. }
  217. /*
  218. ============================================================================
  219. WRITE LBM
  220. ============================================================================
  221. */
  222. /*
  223. ==============
  224. WriteLBMfile
  225. ==============
  226. */
  227. void WriteLBMfile (const char *filename, byte *data,
  228. int width, int height, byte *palette)
  229. {
  230. byte *lbm, *lbmptr;
  231. int *formlength, *bmhdlength, *cmaplength, *bodylength;
  232. int length;
  233. bmhd_t basebmhd;
  234. lbm = lbmptr = malloc (width*height+1000);
  235. //
  236. // start FORM
  237. //
  238. *lbmptr++ = 'F';
  239. *lbmptr++ = 'O';
  240. *lbmptr++ = 'R';
  241. *lbmptr++ = 'M';
  242. formlength = (int*)lbmptr;
  243. lbmptr+=4; // leave space for length
  244. *lbmptr++ = 'P';
  245. *lbmptr++ = 'B';
  246. *lbmptr++ = 'M';
  247. *lbmptr++ = ' ';
  248. //
  249. // write BMHD
  250. //
  251. *lbmptr++ = 'B';
  252. *lbmptr++ = 'M';
  253. *lbmptr++ = 'H';
  254. *lbmptr++ = 'D';
  255. bmhdlength = (int *)lbmptr;
  256. lbmptr+=4; // leave space for length
  257. memset (&basebmhd,0,sizeof(basebmhd));
  258. basebmhd.w = BigShort((short)width);
  259. basebmhd.h = BigShort((short)height);
  260. basebmhd.nPlanes = BigShort(8);
  261. basebmhd.xAspect = BigShort(5);
  262. basebmhd.yAspect = BigShort(6);
  263. basebmhd.pageWidth = BigShort((short)width);
  264. basebmhd.pageHeight = BigShort((short)height);
  265. memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
  266. lbmptr += sizeof(basebmhd);
  267. length = lbmptr-(byte *)bmhdlength-4;
  268. *bmhdlength = BigLong(length);
  269. if (length&1)
  270. *lbmptr++ = 0; // pad chunk to even offset
  271. //
  272. // write CMAP
  273. //
  274. *lbmptr++ = 'C';
  275. *lbmptr++ = 'M';
  276. *lbmptr++ = 'A';
  277. *lbmptr++ = 'P';
  278. cmaplength = (int *)lbmptr;
  279. lbmptr+=4; // leave space for length
  280. memcpy (lbmptr,palette,768);
  281. lbmptr += 768;
  282. length = lbmptr-(byte *)cmaplength-4;
  283. *cmaplength = BigLong(length);
  284. if (length&1)
  285. *lbmptr++ = 0; // pad chunk to even offset
  286. //
  287. // write BODY
  288. //
  289. *lbmptr++ = 'B';
  290. *lbmptr++ = 'O';
  291. *lbmptr++ = 'D';
  292. *lbmptr++ = 'Y';
  293. bodylength = (int *)lbmptr;
  294. lbmptr+=4; // leave space for length
  295. memcpy (lbmptr,data,width*height);
  296. lbmptr += width*height;
  297. length = lbmptr-(byte *)bodylength-4;
  298. *bodylength = BigLong(length);
  299. if (length&1)
  300. *lbmptr++ = 0; // pad chunk to even offset
  301. //
  302. // done
  303. //
  304. length = lbmptr-(byte *)formlength-4;
  305. *formlength = BigLong(length);
  306. if (length&1)
  307. *lbmptr++ = 0; // pad chunk to even offset
  308. //
  309. // write output file
  310. //
  311. SaveFile (filename, lbm, lbmptr-lbm);
  312. free (lbm);
  313. }
  314. /*
  315. ============================================================================
  316. LOAD PCX
  317. ============================================================================
  318. */
  319. typedef struct
  320. {
  321. char manufacturer;
  322. char version;
  323. char encoding;
  324. char bits_per_pixel;
  325. unsigned short xmin,ymin,xmax,ymax;
  326. unsigned short hres,vres;
  327. unsigned char palette[48];
  328. char reserved;
  329. char color_planes;
  330. unsigned short bytes_per_line;
  331. unsigned short palette_type;
  332. char filler[58];
  333. unsigned char data; // unbounded
  334. } pcx_t;
  335. /*
  336. ==============
  337. LoadPCX
  338. ==============
  339. */
  340. void LoadPCX (const char *filename, byte **pic, byte **palette, int *width, int *height)
  341. {
  342. byte *raw;
  343. pcx_t *pcx;
  344. int x, y;
  345. int len;
  346. int dataByte, runLength;
  347. byte *out, *pix;
  348. //
  349. // load the file
  350. //
  351. len = LoadFile (filename, (void **)&raw);
  352. //
  353. // parse the PCX file
  354. //
  355. pcx = (pcx_t *)raw;
  356. raw = &pcx->data;
  357. pcx->xmin = LittleShort(pcx->xmin);
  358. pcx->ymin = LittleShort(pcx->ymin);
  359. pcx->xmax = LittleShort(pcx->xmax);
  360. pcx->ymax = LittleShort(pcx->ymax);
  361. pcx->hres = LittleShort(pcx->hres);
  362. pcx->vres = LittleShort(pcx->vres);
  363. pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
  364. pcx->palette_type = LittleShort(pcx->palette_type);
  365. if (pcx->manufacturer != 0x0a
  366. || pcx->version != 5
  367. || pcx->encoding != 1
  368. || pcx->bits_per_pixel != 8
  369. || pcx->xmax >= 640
  370. || pcx->ymax >= 480)
  371. Error ("Bad pcx file %s", filename);
  372. if (palette)
  373. {
  374. *palette = malloc(768);
  375. memcpy (*palette, (byte *)pcx + len - 768, 768);
  376. }
  377. if (width)
  378. *width = pcx->xmax+1;
  379. if (height)
  380. *height = pcx->ymax+1;
  381. if (!pic)
  382. return;
  383. out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
  384. if (!out)
  385. Error ("Skin_Cache: couldn't allocate");
  386. *pic = out;
  387. pix = out;
  388. for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
  389. {
  390. for (x=0 ; x<=pcx->xmax ; )
  391. {
  392. dataByte = *raw++;
  393. if((dataByte & 0xC0) == 0xC0)
  394. {
  395. runLength = dataByte & 0x3F;
  396. dataByte = *raw++;
  397. }
  398. else
  399. runLength = 1;
  400. // FIXME: this shouldn't happen, but it does. Are we decoding the file wrong?
  401. // Truncate runLength so we don't overrun the end of the buffer
  402. if ( ( y == pcx->ymax ) && ( x + runLength > pcx->xmax + 1 ) ) {
  403. runLength = pcx->xmax - x + 1;
  404. }
  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 (const 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 = 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(1); // 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 BMP
  466. ============================================================================
  467. */
  468. /*
  469. // we can't just use these structures, because
  470. // compiler structure alignment will not be portable
  471. // on this unaligned stuff
  472. typedef struct tagBITMAPFILEHEADER { // bmfh
  473. WORD bfType; // BM
  474. DWORD bfSize;
  475. WORD bfReserved1;
  476. WORD bfReserved2;
  477. DWORD bfOffBits;
  478. } BITMAPFILEHEADER;
  479. typedef struct tagBITMAPINFOHEADER{ // bmih
  480. DWORD biSize;
  481. LONG biWidth;
  482. LONG biHeight;
  483. WORD biPlanes;
  484. WORD biBitCount
  485. DWORD biCompression;
  486. DWORD biSizeImage;
  487. LONG biXPelsPerMeter;
  488. LONG biYPelsPerMeter;
  489. DWORD biClrUsed;
  490. DWORD biClrImportant;
  491. } BITMAPINFOHEADER;
  492. typedef struct tagBITMAPINFO { // bmi
  493. BITMAPINFOHEADER bmiHeader;
  494. RGBQUAD bmiColors[1];
  495. } BITMAPINFO;
  496. typedef struct tagBITMAPCOREHEADER { // bmch
  497. DWORD bcSize;
  498. WORD bcWidth;
  499. WORD bcHeight;
  500. WORD bcPlanes;
  501. WORD bcBitCount;
  502. } BITMAPCOREHEADER;
  503. typedef struct _BITMAPCOREINFO { // bmci
  504. BITMAPCOREHEADER bmciHeader;
  505. RGBTRIPLE bmciColors[1];
  506. } BITMAPCOREINFO;
  507. */
  508. /*
  509. ==============
  510. LoadBMP
  511. ==============
  512. */
  513. void LoadBMP (const char *filename, byte **pic, byte **palette, int *width, int *height)
  514. {
  515. byte *out;
  516. FILE *fin;
  517. int i;
  518. int bfSize;
  519. int bfOffBits;
  520. int structSize;
  521. int bcWidth;
  522. int bcHeight;
  523. int bcPlanes;
  524. int bcBitCount;
  525. byte bcPalette[1024];
  526. qboolean flipped;
  527. fin = fopen (filename, "rb");
  528. if (!fin) {
  529. Error ("Couldn't read %s", filename);
  530. }
  531. i = fgetLittleShort (fin);
  532. if (i != 'B' + ('M'<<8) ) {
  533. Error ("%s is not a bmp file", filename);
  534. }
  535. bfSize = fgetLittleLong (fin);
  536. fgetLittleShort(fin);
  537. fgetLittleShort(fin);
  538. bfOffBits = fgetLittleLong (fin);
  539. // the size will tell us if it is a
  540. // bitmapinfo or a bitmapcore
  541. structSize = fgetLittleLong (fin);
  542. if (structSize == 40) {
  543. // bitmapinfo
  544. bcWidth = fgetLittleLong(fin);
  545. bcHeight= fgetLittleLong(fin);
  546. bcPlanes = fgetLittleShort(fin);
  547. bcBitCount = fgetLittleShort(fin);
  548. fseek (fin, 24, SEEK_CUR);
  549. if (palette) {
  550. fread (bcPalette, 1, 1024, fin);
  551. *palette = malloc(768);
  552. for (i = 0 ; i < 256 ; i++) {
  553. (*palette)[i * 3 + 0] = bcPalette[i * 4 + 2];
  554. (*palette)[i * 3 + 1] = bcPalette[i * 4 + 1];
  555. (*palette)[i * 3 + 2] = bcPalette[i * 4 + 0];
  556. }
  557. }
  558. } else if (structSize == 12) {
  559. // bitmapcore
  560. bcWidth = fgetLittleShort(fin);
  561. bcHeight= fgetLittleShort(fin);
  562. bcPlanes = fgetLittleShort(fin);
  563. bcBitCount = fgetLittleShort(fin);
  564. if (palette) {
  565. fread (bcPalette, 1, 768, fin);
  566. *palette = malloc(768);
  567. for (i = 0 ; i < 256 ; i++) {
  568. (*palette)[i * 3 + 0] = bcPalette[i * 3 + 2];
  569. (*palette)[i * 3 + 1] = bcPalette[i * 3 + 1];
  570. (*palette)[i * 3 + 2] = bcPalette[i * 3 + 0];
  571. }
  572. }
  573. } else {
  574. Error ("%s had strange struct size", filename);
  575. }
  576. if (bcPlanes != 1) {
  577. Error ("%s was not a single plane image", filename);
  578. }
  579. if (bcBitCount != 8) {
  580. Error ("%s was not an 8 bit image", filename);
  581. }
  582. if (bcHeight < 0) {
  583. bcHeight = -bcHeight;
  584. flipped = qtrue;
  585. } else {
  586. flipped = qfalse;
  587. }
  588. if (width)
  589. *width = bcWidth;
  590. if (height)
  591. *height = bcHeight;
  592. if (!pic) {
  593. fclose (fin);
  594. return;
  595. }
  596. out = malloc ( bcWidth * bcHeight );
  597. *pic = out;
  598. fseek (fin, bfOffBits, SEEK_SET);
  599. if (flipped) {
  600. for (i = 0 ; i < bcHeight ; i++) {
  601. fread (out + bcWidth * (bcHeight - 1 - i), 1, bcWidth, fin);
  602. }
  603. } else {
  604. fread (out, 1, bcWidth*bcHeight, fin);
  605. }
  606. fclose (fin);
  607. }
  608. /*
  609. ============================================================================
  610. LOAD IMAGE
  611. ============================================================================
  612. */
  613. /*
  614. ==============
  615. Load256Image
  616. Will load either an lbm or pcx, depending on extension.
  617. Any of the return pointers can be NULL if you don't want them.
  618. ==============
  619. */
  620. void Load256Image (const char *name, byte **pixels, byte **palette,
  621. int *width, int *height)
  622. {
  623. char ext[128];
  624. ExtractFileExtension (name, ext);
  625. if (!Q_stricmp (ext, "lbm"))
  626. {
  627. LoadLBM (name, pixels, palette);
  628. if (width)
  629. *width = bmhd.w;
  630. if (height)
  631. *height = bmhd.h;
  632. }
  633. else if (!Q_stricmp (ext, "pcx"))
  634. {
  635. LoadPCX (name, pixels, palette, width, height);
  636. }
  637. else if (!Q_stricmp (ext, "bmp"))
  638. {
  639. LoadBMP (name, pixels, palette, width, height);
  640. }
  641. else
  642. Error ("%s doesn't have a known image extension", name);
  643. }
  644. /*
  645. ==============
  646. Save256Image
  647. Will save either an lbm or pcx, depending on extension.
  648. ==============
  649. */
  650. void Save256Image (const char *name, byte *pixels, byte *palette,
  651. int width, int height)
  652. {
  653. char ext[128];
  654. ExtractFileExtension (name, ext);
  655. if (!Q_stricmp (ext, "lbm"))
  656. {
  657. WriteLBMfile (name, pixels, width, height, palette);
  658. }
  659. else if (!Q_stricmp (ext, "pcx"))
  660. {
  661. WritePCXfile (name, pixels, width, height, palette);
  662. }
  663. else
  664. Error ("%s doesn't have a known image extension", name);
  665. }
  666. /*
  667. ============================================================================
  668. TARGA IMAGE
  669. ============================================================================
  670. */
  671. typedef struct _TargaHeader {
  672. unsigned char id_length, colormap_type, image_type;
  673. unsigned short colormap_index, colormap_length;
  674. unsigned char colormap_size;
  675. unsigned short x_origin, y_origin, width, height;
  676. unsigned char pixel_size, attributes;
  677. } TargaHeader;
  678. /*
  679. =============
  680. LoadTGABuffer
  681. =============
  682. */
  683. void LoadTGABuffer ( byte *buffer, byte **pic, int *width, int *height)
  684. {
  685. int columns, rows, numPixels;
  686. byte *pixbuf;
  687. int row, column;
  688. byte *buf_p;
  689. TargaHeader targa_header;
  690. byte *targa_rgba;
  691. *pic = NULL;
  692. buf_p = buffer;
  693. targa_header.id_length = *buf_p++;
  694. targa_header.colormap_type = *buf_p++;
  695. targa_header.image_type = *buf_p++;
  696. targa_header.colormap_index = LittleShort ( *(short *)buf_p );
  697. buf_p += 2;
  698. targa_header.colormap_length = LittleShort ( *(short *)buf_p );
  699. buf_p += 2;
  700. targa_header.colormap_size = *buf_p++;
  701. targa_header.x_origin = LittleShort ( *(short *)buf_p );
  702. buf_p += 2;
  703. targa_header.y_origin = LittleShort ( *(short *)buf_p );
  704. buf_p += 2;
  705. targa_header.width = LittleShort ( *(short *)buf_p );
  706. buf_p += 2;
  707. targa_header.height = LittleShort ( *(short *)buf_p );
  708. buf_p += 2;
  709. targa_header.pixel_size = *buf_p++;
  710. targa_header.attributes = *buf_p++;
  711. if (targa_header.image_type!=2
  712. && targa_header.image_type!=10
  713. && targa_header.image_type != 3 )
  714. {
  715. Error("LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n");
  716. }
  717. if ( targa_header.colormap_type != 0 )
  718. {
  719. Error("LoadTGA: colormaps not supported\n" );
  720. }
  721. if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
  722. {
  723. Error("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  724. }
  725. columns = targa_header.width;
  726. rows = targa_header.height;
  727. numPixels = columns * rows;
  728. if (width)
  729. *width = columns;
  730. if (height)
  731. *height = rows;
  732. targa_rgba = malloc (numPixels*4);
  733. *pic = targa_rgba;
  734. if (targa_header.id_length != 0)
  735. buf_p += targa_header.id_length; // skip TARGA image comment
  736. if ( targa_header.image_type==2 || targa_header.image_type == 3 )
  737. {
  738. // Uncompressed RGB or gray scale image
  739. for(row=rows-1; row>=0; row--)
  740. {
  741. pixbuf = targa_rgba + row*columns*4;
  742. for(column=0; column<columns; column++)
  743. {
  744. unsigned char red,green,blue,alphabyte;
  745. switch (targa_header.pixel_size)
  746. {
  747. case 8:
  748. blue = *buf_p++;
  749. green = blue;
  750. red = blue;
  751. *pixbuf++ = red;
  752. *pixbuf++ = green;
  753. *pixbuf++ = blue;
  754. *pixbuf++ = 255;
  755. break;
  756. case 24:
  757. blue = *buf_p++;
  758. green = *buf_p++;
  759. red = *buf_p++;
  760. *pixbuf++ = red;
  761. *pixbuf++ = green;
  762. *pixbuf++ = blue;
  763. *pixbuf++ = 255;
  764. break;
  765. case 32:
  766. blue = *buf_p++;
  767. green = *buf_p++;
  768. red = *buf_p++;
  769. alphabyte = *buf_p++;
  770. *pixbuf++ = red;
  771. *pixbuf++ = green;
  772. *pixbuf++ = blue;
  773. *pixbuf++ = alphabyte;
  774. break;
  775. default:
  776. //Error("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  777. break;
  778. }
  779. }
  780. }
  781. }
  782. else if (targa_header.image_type==10) { // Runlength encoded RGB images
  783. unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  784. red = 0;
  785. green = 0;
  786. blue = 0;
  787. alphabyte = 0xff;
  788. for(row=rows-1; row>=0; row--) {
  789. pixbuf = targa_rgba + row*columns*4;
  790. for(column=0; column<columns; ) {
  791. packetHeader= *buf_p++;
  792. packetSize = 1 + (packetHeader & 0x7f);
  793. if (packetHeader & 0x80) { // run-length packet
  794. switch (targa_header.pixel_size) {
  795. case 24:
  796. blue = *buf_p++;
  797. green = *buf_p++;
  798. red = *buf_p++;
  799. alphabyte = 255;
  800. break;
  801. case 32:
  802. blue = *buf_p++;
  803. green = *buf_p++;
  804. red = *buf_p++;
  805. alphabyte = *buf_p++;
  806. break;
  807. default:
  808. //Error("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  809. break;
  810. }
  811. for(j=0;j<packetSize;j++) {
  812. *pixbuf++=red;
  813. *pixbuf++=green;
  814. *pixbuf++=blue;
  815. *pixbuf++=alphabyte;
  816. column++;
  817. if (column==columns) { // run spans across rows
  818. column=0;
  819. if (row>0)
  820. row--;
  821. else
  822. goto breakOut;
  823. pixbuf = targa_rgba + row*columns*4;
  824. }
  825. }
  826. }
  827. else { // non run-length packet
  828. for(j=0;j<packetSize;j++) {
  829. switch (targa_header.pixel_size) {
  830. case 24:
  831. blue = *buf_p++;
  832. green = *buf_p++;
  833. red = *buf_p++;
  834. *pixbuf++ = red;
  835. *pixbuf++ = green;
  836. *pixbuf++ = blue;
  837. *pixbuf++ = 255;
  838. break;
  839. case 32:
  840. blue = *buf_p++;
  841. green = *buf_p++;
  842. red = *buf_p++;
  843. alphabyte = *buf_p++;
  844. *pixbuf++ = red;
  845. *pixbuf++ = green;
  846. *pixbuf++ = blue;
  847. *pixbuf++ = alphabyte;
  848. break;
  849. default:
  850. //Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
  851. break;
  852. }
  853. column++;
  854. if (column==columns) { // pixel packet run spans across rows
  855. column=0;
  856. if (row>0)
  857. row--;
  858. else
  859. goto breakOut;
  860. pixbuf = targa_rgba + row*columns*4;
  861. }
  862. }
  863. }
  864. }
  865. breakOut:;
  866. }
  867. }
  868. //free(buffer);
  869. }
  870. /*
  871. =============
  872. LoadTGA
  873. =============
  874. */
  875. void LoadTGA (const char *name, byte **pixels, int *width, int *height)
  876. {
  877. byte *buffer;
  878. int nLen;
  879. //
  880. // load the file
  881. //
  882. nLen = LoadFile ( ( char * ) name, (void **)&buffer);
  883. if (nLen == -1)
  884. {
  885. Error ("Couldn't read %s", name);
  886. }
  887. LoadTGABuffer(buffer, pixels, width, height);
  888. }
  889. /*
  890. ================
  891. WriteTGA
  892. ================
  893. */
  894. void WriteTGA (const char *filename, byte *data, int width, int height) {
  895. byte *buffer;
  896. int i;
  897. int c;
  898. FILE *f;
  899. buffer = malloc(width*height*4 + 18);
  900. memset (buffer, 0, 18);
  901. buffer[2] = 2; // uncompressed type
  902. buffer[12] = width&255;
  903. buffer[13] = width>>8;
  904. buffer[14] = height&255;
  905. buffer[15] = height>>8;
  906. buffer[16] = 32; // pixel size
  907. // swap rgb to bgr
  908. c = 18 + width * height * 4;
  909. for (i=18 ; i<c ; i+=4)
  910. {
  911. buffer[i] = data[i-18+2]; // blue
  912. buffer[i+1] = data[i-18+1]; // green
  913. buffer[i+2] = data[i-18+0]; // red
  914. buffer[i+3] = data[i-18+3]; // alpha
  915. }
  916. f = fopen (filename, "wb");
  917. fwrite (buffer, 1, c, f);
  918. fclose (f);
  919. free (buffer);
  920. }
  921. /*
  922. ============================================================================
  923. LOAD32BITIMAGE
  924. ============================================================================
  925. */
  926. /*
  927. ==============
  928. Load32BitImage
  929. Any of the return pointers can be NULL if you don't want them.
  930. ==============
  931. */
  932. void Load32BitImage (const char *name, unsigned **pixels, int *width, int *height)
  933. {
  934. char ext[128];
  935. byte *palette;
  936. byte *pixels8;
  937. byte *pixels32;
  938. int size;
  939. int i;
  940. int v;
  941. ExtractFileExtension (name, ext);
  942. if (!Q_stricmp (ext, "tga")) {
  943. LoadTGA (name, (byte **)pixels, width, height);
  944. } else {
  945. Load256Image (name, &pixels8, &palette, width, height);
  946. if (!pixels) {
  947. return;
  948. }
  949. size = *width * *height;
  950. pixels32 = malloc(size * 4);
  951. *pixels = (unsigned *)pixels32;
  952. for (i = 0 ; i < size ; i++) {
  953. v = pixels8[i];
  954. pixels32[i*4 + 0] = palette[ v * 3 + 0 ];
  955. pixels32[i*4 + 1] = palette[ v * 3 + 1 ];
  956. pixels32[i*4 + 2] = palette[ v * 3 + 2 ];
  957. pixels32[i*4 + 3] = 0xff;
  958. }
  959. }
  960. }