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: }