CImageLoaderTEX.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #include "CImageLoaderTEX.h"
  5. #include <irrlicht/irrlicht.h>
  6. #include <lz4.h>
  7. #include <wallpaperengine/irrlicht.h>
  8. #include <string>
  9. namespace irr {
  10. namespace video {
  11. //! returns true if the file maybe is able to be loaded by this class
  12. //! based on the file extension (e.g. ".tga")
  13. bool CImageLoaderTex::isALoadableFileExtension (const io::path &filename) const
  14. {
  15. return core::hasFileExtension (filename, "tex");
  16. }
  17. //! returns true if the file maybe is able to be loaded by this class
  18. bool CImageLoaderTex::isALoadableFileFormat (io::IReadFile *file) const
  19. {
  20. return false;
  21. }
  22. // load in the image data
  23. IImage *CImageLoaderTex::loadImage (io::IReadFile *input) const
  24. {
  25. if (!input)
  26. return 0;
  27. video::IImage *image = 0;
  28. char buffer [1024];
  29. if (input->read (buffer, 9) != 9)
  30. {
  31. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot read header\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  32. return 0;
  33. }
  34. if (memcmp (buffer, "TEXV0005", 9) != 0)
  35. {
  36. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: not really a tex\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  37. return 0;
  38. }
  39. if (input->read (buffer, 9) != 9)
  40. {
  41. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot read second header\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  42. return 0;
  43. }
  44. if (memcmp (buffer, "TEXI0001", 9) != 0)
  45. {
  46. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: not really a tex\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  47. return 0;
  48. }
  49. u32 width;
  50. u32 height;
  51. u32 texture_width;
  52. u32 texture_height;
  53. u32 format;
  54. input->read (&format, 4);
  55. input->seek (4, true); // ignore bytes
  56. input->read (&texture_width, 4);
  57. input->read (&texture_height, 4);
  58. input->read (&width, 4);
  59. input->read (&height, 4);
  60. input->seek (4, true); // ignore bytes
  61. input->read (buffer, 9);
  62. if (memcmp (buffer, "TEXB0003", 9) == 0)
  63. {
  64. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: TEXB0003 container not supported yet\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  65. return 0;
  66. }
  67. else if (memcmp (buffer, "TEXB0002", 9) == 0)
  68. {
  69. input->seek (4, true);
  70. }
  71. else
  72. {
  73. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: Unknown container type\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  74. return 0;
  75. }
  76. if (format != TextureFormat::ARGB8888)
  77. {
  78. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: Only ARGB8888 supported\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  79. return 0;
  80. }
  81. u32 mipmap_count = 0;
  82. input->read (&mipmap_count, 4);
  83. u32 mipmap_width = 0;
  84. u32 mipmap_height = 0;
  85. u32 mipmap_compression = 0;
  86. u32 mipmap_uncompressed_size = 0;
  87. u32 mipmap_compressed_size = 0;
  88. input->read (&mipmap_width, 4);
  89. input->read (&mipmap_height, 4);
  90. input->read (&mipmap_compression, 4);
  91. input->read (&mipmap_uncompressed_size, 4);
  92. input->read (&mipmap_compressed_size, 4);
  93. char *decompressedBuffer = new char [mipmap_uncompressed_size];
  94. if (mipmap_compression == 1)
  95. {
  96. char *compressedBuffer = new char [mipmap_compressed_size];
  97. input->read (compressedBuffer, mipmap_compressed_size);
  98. int result = LZ4_decompress_safe (compressedBuffer, decompressedBuffer, mipmap_compressed_size, mipmap_uncompressed_size);
  99. if (!result)
  100. {
  101. delete [] decompressedBuffer;
  102. delete [] compressedBuffer;
  103. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot decompress texture data\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  104. return 0;
  105. }
  106. delete [] compressedBuffer;
  107. }
  108. else
  109. {
  110. input->read (decompressedBuffer, mipmap_uncompressed_size);
  111. }
  112. image = wp::irrlicht::driver->createImage (ECF_A8R8G8B8, irr::core::dimension2d<u32> (texture_width, texture_height));
  113. if (!image)
  114. {
  115. delete [] decompressedBuffer;
  116. delete image;
  117. wp::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot create destination image\n", input->getFileName ().c_str (), irr::ELL_ERROR);
  118. return 0;
  119. }
  120. u32 bytesPerPixel = image->getBytesPerPixel ();
  121. char *imagedata = (char *) image->lock ();
  122. for (u32 y = 0; y < height; y++)
  123. {
  124. u32 baseDestination = y * image->getPitch ();
  125. u32 baseOrigin = y * (texture_width * 4);
  126. for (u32 x = 0; x < width; x++)
  127. {
  128. imagedata[baseDestination + (x * bytesPerPixel) + 0] = decompressedBuffer[baseOrigin + ((texture_width - x) * 4) + 0];
  129. imagedata[baseDestination + (x * bytesPerPixel) + 1] = decompressedBuffer[baseOrigin + ((texture_width - x) * 4) + 1];
  130. imagedata[baseDestination + (x * bytesPerPixel) + 2] = decompressedBuffer[baseOrigin + ((texture_width - x) * 4) + 2];
  131. imagedata[baseDestination + (x * bytesPerPixel) + 3] = decompressedBuffer[baseOrigin + ((texture_width - x) * 4) + 3];
  132. }
  133. }
  134. image->unlock ();
  135. delete [] decompressedBuffer;
  136. return image;
  137. }
  138. }// end namespace irr
  139. }//end namespace video