1e16b04aa6041efb6507546547737e9603fa1606emsarett/*
2e16b04aa6041efb6507546547737e9603fa1606emsarett * Copyright 2015 Google Inc.
3e16b04aa6041efb6507546547737e9603fa1606emsarett *
4e16b04aa6041efb6507546547737e9603fa1606emsarett * Use of this source code is governed by a BSD-style license that can be
5e16b04aa6041efb6507546547737e9603fa1606emsarett * found in the LICENSE file.
6e16b04aa6041efb6507546547737e9603fa1606emsarett */
7e16b04aa6041efb6507546547737e9603fa1606emsarett
8e16b04aa6041efb6507546547737e9603fa1606emsarett#ifndef SkJpegCodec_DEFINED
9e16b04aa6041efb6507546547737e9603fa1606emsarett#define SkJpegCodec_DEFINED
10e16b04aa6041efb6507546547737e9603fa1606emsarett
11e16b04aa6041efb6507546547737e9603fa1606emsarett#include "SkCodec.h"
12e16b04aa6041efb6507546547737e9603fa1606emsarett#include "SkImageInfo.h"
1339b2d5a1ac4171aba0e92cb3f9882f62e5730e3emsarett#include "SkSwizzler.h"
14e16b04aa6041efb6507546547737e9603fa1606emsarett#include "SkStream.h"
15565901db954c231840750ea955ed31b820b9ade8scroggo#include "SkTemplates.h"
16e16b04aa6041efb6507546547737e9603fa1606emsarett
1739b2d5a1ac4171aba0e92cb3f9882f62e5730e3emsarettclass JpegDecoderMgr;
18e16b04aa6041efb6507546547737e9603fa1606emsarett
19e16b04aa6041efb6507546547737e9603fa1606emsarett/*
20e16b04aa6041efb6507546547737e9603fa1606emsarett *
21e16b04aa6041efb6507546547737e9603fa1606emsarett * This class implements the decoding for jpeg images
22e16b04aa6041efb6507546547737e9603fa1606emsarett *
23e16b04aa6041efb6507546547737e9603fa1606emsarett */
24e16b04aa6041efb6507546547737e9603fa1606emsarettclass SkJpegCodec : public SkCodec {
25e16b04aa6041efb6507546547737e9603fa1606emsarettpublic:
26db30be2f9470d21fe37b63d145c1fcca9a6ad98cscroggo    static bool IsJpeg(const void*, size_t);
27e16b04aa6041efb6507546547737e9603fa1606emsarett
28e16b04aa6041efb6507546547737e9603fa1606emsarett    /*
29e16b04aa6041efb6507546547737e9603fa1606emsarett     * Assumes IsJpeg was called and returned true
30e16b04aa6041efb6507546547737e9603fa1606emsarett     * Creates a jpeg decoder
31e16b04aa6041efb6507546547737e9603fa1606emsarett     * Takes ownership of the stream
32e16b04aa6041efb6507546547737e9603fa1606emsarett     */
33e16b04aa6041efb6507546547737e9603fa1606emsarett    static SkCodec* NewFromStream(SkStream*);
34e16b04aa6041efb6507546547737e9603fa1606emsarett
35e16b04aa6041efb6507546547737e9603fa1606emsarettprotected:
36e16b04aa6041efb6507546547737e9603fa1606emsarett
37e16b04aa6041efb6507546547737e9603fa1606emsarett    /*
38e16b04aa6041efb6507546547737e9603fa1606emsarett     * Recommend a set of destination dimensions given a requested scale
39e16b04aa6041efb6507546547737e9603fa1606emsarett     */
40e16b04aa6041efb6507546547737e9603fa1606emsarett    SkISize onGetScaledDimensions(float desiredScale) const override;
41e16b04aa6041efb6507546547737e9603fa1606emsarett
42e16b04aa6041efb6507546547737e9603fa1606emsarett    /*
43e16b04aa6041efb6507546547737e9603fa1606emsarett     * Initiates the jpeg decode
44e16b04aa6041efb6507546547737e9603fa1606emsarett     */
45e16b04aa6041efb6507546547737e9603fa1606emsarett    Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
46e6dd004c1b8a81dc37a370570877b8b7d6dbe308msarett            SkPMColor*, int*, int*) override;
47e16b04aa6041efb6507546547737e9603fa1606emsarett
48b714fb0199e8727ef2b6cddbee7eba6046f01554msarett    bool onQueryYUV8(YUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override;
49b714fb0199e8727ef2b6cddbee7eba6046f01554msarett
50b714fb0199e8727ef2b6cddbee7eba6046f01554msarett    Result onGetYUV8Planes(const YUVSizeInfo& sizeInfo, void* pixels[3]) override;
51b714fb0199e8727ef2b6cddbee7eba6046f01554msarett
52e16b04aa6041efb6507546547737e9603fa1606emsarett    SkEncodedFormat onGetEncodedFormat() const override {
53e16b04aa6041efb6507546547737e9603fa1606emsarett        return kJPEG_SkEncodedFormat;
54e16b04aa6041efb6507546547737e9603fa1606emsarett    }
55e16b04aa6041efb6507546547737e9603fa1606emsarett
56b427db1d457a083f2652756a453fbb91bc6a7447scroggo    bool onRewind() override;
57b427db1d457a083f2652756a453fbb91bc6a7447scroggo
58e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671scroggo    bool onDimensionsSupported(const SkISize&) override;
59e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671scroggo
60e16b04aa6041efb6507546547737e9603fa1606emsarettprivate:
61e16b04aa6041efb6507546547737e9603fa1606emsarett
62e16b04aa6041efb6507546547737e9603fa1606emsarett    /*
63e16b04aa6041efb6507546547737e9603fa1606emsarett     * Read enough of the stream to initialize the SkJpegCodec.
64e16b04aa6041efb6507546547737e9603fa1606emsarett     * Returns a bool representing success or failure.
65e16b04aa6041efb6507546547737e9603fa1606emsarett     *
66e16b04aa6041efb6507546547737e9603fa1606emsarett     * @param codecOut
6796fcdcc219d2a0d3579719b84b28bede76efba64halcanary     * If this returns true, and codecOut was not nullptr,
68e16b04aa6041efb6507546547737e9603fa1606emsarett     * codecOut will be set to a new SkJpegCodec.
69e16b04aa6041efb6507546547737e9603fa1606emsarett     *
70e16b04aa6041efb6507546547737e9603fa1606emsarett     * @param decoderMgrOut
7196fcdcc219d2a0d3579719b84b28bede76efba64halcanary     * If this returns true, and codecOut was nullptr,
7296fcdcc219d2a0d3579719b84b28bede76efba64halcanary     * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
73e16b04aa6041efb6507546547737e9603fa1606emsarett     * JpegDecoderMgr pointer.
74e16b04aa6041efb6507546547737e9603fa1606emsarett     *
75e16b04aa6041efb6507546547737e9603fa1606emsarett     * @param stream
76e16b04aa6041efb6507546547737e9603fa1606emsarett     * Deleted on failure.
77e16b04aa6041efb6507546547737e9603fa1606emsarett     * codecOut will take ownership of it in the case where we created a codec.
78e16b04aa6041efb6507546547737e9603fa1606emsarett     * Ownership is unchanged when we set decoderMgrOut.
79e16b04aa6041efb6507546547737e9603fa1606emsarett     *
80e16b04aa6041efb6507546547737e9603fa1606emsarett     */
81e16b04aa6041efb6507546547737e9603fa1606emsarett    static bool ReadHeader(SkStream* stream, SkCodec** codecOut,
82e16b04aa6041efb6507546547737e9603fa1606emsarett            JpegDecoderMgr** decoderMgrOut);
83e16b04aa6041efb6507546547737e9603fa1606emsarett
84e16b04aa6041efb6507546547737e9603fa1606emsarett    /*
85e16b04aa6041efb6507546547737e9603fa1606emsarett     * Creates an instance of the decoder
86e16b04aa6041efb6507546547737e9603fa1606emsarett     * Called only by NewFromStream
87e16b04aa6041efb6507546547737e9603fa1606emsarett     *
88e16b04aa6041efb6507546547737e9603fa1606emsarett     * @param srcInfo contains the source width and height
89e16b04aa6041efb6507546547737e9603fa1606emsarett     * @param stream the encoded image data
90e16b04aa6041efb6507546547737e9603fa1606emsarett     * @param decoderMgr holds decompress struct, src manager, and error manager
91e16b04aa6041efb6507546547737e9603fa1606emsarett     *                   takes ownership
92e16b04aa6041efb6507546547737e9603fa1606emsarett     */
93e16b04aa6041efb6507546547737e9603fa1606emsarett    SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, JpegDecoderMgr* decoderMgr);
94e16b04aa6041efb6507546547737e9603fa1606emsarett
9597fdea6c4393cf0102d7eee5790782509fb4f57bmsarett    /*
961c8a587120fd33854974457cf2a795ead98183a9msarett     * Checks if the conversion between the input image and the requested output
971c8a587120fd33854974457cf2a795ead98183a9msarett     * image has been implemented
981c8a587120fd33854974457cf2a795ead98183a9msarett     * Sets the output color space
991c8a587120fd33854974457cf2a795ead98183a9msarett     */
1001c8a587120fd33854974457cf2a795ead98183a9msarett    bool setOutputColorSpace(const SkImageInfo& dst);
1011c8a587120fd33854974457cf2a795ead98183a9msarett
10246c574725676b26ada63ac15e42cda309dcd5090scroggo    // scanline decoding
103fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett    void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
104e6dd004c1b8a81dc37a370570877b8b7d6dbe308msarett    SkSampler* getSampler(bool createIfNecessary) override;
10546c574725676b26ada63ac15e42cda309dcd5090scroggo    Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
106fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett            SkPMColor ctable[], int* ctableCount) override;
107e6dd004c1b8a81dc37a370570877b8b7d6dbe308msarett    int onGetScanlines(void* dst, int count, size_t rowBytes) override;
108e6dd004c1b8a81dc37a370570877b8b7d6dbe308msarett    bool onSkipScanlines(int count) override;
10946c574725676b26ada63ac15e42cda309dcd5090scroggo
110e16b04aa6041efb6507546547737e9603fa1606emsarett    SkAutoTDelete<JpegDecoderMgr> fDecoderMgr;
111fbccb5995dcda645a3a8af51805639cb0c0d2300msarett    // We will save the state of the decompress struct after reading the header.
112fbccb5995dcda645a3a8af51805639cb0c0d2300msarett    // This allows us to safely call onGetScaledDimensions() at any time.
113fbccb5995dcda645a3a8af51805639cb0c0d2300msarett    const int                     fReadyState;
114e16b04aa6041efb6507546547737e9603fa1606emsarett
11546c574725676b26ada63ac15e42cda309dcd5090scroggo    // scanline decoding
116565901db954c231840750ea955ed31b820b9ade8scroggo    SkAutoTMalloc<uint8_t>     fStorage;    // Only used if sampling is needed
11746c574725676b26ada63ac15e42cda309dcd5090scroggo    uint8_t*                   fSrcRow;     // Only used if sampling is needed
11891c22b2ea6bd13a31321ead01645467f21858cd0msarett    // libjpeg-turbo provides some subsetting.  In the case that libjpeg-turbo
11991c22b2ea6bd13a31321ead01645467f21858cd0msarett    // cannot take the exact the subset that we need, we will use the swizzler
12091c22b2ea6bd13a31321ead01645467f21858cd0msarett    // to further subset the output from libjpeg-turbo.
12191c22b2ea6bd13a31321ead01645467f21858cd0msarett    SkIRect                    fSwizzlerSubset;
12246c574725676b26ada63ac15e42cda309dcd5090scroggo    SkAutoTDelete<SkSwizzler>  fSwizzler;
12346c574725676b26ada63ac15e42cda309dcd5090scroggo
124e16b04aa6041efb6507546547737e9603fa1606emsarett    typedef SkCodec INHERITED;
125e16b04aa6041efb6507546547737e9603fa1606emsarett};
126e16b04aa6041efb6507546547737e9603fa1606emsarett
127e16b04aa6041efb6507546547737e9603fa1606emsarett#endif
128