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

From Wikisource
Jump to: navigation, search
/* 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;
 
}