PVRTC_Compress.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /******************************************************************************
  2. Have to keep this as a separate file, so it won't be linked if unused.
  3. Because it's linked separately, its name can't include spaces (due to Android building toolchain).
  4. /******************************************************************************/
  5. #include "stdafx.h"
  6. /******************************************************************************/
  7. #include "../../../../ThirdPartyLibs/begin.h"
  8. #include "../../../../ThirdPartyLibs/PVRTC/PVRTex/PVRTextureDefines.h"
  9. #include "../../../../ThirdPartyLibs/end.h"
  10. /******************************************************************************/
  11. namespace EE{
  12. /******************************************************************************/
  13. extern Bool _CompressPVRTC(Int w, Int h, CPtr data, Int type, Int quality, Ptr &compressed_data, Int &compressed_size);
  14. /******************************************************************************/
  15. Bool _CompressPVRTC(C Image &src, Image &dest, Int quality)
  16. {
  17. Bool ok=false;
  18. if((dest.hwType()==IMAGE_PVRTC1_2 || dest.hwType()==IMAGE_PVRTC1_4) && src.lockRead())
  19. {
  20. if(dest.lock(LOCK_WRITE))
  21. {
  22. Image temp; if(temp.createTry(PaddedWidth(dest.w(), dest.h(), 0, dest.hwType()), PaddedHeight(dest.w(), dest.h(), 0, dest.hwType()), 1, IMAGE_R8G8B8A8, IMAGE_SOFT, 1)) // use R8G8B8A8 because PVRTEX operates on that format
  23. {
  24. ok=true;
  25. REPD(z, dest.d())
  26. {
  27. // copy 'src' to 'temp'
  28. REPD(y, temp.h())
  29. REPD(x, temp.w())temp.color(x, y, src.color3D(Min(x, src.w()-1), Min(y, src.h()-1), z)); // use clamping to avoid black borders
  30. // compress
  31. Ptr data=null;
  32. Int size=0;
  33. if(quality<0)quality=((dest.hwType()==IMAGE_PVRTC1_2) ? GetPVRTCQuality() : 4); // for PVRTC1_2 default to specified settings, for others use best quality as it's not so slow for those types
  34. switch(quality)
  35. {
  36. case 0: quality=pvrtexture::ePVRTCFastest; break;
  37. case 1: quality=pvrtexture::ePVRTCFast ; break;
  38. case 2: quality=pvrtexture::ePVRTCNormal ; break;
  39. case 3: quality=pvrtexture::ePVRTCHigh ; break;
  40. default: quality=pvrtexture::ePVRTCBest ; break;
  41. }
  42. if(_CompressPVRTC(temp.w(), temp.h(), temp.data(), (dest.hwType()==IMAGE_PVRTC1_2) ? ePVRTPF_PVRTCI_2bpp_RGBA : ePVRTPF_PVRTCI_4bpp_RGBA, quality, data, size))
  43. {
  44. if(size==temp.w()*temp.h()*ImageTI[dest.hwType()].bit_pp/8)
  45. {
  46. Byte *dest_data=dest.data() + z*dest.pitch2();
  47. Int pitch=ImagePitch (temp.w(), temp.h(), 0, dest.hwType()), // compressed pitch of 'data'
  48. blocks_y=ImageBlocksY(dest.w(), dest.h(), 0, dest.hwType());
  49. REPD(y, blocks_y)Copy(dest_data + y*dest.pitch(), (Byte*)data + y*pitch, dest.pitch(), pitch); // zero remaining Pow2Padded data to avoid garbage
  50. Int written=blocks_y*dest.pitch(); Zero(dest_data+written, dest.pitch2()-written); // zero remaining Pow2Padded data to avoid garbage
  51. }else ok=false;
  52. free(data); // was allocated using 'malloc'
  53. }else ok=false;
  54. if(!ok)break;
  55. }
  56. }
  57. dest.unlock();
  58. }
  59. src.unlock();
  60. }
  61. return ok;
  62. }
  63. /******************************************************************************/
  64. }
  65. /******************************************************************************/