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