ゆとりーなの日記

日記的な事を書いて行くと思はれる

東方PSP向けの画像変換機

東方のdatファイルは専用の解凍機(brightmoonとか言ったかな)にかければ中のファイルを取り出せます。紅魔の場合は他のwin用のやつとは違って画像がそのままjpegpng形式で出てくるので手間が省けます。
PSPでこれらの画像を表示するには、libpngやらを使えばいいといえばいいのですが、なんか面倒だったので、構造が簡単なDDS形式を使うことにしたのは前述の通りです。DDSはDirectX用の画像形式で、DirectXSDKをいれれば変換機が付いてきます。しかしこいつで変換するだけだと、PSPで読み込むにはRとBが逆なので、これらをひっくり返す変換機を作ることになったのも前述の通りです。
以下ソースです。

#pragma comment(lib, "shlwapi.lib")
#include <fstream>
#include <shlwapi.h>

int main(int argc, char** argv) {
  std::ifstream fin(argv[1], std::ios::in | std::ios::binary);
  fin.clear();
  fin.seekg(0x0c);
  int height;
  fin.read((char *)&height, 4);
  int width;
  fin.read((char *)&width, 4);
  fin.clear();
  fin.seekg(0);
  PathRenameExtension(argv[1], ".img");
  std::ofstream fout(argv[1], std::ios::out | std::ios::binary);
  for (int i = 0; i < 0x80; ++i) {
    char data;
    fin.read(&data, 1);
    fout << data;
  }
  for (int i = 0; i < width * height; ++i) {
    char data[4];
    fin.read(data, 4);
    fout << data[2];
    fout << data[1];
    fout << data[0];
    fout << data[3];
  }
  return 0;
}

透明とか半透明とかがないやつはこれでいいのですが、透明とか半透明とかがあるやつはマスク合成を前提とした感じのファイル構成になっているので、こちらも専用の変換機を作ることになりました。

#pragma comment(lib, "shlwapi.lib")
#include <fstream>
#include <shlwapi.h>

int main(int argc, char** argv) {
  std::ifstream fin(argv[1], std::ios::in | std::ios::binary);
  PathRemoveExtension(argv[1]);
  strcat(argv[1], "_a.dds");
  std::ifstream fin2(argv[1], std::ios::in | std::ios::binary);
  fin.clear();
  fin.seekg(0x0c);
  int height;
  fin.read((char *)&height, 4);
  int width;
  fin.read((char *)&width, 4);
  fin.clear();
  fin.seekg(0);
  fin2.seekg(0x80);
  PathRenameExtension(argv[1], ".img");
  std::ofstream fout(argv[1], std::ios::out | std::ios::binary);
  for (int i = 0; i < 0x80; ++i) {
    char data;
    fin.read(&data, 1);
    fout << data;
  }
  for (int i = 0; i < width * height; ++i) {
    char data[4];
    char data2[4];
    fin.read(data, 4);
    fin2.read(data2, 4);
    std::swap(data[0], data[2]);
    fout << data[2];
    fout << data[1];
    fout << data[0];
    fout << data2[0];
  }
  return 0;
}