ImageData.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright (c) 2010 LearnBoost <tj@learnboost.com>
  2. #include "ImageData.h"
  3. using namespace v8;
  4. Nan::Persistent<FunctionTemplate> ImageData::constructor;
  5. /*
  6. * Initialize ImageData.
  7. */
  8. void
  9. ImageData::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
  10. Nan::HandleScope scope;
  11. // Constructor
  12. Local<FunctionTemplate> ctor = Nan::New<FunctionTemplate>(ImageData::New);
  13. constructor.Reset(ctor);
  14. ctor->InstanceTemplate()->SetInternalFieldCount(1);
  15. ctor->SetClassName(Nan::New("ImageData").ToLocalChecked());
  16. // Prototype
  17. Local<ObjectTemplate> proto = ctor->PrototypeTemplate();
  18. Nan::SetAccessor(proto, Nan::New("width").ToLocalChecked(), GetWidth);
  19. Nan::SetAccessor(proto, Nan::New("height").ToLocalChecked(), GetHeight);
  20. Local<Context> ctx = Nan::GetCurrentContext();
  21. Nan::Set(target, Nan::New("ImageData").ToLocalChecked(), ctor->GetFunction(ctx).ToLocalChecked());
  22. }
  23. /*
  24. * Initialize a new ImageData object.
  25. */
  26. NAN_METHOD(ImageData::New) {
  27. if (!info.IsConstructCall()) {
  28. return Nan::ThrowTypeError("Class constructors cannot be invoked without 'new'");
  29. }
  30. Local<TypedArray> dataArray;
  31. uint32_t width;
  32. uint32_t height;
  33. int length;
  34. if (info[0]->IsUint32() && info[1]->IsUint32()) {
  35. width = Nan::To<uint32_t>(info[0]).FromMaybe(0);
  36. if (width == 0) {
  37. Nan::ThrowRangeError("The source width is zero.");
  38. return;
  39. }
  40. height = Nan::To<uint32_t>(info[1]).FromMaybe(0);
  41. if (height == 0) {
  42. Nan::ThrowRangeError("The source height is zero.");
  43. return;
  44. }
  45. length = width * height * 4; // ImageData(w, h) constructor assumes 4 BPP; documented.
  46. dataArray = Uint8ClampedArray::New(ArrayBuffer::New(Isolate::GetCurrent(), length), 0, length);
  47. } else if (info[0]->IsUint8ClampedArray() && info[1]->IsUint32()) {
  48. dataArray = info[0].As<Uint8ClampedArray>();
  49. length = dataArray->Length();
  50. if (length == 0) {
  51. Nan::ThrowRangeError("The input data has a zero byte length.");
  52. return;
  53. }
  54. // Don't assert that the ImageData length is a multiple of four because some
  55. // data formats are not 4 BPP.
  56. width = Nan::To<uint32_t>(info[1]).FromMaybe(0);
  57. if (width == 0) {
  58. Nan::ThrowRangeError("The source width is zero.");
  59. return;
  60. }
  61. // Don't assert that the byte length is a multiple of 4 * width, ditto.
  62. if (info[2]->IsUint32()) { // Explicit height given
  63. height = Nan::To<uint32_t>(info[2]).FromMaybe(0);
  64. } else { // Calculate height assuming 4 BPP
  65. int size = length / 4;
  66. height = size / width;
  67. }
  68. } else if (info[0]->IsUint16Array() && info[1]->IsUint32()) { // Intended for RGB16_565 format
  69. dataArray = info[0].As<Uint16Array>();
  70. length = dataArray->Length();
  71. if (length == 0) {
  72. Nan::ThrowRangeError("The input data has a zero byte length.");
  73. return;
  74. }
  75. width = Nan::To<uint32_t>(info[1]).FromMaybe(0);
  76. if (width == 0) {
  77. Nan::ThrowRangeError("The source width is zero.");
  78. return;
  79. }
  80. if (info[2]->IsUint32()) { // Explicit height given
  81. height = Nan::To<uint32_t>(info[2]).FromMaybe(0);
  82. } else { // Calculate height assuming 2 BPP
  83. int size = length / 2;
  84. height = size / width;
  85. }
  86. } else {
  87. Nan::ThrowTypeError("Expected (Uint8ClampedArray, width[, height]), (Uint16Array, width[, height]) or (width, height)");
  88. return;
  89. }
  90. Nan::TypedArrayContents<uint8_t> dataPtr(dataArray);
  91. ImageData *imageData = new ImageData(reinterpret_cast<uint8_t*>(*dataPtr), width, height);
  92. imageData->Wrap(info.This());
  93. Nan::Set(info.This(), Nan::New("data").ToLocalChecked(), dataArray).Check();
  94. info.GetReturnValue().Set(info.This());
  95. }
  96. /*
  97. * Get width.
  98. */
  99. NAN_GETTER(ImageData::GetWidth) {
  100. if (!ImageData::constructor.Get(info.GetIsolate())->HasInstance(info.This())) {
  101. Nan::ThrowTypeError("Method ImageData.GetWidth called on incompatible receiver");
  102. return;
  103. }
  104. ImageData *imageData = Nan::ObjectWrap::Unwrap<ImageData>(info.This());
  105. info.GetReturnValue().Set(Nan::New<Number>(imageData->width()));
  106. }
  107. /*
  108. * Get height.
  109. */
  110. NAN_GETTER(ImageData::GetHeight) {
  111. if (!ImageData::constructor.Get(info.GetIsolate())->HasInstance(info.This())) {
  112. Nan::ThrowTypeError("Method ImageData.GetHeight called on incompatible receiver");
  113. return;
  114. }
  115. ImageData *imageData = Nan::ObjectWrap::Unwrap<ImageData>(info.This());
  116. info.GetReturnValue().Set(Nan::New<Number>(imageData->height()));
  117. }