// ビットマップファイル縦方向等分割ツール T.KOHNO '99/09/22 #include #include #include typedef struct { /* ファイルヘッダ */ char type[ 2 ]; /* ファイルのID (固定 "BM") */ char fsize[ 4 ]; /* ファイルのサイズ */ char reserve1[ 2 ]; /* 予約1 */ char reserve2[ 2 ]; /* 予約2 */ char fhsize[ 4 ]; /* ファイルヘッダ+情報ヘッダのサイズ (54固定) */ /* 情報ヘッダ */ char infosize[ 4 ]; /* このヘッダのサイズ(40固定) */ char wsize[ 4 ]; /* イメージの幅 */ char hsize[ 4 ]; /* イメージの高さ */ char planes[ 2 ]; /* プレーン数 (1固定) */ char bitcount[ 2 ]; /* ピクセルあたりのビット数 (24固定) */ char compress[ 4 ]; /* 圧縮方式 (0固定) */ char imgsize[ 4 ]; /* イメージサイズ */ char xppm[ 4 ]; /* 水平解像度(0固定) */ char yppm[ 4 ]; /* 垂直解像度(0固定) */ char clrused[ 4 ]; /* 色数(0固定) */ char clrimportant[ 4 ]; /* 重要色数(0固定) */ } BMPHeader; #define TOC(x, y) {x[0] = y & 0x0ff; \ x[1] = (y >> 8) & 0x0ff; \ x[2] = (y >> 16) & 0x0ff; \ x[3] = (y >> 24) & 0x0ff;} #define TOI(x) (((unsigned char)x[3] << 24) + ((unsigned char)x[2] << 16) + ((unsigned char)x[1] << 8) + (unsigned char)x[0]) void PrintUsage(void); // メイン int main(int argc, char* argv[]) { // 引数の解析 for( ;argc > 1 && argv[1][0] == '-'; argv++,argc--){ switch(argv[1][1]){ case '?': // 使い方の表示 case 'h': PrintUsage(); argv++,argc--; return 1; default: break; } } // 引数がない場合は USAGE を表示して終了 if (argc<2){ PrintUsage(); return 1; } // 第1引数で指定されたファイルをオープン FILE* fp; if (!(fp = fopen(argv[1], "rb"))){ perror("Can't open file."); return 1; } // ヘッダ情報の読み込み BMPHeader Header; fseek(fp, SEEK_SET, 0); if (fread(&Header, 1, sizeof(BMPHeader), fp) < sizeof(BMPHeader)){ if (ferror(fp)){ perror("Can't read header.\n"); } else { fprintf(stderr, "File length is less than BITMAP header.\n"); } return 1; } // 分割数が与えられないときはファイルのピクセル数を表示して終了 if (argc==2){ fprintf(stdout, "Width %d, Height %d\n", TOI(Header.wsize), TOI(Header.hsize)); return 0; } // 第2引数から分割数を取得し各画像の縦方向のピクセル数・データサイズを計算 int lp; int num; int lines; if ((num = atoi(argv[2])) < 1){ fprintf(stderr, "Number is must larger than 0.\n"); return 1; } if ((lines = TOI(Header.hsize) / num) == 0){ fprintf(stderr, "Can't split %d. Because hight is %d.\n", num, Header.hsize); } char* pBuf; unsigned int buflen; int mod = ( 2 - (TOI(Header.wsize) % 2)); buflen = lines * (TOI(Header.wsize) * 3 + mod); if (!(pBuf = (char*)malloc(buflen))){ perror("Can't allocate memory.\n"); return 1; } char newfile[_MAX_PATH]; FILE* ofp; TOC(Header.hsize, lines); TOC(Header.fsize, buflen); // 指定された分割数分だけファイルを作成する。 for (lp=0; lp