User:GrafZahl/How to digitalise works for Wikisource/pbmextract.c

/* extract a subimage from a pbm image */

/*
 * Copyright (C) 2007, GrafZahl (en.wikisource.org user).
 *
 * Licence: GPLv2
 *
 * Compile with: gcc -Wall -lnetpbm -o pbmextract pbmextract.c
 */

#include<pam.h>
#include<stdio.h>
#include<stdlib.h>

/* geometry */
int left, top, right, bottom;

/* files */
char * infilename;
char * outfilename;
FILE * infile;
FILE * outfile;

/* library handle */
struct pam inhandle;

/* usage() */

void usage(void)
{

        fputs("Usage:\n"
                "pbmextract infile outfile left top right bottom\n", stderr);

}

/* read_args() */

void read_args(argc, argv)
        int argc;
        char ** argv;
{

        if(argc != 7)
        {

                fputs("Wrong number of arguments.\n", stderr);
                usage();
                exit(1);

        }

        infilename = argv[1];
        outfilename = argv[2];

        left = strtol(argv[3], NULL, 0);
        top = strtol(argv[4], NULL, 0);
        right = strtol(argv[5], NULL, 0);
        bottom = strtol(argv[6], NULL, 0);

        if((left < 0) ||
           (top < 0) ||
           (right <= left) ||
           (bottom <= top))
           {

                fputs("Invalid geometry specified\n", stderr);
                exit(1);

           }

        infile = fopen(infilename, "r");

        if(infile == NULL)
        {

                perror("Error opening input file");
                exit(1);

        }

}

int main(int argc, char ** argv)
{

        int i;
        xel * row;

        pnm_init(&argc, argv);
        read_args(argc, argv);

        pnm_readpaminit(infile, &inhandle, sizeof(inhandle));

        if((inhandle.height < bottom) ||
           (inhandle.width < right))
           {

                fprintf(stderr,
                        "Bad geometry for given image size (%dx%d)\n",
                        inhandle.width, inhandle.height);
                exit(1);

           }

        /* prepare writing */

        outfile = fopen(outfilename, "w");

        if(outfile == NULL)
        {

                perror("Error opening output file");
                return 1;

        }

        pnm_writepnminit(outfile, right - left, bottom - top, inhandle.maxval,
                inhandle.format, 0);

        row = pnm_allocrow(inhandle.width);

        /* skip top rows */

        for(i = 0; i != top; ++i)
                pnm_readpnmrow(infile, row, inhandle.width, inhandle.maxval,
                        inhandle.format);

        /* write rows until bottom */

        for(i = 0; i != bottom - top; ++i)
        {

                pnm_readpnmrow(infile, row, inhandle.width, inhandle.maxval,
                        inhandle.format);
                pnm_writepnmrow(outfile, row + left, right - left,
                        inhandle.maxval, inhandle.format, 0);

        }

        pnm_freepamrow(row);

        if(fclose(outfile) == EOF)
        {

                perror("Error closing output file");
                return 1;

        }

        return 0;

}