1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_image_decoders_nsJPEGDecoder_h
8 #define mozilla_image_decoders_nsJPEGDecoder_h
9 
10 #include "RasterImage.h"
11 #include "SurfacePipe.h"
12 
13 // On Windows systems, RasterImage.h brings in 'windows.h', which defines INT32.
14 // But the jpeg decoder has its own definition of INT32. To avoid build issues,
15 // we need to undefine the version from 'windows.h'.
16 #undef INT32
17 
18 #include "Decoder.h"
19 
20 extern "C" {
21 #include "jpeglib.h"
22 }
23 
24 #include <setjmp.h>
25 
26 namespace mozilla {
27 namespace image {
28 
29 typedef struct {
30   struct jpeg_error_mgr pub;  // "public" fields for IJG library
31   jmp_buf setjmp_buffer;      // For handling catastropic errors
32 } decoder_error_mgr;
33 
34 typedef enum {
35   JPEG_HEADER,  // Reading JFIF headers
36   JPEG_START_DECOMPRESS,
37   JPEG_DECOMPRESS_PROGRESSIVE,  // Output progressive pixels
38   JPEG_DECOMPRESS_SEQUENTIAL,   // Output sequential pixels
39   JPEG_DONE,
40   JPEG_SINK_NON_JPEG_TRAILER,  // Some image files have a
41                                // non-JPEG trailer
42   JPEG_ERROR
43 } jstate;
44 
45 class RasterImage;
46 struct Orientation;
47 
48 class nsJPEGDecoder : public Decoder {
49  public:
50   virtual ~nsJPEGDecoder();
51 
GetType()52   DecoderType GetType() const override { return DecoderType::JPEG; }
53 
54   void NotifyDone();
55 
56  protected:
57   nsresult InitInternal() override;
58   LexerResult DoDecode(SourceBufferIterator& aIterator,
59                        IResumable* aOnResume) override;
60   nsresult FinishInternal() override;
61 
62   Maybe<Telemetry::HistogramID> SpeedHistogram() const override;
63 
64  protected:
65   Orientation ReadOrientationFromEXIF();
66   WriteState OutputScanlines();
67 
68  private:
69   friend class DecoderFactory;
70 
71   // Decoders should only be instantiated via DecoderFactory.
72   nsJPEGDecoder(RasterImage* aImage, Decoder::DecodeStyle aDecodeStyle);
73 
74   enum class State { JPEG_DATA, FINISHED_JPEG_DATA };
75 
76   void FinishRow(uint32_t aLastSourceRow);
77   LexerTransition<State> ReadJPEGData(const char* aData, size_t aLength);
78   LexerTransition<State> FinishedJPEGData();
79 
80   StreamingLexer<State> mLexer;
81 
82  public:
83   struct jpeg_decompress_struct mInfo;
84   struct jpeg_source_mgr mSourceMgr;
85   decoder_error_mgr mErr;
86   jstate mState;
87 
88   uint32_t mBytesToSkip;
89 
90   const JOCTET* mSegment;  // The current segment we are decoding from
91   uint32_t mSegmentLen;    // amount of data in mSegment
92 
93   JOCTET* mBackBuffer;
94   uint32_t mBackBufferLen;   // Offset of end of active backtrack data
95   uint32_t mBackBufferSize;  // size in bytes what mBackBuffer was created with
96   uint32_t mBackBufferUnreadLen;  // amount of data currently in mBackBuffer
97 
98   JOCTET* mProfile;
99   uint32_t mProfileLength;
100 
101   uint32_t* mCMSLine;
102 
103   bool mReading;
104 
105   const Decoder::DecodeStyle mDecodeStyle;
106 
107   SurfacePipe mPipe;
108 };
109 
110 }  // namespace image
111 }  // namespace mozilla
112 
113 #endif  // mozilla_image_decoders_nsJPEGDecoder_h
114