Show mergealpha.c syntax highlighted
// Merge images to produce an alpha-mapped image.
// By Brendon Higgins: bh_doc@users.sf.net
// Released in Dec 2002 under GPL. See www.gnu.org if you don't know what that is.
#include <stdio.h>
#include <pngio.h>
// Clip an integer to the range of a normal 8-bit colour channel.
unsigned char clip(int x) {
if (x > 255) return 255;
if (x < 0) return 0;
return x;
}
unsigned char calc_alpha(colour white, colour black) {
// We could calculate the alpha for a pixel 3 ways using the red, green or
// blue channels, so here we try to be extra accurate and take the average.
return 255 - clip(((int)white.red - black.red
+ white.green - black.green
+ white.blue - black.blue) / 3);
}
unsigned char calc_col(unsigned char black, unsigned char alpha) {
if (alpha == 0) {
// We can't tell what the colour should be! Avoid a divide-by-zero.
// White will do. It doesn't matter - no-one will see it.
return 255;
}
return clip((int)black * 255 / alpha);
}
int main(int argc, char* argv[]) {
pngstuff white, black;
int x, y, width, height, ok;
unsigned char al;
colour** rows_out;
if (argc != 4) {
printf("Merges the colours of two pictures to produce an alpha map of those pictures,\n");
printf("Writes to a file the picture with the new alpha information.\n");
printf("One of the two input pictures must have a white background, the other black.\n\n");
printf("Usage:\n mergealpha <whitepic> <blackpic> <outpic>\n\n");
printf("Input and output files must be PNG.\n\n");
return 1;
}
printf("mergealpha: %s & %s -> %s ... ", argv[1], argv[2], argv[3]);
if (open_png(argv[1], &white) != 0) {
printf("Error reading %s", argv[1]);
return 2;
}
if (open_png(argv[2], &black) != 0) {
printf("Error reading %s", argv[2]);
close_png(&white);
return 3;
}
width = png_get_image_width(white.png, white.info);
height = png_get_image_height(white.png, white.info);
// TODO Check malloc != NULL
rows_out = (colour**) malloc(height * sizeof(colour*));
for (y = 0; y < height; ++y) {
rows_out[y] = (colour*) malloc(width * sizeof(colour));
for (x = 0; x < width; ++x) {
al = calc_alpha(white.rows[y][x], black.rows[y][x]);
rows_out[y][x].alpha = al;
rows_out[y][x].red = calc_col(black.rows[y][x].red, al);
rows_out[y][x].green = calc_col(black.rows[y][x].green, al);
rows_out[y][x].blue = calc_col(black.rows[y][x].blue, al);
}
}
ok = 0;
if (write_png(argv[3], rows_out, width, height) != 0) {
printf("Error writing %s", argv[3]);
ok = 4;
}
for (y = 0; y < height; ++y) {
free(rows_out[y]);
}
free(rows_out);
close_png(&white);
close_png(&black);
if (ok == 0) {
printf("Done\n");
} else {
return ok;
}
return 0;
}
See more files for this project here