1+ #ifndef __JPEGENC__
2+ #error "You must include JPEGENC.h *before* eloquent_esp32cam"
3+ #else
4+
5+ #ifndef ELOQUENTESP32CAM_JPEGENC
6+ #define ELOQUENTESP32CAM_JPEGENC
7+
8+ #include " ../mem.h"
9+ #include " ../camera/camera.h"
10+ #include " ../extra/exception.h"
11+ #include " ../extra/time/benchmark.h"
12+
13+ using eloq::camera;
14+ using Eloquent::Error::Exception;
15+ using Eloquent::Extra::Time::Benchmark;
16+
17+ namespace Eloquent {
18+ namespace Esp32cam {
19+ namespace JPEG {
20+ /* *
21+ * Eloquent interface to JPEGENC library
22+ */
23+ class JPEGENCWrapper {
24+ public:
25+ uint8_t *bytes;
26+ JPEGENC jpeg;
27+ Exception exception;
28+ Benchmark benchmark;
29+
30+ JPEGENCWrapper () :
31+ exception (" JPEGENC" ),
32+ _length (0 ),
33+ _numBytes (0 ),
34+ _pixelType (JPEGE_PIXEL_RGB565),
35+ _quality (JPEGE_Q_HIGH),
36+ _subsample (JPEGE_SUBSAMPLE_444) {
37+
38+ }
39+
40+ /* *
41+ *
42+ */
43+ void fromRGB565 () {
44+ _pixelType = JPEGE_PIXEL_RGB565;
45+ }
46+
47+ /* *
48+ *
49+ */
50+ void fromGrayscale () {
51+ _pixelType = JPEGE_PIXEL_GRAYSCALE;
52+ }
53+
54+ /* *
55+ *
56+ */
57+ void toBestQuality () {
58+ _quality = JPEGE_Q_BEST;
59+ }
60+
61+ /* *
62+ *
63+ */
64+ void toGoodQuality () {
65+ _quality = JPEGE_Q_HIGH;
66+ }
67+
68+ /* *
69+ *
70+ */
71+ void toMediumQuality () {
72+ _quality = JPEGE_Q_MED;
73+ }
74+
75+ /* *
76+ *
77+ */
78+ void toLowQuality () {
79+ _quality = JPEGE_Q_LOW;
80+ }
81+
82+ /* *
83+ *
84+ */
85+ void subsample () {
86+ _subsample = JPEGE_SUBSAMPLE_420;
87+ }
88+
89+ /* *
90+ * Allocate buffer for decoding
91+ */
92+ Exception& allocate (size_t numBytes) {
93+ bytes = eloq::realloc<uint8_t >(bytes, numBytes);
94+ _numBytes = numBytes;
95+
96+ return bytes == NULL ? exception.set (" Can't allocate memory" ) : exception.clear ();
97+ }
98+
99+ /* *
100+ * Encode raw pixels
101+ */
102+ Exception& encode (uint8_t *pixels, uint16_t width, uint16_t height) {
103+ benchmark.benchmark ([this , pixels, width, height]() {
104+ JPEGENCODE enc;
105+
106+ if (JPEGE_SUCCESS != jpeg.open (bytes, _numBytes)) {
107+ exception.set (" Cannot open JPEG" );
108+ return ;
109+ }
110+
111+ if (JPEGE_SUCCESS != jpeg.encodeBegin (&enc, width, height, _pixelType, _subsample, _quality)) {
112+ exception.set (" Cannot setup encoding" );
113+ return ;
114+ }
115+
116+ if (JPEGE_SUCCESS != jpeg.addFrame (&enc, pixels, width * bpp ())) {
117+ exception.set (" Cannot add frame" );
118+ return ;
119+ }
120+
121+ _length = jpeg.close ();
122+ });
123+
124+ return _length > 0 ? exception.clear () : exception.set (" Empty output" );
125+ }
126+
127+ /* *
128+ * Encode current frame
129+ */
130+ Exception& encode () {
131+ if (!camera.hasFrame ())
132+ return exception.set (" Can't encode empty frame" );
133+
134+ return this ->encode (camera.frame ->buf , camera.frame ->width , camera.frame ->height );
135+ }
136+
137+ /* *
138+ * Get JPEG size
139+ */
140+ inline size_t size () {
141+ return _length;
142+ }
143+
144+ /* *
145+ * Bytes per pixel
146+ */
147+ inline uint8_t bpp () {
148+ return _pixelType == JPEGE_PIXEL_GRAYSCALE ? 1 : 2 ;
149+ }
150+
151+ protected:
152+ size_t _length;
153+ size_t _numBytes;
154+ uint8_t _pixelType;
155+ uint8_t _quality;
156+ uint8_t _subsample;
157+ };
158+ }
159+ }
160+ }
161+
162+ namespace eloq {
163+ static Eloquent::Esp32cam::JPEG::JPEGENCWrapper jpegenc;
164+ }
165+ #endif
166+
167+ #endif
0 commit comments