/* ================================== TEXPOW2 by Iikka Keranen 2001 Loads TGA files and scales them up to the closest power of two. Overwrites the originals, so be careful and make backups. ================================== */ #define FLIST_LEN 2000 #include #include #include #include #include #include "texpow2.h" /* ======= PROTOTYPES FOR FUNCS ======= */ long countval(char *str); /* ======= MAIN ======= */ // Glob vars... long width, height; void main(int argc, char *argv[]) { unsigned char *animname=NULL; unsigned char odname[256]; unsigned char ofname[256]; unsigned char *fname[FLIST_LEN]; long flags=0, contents=0, value=0; long x; unsigned char ignpal=0; short opn=0, numsrc=0; t_i_image *in; t_i_image *out; printf("TEXPOW2 by Iikka Ker„nen 2001\n\n"); if (argc<2) { printf("Usage: TEXPOW2 [source2] [source3] ... [options]\n"); printf("Options:\n"); printf("-o output dir -- output directory (by default, replaces original)\n\n"); return; } for (x=1;xw) w = w * 2; while (h < img1->h) h = h * 2; if (w < 2 || h < 2) return NULL; img=new_image(w, h); if (!img) return NULL; dx = ((img1->w) << 16) / (w); dy = ((img1->h) << 16) / (h); ty = 0; for (y = 0; y < h; y++) { tx = 0; for (x = 0; x < w; x++) { c1 = i_getpixel(img1, (tx>>16), (ty>>16)); c2 = i_getpixel(img1, (tx>>16)+1, (ty>>16)); c3 = i_getpixel(img1, (tx>>16), (ty>>16)+1); c4 = i_getpixel(img1, (tx>>16)+1, (ty>>16)+1); c1 = i_pixel_alphamix(c1, c2, (tx & 0xffff)>>8); c2 = i_pixel_alphamix(c3, c4, (tx & 0xffff)>>8); c1 = i_pixel_alphamix(c1, c2, (ty & 0xffff)>>8); i_putpixel(img, x, y, c1); tx += dx; } ty += dy; } return img; } /* ======== IMAGE ======== */ t_i_image *new_image(int32 w, int32 h) { t_i_image *img; img=malloc(sizeof(t_i_image)); if (!img) { return NULL; } img->w=w; img->h=h; img->data=calloc(w*h, sizeof(uint32)); if (!img->data) { free(img); return NULL; } img->data32 = (int32 *) img->data; return img; } void del_image(t_i_image *img) { if (!img) return; if (img->data) free(img->data); free(img); } /* ============= TGA SAVE/LOAD ============= */ t_i_image *i_load_tga(char *fname) { uint8 id_len, pal_type, img_type; uint16 f_color, pal_colors; uint8 pal_size; uint16 left, top, img_w, img_h; uint8 bpp, des_bits; t_i_image *image; uint8 *buffer; uint8 *line; int32 x,y,po; uint8 die=0; FILE *img; img=fopen(fname, "rb"); if (!img) return NULL; // load header id_len=fgetc(img); pal_type=fgetc(img); img_type=fgetc(img); f_color=fgetc(img); f_color+=fgetc(img)<<8; pal_colors=fgetc(img); pal_colors+=fgetc(img)<<8; pal_size=fgetc(img); left=fgetc(img); left+=fgetc(img)<<8; top=fgetc(img); top+=fgetc(img)<<8; img_w=fgetc(img); img_w+=fgetc(img)<<8; img_h=fgetc(img); img_h+=fgetc(img)<<8; bpp=fgetc(img); des_bits=fgetc(img); // check for unsupported features if (id_len!=0 || pal_colors!=0 || (img_type!=2 && img_type!=3)) die=1; if (img_type==3 && bpp!=8) die=1; if (img_type==2 && bpp!=24 && bpp!=32) die=1; if (die) { fclose(img); return NULL; } // allocate buffer for the image image=new_image(img_w, img_h); if (!image) return NULL; buffer=image->data; // allocate temp buffer to store each line as they're read from the file line=malloc(img_w*(bpp>>3)); if (!line) { del_image(image); fclose(img); return NULL; } image->data32=(uint32 *)image->data; // actually read the image data from file for (y=0;y>3), img); // convert into 32bit truecolor if (des_bits & 0x20) po=y*img_w*4; else po=(img_h-y-1)*img_w*4; for (x=0;xw, img_h=image->h; uint8 *buffer; int32 y,x, po; FILE *img; img=fopen(fname, "wb"); if (!img) return; // save header fputc(0, img); // id_len fputc(0, img); // pal_type fputc(2, img); // img_type fputc(0, img); fputc(0, img); // f_color fputc(0, img); fputc(0, img); // pal_colors fputc(0, img); // pal_size fputc(0, img); fputc(0, img); // left fputc(0, img); fputc(0, img); // top fputc(img_w&255, img); fputc(img_w>>8, img); // width fputc(img_h&255, img); fputc(img_h>>8, img); // height fputc(24, img); // bpp fputc(0, img); // des_bits buffer=image->data; // save the image data to file for (y=0;ydata32[(y%img->h)*img->w+(x%img->w)]=co; } void i_putpixel_rgba(t_i_image *img, int32 x, int32 y, int32 r, int32 g, int32 b, int32 a) { uint32 co; co=i_rgb_to_32(r,g,b,a); //(a<<24)+(r<<16)+(g<<8)+b; img->data32[(y%img->h)*img->w+(x%img->w)]=co; } uint32 i_getpixel(t_i_image *img, int32 x, int32 y) { uint32 co; co=img->data32[(y%img->h)*img->w+(x%img->w)]; return co; } int32 i_getpixel_ch(t_i_image *img, int32 x, int32 y, int32 ch) { uint32 co; co=img->data32[(y%img->h)*img->w+(x%img->w)]; // ch: 0:red 1:green 2:blue 3:alpha switch (ch) { case 0: // red co=(co>>16)&255; break; case 1: // green co=(co>>8)&255; break; case 2: // blue co=co&255; break; case 3: // alpha co=(co>>24)&255; break; default: ; } return co; } uint32 i_pixel_alphamix(uint32 c1, uint32 c2, uint32 p) { uint32 co; co=i_pixel_add(i_pixel_multiply_n(c1,256-p), i_pixel_multiply_n(c2,p)); return co; } uint32 i_pixel_multiply_n(uint32 c1, uint32 n) { uint32 co,r,g,b,a; r=(((c1>>16)&255)*n)>>8; g=(((c1>>8)&255) *n)>>8; b=(((c1>>0)&255) *n)>>8; a=(((c1>>24)&255)*n)>>8; co=i_rgb_to_32(r,g,b,a); return co; } uint32 i_pixel_add(uint32 co1, uint32 co2) { uint32 co,r,g,b,a; r=MIN(255, MAX(0, ((co1>>16)&255)+((co2>>16)&255))); g=MIN(255, MAX(0, ((co1>>8 )&255)+((co2>>8 )&255))); b=MIN(255, MAX(0, ((co1>>0 )&255)+((co2>>0 )&255))); a=MIN(255, MAX(0, ((co1>>24)&255)+((co2>>24)&255))); co=i_rgb_to_32(r,g,b,a); return co; } /* ======== MISC ======== */ long countval(char *str) { long val=0,n,l; l=strlen(str); for (n=0;n47 && str[n]<58) val=val*10+str[n]-48; return val; }