ImageData.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "ImageData.h"
  2. #include "ImageUtils.h"
  3. USING_NS_BF;
  4. ImageData::ImageData()
  5. {
  6. mSrcData = NULL;
  7. mOwnsSrcData = false;
  8. mKeepSrcDataValid = false;
  9. mBits = NULL;
  10. mHWBitsType = 0;
  11. mHWBitsLength = 0;
  12. mHWBits = NULL;
  13. mX = 0;
  14. mY = 0;
  15. mWidth = 0;
  16. mHeight = 0;
  17. mStride = 0;
  18. mWantsAlphaPremultiplied = true;
  19. mAlphaPremultiplied = false;
  20. mIsAdditive = false;
  21. mSrcDataLen = 0;
  22. mRefCount = 1;
  23. }
  24. ImageData::~ImageData()
  25. {
  26. BF_ASSERT(mRefCount <= 1); // Allow direct delete if we only have one reference
  27. delete [] mBits;
  28. delete [] mSrcData;
  29. }
  30. void ImageData::AddRef()
  31. {
  32. mRefCount++;
  33. }
  34. void ImageData::Deref()
  35. {
  36. if (--mRefCount == 0)
  37. delete this;
  38. }
  39. void ImageData::SwapRAndB()
  40. {
  41. int aSize = mWidth*mHeight;
  42. uint32* aPtr = mBits;
  43. for (int i = 0; i < aSize; i++)
  44. {
  45. uint32 aColor = *aPtr;
  46. int a = (aColor & 0xFF000000) >> 24;
  47. int r = (aColor & 0x00FF0000) >> 16;
  48. int g = (aColor & 0x0000FF00) >> 8;
  49. int b = (aColor & 0x000000FF);
  50. *(aPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
  51. }
  52. }
  53. void ImageData::CreateNew(int x, int y, int width, int height, bool clear)
  54. {
  55. CreateNew(width, height, clear);
  56. mX = x;
  57. mY = y;
  58. }
  59. void ImageData::CreateNew(int width, int height, bool clear)
  60. {
  61. mWidth = mStride = width;
  62. mHeight = height;
  63. mBits = new uint32[mWidth*mHeight];
  64. if (clear)
  65. memset(mBits, 0, mWidth*mHeight*sizeof(uint32));
  66. }
  67. void ImageData::CopyFrom(ImageData* img, int x, int y)
  68. {
  69. int destStartX = BF_MAX(x + img->mX - mX, 0);
  70. int destStartY = BF_MAX(y + img->mY - mY, 0);
  71. int destEndX = BF_MIN(x + img->mX - mX + img->mWidth, mWidth);
  72. int destEndY = BF_MIN(y + img->mY - mY + img->mHeight, mHeight);
  73. int srcXOfs = -x - img->mX;
  74. int srcYOfs = -y - img->mY;
  75. for (int y = destStartY; y < destEndY; y++)
  76. {
  77. for (int x = destStartX; x < destEndX; x++)
  78. {
  79. mBits[x + y * mStride] = img->mBits[(x + srcXOfs) + (y + srcYOfs)*img->mStride];
  80. }
  81. }
  82. }
  83. void ImageData::Fill(uint32 color)
  84. {
  85. int size = mWidth*mHeight;
  86. for (int i = 0; i < size; i++)
  87. mBits[i] = color;
  88. }
  89. ImageData* ImageData::Duplicate()
  90. {
  91. ImageData* copy = new ImageData();
  92. copy->CreateNew(mWidth, mHeight);
  93. copy->mX = mX;
  94. copy->mY = mY;
  95. copy->mAlphaPremultiplied = mAlphaPremultiplied;
  96. copy->mIsAdditive = mIsAdditive;
  97. memcpy(copy->mBits, mBits, mWidth*mHeight*sizeof(uint32));
  98. return copy;
  99. }
  100. bool ImageData::LoadFromMemory(void* ptr, int size)
  101. {
  102. SetSrcData((uint8*)ptr, size);
  103. bool result = ReadData();
  104. mSrcData = NULL;
  105. return result;
  106. }
  107. bool ImageData::LoadFromFile(const StringImpl& path)
  108. {
  109. int size = 0;
  110. uint8* aData = LoadBinaryData(path, &size);
  111. if (aData == NULL)
  112. return false;
  113. SetSrcData(aData, size);
  114. bool result = ReadData();
  115. if (mKeepSrcDataValid)
  116. {
  117. mOwnsSrcData = true;
  118. }
  119. else
  120. {
  121. delete [] mSrcData;
  122. mSrcData = NULL;
  123. }
  124. return result;
  125. }
  126. void ImageData::SetSrcData(uint8* data, int dataLen)
  127. {
  128. mSrcData = data;
  129. mSrcDataLen = dataLen;
  130. }
  131. void ImageData::PremultiplyAlpha()
  132. {
  133. if (mBits == NULL)
  134. return;
  135. if (!mAlphaPremultiplied)
  136. {
  137. mAlphaPremultiplied = true;
  138. int size = mWidth*mHeight;
  139. for (int i = 0; i < size; i++)
  140. {
  141. PackedColor* packedColor = (PackedColor*) (mBits + i);
  142. packedColor->r = (packedColor->r * packedColor->a) / 255;
  143. packedColor->g = (packedColor->g * packedColor->a) / 255;
  144. packedColor->b = (packedColor->b * packedColor->a) / 255;
  145. if (mIsAdditive)
  146. packedColor->a = 0;
  147. }
  148. }
  149. }
  150. void ImageData::UnPremultiplyAlpha()
  151. {
  152. if (mBits == NULL)
  153. return;
  154. if (mAlphaPremultiplied)
  155. {
  156. mAlphaPremultiplied = false;
  157. int size = mWidth * mHeight;
  158. for (int i = 0; i < size; i++)
  159. {
  160. PackedColor* packedColor = (PackedColor*)(mBits + i);
  161. if (packedColor->a != 0)
  162. {
  163. packedColor->r = BF_MIN((packedColor->r * 255) / packedColor->a, 255);
  164. packedColor->g = BF_MIN((packedColor->g * 255) / packedColor->a, 255);
  165. packedColor->b = BF_MIN((packedColor->b * 255) / packedColor->a, 255);
  166. }
  167. if (mIsAdditive)
  168. packedColor->a = 0;
  169. }
  170. }
  171. }