SkMallocPixelRef.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright 2011 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkData.h"
  8. #include "include/core/SkImageInfo.h"
  9. #include "include/core/SkMallocPixelRef.h"
  10. #include "include/private/SkMalloc.h"
  11. #include "src/core/SkSafeMath.h"
  12. void* sk_calloc_throw(size_t count, size_t elemSize) {
  13. return sk_calloc_throw(SkSafeMath::Mul(count, elemSize));
  14. }
  15. void* sk_malloc_throw(size_t count, size_t elemSize) {
  16. return sk_malloc_throw(SkSafeMath::Mul(count, elemSize));
  17. }
  18. void* sk_realloc_throw(void* buffer, size_t count, size_t elemSize) {
  19. return sk_realloc_throw(buffer, SkSafeMath::Mul(count, elemSize));
  20. }
  21. void* sk_malloc_canfail(size_t count, size_t elemSize) {
  22. return sk_malloc_canfail(SkSafeMath::Mul(count, elemSize));
  23. }
  24. ///////////////////////////////////////////////////////////////////////////////////////////////////
  25. // assumes ptr was allocated via sk_malloc
  26. static void sk_free_releaseproc(void* ptr, void*) {
  27. sk_free(ptr);
  28. }
  29. static bool is_valid(const SkImageInfo& info) {
  30. if (info.width() < 0 || info.height() < 0 ||
  31. (unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType ||
  32. (unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType)
  33. {
  34. return false;
  35. }
  36. return true;
  37. }
  38. sk_sp<SkPixelRef> SkMallocPixelRef::MakeDirect(const SkImageInfo& info,
  39. void* addr,
  40. size_t rowBytes) {
  41. if (!is_valid(info)) {
  42. return nullptr;
  43. }
  44. return sk_sp<SkPixelRef>(new SkMallocPixelRef(info, addr, rowBytes, nullptr, nullptr));
  45. }
  46. sk_sp<SkPixelRef> SkMallocPixelRef::MakeAllocate(const SkImageInfo& info, size_t rowBytes) {
  47. if (rowBytes == 0) {
  48. rowBytes = info.minRowBytes();
  49. // rowBytes can still be zero, if it overflowed (width * bytesPerPixel > size_t)
  50. // or if colortype is unknown
  51. }
  52. if (!is_valid(info) || !info.validRowBytes(rowBytes)) {
  53. return nullptr;
  54. }
  55. size_t size = 0;
  56. if (!info.isEmpty() && rowBytes) {
  57. size = info.computeByteSize(rowBytes);
  58. if (SkImageInfo::ByteSizeOverflowed(size)) {
  59. return nullptr;
  60. }
  61. }
  62. void* addr = sk_calloc_canfail(size);
  63. if (nullptr == addr) {
  64. return nullptr;
  65. }
  66. return sk_sp<SkPixelRef>(new SkMallocPixelRef(info, addr, rowBytes,
  67. sk_free_releaseproc, nullptr));
  68. }
  69. static void sk_data_releaseproc(void*, void* dataPtr) {
  70. (static_cast<SkData*>(dataPtr))->unref();
  71. }
  72. sk_sp<SkPixelRef> SkMallocPixelRef::MakeWithProc(const SkImageInfo& info,
  73. size_t rowBytes,
  74. void* addr,
  75. SkMallocPixelRef::ReleaseProc proc,
  76. void* context) {
  77. if (!is_valid(info)) {
  78. if (proc) {
  79. proc(addr, context);
  80. }
  81. return nullptr;
  82. }
  83. return sk_sp<SkPixelRef>(new SkMallocPixelRef(info, addr, rowBytes, proc, context));
  84. }
  85. sk_sp<SkPixelRef> SkMallocPixelRef::MakeWithData(const SkImageInfo& info,
  86. size_t rowBytes,
  87. sk_sp<SkData> data) {
  88. SkASSERT(data != nullptr);
  89. if (!is_valid(info)) {
  90. return nullptr;
  91. }
  92. // TODO: what should we return if computeByteSize returns 0?
  93. // - the info was empty?
  94. // - we overflowed computing the size?
  95. if ((rowBytes < info.minRowBytes()) || (data->size() < info.computeByteSize(rowBytes))) {
  96. return nullptr;
  97. }
  98. // must get this address before we call release
  99. void* pixels = const_cast<void*>(data->data());
  100. SkPixelRef* pr = new SkMallocPixelRef(info, pixels, rowBytes,
  101. sk_data_releaseproc, data.release());
  102. pr->setImmutable(); // since we were created with (immutable) data
  103. return sk_sp<SkPixelRef>(pr);
  104. }
  105. ///////////////////////////////////////////////////////////////////////////////
  106. SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage,
  107. size_t rowBytes,
  108. SkMallocPixelRef::ReleaseProc proc,
  109. void* context)
  110. : INHERITED(info.width(), info.height(), storage, rowBytes)
  111. , fReleaseProc(proc)
  112. , fReleaseProcContext(context)
  113. {}
  114. SkMallocPixelRef::~SkMallocPixelRef() {
  115. if (fReleaseProc != nullptr) {
  116. fReleaseProc(this->pixels(), fReleaseProcContext);
  117. }
  118. }