Image.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright (c) 2010 LearnBoost <tj@learnboost.com>
  2. #pragma once
  3. #include <cairo.h>
  4. #include "CanvasError.h"
  5. #include <functional>
  6. #include <nan.h>
  7. #include <stdint.h> // node < 7 uses libstdc++ on macOS which lacks complete c++11
  8. #include <v8.h>
  9. #ifdef HAVE_JPEG
  10. #include <jpeglib.h>
  11. #include <jerror.h>
  12. #endif
  13. #ifdef HAVE_GIF
  14. #include <gif_lib.h>
  15. #if GIFLIB_MAJOR > 5 || GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1
  16. #define GIF_CLOSE_FILE(gif) DGifCloseFile(gif, NULL)
  17. #else
  18. #define GIF_CLOSE_FILE(gif) DGifCloseFile(gif)
  19. #endif
  20. #endif
  21. #ifdef HAVE_RSVG
  22. #include <librsvg/rsvg.h>
  23. // librsvg <= 2.36.1, identified by undefined macro, needs an extra include
  24. #ifndef LIBRSVG_CHECK_VERSION
  25. #include <librsvg/rsvg-cairo.h>
  26. #endif
  27. #endif
  28. using JPEGDecodeL = std::function<uint32_t (uint8_t* const src)>;
  29. class Image: public Nan::ObjectWrap {
  30. public:
  31. char *filename;
  32. int width, height;
  33. int naturalWidth, naturalHeight;
  34. static Nan::Persistent<v8::FunctionTemplate> constructor;
  35. static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target);
  36. static NAN_METHOD(New);
  37. static NAN_GETTER(GetComplete);
  38. static NAN_GETTER(GetWidth);
  39. static NAN_GETTER(GetHeight);
  40. static NAN_GETTER(GetNaturalWidth);
  41. static NAN_GETTER(GetNaturalHeight);
  42. static NAN_GETTER(GetDataMode);
  43. static NAN_SETTER(SetDataMode);
  44. static NAN_SETTER(SetWidth);
  45. static NAN_SETTER(SetHeight);
  46. static NAN_METHOD(GetSource);
  47. static NAN_METHOD(SetSource);
  48. inline uint8_t *data(){ return cairo_image_surface_get_data(_surface); }
  49. inline int stride(){ return cairo_image_surface_get_stride(_surface); }
  50. static int isPNG(uint8_t *data);
  51. static int isJPEG(uint8_t *data);
  52. static int isGIF(uint8_t *data);
  53. static int isSVG(uint8_t *data, unsigned len);
  54. static int isBMP(uint8_t *data, unsigned len);
  55. static cairo_status_t readPNG(void *closure, unsigned char *data, unsigned len);
  56. inline int isComplete(){ return COMPLETE == state; }
  57. cairo_surface_t *surface();
  58. cairo_status_t loadSurface();
  59. cairo_status_t loadFromBuffer(uint8_t *buf, unsigned len);
  60. cairo_status_t loadPNGFromBuffer(uint8_t *buf);
  61. cairo_status_t loadPNG();
  62. void clearData();
  63. #ifdef HAVE_RSVG
  64. cairo_status_t loadSVGFromBuffer(uint8_t *buf, unsigned len);
  65. cairo_status_t loadSVG(FILE *stream);
  66. cairo_status_t renderSVGToSurface();
  67. #endif
  68. #ifdef HAVE_GIF
  69. cairo_status_t loadGIFFromBuffer(uint8_t *buf, unsigned len);
  70. cairo_status_t loadGIF(FILE *stream);
  71. #endif
  72. #ifdef HAVE_JPEG
  73. cairo_status_t loadJPEGFromBuffer(uint8_t *buf, unsigned len);
  74. cairo_status_t loadJPEG(FILE *stream);
  75. void jpegToARGB(jpeg_decompress_struct* args, uint8_t* data, uint8_t* src, JPEGDecodeL decode);
  76. cairo_status_t decodeJPEGIntoSurface(jpeg_decompress_struct *info);
  77. cairo_status_t decodeJPEGBufferIntoMimeSurface(uint8_t *buf, unsigned len);
  78. cairo_status_t assignDataAsMime(uint8_t *data, int len, const char *mime_type);
  79. #endif
  80. cairo_status_t loadBMPFromBuffer(uint8_t *buf, unsigned len);
  81. cairo_status_t loadBMP(FILE *stream);
  82. CanvasError errorInfo;
  83. void loaded();
  84. cairo_status_t load();
  85. Image();
  86. enum {
  87. DEFAULT
  88. , LOADING
  89. , COMPLETE
  90. } state;
  91. enum data_mode_t {
  92. DATA_IMAGE = 1
  93. , DATA_MIME = 2
  94. } data_mode;
  95. typedef enum {
  96. UNKNOWN
  97. , GIF
  98. , JPEG
  99. , PNG
  100. , SVG
  101. } type;
  102. static type extension(const char *filename);
  103. private:
  104. cairo_surface_t *_surface;
  105. uint8_t *_data = nullptr;
  106. int _data_len;
  107. #ifdef HAVE_RSVG
  108. RsvgHandle *_rsvg;
  109. bool _is_svg;
  110. int _svg_last_width;
  111. int _svg_last_height;
  112. #endif
  113. ~Image();
  114. };