Code Search for Developers
 
 
  

mergealpha.c from FreePop at Krugle


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

FreePop

FreePop is a multi-platform tile-based game based on the great old game Populous 2 by Bullfrog Productions Ltd., but much improved.

Project homepage: http://sourceforge.net/projects/freepop
Programming language(s): C++
License: other

  AUTHORS
  ChangeLog
  Makefile.am
  NEWS
  README
  autogen.sh
  configure.ac
  mergealpha.c
  mergecloth.c
  pngio.h