ddsHandler.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /**
  2. * Copyright (c) 2006-2017 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "ddsHandler.h"
  21. #include "common/Exception.h"
  22. namespace love
  23. {
  24. namespace image
  25. {
  26. namespace magpie
  27. {
  28. bool DDSHandler::canParseCompressed(Data *data)
  29. {
  30. return dds::isCompressedDDS(data->getData(), data->getSize());
  31. }
  32. StrongRef<CompressedMemory> DDSHandler::parseCompressed(Data *filedata, std::vector<StrongRef<CompressedSlice>> &images, PixelFormat &format, bool &sRGB)
  33. {
  34. if (!dds::isDDS(filedata->getData(), filedata->getSize()))
  35. throw love::Exception("Could not decode compressed data (not a DDS file?)");
  36. PixelFormat texformat = PIXELFORMAT_UNKNOWN;
  37. bool isSRGB = false;
  38. StrongRef<CompressedMemory> memory;
  39. size_t dataSize = 0;
  40. images.clear();
  41. // Attempt to parse the dds file.
  42. dds::Parser parser(filedata->getData(), filedata->getSize());
  43. texformat = convertFormat(parser.getFormat(), isSRGB);
  44. if (texformat == PIXELFORMAT_UNKNOWN)
  45. throw love::Exception("Could not parse compressed data: Unsupported format.");
  46. if (parser.getMipmapCount() == 0)
  47. throw love::Exception("Could not parse compressed data: No readable texture data.");
  48. // Calculate the size of the block of memory we're returning.
  49. for (size_t i = 0; i < parser.getMipmapCount(); i++)
  50. {
  51. const dds::Image *img = parser.getImageData(i);
  52. dataSize += img->dataSize;
  53. }
  54. memory.set(new CompressedMemory(dataSize), Acquire::NORETAIN);
  55. size_t dataOffset = 0;
  56. // Copy the parsed mipmap levels from the FileData to our CompressedImageData.
  57. for (size_t i = 0; i < parser.getMipmapCount(); i++)
  58. {
  59. // Fetch the data for this mipmap level.
  60. const dds::Image *img = parser.getImageData(i);
  61. // Copy the mipmap image from the FileData to our block of memory.
  62. memcpy(memory->data + dataOffset, img->data, img->dataSize);
  63. auto slice = new CompressedSlice(texformat, img->width, img->height, memory, dataOffset, img->dataSize);
  64. images.emplace_back(slice, Acquire::NORETAIN);
  65. dataOffset += img->dataSize;
  66. }
  67. format = texformat;
  68. sRGB = isSRGB;
  69. return memory;
  70. }
  71. PixelFormat DDSHandler::convertFormat(dds::Format ddsformat, bool &sRGB)
  72. {
  73. sRGB = false;
  74. switch (ddsformat)
  75. {
  76. case dds::FORMAT_DXT1:
  77. return PIXELFORMAT_DXT1;
  78. case dds::FORMAT_DXT3:
  79. return PIXELFORMAT_DXT3;
  80. case dds::FORMAT_DXT5:
  81. return PIXELFORMAT_DXT5;
  82. case dds::FORMAT_BC4:
  83. return PIXELFORMAT_BC4;
  84. case dds::FORMAT_BC4s:
  85. return PIXELFORMAT_BC4s;
  86. case dds::FORMAT_BC5:
  87. return PIXELFORMAT_BC5;
  88. case dds::FORMAT_BC5s:
  89. return PIXELFORMAT_BC5s;
  90. case dds::FORMAT_BC6H:
  91. return PIXELFORMAT_BC6H;
  92. case dds::FORMAT_BC6Hs:
  93. return PIXELFORMAT_BC6Hs;
  94. case dds::FORMAT_BC7:
  95. return PIXELFORMAT_BC7;
  96. case dds::FORMAT_BC7srgb:
  97. sRGB = true;
  98. return PIXELFORMAT_BC7;
  99. default:
  100. return PIXELFORMAT_UNKNOWN;
  101. }
  102. }
  103. } // magpie
  104. } // image
  105. } // love