C program to merge two given image files binary based ppm files P6
Write a C program to merge two given binary-based ppm files (P6). The names of the two given
image files and the name of the combined image file are given as command line arguments. The
combined image is obtained by putting the second image to the top-right corner of the first
image. The sizes of the given image files are not fixed. If the width or the height of the first
image is less than that of the second, your program should report error.
All these image files can be opened with image viewer tools that can work with ppm file format.
For simplicity, the following restrictions are added to the file format of the input:
• no comment line after the file type specification
• width (number of columns) and height (number of rows) formatted as ASCII decimal in
the second line
• maximal value of color components given in the third line
This is a practice on using System Call I/O. You are not allowed to use standard I/O library
functions or other graphics related libraries.
Sample input (firework.ppm and 150.ppm):
Answer:
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[]){
long int fd1width=0,fd1height=0, fd2width=0,fd2height=0;
char buf;
int width=0, height=0, p=0;
int fd1 = open (argv[1],O_RDONLY); // open fd1
int fd2 = open (argv[2],O_RDONLY); // open fd2
int fd3 = open(argv[3],O_WRONLY | O_CREAT | O_TRUNC,0755); // open/create fd3
// fd1
do{ //reads first line
read(fd1,&buf,1);
}while(buf != '\n');
while (buf < '0' || buf > '9') //ignores any whitespace
read(fd1,&buf,1);
while (buf >= '0' && buf <= '9'){ //getting width of fd1
fd1width*=10;
fd1width+=(buf-'0');
read(fd1,&buf,1);
}
while (buf < '0' || buf > '9') //ignores any whitespace
read(fd1,&buf,1);
while(buf != '\n'){ //getting height of fd1
fd1height*=10;
fd1height+=(buf - '0');
read(fd1,&buf,1);
}
while (buf < '0' || buf > '9') // ignores any whitespace
read(fd1,&buf,1);
while(buf != '\n') // reads the max value of color
read(fd1,&buf,1);
// fd2
do{ //skip first line
read(fd2,&buf,1);
}while(buf != '\n');
while (buf < '0' || buf > '9')
read(fd2,&buf,1);
while (buf >= '0' && buf <= '9'){ //getting width of fd2
fd2width*=10;
fd2width+=(buf-'0');
read(fd2,&buf,1);
}
while (buf < '0' || buf > '9')
read(fd2,&buf,1);
while (buf != '\n'){ //getting height of fd2
fd2height*=10;
fd2height+=(buf-'0');
read(fd2,&buf,1);
}
while (buf < '0' || buf > '9')
read(fd2,&buf,1);
while(buf != '\n') // reads the max value of color
read(fd2,&buf, 1);
lseek(fd1,0,SEEK_SET); //set fd1 pointer back to the beginning
//copy the first 3 line of fd1 to fd3
while (p != 3){
read(fd1,&buf,1);
write(fd3,&buf,1);
if (buf == '\n')
p++;
}
int px1[fd1width][fd1height];
while(width < fd1width && height < fd1height){ //read fd1 and store in px1
read(fd1,&px1[width][height],3);
width++;
if (width == fd1width){
width = 0;
height++;
}
}
// reset width, height
width = 0;
height = 0;
int px2[fd2width][fd2height];
while (width < fd2width && height < fd2height){ //read fd2 and store px2
read(fd2,&px2[width][height],3);
width++;
//start new line
if (width == fd2width){
width = 0;
height++;
}
}
// reset width, height
width = 0;
height = 0;
//copy fd1 and fd2 into fd3
while (width < fd1width && height < fd1height){
//copy fd2 to the top-right of fd3
if (width >= (fd1width-fd2width-1) && height < fd2height){
//copys an entire line of fd2
for (int i = 0; i <= fd2width;i++){
write(fd3,&px2[i][height],3);
}
//start next height
width = 0;
height++;
}
else{
// copys fd1 into fd3
write(fd3,&px1[width][height],3);
width++;
}
//start new line
if (width == fd1width){
width = 0;
height++;
}
}
close(fd1);
close(fd2);
close(fd3);
return 0;
}
Leave a reply