UNPKG

3.75 kBtext/x-cView Raw
1// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
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 // librsvg <= 2.36.1, identified by undefined macro, needs an extra include
30 #ifndef LIBRSVG_CHECK_VERSION
31 #include <librsvg/rsvg-cairo.h>
32 #endif
33#endif
34
35using JPEGDecodeL = std::function<uint32_t (uint8_t* const src)>;
36
37class 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};