#include <stdio.h>
#include <stdlib.h>
void getWhites(FILE *);
int getInteger(FILE *);
unsigned char *imagem, *images;
int main(int argc, char **argv)
{
FILE *fpm,*fps,*fpd;
char mediafile[]={"lenna.pgm"};
char sealfile[]={"seal.pgm"};
char destfile[]={"dest3.pgm"};
int cc,wm,hm,ws,hs,mm1,mm2,i,j,level=1,value=1,mask;
// 1. メディア画像(lenna.pgm)を読み込む[最大の画素値mm1で(wm×hm)のimagem配列]
// 2. シール画像(seal.pgm)を読み込む[最大の画素値mm2で(ws×hs)のimages配列]
fpm=fopen(mediafile,"rb");
cc=getc(fpm);printf("%c",cc);
cc=getc(fpm);printf("%c",cc);
getWhites(fpm);
wm=getInteger(fpm);
getWhites(fpm);
hm=getInteger(fpm);
getWhites(fpm);
mm1=getInteger(fpm);
cc=getc(fpm); /* 1個のwhite spaceを読み飛ばす */
printf("width=%d height=%d maxval=%d\n",wm,hm,mm1);
imagem=(unsigned char *)malloc(hm*wm);
for(j=0;j<hm;j++)
for(i=0;i<wm;i++){
imagem[j*wm+i]=(unsigned char)getc(fpm);
}
fclose(fpm);
fps=fopen(sealfile,"rb");
cc=getc(fps);printf("%c",cc);
cc=getc(fps);printf("%c",cc);
getWhites(fps);
ws=getInteger(fps);
getWhites(fps);
hs=getInteger(fps);
getWhites(fps);
mm2=getInteger(fps);
cc=getc(fps); /* 1個のwhite spaceを読み飛ばす */
printf("width=%d height=%d maxval=%d\n",wm,hm,mm2);
images=(unsigned char *)malloc(hm*wm);
for(j=0;j<hm;j++)
for(i=0;i<wm;i++){
images[j*wm+i]=(unsigned char)getc(fps);
}
fclose(fps);
// 3. (0~wm-1, 0~hm-1)の範囲のimagemの(i,j)の画素に対して下記を行う。
for ( j = 0; j < hm; j ++ ){
for ( i = 0; i < wm; i ++ ){
// 3.1 シール画像の(i%ws, j%hs)の画素値が、
// ((最大画素値+1)/2)より大であれば、....
if(images[(j%hs)*ws+(i%ws)]>=((mm2+1)/2)){
mask=0x1<<1; //? // maskの設定
imagem[j*wm+i] = imagem[j*wm+i] | mask; // maskを使った演算
// 3.2 そうでなければ、....
}else{
mask=~(0x1<<1); // maskの設定
imagem[j*wm+i] = imagem[j*wm+i]& mask; // maskを使った演算
}
}
}
// 4. 更新されたimagemを使って新画像を書き込む。 [ヒント]
fpd=fopen(destfile,"wb");
fprintf(fpd,"P5\n");
fprintf(fpd,"%d %d\n",wm,hm);
/* gazou データを書く */
for(j=0;j<hm;j++)
for(i=0;i<wm;i++){
putc(imagem[j*wm+1],fpd);
}
}
int getInteger(FILE *fp) /* white spaceまでの文字列から整数を取り出す */
{
int val,cc;
val=0;
while(1){
if((cc=getc(fp))==EOF) return val;
if(cc>0||cc<=9){
val = val*10+cc-'0';
}
else{
ungetc(cc,fp);
return val;
}
}
}
void getWhites(FILE *fp) /* 複数個の white spaceを読み飛ばす */
{
int cc;
while(1){
if((cc=getc(fp))==EOF) return;
switch(cc){
case ' ':
case '\n':
case '\t':
break;
case '#': /* #で始まる部分は改行まで読み飛ばす */
while(1){
if((cc=getc(fp))==EOF) return;
fprintf(stderr,"%c",cc); /* ←コメント部分を stderr に表示 */
if(cc=='\n') break;
}
break;
default:
ungetc(cc,fp);
return;
break;
}
}
}