/*
 * Copyright 2017 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkJpegEncoderImpl_DEFINED
#define SkJpegEncoderImpl_DEFINED

#include "include/codec/SkEncodedOrigin.h"
#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkYUVAPixmaps.h"
#include "include/encode/SkEncoder.h"

#include <cstdint>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

class SkColorSpace;
class SkJpegEncoderMgr;
class SkPixmap;
class SkWStream;

namespace SkJpegEncoder {
struct Options;
}  // namespace SkJpegEncoder

// JPEG metadata is included in marker-based segments in the header of the image (the part before
// the first StartOfScan marker). These functions append these parameters to an SkJpegMarkerList.
namespace SkJpegMetadataEncoder {

// Metadata segments that will be added to the encoded file using
struct Segment {
    Segment(uint8_t marker, sk_sp<SkData> parameters)
            : fMarker(marker), fParameters(std::move(parameters)) {}
    uint8_t fMarker = 0;
    sk_sp<SkData> fParameters;
};

using SegmentList = std::vector<Segment>;

// Include an ICC profile in the image. If |colorSpace| is nullptr, then include no profile. If
// |options| specifies ICC profile data, then use that data, otherwise, generate a profile for
// |colorSpace|.
void AppendICC(SegmentList& segmentList,
               const SkJpegEncoder::Options& options,
               const SkColorSpace* colorSpace);

// Include a standard (as opposed to extended) XMP metadata segment.
void AppendXMPStandard(SegmentList& segmentList, const SkData* xmpMetadata);

// Include an origin as part of an Exif metadata segment.
void AppendOrigin(SegmentList& segmentList, SkEncodedOrigin origin);

}  // namespace SkJpegMetadataEncoder

class SkJpegEncoderImpl : public SkEncoder {
public:
    // Make an encoder from RGB or YUV data. Encoding options are specified in |options|. Metadata
    // markers are listed in |metadata|. The ICC profile and XMP metadata are read from |metadata|
    // and not from |options|.
    static std::unique_ptr<SkEncoder> MakeRGB(SkWStream* dst,
                                              const SkPixmap& src,
                                              const SkJpegEncoder::Options& options,
                                              const SkJpegMetadataEncoder::SegmentList& metadata);
    static std::unique_ptr<SkEncoder> MakeYUV(SkWStream* dst,
                                              const SkYUVAPixmaps& srcYUVA,
                                              const SkColorSpace* srcYUVAColorSpace,
                                              const SkJpegEncoder::Options& options,
                                              const SkJpegMetadataEncoder::SegmentList& metadata);

    ~SkJpegEncoderImpl() override;

protected:
    bool onEncodeRows(int numRows) override;

private:
    SkJpegEncoderImpl(std::unique_ptr<SkJpegEncoderMgr>, const SkPixmap& src);
    SkJpegEncoderImpl(std::unique_ptr<SkJpegEncoderMgr>, const SkYUVAPixmaps& srcYUVA);

    std::unique_ptr<SkJpegEncoderMgr> fEncoderMgr;
    std::optional<SkYUVAPixmaps> fSrcYUVA;
};

#endif
