xref: /aosp_15_r20/external/skia/src/codec/SkJpegPriv.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2017 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 
9 #ifndef SkJpegPriv_DEFINED
10 #define SkJpegPriv_DEFINED
11 
12 #include "include/codec/SkEncodedOrigin.h"
13 #include "include/core/SkStream.h"
14 #include "include/private/base/SkTArray.h"
15 
16 #include <setjmp.h>
17 // stdio is needed for jpeglib
18 #include <stdio.h>
19 
20 extern "C" {
21     #include "jpeglib.h"  // NO_G3_REWRITE
22     #include "jerror.h"   // NO_G3_REWRITE
23 }
24 
25 /*
26  * Error handling struct
27  */
28 struct skjpeg_error_mgr : public jpeg_error_mgr {
29     class AutoPushJmpBuf {
30     public:
AutoPushJmpBufskjpeg_error_mgr31         AutoPushJmpBuf(skjpeg_error_mgr* mgr) : fMgr(mgr) { fMgr->push(&fJmpBuf); }
~AutoPushJmpBufskjpeg_error_mgr32         ~AutoPushJmpBuf()                                 { fMgr->pop(&fJmpBuf); }
33         operator jmp_buf&()                               { return fJmpBuf; }
34 
35     private:
36         skjpeg_error_mgr* const fMgr;
37         jmp_buf fJmpBuf;
38     };
39 
40       // When libjpeg initializes the fields of a `jpeg_error_mgr` (in `jpeg_std_error`), it
41       // leaves the msg_parm fields uninitialized. This is safe, but confuses MSAN, so we
42       // explicitly zero out the structure when constructing it. (crbug.com/oss-fuzz/68691)
skjpeg_error_mgrskjpeg_error_mgr43     skjpeg_error_mgr() : jpeg_error_mgr({}) {}
44 
pushskjpeg_error_mgr45     void push(jmp_buf* j) {
46         SkASSERT(fStack[3] == nullptr);  // if we assert here, the stack has overflowed
47         fStack[3] = fStack[2];
48         fStack[2] = fStack[1];
49         fStack[1] = fStack[0];
50         fStack[0] = j;
51     }
52 
popskjpeg_error_mgr53     void pop(jmp_buf* j) {
54         SkASSERT(fStack[0] == j);  // if we assert here, the pushes and pops were unbalanced
55         fStack[0] = fStack[1];
56         fStack[1] = fStack[2];
57         fStack[2] = fStack[3];
58         fStack[3] = nullptr;
59     }
60 
61     jmp_buf* fStack[4] = {};
62 };
63 
64 #endif
65