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.

482 lines
7.9 KiB

  1. /*
  2. ==================================
  3. TEXPOW2 by Iikka Keranen 2001
  4. Loads TGA files and scales them
  5. up to the closest power of two.
  6. Overwrites the originals, so be
  7. careful and make backups.
  8. ==================================
  9. */
  10. #define FLIST_LEN 2000
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <memory.h>
  15. #include <math.h>
  16. #include "texpow2.h"
  17. /*
  18. ======= PROTOTYPES FOR FUNCS =======
  19. */
  20. long countval(char *str);
  21. /*
  22. ======= MAIN =======
  23. */
  24. // Glob vars...
  25. long width, height;
  26. void main(int argc, char *argv[])
  27. {
  28. unsigned char *animname=NULL;
  29. unsigned char odname[256];
  30. unsigned char ofname[256];
  31. unsigned char *fname[FLIST_LEN];
  32. long flags=0, contents=0, value=0;
  33. long x;
  34. unsigned char ignpal=0;
  35. short opn=0, numsrc=0;
  36. t_i_image *in;
  37. t_i_image *out;
  38. printf("TEXPOW2 by Iikka Ker�nen 2001\n\n");
  39. if (argc<2)
  40. {
  41. printf("Usage: TEXPOW2 <source> [source2] [source3] ... [options]\n");
  42. printf("Options:\n");
  43. printf("-o output dir -- output directory (by default, replaces original)\n\n");
  44. return;
  45. }
  46. for (x=1;x<argc;x++)
  47. {
  48. if (!stricmp(argv[x]+strlen(argv[x])-4,".tga"))
  49. {
  50. fname[numsrc]=argv[x];
  51. numsrc++;
  52. }
  53. if (x<argc-1)
  54. {
  55. if (!strcmp(argv[x],"-o"))
  56. {
  57. strcpy(odname, argv[x+1]);
  58. opn=1;
  59. }
  60. }
  61. }
  62. if (numsrc==1)
  63. printf("%d texture to be converted...\n", numsrc);
  64. else
  65. printf("%d textures to be converted...\n", numsrc);
  66. for (x=0;x<numsrc;x++)
  67. {
  68. printf("%s ... ",fname[x]);
  69. if (!opn) strcpy(ofname, fname[x]);
  70. else sprintf(ofname, "%s/%s", odname, fname[x]);
  71. in = i_load_tga(fname[x]);
  72. if (in)
  73. {
  74. out = powerof2(in);
  75. if (out)
  76. {
  77. i_save_tga(out, ofname);
  78. printf("Saved %s\n", ofname);
  79. }
  80. else
  81. {
  82. printf("Error!\n");
  83. }
  84. }
  85. }
  86. }
  87. /*
  88. ========
  89. SCALE
  90. ========
  91. */
  92. t_i_image *powerof2(t_i_image *img1)
  93. {
  94. int32 x,y,w,h;
  95. int32 dx, dy, tx, ty;
  96. uint32 c1, c2, c3, c4;
  97. t_i_image *img;
  98. w = 1; h = 1;
  99. while (w < img1->w)
  100. w = w * 2;
  101. while (h < img1->h)
  102. h = h * 2;
  103. if (w < 2 || h < 2)
  104. return NULL;
  105. img=new_image(w, h);
  106. if (!img)
  107. return NULL;
  108. dx = ((img1->w) << 16) / (w);
  109. dy = ((img1->h) << 16) / (h);
  110. ty = 0;
  111. for (y = 0; y < h; y++)
  112. {
  113. tx = 0;
  114. for (x = 0; x < w; x++)
  115. {
  116. c1 = i_getpixel(img1, (tx>>16), (ty>>16));
  117. c2 = i_getpixel(img1, (tx>>16)+1, (ty>>16));
  118. c3 = i_getpixel(img1, (tx>>16), (ty>>16)+1);
  119. c4 = i_getpixel(img1, (tx>>16)+1, (ty>>16)+1);
  120. c1 = i_pixel_alphamix(c1, c2, (tx & 0xffff)>>8);
  121. c2 = i_pixel_alphamix(c3, c4, (tx & 0xffff)>>8);
  122. c1 = i_pixel_alphamix(c1, c2, (ty & 0xffff)>>8);
  123. i_putpixel(img, x, y, c1);
  124. tx += dx;
  125. }
  126. ty += dy;
  127. }
  128. return img;
  129. }
  130. /*
  131. ========
  132. IMAGE
  133. ========
  134. */
  135. t_i_image *new_image(int32 w, int32 h)
  136. {
  137. t_i_image *img;
  138. img=malloc(sizeof(t_i_image));
  139. if (!img)
  140. {
  141. return NULL;
  142. }
  143. img->w=w;
  144. img->h=h;
  145. img->data=calloc(w*h, sizeof(uint32));
  146. if (!img->data)
  147. {
  148. free(img);
  149. return NULL;
  150. }
  151. img->data32 = (int32 *) img->data;
  152. return img;
  153. }
  154. void del_image(t_i_image *img)
  155. {
  156. if (!img)
  157. return;
  158. if (img->data)
  159. free(img->data);
  160. free(img);
  161. }
  162. /*
  163. =============
  164. TGA SAVE/LOAD
  165. =============
  166. */
  167. t_i_image *i_load_tga(char *fname)
  168. {
  169. uint8 id_len, pal_type, img_type;
  170. uint16 f_color, pal_colors;
  171. uint8 pal_size;
  172. uint16 left, top, img_w, img_h;
  173. uint8 bpp, des_bits;
  174. t_i_image *image;
  175. uint8 *buffer;
  176. uint8 *line;
  177. int32 x,y,po;
  178. uint8 die=0;
  179. FILE *img;
  180. img=fopen(fname, "rb");
  181. if (!img)
  182. return NULL;
  183. // load header
  184. id_len=fgetc(img);
  185. pal_type=fgetc(img);
  186. img_type=fgetc(img);
  187. f_color=fgetc(img);
  188. f_color+=fgetc(img)<<8;
  189. pal_colors=fgetc(img);
  190. pal_colors+=fgetc(img)<<8;
  191. pal_size=fgetc(img);
  192. left=fgetc(img);
  193. left+=fgetc(img)<<8;
  194. top=fgetc(img);
  195. top+=fgetc(img)<<8;
  196. img_w=fgetc(img);
  197. img_w+=fgetc(img)<<8;
  198. img_h=fgetc(img);
  199. img_h+=fgetc(img)<<8;
  200. bpp=fgetc(img);
  201. des_bits=fgetc(img);
  202. // check for unsupported features
  203. if (id_len!=0 || pal_colors!=0 || (img_type!=2 && img_type!=3))
  204. die=1;
  205. if (img_type==3 && bpp!=8)
  206. die=1;
  207. if (img_type==2 && bpp!=24 && bpp!=32)
  208. die=1;
  209. if (die)
  210. {
  211. fclose(img);
  212. return NULL;
  213. }
  214. // allocate buffer for the image
  215. image=new_image(img_w, img_h);
  216. if (!image)
  217. return NULL;
  218. buffer=image->data;
  219. // allocate temp buffer to store each line as they're read from the file
  220. line=malloc(img_w*(bpp>>3));
  221. if (!line)
  222. {
  223. del_image(image);
  224. fclose(img);
  225. return NULL;
  226. }
  227. image->data32=(uint32 *)image->data;
  228. // actually read the image data from file
  229. for (y=0;y<img_h;y++)
  230. {
  231. // read a line into memory
  232. fread(line, 1, img_w*(bpp>>3), img);
  233. // convert into 32bit truecolor
  234. if (des_bits & 0x20)
  235. po=y*img_w*4;
  236. else
  237. po=(img_h-y-1)*img_w*4;
  238. for (x=0;x<img_w;x++)
  239. {
  240. switch(bpp)
  241. {
  242. case 8:
  243. buffer[po++]=line[x];
  244. buffer[po++]=line[x];
  245. buffer[po++]=line[x];
  246. buffer[po++]=0;
  247. break;
  248. case 24:
  249. buffer[po++]=line[x*3];
  250. buffer[po++]=line[x*3+1];
  251. buffer[po++]=line[x*3+2];
  252. buffer[po++]=0;
  253. break;
  254. case 32:
  255. buffer[po++]=line[x*4];
  256. buffer[po++]=line[x*4+1];
  257. buffer[po++]=line[x*4+2];
  258. buffer[po++]=line[x*4+3];
  259. break;
  260. }
  261. }
  262. }
  263. free(line);
  264. return image;
  265. }
  266. void i_save_tga(t_i_image *image, char *fname)
  267. {
  268. uint16 img_w=image->w, img_h=image->h;
  269. uint8 *buffer;
  270. int32 y,x, po;
  271. FILE *img;
  272. img=fopen(fname, "wb");
  273. if (!img)
  274. return;
  275. // save header
  276. fputc(0, img); // id_len
  277. fputc(0, img); // pal_type
  278. fputc(2, img); // img_type
  279. fputc(0, img); fputc(0, img); // f_color
  280. fputc(0, img); fputc(0, img); // pal_colors
  281. fputc(0, img); // pal_size
  282. fputc(0, img); fputc(0, img); // left
  283. fputc(0, img); fputc(0, img); // top
  284. fputc(img_w&255, img); fputc(img_w>>8, img); // width
  285. fputc(img_h&255, img); fputc(img_h>>8, img); // height
  286. fputc(24, img); // bpp
  287. fputc(0, img); // des_bits
  288. buffer=image->data;
  289. // save the image data to file
  290. for (y=0;y<img_h;y++)
  291. {
  292. po=(img_h-y-1)*img_w*4;
  293. for (x = 0; x < img_w; x++)
  294. {
  295. fputc(buffer[po+x*4], img);
  296. fputc(buffer[po+x*4+1], img);
  297. fputc(buffer[po+x*4+2], img);
  298. }
  299. //fwrite(buffer+po, 1, img_w*4, img);
  300. }
  301. }
  302. /*
  303. =========
  304. PIXEL
  305. =========
  306. */
  307. uint32 i_rgb_to_32(uint32 r, uint32 g, uint32 b, uint32 a)
  308. {
  309. uint32 co;
  310. co=(a<<24)+(r<<16)+(g<<8)+b;
  311. return co;
  312. }
  313. void i_putpixel(t_i_image *img, int32 x, int32 y, uint32 co)
  314. {
  315. img->data32[(y%img->h)*img->w+(x%img->w)]=co;
  316. }
  317. void i_putpixel_rgba(t_i_image *img, int32 x, int32 y, int32 r, int32 g, int32 b, int32 a)
  318. {
  319. uint32 co;
  320. co=i_rgb_to_32(r,g,b,a); //(a<<24)+(r<<16)+(g<<8)+b;
  321. img->data32[(y%img->h)*img->w+(x%img->w)]=co;
  322. }
  323. uint32 i_getpixel(t_i_image *img, int32 x, int32 y)
  324. {
  325. uint32 co;
  326. co=img->data32[(y%img->h)*img->w+(x%img->w)];
  327. return co;
  328. }
  329. int32 i_getpixel_ch(t_i_image *img, int32 x, int32 y, int32 ch)
  330. {
  331. uint32 co;
  332. co=img->data32[(y%img->h)*img->w+(x%img->w)];
  333. // ch: 0:red 1:green 2:blue 3:alpha
  334. switch (ch)
  335. {
  336. case 0: // red
  337. co=(co>>16)&255;
  338. break;
  339. case 1: // green
  340. co=(co>>8)&255;
  341. break;
  342. case 2: // blue
  343. co=co&255;
  344. break;
  345. case 3: // alpha
  346. co=(co>>24)&255;
  347. break;
  348. default: ;
  349. }
  350. return co;
  351. }
  352. uint32 i_pixel_alphamix(uint32 c1, uint32 c2, uint32 p)
  353. {
  354. uint32 co;
  355. co=i_pixel_add(i_pixel_multiply_n(c1,256-p), i_pixel_multiply_n(c2,p));
  356. return co;
  357. }
  358. uint32 i_pixel_multiply_n(uint32 c1, uint32 n)
  359. {
  360. uint32 co,r,g,b,a;
  361. r=(((c1>>16)&255)*n)>>8;
  362. g=(((c1>>8)&255) *n)>>8;
  363. b=(((c1>>0)&255) *n)>>8;
  364. a=(((c1>>24)&255)*n)>>8;
  365. co=i_rgb_to_32(r,g,b,a);
  366. return co;
  367. }
  368. uint32 i_pixel_add(uint32 co1, uint32 co2)
  369. {
  370. uint32 co,r,g,b,a;
  371. r=MIN(255, MAX(0, ((co1>>16)&255)+((co2>>16)&255)));
  372. g=MIN(255, MAX(0, ((co1>>8 )&255)+((co2>>8 )&255)));
  373. b=MIN(255, MAX(0, ((co1>>0 )&255)+((co2>>0 )&255)));
  374. a=MIN(255, MAX(0, ((co1>>24)&255)+((co2>>24)&255)));
  375. co=i_rgb_to_32(r,g,b,a);
  376. return co;
  377. }
  378. /*
  379. ========
  380. MISC
  381. ========
  382. */
  383. long countval(char *str)
  384. {
  385. long val=0,n,l;
  386. l=strlen(str);
  387. for (n=0;n<l;n++)
  388. if (str[n]>47 && str[n]<58)
  389. val=val*10+str[n]-48;
  390. return val;
  391. }