#include #include #include #define NAME "alphaconv" #define RNG(x) ((x)>res1?res1:((x)<0?0:(x))) void fail(char * s) { fprintf(stderr,s,NAME); exit(1); } int checkmagic(FILE *f) { int c; if (getc(f) != 'P' || getc(f) != '6') return 0; /* The code below is because ghostscript inserts a non-standard comment after the magic number */ while(isspace(c=getc(f))); if (c=='#') while(getc(f)!='\n'); else ungetc(c,f); return 1; } main(int argc, char *argv[]) { int width1, height1, width2, height2, res1, res2; long length; int red_b,green_b,blue_b, red_w, green_w, blue_w; int red, green, blue; int alpha; FILE *inb, *inw, *rgb, *al; if (argc !=5) fail("Usage: %s \n"); if (!(inb=fopen(argv[1],"rb")) || !(inw=fopen(argv[2],"rb"))) fail("\n%s: Unable to open input file\n"); if (!checkmagic(inb) || !checkmagic(inw)) fail("\n%s: Unsupported input file format\n"); if ((fscanf(inb,"%d %d %d", &width1, &height1, &res1)!=3) || (fscanf(inw,"%d %d %d", &width2, &height2, &res2)!=3) || !isspace(getc(inb)) || !isspace(getc(inw))) fail("\n%s: Unsupported input file format\n"); if ( width1 != width2 || height1 != height2) fail("\n%s: Input images are different shapes\n"); if ( res1 != res2) fail("\n%s: Files have different colour depths\n"); if ( res1 >255 || width1 <1 || height1 < 1 || res1 <1 ) fail("\n%s: Unsupported input file format\n"); if (!(rgb=fopen(argv[3],"wb"))) fail("\n%s: Unable to open output file\n"); if (!(al=fopen(argv[4],"wb"))) fclose(rgb), fail("\n%s: Unable to open output file\n"); if (fprintf(rgb,"P6\n%d %d\n%d\n",width1,height1,res1)<0 || fprintf(al, "P5\n%d %d\n%d\n",width1,height1,res1)<0) fclose(rgb), fclose(al), fail("\n%s: File write error"); length=(long)width1*(long)height1; while (length--) { if((red_b=getc(inb))==EOF || (green_b=getc(inb))==EOF || (blue_b=getc(inb)) == EOF || (red_w=getc(inw))==EOF || (green_w=getc(inw))==EOF || (blue_w=getc(inw))==EOF) fclose(rgb), fclose(al), fail("\n%s: File read error\n"); alpha = RNG(res1+(red_b+green_b+blue_b-red_w-green_w-blue_w)/3); if (alpha==0) /* If there's no alpha, make it white */ red=green=blue=res1; else { red =RNG(((long)red_b *(long)res1)/(long)alpha); green=RNG(((long)green_b*(long)res1)/(long)alpha); blue =RNG(((long)blue_b *(long)res1)/(long)alpha); } if(fputc(alpha,al) == EOF || fputc(red,rgb) == EOF || fputc(green,rgb) == EOF || fputc(blue,rgb) == EOF) fclose(rgb), fclose(al), fail("\n%s: File write error\n"); } if (fclose(rgb)) fclose (al), fail("\n%s: File close error\n"); if (fclose(al)) fail("\n%s: File close error\n"); fclose(inb); fclose(inw); exit(0); }