MUSASHI C source: ppm2xt.c


0001: /*============================================================================*/ 
0002: /* 変更履歴                                                                   */ 
0003: /*----------------------------------------------------------------------------*/ 
0004: /* 1.0 : 新規作成(2003/08/07)                                                 */ 
0005: /*============================================================================*/ 
0006:  
0007: #include <musashi.h
0008: #include <stdio.h> 
0009: #include <stdlib.h> 
0010: #include <string.h> 
0011:  
0012: #include <ppm2xtHelp.h> 
0013: struct mssComHelp comHelp={ 
0014:   "ppm2xt",       /* コマンド名       */ 
0015:   "1.0",          /* バージョン       */ 
0016:   HELPT,          /* コマンドタイトル */ 
0017:   HELPS,          /* 要約             */ 
0018:   HELPE,          /* 利用例           */ 
0019:   HELPR,          /* 参照コマンド     */ 
0020:   HELPA,          /* 作者情報         */ 
0021:   HELPB,          /* バグレポート情報 */ 
0022:   HELPH           /* ホームページ     */ 
0023: }; 
0024:  
0025: extern struct mssGlobalVariables mssGV; 
0026:  
0027: /*次の改行まで読み込み、その次の文字を返す*/ 
0028: int skipComment(FILE *fpr){ 
0029:   int c; 
0030:  
0031:   while(1){ 
0032:     c=fgetc(fpr); 
0033:     if(c==EOF) break; 
0034:  
0035:     if(c=='\n'){ 
0036:       break; 
0037:     } 
0038:   } 
0039:   return(c); /*to avoid warning message*/ 
0040: } 
0041:  
0042: /* 
0043:  * PPMファイルから、一つの値をbufにセットする。 
0044:  * 一つの値とはデリミタ(' ','\t','\n'で区切られた文字列のこと 
0045:  */ 
0046: int readOneValuePPM(char *buf, FILE *fpr ){ 
0047:   int c; 
0048:   int cnt=0; 
0049:  
0050:   while(1){ 
0051:     c=fgetc(fpr); 
0052:     if(c==EOF) break; 
0053:  
0054:     /*コメント処理*/ 
0055:     if(cnt==0 && c=='#') { 
0056:       c=skipComment(fpr); 
0057:       if(c==EOF) break; 
0058:     } 
0059:  
0060:     /*複数のデリミタはスキップする*/ 
0061:     if( cnt==0 && (c==' ' || c=='\t' || c=='\n') ){ 
0062:       if(c=='\n') mssGV.inCnt++; 
0063:       continue; 
0064:     } 
0065:  
0066:     /*デリミタのチェック*/ 
0067:     if(c==' ' || c=='\t' || c=='\n'){ 
0068:       if(c=='\n') mssGV.inCnt++; 
0069:       *(buf+cnt)='\0'; 
0070:       break; 
0071:     } 
0072:  
0073:     /*8桁を超えることはないはず*/ 
0074:     if(cnt>=8){ 
0075:       mssShowErrMsg("detected the too large number of a pixel element"); 
0076:       mssEnd(mssErrorNoDefault); 
0077:     } 
0078:  
0079:     *(buf+cnt++)=(unsigned char)c; 
0080:   } 
0081:   return(c); 
0082: } 
0083:  
0084: int main(int argc, char *argv[]){ 
0085: /*============================================================================*/ 
0086: /* オプション宣言&定義                                                       */ 
0087: /*============================================================================*/ 
0088: /*----------------------------------------------------------------------------*/ 
0089: /* 入力ファイル                                                               */ 
0090: /*----------------------------------------------------------------------------*/ 
0091:   MssOptSTR optINF={ 
0092:     OSTR,   /* オプションタイプ                                             */ 
0093:     "i",    /* キーワード(複数文字は不可)                                   */ 
0094:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0095:     NULL,   /* デフォルト                                                   */ 
0096:     1,      /* 文字列の最小長                                               */ 
0097:     MssFileNameMaxLen, /* 文字列の最大長                                    */ 
0098:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0099:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0100:   }; 
0101:  
0102: /*----------------------------------------------------------------------------*/ 
0103: /* 出力ファイル                                                               */ 
0104: /*----------------------------------------------------------------------------*/ 
0105:   MssOptOTF optOTF={ 
0106:     OOTF,   /* オプションタイプ                                             */ 
0107:     "o",    /* キーワード(複数文字は不可)                                   */ 
0108:     0,      /* 0:オプション, 1:必須                                         */ 
0109:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0110:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0111:   }; 
0112:  
0113: /*----------------------------------------------------------------------------*/ 
0114: /* オプションをまとめる                                                       */ 
0115: /*----------------------------------------------------------------------------*/ 
0116:   void *opt[]={&optINF,&optOTF,NULL}; 
0117:  
0118:   FILE *fpr; 
0119:   struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/ 
0120:   struct mssFPW    *fpw; /*出力ファイル構造体*/ 
0121:   char buf[20]; 
0122:   char bufr[20]; 
0123:   char bufg[20]; 
0124:   char bufb[20]; 
0125:   int magicNo; 
0126:   int xlen,ylen,depth; 
0127:  
0128:   int x,y; 
0129:  
0130: /*----------------------------------------------------------------------------*/ 
0131: /* 前処理                                                                     */ 
0132: /*----------------------------------------------------------------------------*/ 
0133:   mssInit(argc,argv,&comHelp);        /* シグナル処理などの初期化     */ 
0134:   mssHelpDoc(opt,&comHelp,argc,argv); /* ヘルプ                       */ 
0135:   mssSetOption(opt,argc,argv);        /* コマンドオプションの設定     */ 
0136:  
0137:   if (optINF.set) { 
0138:     fpr=fopen(optINF.str,"r"); 
0139:     if(fpr==NULL){ 
0140:       mssShowErrMsg("cannot open file: %s",optINF.str); 
0141:       mssEnd(mssErrorNoDefault); 
0142:     } 
0143:   } else { 
0144:     fpr=stdin; 
0145:   } 
0146:  
0147: /*prnOption(opt);*/ 
0148: /*prnHeader(hdi);*/ 
0149:  
0150: /*----------------------------------------------------------------------------*/ 
0151: /*出力ヘッダーの作成と出力                                                    */ 
0152: /*----------------------------------------------------------------------------*/ 
0153:   hdo=mssInitHeader(NULL,NULL); 
0154:   mssAddFieldsByStr( hdo->flds, "X"); 
0155:   mssAddFieldsByStr( hdo->flds, "Y"); 
0156:   mssAddFieldsByStr( hdo->flds, "Red"); 
0157:   mssAddFieldsByStr( hdo->flds, "Green"); 
0158:   mssAddFieldsByStr( hdo->flds, "Blue"); 
0159:   mssSetFldInfoSort(*(hdo->flds->fi+1),1,0,1); 
0160:   mssSetFldInfoSort(*(hdo->flds->fi+0),2,0,1); 
0161:  
0162:   /*標準出力オープン+ヘッダーの出力*/ 
0163:   fpw=mssOpenFPW(optOTF.str,0,0); 
0164:   mssWriteHeader(hdo,fpw); 
0165:  
0166: /*----------------------------------------------------------------------------*/ 
0167: /*メインルーチン                                                              */ 
0168: /*----------------------------------------------------------------------------*/ 
0169:   /*----- PPMヘッダー部読み込み*/ 
0170:   /*マジックナンバー*/ 
0171:   if(EOF == readOneValuePPM(buf,fpr) ){ 
0172:     mssShowErrMsg("invalid PPM header"); 
0173:     mssEnd(mssErrorNoDefault); 
0174:   } 
0175:   if( strlen(buf)!=2 ){ 
0176:     mssShowErrMsg("invalid PPM header"); 
0177:     mssEnd(mssErrorNoDefault); 
0178:   } 
0179:   if( *buf!='P' ){ 
0180:     mssShowErrMsg("invalid PPM header"); 
0181:     mssEnd(mssErrorNoDefault); 
0182:   } 
0183:   magicNo=atoi(buf+1); 
0184:   if( magicNo!=3 ){ 
0185:     mssShowErrMsg("this command can handle only an ascii format of PPM"); 
0186:     mssEnd(mssErrorNoDefault); 
0187:   } 
0188:  
0189:   /*X長*/ 
0190:   if(EOF == readOneValuePPM(buf,fpr) ){ 
0191:     mssShowErrMsg("invalid PPM header"); 
0192:     mssEnd(mssErrorNoDefault); 
0193:   } 
0194:   xlen=atoi(buf); 
0195:  
0196:   /*Y長*/ 
0197:   if(EOF == readOneValuePPM(buf,fpr) ){ 
0198:     mssShowErrMsg("invalid PPM header"); 
0199:     mssEnd(mssErrorNoDefault); 
0200:   } 
0201:   ylen=atoi(buf); 
0202:  
0203:   /*画素値の最大値*/ 
0204:   if(EOF == readOneValuePPM(buf,fpr) ){ 
0205:     mssShowErrMsg("invalid PPM header"); 
0206:     mssEnd(mssErrorNoDefault); 
0207:   } 
0208:   depth=atoi(buf); 
0209:   
0210:   /*----- データ部読み込み*/ 
0211:   for(y=0; y<ylen; y++){ 
0212:     for(x=0; x<xlen; x++){ 
0213:       /*red*/ 
0214:       if(EOF == readOneValuePPM(bufr,fpr) ){ 
0215:         mssShowErrMsg("inconsistent data size and PPM header"); 
0216:         mssEnd(mssErrorNoDefault); 
0217:       } 
0218:  
0219:       /*green*/ 
0220:       if(EOF == readOneValuePPM(bufg,fpr) ){ 
0221:         mssShowErrMsg("inconsistent data size and PPM header"); 
0222:         mssEnd(mssErrorNoDefault); 
0223:       } 
0224:  
0225:       /*blue*/ 
0226:       if(EOF == readOneValuePPM(bufb,fpr) ){ 
0227:         mssShowErrMsg("inconsistent data size and PPM header"); 
0228:         mssEnd(mssErrorNoDefault); 
0229:       } 
0230:       mssWriteInt(x,fpw); 
0231:       mssWriteDlm(fpw); 
0232:       mssWriteInt(y,fpw); 
0233:       mssWriteDlm(fpw); 
0234:       mssWriteInt(atoi(bufr),fpw); 
0235:       mssWriteDlm(fpw); 
0236:       mssWriteInt(atoi(bufg),fpw); 
0237:       mssWriteDlm(fpw); 
0238:       mssWriteInt(atoi(bufb),fpw); 
0239:       mssWriteRet(fpw); 
0240:       mssGV.outCnt++; 
0241:     } 
0242:   } 
0243:  
0244: /*----------------------------------------------------------------------------*/ 
0245: /*フッター出力&終了処理                                                       */ 
0246: /*----------------------------------------------------------------------------*/ 
0247:   mssWriteFooter(fpw);    /*フッターの出力*/ 
0248:   fclose(fpr);            /*入力ファイルのクローズ*/ 
0249:   mssCloseFPW(fpw);       /*出力ファイルのクローズ*/ 
0250:   mssFreeHeader(hdo);     /*出力ヘッダ領域開放*/ 
0251:   mssFreeOption(opt);     /*オプション領域開放*/ 
0252:   mssShowEndMsg();        /*完了メッセージ*/ 
0253:   mssEnd(mssExitSuccess); /*終了*/ 
0254:   return(0); /* to avoid warning message*/ 
0255: }