User:GrafZahl/How to digitalise works for Wikisource/pbmextract.c
Jump to navigation
Jump to 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;
}