MCPcopy Create free account
hub / github.com/OpenNFS/OpenNFS / ExtractPSH

Function ExtractPSH

src/Util/Utils.cpp:366–517  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

364 }
365
366 bool ExtractPSH(const std::string &psh_path, const std::string &output_path) {
367 using namespace NFS2_DATA;
368
369 LOG(INFO) << "Extracting PSH file: " << psh_path << " to " << output_path;
370
371 if (boost::filesystem::exists(output_path)) {
372 LOG(INFO) << "Textures already exist at " << output_path << ". Nothing to extract.";
373 return true;
374 }
375
376 boost::filesystem::create_directories(output_path);
377 ifstream psh(psh_path, ios::in | ios::binary);
378
379 PS1::PSH::HEADER *pshHeader = new PS1::PSH::HEADER();
380
381 // Check we're in a valid TRK file
382 if (psh.read(((char *) pshHeader), sizeof(PS1::PSH::HEADER)).gcount() != sizeof(PS1::PSH::HEADER)) {
383 LOG(WARNING) << "Couldn't open file/truncated.";
384 delete pshHeader;
385 return false;
386 }
387
388 LOG(INFO) << pshHeader->nDirectories << " images inside PSH";
389
390 // Header should contain TRAC
391 if (memcmp(pshHeader->header, "SHPP", sizeof(pshHeader->header)) != 0 &&
392 memcmp(pshHeader->chk, "GIMX", sizeof(pshHeader->chk)) != 0) {
393 LOG(WARNING) << "Invalid PSH Header(s).";
394 delete pshHeader;
395 return false;
396 }
397
398 // Get the offsets to each image in the PSH
399 auto *directoryEntries = new PS1::PSH::DIR_ENTRY[pshHeader->nDirectories];
400 psh.read(((char *) directoryEntries), pshHeader->nDirectories * sizeof(PS1::PSH::DIR_ENTRY));
401
402 for (uint32_t image_Idx = 0; image_Idx < pshHeader->nDirectories; ++image_Idx) {
403 LOG(INFO) << "Extracting GIMX " << image_Idx << ": " << directoryEntries[image_Idx].imageName[0] << directoryEntries[image_Idx].imageName[1] << directoryEntries[image_Idx].imageName[2] << directoryEntries[image_Idx].imageName[3] << ".BMP";
404 psh.seekg(directoryEntries[image_Idx].imageOffset, ios_base::beg);
405 auto *imageHeader = new PS1::PSH::IMAGE_HEADER();
406 psh.read(((char *) imageHeader), sizeof(PS1::PSH::IMAGE_HEADER));
407
408 uint8_t bitDepth = static_cast<uint8_t>(imageHeader->imageType & 0x3);
409 uint32_t *pixels = new uint32_t[imageHeader->width * imageHeader->height];
410 uint8_t *indexPair = new uint8_t();
411 uint8_t *indexes = new uint8_t[imageHeader->width * imageHeader->height]; // Only used if indexed
412 bool hasAlpha = false;
413 bool isPadded = false;
414 if (bitDepth == 0) {
415 isPadded = (imageHeader->width % 4 == 1) || (imageHeader->width % 4 == 2);
416 } else if (bitDepth == 1 || bitDepth == 3) {
417 isPadded = imageHeader->width % 2 == 1;
418 }
419
420 for (int y = 0; y < imageHeader->height; y++) {
421 for (int x = 0; x < imageHeader->width; x++) {
422 switch (bitDepth) {
423 case 0: { // 4-bit indexed colour

Callers 2

ExtractTrackTexturesFunction · 0.85
LoadCarMethod · 0.85

Calls 2

abgr1555ToARGB8888Function · 0.85
SaveImageFunction · 0.85

Tested by

no test coverage detected