Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

557 lines
13 KiB

  1. #include "toollib.h"
  2. #include "piclib.h"
  3. byte_t* g_tgabuffer;
  4. byte_t* g_tgabuffptr;
  5. /*****************************************************************************
  6. TL_LoadPCX
  7. *****************************************************************************/
  8. void TL_LoadPCX(char* filename, byte_t** pic, byte_t** palette, int* width, int* height)
  9. {
  10. byte_t* raw;
  11. pcx_t* pcx;
  12. int x;
  13. int y;
  14. int len;
  15. int databyte;
  16. int runlength;
  17. byte_t* out;
  18. byte_t* pix;
  19. // load the file
  20. len = TL_LoadFile(filename,(void **)&raw);
  21. // parse the PCX file
  22. pcx = (pcx_t*)raw;
  23. raw = &pcx->data;
  24. pcx->xmin = TL_LittleShort(pcx->xmin);
  25. pcx->ymin = TL_LittleShort(pcx->ymin);
  26. pcx->xmax = TL_LittleShort(pcx->xmax);
  27. pcx->ymax = TL_LittleShort(pcx->ymax);
  28. pcx->hres = TL_LittleShort(pcx->hres);
  29. pcx->vres = TL_LittleShort(pcx->vres);
  30. pcx->bytes_per_line = TL_LittleShort(pcx->bytes_per_line);
  31. pcx->palette_type = TL_LittleShort(pcx->palette_type);
  32. if (pcx->manufacturer != 0x0a ||
  33. pcx->version != 5 ||
  34. pcx->encoding != 1 ||
  35. pcx->bits_per_pixel != 8 ||
  36. pcx->xmax >= 640 ||
  37. pcx->ymax >= 480)
  38. TL_Error("Bad pcx file %s",filename);
  39. if (palette)
  40. {
  41. *palette = (byte_t*)TL_Malloc(768);
  42. memcpy(*palette,(byte_t*)pcx + len - 768,768);
  43. }
  44. if (width)
  45. *width = pcx->xmax+1;
  46. if (height)
  47. *height = pcx->ymax+1;
  48. if (!pic)
  49. return;
  50. out = (byte_t*)TL_Malloc((pcx->ymax+1)*(pcx->xmax+1));
  51. *pic = out;
  52. pix = out;
  53. for (y=0; y<=pcx->ymax; y++, pix += pcx->xmax+1)
  54. {
  55. for (x=0; x<=pcx->xmax; )
  56. {
  57. databyte = *raw++;
  58. if((databyte & 0xC0) == 0xC0)
  59. {
  60. runlength = databyte & 0x3F;
  61. databyte = *raw++;
  62. }
  63. else
  64. runlength = 1;
  65. while (runlength-- > 0)
  66. pix[x++] = databyte;
  67. }
  68. }
  69. if (raw - (byte_t *)pcx > len)
  70. TL_Error("PCX file %s was malformed",filename);
  71. TL_Free(pcx);
  72. }
  73. /*****************************************************************************
  74. TL_SavePCX
  75. *****************************************************************************/
  76. void TL_SavePCX(char* filename, byte_t* data, int width, int height, byte_t* palette)
  77. {
  78. int i;
  79. int j;
  80. int length;
  81. pcx_t* pcx;
  82. byte_t* pack;
  83. pcx = (pcx_t*)TL_Malloc(width*height*2+1000);
  84. pcx->manufacturer = 0x0A; // PCX id
  85. pcx->version = 5; // 256 color
  86. pcx->encoding = 1; // uncompressed
  87. pcx->bits_per_pixel = 8; // 256 color
  88. pcx->xmin = 0;
  89. pcx->ymin = 0;
  90. pcx->xmax = TL_LittleShort((short)(width-1));
  91. pcx->ymax = TL_LittleShort((short)(height-1));
  92. pcx->hres = TL_LittleShort((short)width);
  93. pcx->vres = TL_LittleShort((short)height);
  94. pcx->color_planes = 1; // chunky image
  95. pcx->bytes_per_line = TL_LittleShort((short)width);
  96. pcx->palette_type = TL_LittleShort(2); // not a grey scale
  97. // pack the image
  98. pack = &pcx->data;
  99. for (i=0; i<height; i++)
  100. {
  101. for (j=0; j<width; j++)
  102. {
  103. if ((*data & 0xc0) != 0xC0)
  104. *pack++ = *data++;
  105. else
  106. {
  107. *pack++ = 0xC1;
  108. *pack++ = *data++;
  109. }
  110. }
  111. }
  112. // write the palette
  113. *pack++ = 0x0C;
  114. for (i=0; i<768; i++)
  115. *pack++ = *palette++;
  116. // write output file
  117. length = pack - (byte_t*)pcx;
  118. TL_SaveFile(filename,pcx,length);
  119. TL_Free(pcx);
  120. }
  121. /*****************************************************************************
  122. TGA_GetByte
  123. *****************************************************************************/
  124. byte_t TGA_GetByte(void)
  125. {
  126. return (*g_tgabuffptr++);
  127. }
  128. /*****************************************************************************
  129. TGA_GetShort
  130. *****************************************************************************/
  131. short TGA_GetShort(void)
  132. {
  133. byte_t msb;
  134. byte_t lsb;
  135. lsb = g_tgabuffptr[0];
  136. msb = g_tgabuffptr[1];
  137. g_tgabuffptr += 2;
  138. return ((msb<<8)|lsb);
  139. }
  140. /*****************************************************************************
  141. TL_LoadTGA
  142. *****************************************************************************/
  143. void TL_LoadTGA(char* name, byte_t** pixels, int* width, int* height)
  144. {
  145. int columns;
  146. int rows;
  147. int numPixels;
  148. byte_t* pixbuf;
  149. int row;
  150. int column;
  151. byte_t* targa_rgba;
  152. tga_t targa_header;
  153. byte_t red;
  154. byte_t green;
  155. byte_t blue;
  156. byte_t alphabyte;
  157. byte_t packetHeader;
  158. byte_t packetSize;
  159. byte_t j;
  160. TL_LoadFile(name,(void**)&g_tgabuffer);
  161. g_tgabuffptr = g_tgabuffer;
  162. /* load unaligned tga data */
  163. targa_header.id_length = TGA_GetByte();
  164. targa_header.colormap_type = TGA_GetByte();
  165. targa_header.image_type = TGA_GetByte();
  166. targa_header.colormap_index = TGA_GetShort();
  167. targa_header.colormap_length = TGA_GetShort();
  168. targa_header.colormap_size = TGA_GetByte();
  169. targa_header.x_origin = TGA_GetShort();
  170. targa_header.y_origin = TGA_GetShort();
  171. targa_header.width = TGA_GetShort();
  172. targa_header.height = TGA_GetShort();
  173. targa_header.pixel_size = TGA_GetByte();
  174. targa_header.attributes = TGA_GetByte();
  175. if (targa_header.image_type != 2 && targa_header.image_type != 10)
  176. TL_Error("TL_LoadTGA: %s - Only type 2 and 10 targa RGB images supported",name);
  177. if ((targa_header.colormap_type != 0) || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24))
  178. TL_Error("TL_LoadTGA: %s - Only 32 or 24 bit images supported (no colormaps)",name);
  179. columns = targa_header.width;
  180. rows = targa_header.height;
  181. numPixels = columns * rows;
  182. if (width)
  183. *width = columns;
  184. if (height)
  185. *height = rows;
  186. targa_rgba = (byte_t*)TL_Malloc(numPixels*4);
  187. *pixels = targa_rgba;
  188. if (targa_header.id_length != 0)
  189. {
  190. // skip TARGA image comment
  191. g_tgabuffptr += targa_header.id_length;
  192. }
  193. if (targa_header.image_type==2)
  194. {
  195. // Uncompressed, RGB images
  196. for (row=rows-1; row>=0; row--)
  197. {
  198. pixbuf = targa_rgba + row*columns*4;
  199. for(column=0; column<columns; column++)
  200. {
  201. switch (targa_header.pixel_size)
  202. {
  203. case 24:
  204. blue = TGA_GetByte();
  205. green = TGA_GetByte();
  206. red = TGA_GetByte();
  207. alphabyte = 255;
  208. break;
  209. case 32:
  210. blue = TGA_GetByte();
  211. green = TGA_GetByte();
  212. red = TGA_GetByte();
  213. alphabyte = TGA_GetByte();
  214. break;
  215. }
  216. *pixbuf++ = red;
  217. *pixbuf++ = green;
  218. *pixbuf++ = blue;
  219. *pixbuf++ = alphabyte;
  220. }
  221. }
  222. }
  223. else if (targa_header.image_type==10)
  224. {
  225. // Runlength encoded RGB images
  226. for (row=rows-1; row>=0; row--)
  227. {
  228. pixbuf = targa_rgba + row*columns*4;
  229. for(column=0; column<columns; )
  230. {
  231. packetHeader = TGA_GetByte();
  232. packetSize = 1 + (packetHeader & 0x7f);
  233. if (packetHeader & 0x80)
  234. {
  235. // run-length packet
  236. switch (targa_header.pixel_size)
  237. {
  238. case 24:
  239. blue = TGA_GetByte();
  240. green = TGA_GetByte();
  241. red = TGA_GetByte();
  242. alphabyte = 255;
  243. break;
  244. case 32:
  245. blue = TGA_GetByte();
  246. green = TGA_GetByte();
  247. red = TGA_GetByte();
  248. alphabyte = TGA_GetByte();
  249. break;
  250. }
  251. for(j=0; j<packetSize; j++)
  252. {
  253. *pixbuf++ = red;
  254. *pixbuf++ = green;
  255. *pixbuf++ = blue;
  256. *pixbuf++ = alphabyte;
  257. column++;
  258. if (column==columns)
  259. {
  260. // run spans across rows
  261. column=0;
  262. if (row>0)
  263. row--;
  264. else
  265. goto breakOut;
  266. pixbuf = targa_rgba + row*columns*4;
  267. }
  268. }
  269. }
  270. else
  271. {
  272. // non run-length packet
  273. for(j=0; j<packetSize; j++)
  274. {
  275. switch (targa_header.pixel_size)
  276. {
  277. case 24:
  278. blue = TGA_GetByte();
  279. green = TGA_GetByte();
  280. red = TGA_GetByte();
  281. alphabyte = 255;
  282. break;
  283. case 32:
  284. blue = TGA_GetByte();
  285. green = TGA_GetByte();
  286. red = TGA_GetByte();
  287. alphabyte = TGA_GetByte();
  288. break;
  289. }
  290. *pixbuf++ = red;
  291. *pixbuf++ = green;
  292. *pixbuf++ = blue;
  293. *pixbuf++ = alphabyte;
  294. column++;
  295. if (column == columns)
  296. {
  297. // pixel packet run spans across rows
  298. column=0;
  299. if (row>0)
  300. row--;
  301. else
  302. goto breakOut;
  303. pixbuf = targa_rgba + row*columns*4;
  304. }
  305. }
  306. }
  307. }
  308. breakOut:;
  309. }
  310. }
  311. TL_Free(g_tgabuffer);
  312. }
  313. /*****************************************************************************
  314. TL_SaveTGA
  315. Saves TGA. Supports r/w 16/24/32 bpp.
  316. *****************************************************************************/
  317. void TL_SaveTGA(char* filename, byte_t* pixels, int width, int height, int sbpp, int tbpp)
  318. {
  319. int handle;
  320. tga_t tga;
  321. unsigned short rgba5551;
  322. unsigned long rgba8888;
  323. int r;
  324. int g;
  325. int b;
  326. int x;
  327. int y;
  328. int a;
  329. byte_t* tgabuffer;
  330. byte_t* tgabufferptr;
  331. byte_t* rawbufferptr;
  332. byte_t* tempbuffer;
  333. byte_t* tempbufferptr;
  334. int bytesperpixel;
  335. // all source is upsampled into easy 32 bit rgba8888
  336. // and downsampled into tga buffer
  337. tempbuffer = (byte_t*)TL_Malloc(width*height*4);
  338. if (sbpp == 16)
  339. {
  340. /* source is 16 bit rgba */
  341. rawbufferptr = pixels;
  342. for (y=0; y<height; y++)
  343. {
  344. tempbufferptr = tempbuffer + y*width*4;
  345. for (x=0; x<width; x++)
  346. {
  347. rgba5551 = *(unsigned short*)rawbufferptr;
  348. r = (rgba5551 & 0xF800)>>11;
  349. g = (rgba5551 & 0x07C0)>>6;
  350. b = (rgba5551 & 0x003E)>>1;
  351. a = (rgba5551 & 0x01);
  352. tempbufferptr[0] = (byte_t)(b * (255.0/31.0));
  353. tempbufferptr[1] = (byte_t)(g * (255.0/31.0));
  354. tempbufferptr[2] = (byte_t)(r * (255.0/31.0));
  355. tempbufferptr[3] = (byte_t)(a * 255.0);
  356. rawbufferptr += sizeof(unsigned short);
  357. tempbufferptr += 4;
  358. }
  359. }
  360. }
  361. else if (sbpp == 24)
  362. {
  363. /* source is 24 bit rgba */
  364. rawbufferptr = pixels;
  365. for (y=0; y<height; y++)
  366. {
  367. tempbufferptr = tempbuffer + y*width*4;
  368. for (x=0; x<width; x++)
  369. {
  370. tempbufferptr[0] = rawbufferptr[0];
  371. tempbufferptr[1] = rawbufferptr[1];
  372. tempbufferptr[2] = rawbufferptr[2];
  373. tempbufferptr[3] = 255;
  374. rawbufferptr += 3;
  375. tempbufferptr += 4;
  376. }
  377. }
  378. }
  379. else if (sbpp == 32)
  380. {
  381. /* source is 32 bit rgba */
  382. memcpy(tempbuffer,pixels,width*height*4);
  383. }
  384. else
  385. TL_Error("TL_SaveTGA: cannot handle source %d bits per pixel",sbpp);
  386. if (tbpp == 16)
  387. bytesperpixel = 2;
  388. else if (tbpp == 24)
  389. bytesperpixel = 3;
  390. else if (tbpp == 32)
  391. bytesperpixel = 4;
  392. else
  393. TL_Error("TL_SaveTGA: cannot handle target %d bits per pixel",tbpp);
  394. handle = TL_SafeOpenWrite(filename);
  395. /* write the targa header */
  396. tga.id_length = 0;
  397. tga.colormap_type = 0;
  398. tga.image_type = 2;
  399. tga.colormap_index = 0;
  400. tga.colormap_length = 0;
  401. tga.colormap_size = 0;
  402. tga.x_origin = 0;
  403. tga.y_origin = 0;
  404. tga.width = width;
  405. tga.height = height;
  406. tga.pixel_size = tbpp;
  407. tga.attributes = 0;
  408. TL_SafeWrite(handle,&tga.id_length,sizeof(tga.id_length));
  409. TL_SafeWrite(handle,&tga.colormap_type,sizeof(tga.colormap_type));
  410. TL_SafeWrite(handle,&tga.image_type,sizeof(tga.image_type));
  411. TL_SafeWrite(handle,&tga.colormap_index,sizeof(tga.colormap_index));
  412. TL_SafeWrite(handle,&tga.colormap_length,sizeof(tga.colormap_length));
  413. TL_SafeWrite(handle,&tga.colormap_size,sizeof(tga.colormap_size));
  414. TL_SafeWrite(handle,&tga.x_origin,sizeof(tga.x_origin));
  415. TL_SafeWrite(handle,&tga.y_origin,sizeof(tga.y_origin));
  416. TL_SafeWrite(handle,&tga.width,sizeof(tga.width));
  417. TL_SafeWrite(handle,&tga.height,sizeof(tga.height));
  418. TL_SafeWrite(handle,&tga.pixel_size,sizeof(tga.pixel_size));
  419. TL_SafeWrite(handle,&tga.attributes,sizeof(tga.attributes));
  420. /* tga images are upside down left to right - !@#$% */
  421. tgabuffer = (byte_t*)TL_Malloc(width*height*bytesperpixel);
  422. /* source is 32 bit rgba */
  423. rawbufferptr = tempbuffer;
  424. for (y=height-1; y>=0; y--)
  425. {
  426. tgabufferptr = tgabuffer + y*width*bytesperpixel;
  427. for (x=0; x<width; x++)
  428. {
  429. switch (bytesperpixel)
  430. {
  431. case 2:
  432. break;
  433. case 3:
  434. rgba8888 = TL_BigLong(*(unsigned long*)rawbufferptr);
  435. r = (rgba8888 & 0xFF000000)>>24;
  436. g = (rgba8888 & 0x00FF0000)>>16;
  437. b = (rgba8888 & 0x0000FF00)>>8;
  438. tgabufferptr[0] = b;
  439. tgabufferptr[1] = g;
  440. tgabufferptr[2] = r;
  441. break;
  442. case 4:
  443. rgba8888 = TL_BigLong(*(unsigned long*)rawbufferptr);
  444. r = (rgba8888 & 0xFF000000)>>24;
  445. g = (rgba8888 & 0x00FF0000)>>16;
  446. b = (rgba8888 & 0x0000FF00)>>8;
  447. a = rgba8888 & 0xFF;
  448. tgabufferptr[0] = b;
  449. tgabufferptr[1] = g;
  450. tgabufferptr[2] = r;
  451. tgabufferptr[3] = a;
  452. break;
  453. }
  454. rawbufferptr += 4;
  455. tgabufferptr += bytesperpixel;
  456. }
  457. }
  458. TL_SafeWrite(handle,tgabuffer,width*height*bytesperpixel);
  459. close(handle);
  460. TL_Free(tempbuffer);
  461. TL_Free(tgabuffer);
  462. }
  463. /*****************************************************************************
  464. TL_LoadImage
  465. Loads an image based on extension.
  466. *****************************************************************************/
  467. void TL_LoadImage(char* name, byte_t** pixels, byte_t** palette, int* width, int* height)
  468. {
  469. char ext[16];
  470. TL_GetExtension(name,ext);
  471. if (!stricmp(ext,"pcx"))
  472. TL_LoadPCX(name,pixels,palette,width,height);
  473. else if (!stricmp(ext,"tga"))
  474. {
  475. TL_LoadTGA(name,pixels,width,height);
  476. *palette = NULL;
  477. }
  478. else
  479. TL_Error("TL_LoadImage: unknown image extension %s",ext);
  480. }