恐らく最も何も考えなくても使え、少なくとも結果確認には最良の選択のPNM形式のうち、カラーが扱えるPPMの、吐き出すのが比較的楽そうなP6について、読み込みコードを書いた。
//! @brief PPM(RGB各1byte,カラー,バイナリ)を読み込む //! @param [in] fname ファイル名 //! @param [out] vmax 全てのRGBの中の最大値 //! @param [out] width 画像の幅 //! @param [out] height 画像の高さ //! @param [in] 画像を読み込んだメモリアドレスを返すためのポインタへのポインタ //! @retval true 成功 //! @retval false 失敗 //! @warning RGBが各1byteでないと動作しない //! @details ファイルを読み込み、width*height*3のメモリを確保したうえでRGBをそこへ格納する bool pnmP6_Read(TCHAR* fname, int* vmax, int *width, int *height, unsigned char** p) { // PPM BINARY *width = -1; *height = -1; *vmax = -1; FILE* fp; fp = _tfopen(fname, _T("rb")); char tmp[2048]; char c; while ( c=fgetc(fp)) { if (isspace(c)) continue; if (c == 'P') { //フォーマットを特定する c = fgetc(fp) - '0'; if (c != 6) { fclose(fp); return false; } continue; } if (c == '#') { //コメントを読み飛ばす while (c != '\r' && c != '\n') c = fgetc(fp); continue; } if (*width < 0) { int s = 0; while(1) { if (isdigit(c)) { tmp[s++] = c; c = fgetc(fp); } else { tmp[s] = '\0'; *width = atoi(tmp); break; } } continue; } if (*height < 0) { int s = 0; while (1) { if (isdigit(c)) { tmp[s++] = c; c = fgetc(fp); } else { tmp[s] = '\0'; *height = atoi(tmp); break; } } continue; } if (*vmax < 0) { int s = 0; while (1) { if (isdigit(c)) { tmp[s++] = c; c = fgetc(fp); } else { tmp[s] = '\0'; *vmax = atoi(tmp); break; } } break; } else { break; } } if (*width < 0 || *height < 0 || *vmax < 0) { return false; } const size_t maxsize = *width* *height; unsigned char r, g, b; *p = new unsigned char[maxsize * 3]; for (size_t i = 0; i < maxsize; i++) { fread(&r, 1, 1, fp); fread(&g, 1, 1, fp); fread(&b, 1, 1, fp); (*p)[i * 3 + 0] = r; (*p)[i * 3 + 1] = g; (*p)[i * 3 + 2] = b; } fclose(fp); return true; }