Show mergecloth.c syntax highlighted
// Merge images to produce background and overlay images.
// By Brendon Higgins: bh_doc@users.sourceforge.net
// Released in Nov 2003 under GPL. See www.gnu.org if you don't know what that is.
// 2005-06-24: Made changes so that now the overlay is always completely white
// with a varying alpha channel. The input pictures now must both be shaded -
// ie a shaded red colour with white background and a shaded blue colour with
// a black background. This should make things easier.
#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;
}
colour calc_over(colour red, colour blue) {
colour col;
col.red = col.green = col.blue = 255;
col.alpha = clip((int)red.red - red.green - blue.red + blue.green);
return col;
}
colour calc_back(colour red, colour blue) {
colour col;
int x = red.red - blue.red - 255;
int y;
if (x == 0) {
col.red = 255;
col.green = 255;
col.blue = 255;
col.alpha = 0;
} else {
col.red = clip(-(int)blue.red * 255 / x);
col.green = clip(-(int)blue.green * 255 / x);
col.blue = clip(((int)red.green - red.blue - blue.green) * 255 / x);
y = (int)red.red - red.green - blue.red + blue.green - 255;
if (y == 0) {
col.alpha = 255;
} else {
col.alpha = clip(x * 255 / y);
}
}
return col;
}
int main(int argc, char* argv[]) {
pngstuff red, blue;
int x, y, width, height, ok;
unsigned char al, c;
colour** rows_col;
colour** rows_back;
if (argc != 5) {
printf("Merges the colours of two special pictures to produce an alpha mapped overlay\n");
printf("for the cloth of those pictures, and a background picture.\n");
printf("Writes to the files given the pictures with the alpha information.\n");
printf("One picture must have a red cloth with a white background,\n");
printf("the other a blue cloth with a black background.\n\n");
printf("Usage:\n mergecloth <redwhitepic> <blueblackpic> <overlayoutpic> <backoutpic>\n\n");
printf("Input and output must be PNG.\n\n");
return 1;
}
printf("mergecloth: %s & %s -> %s & %s ... ", argv[1], argv[2], argv[3], argv[4]);
if (open_png(argv[1], &red) != 0) {
printf("Error reading %s", argv[1]);
return 2;
}
if (open_png(argv[2], &blue) != 0) {
printf("Error reading %s", argv[2]);
close_png(&red);
return 3;
}
width = png_get_image_width(red.png, red.info);
height = png_get_image_height(red.png, red.info);
// TODO Check malloc != NULL
rows_col = (colour**) malloc(height * sizeof(colour*));
rows_back = (colour**) malloc(height * sizeof(colour*));
for (y = 0; y < height; ++y) {
rows_col[y] = (colour*) malloc(width * sizeof(colour));
rows_back[y] = (colour*) malloc(width * sizeof(colour));
for (x = 0; x < width; ++x) {
rows_col[y][x] = calc_over(red.rows[y][x], blue.rows[y][x]);
rows_back[y][x] = calc_back(red.rows[y][x], blue.rows[y][x]);
}
}
ok = 0;
if (write_png(argv[3], rows_col, width, height) != 0) {
printf("Error writing %s", argv[3]);
ok = 4;
}
if (write_png(argv[4], rows_back, width, height) != 0) {
printf("Error writing %s", argv[4]);
ok = 5;
}
for (y = 0; y < height; ++y) {
free(rows_col[y]);
free(rows_back[y]);
}
free(rows_col);
free(rows_back);
close_png(&red);
close_png(&blue);
if (ok == 0) {
printf("Done\n");
} else {
return ok;
}
return 0;
}
See more files for this project here