DdsSubfile.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. ///
  2. // Created by Иван_Архипов on 24.11.2017.
  3. //
  4. #include "DdsSubfile.h"
  5. #include "../BinaryData.h"
  6. #include "../DatFile.h"
  7. #include "../Common/DatException.h"
  8. namespace LOTRO_DAT {
  9. DdsSubfile::DdsSubfile() {}
  10. DdsSubfile::DdsSubfile(DatFile *dat, long long fragments_count, long long unknown1,
  11. long long file_id, long long file_offset, long long file_size,
  12. long long timestamp,
  13. long long version, long long block_size)
  14. : Subfile(dat, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size) {
  15. BinaryData header(20);
  16. dat_->ReadData(header, 10, file_offset_ + 8);
  17. compressed_ = header.CheckCompression();
  18. }
  19. FILE_TYPE DdsSubfile::FileType() const {
  20. return DDS;
  21. }
  22. std::string DdsSubfile::Extension() const {
  23. return ".dds";
  24. }
  25. bool DdsSubfile::PrepareForExport(const BinaryData &file_data, long long &export_size, std::vector<BinaryData> &binary_data,
  26. std::vector<std::u16string> &text_data, std::vector<YAML::Node> &options) {
  27. BinaryData data = file_data;
  28. if (compressed_)
  29. data = data.DecompressData(4);
  30. BinaryData ddsData(data.size() - 24 + 128);
  31. for (int i = 0; i < 128; i++)
  32. ddsData[i] = 0;
  33. memcpy(ddsData.data() + 128, data.data() + 24, data.size() - 24);
  34. ddsData[0] = 0x44; // D
  35. ddsData[1] = 0x44; // D
  36. ddsData[2] = 0x53; // S
  37. ddsData[3] = 0x20;
  38. ddsData[4] = 0x7C;
  39. ddsData[8] = 7;
  40. ddsData[9] = 0x10;
  41. // width, height
  42. ddsData[12] = data[12];
  43. ddsData[13] = data[13];
  44. ddsData[14] = data[14];
  45. ddsData[15] = data[15];
  46. ddsData[16] = data[8];
  47. ddsData[17] = data[9];
  48. ddsData[18] = data[10];
  49. ddsData[19] = data[11];
  50. long long compression = data.ToNumber<4>(0x10);
  51. switch (compression) {
  52. case 20: // 14 00 00 00 - 888 (R8G8B8)
  53. ddsData[0x4C] = 0x20; // ?
  54. ddsData[0x50] = 0x40; // compressed or not
  55. ddsData[0x58] = 0x18; // bytes per pixel
  56. ddsData[0x5E] = 0xFF;
  57. ddsData[0x61] = 0xFF;
  58. ddsData[0x64] = 0xFF;
  59. break;
  60. case 21: // 15 00 00 00 - 8888 (R8G8B8A8)
  61. ddsData[0x4C] = 0x20; // ?
  62. ddsData[0x50] = 0x40; // compressed or not
  63. ddsData[0x58] = 0x20; // bytes per pixel
  64. ddsData[0x5E] = 0xFF;
  65. ddsData[0x61] = 0xFF;
  66. ddsData[0x64] = 0xFF;
  67. ddsData[0x6B] = 0xFF;
  68. break;
  69. case 28: // 1C 00 00 00 - 332 (?)
  70. ddsData[0x4C] = 0x20; // ?
  71. ddsData[0x50] = 0x40; // compressed or not
  72. ddsData[0x58] = 0x08; // bytes per pixel
  73. ddsData[0x5E] = 0xFF;
  74. ddsData[0x61] = 0xFF;
  75. ddsData[0x64] = 0xFF;
  76. break;
  77. case 827611204: // 44 58 54 31 - DXT1
  78. ddsData[76] = 32;
  79. ddsData[80] = 4;
  80. ddsData[84] = 68;
  81. ddsData[85] = 88;
  82. ddsData[86] = 84;
  83. ddsData[87] = 49;
  84. break;
  85. case 861165636: // 44 58 54 33 - DXT3
  86. ddsData[22] = 1;
  87. ddsData[76] = 32;
  88. ddsData[80] = 4;
  89. ddsData[84] = 68;
  90. ddsData[85] = 88;
  91. ddsData[86] = 84;
  92. ddsData[87] = 51;
  93. ddsData[108] = 8;
  94. ddsData[109] = 16;
  95. ddsData[110] = 64;
  96. break;
  97. case 894720068: // 44 58 54 35 - DXT5
  98. ddsData[10] = 8;
  99. ddsData[22] = 1;
  100. ddsData[28] = 1;
  101. ddsData[76] = 32;
  102. ddsData[80] = 4;
  103. ddsData[84] = 68;
  104. ddsData[85] = 88;
  105. ddsData[86] = 84;
  106. ddsData[87] = 53;
  107. ddsData[88] = 32;
  108. ddsData[94] = 255;
  109. ddsData[97] = 255;
  110. ddsData[100] = 255;
  111. ddsData[107] = 255;
  112. ddsData[109] = 16;
  113. break;
  114. default:
  115. throw DatException("Bad DdsSubfile::PrepareAsBinary() - unknown header format.", EXPORT_EXCEPTION);
  116. }
  117. export_size = 1;
  118. binary_data.emplace_back(ddsData);
  119. text_data.emplace_back(u"");
  120. options.emplace_back(YAML::Node());
  121. options[0]["file_id"] = file_id();
  122. options[0]["extension"] = Extension();
  123. return true;
  124. }
  125. BinaryData DdsSubfile::MakeForImport(const BinaryData &old_data, const BinaryData &binary_data, const std::u16string &text_data,
  126. const YAML::Node &options) {
  127. if (!options["extension"] || options["extension"].as<std::string>() != Extension() ||
  128. !options["file_id"] || options["file_id"].as<long long>() != file_id()) {
  129. throw DatException("Bad DdsSubfile::MakeForImport() - invalid options data!", IMPORT_EXCEPTION);
  130. }
  131. if (compressed_)
  132. return old_data.CutData(0, 12) + (old_data.CutData(12, 16) + binary_data.CutData(128)).CompressData();
  133. else
  134. return old_data.CutData(0, 16) + binary_data.CutData(128);
  135. }
  136. };