18c8f22a3bba18edaad41d6ac8451a77aa093a958msarett/*
28c8f22a3bba18edaad41d6ac8451a77aa093a958msarett * Copyright 2015 Google Inc.
38c8f22a3bba18edaad41d6ac8451a77aa093a958msarett *
48c8f22a3bba18edaad41d6ac8451a77aa093a958msarett * Use of this source code is governed by a BSD-style license that can be
58c8f22a3bba18edaad41d6ac8451a77aa093a958msarett * found in the LICENSE file.
68c8f22a3bba18edaad41d6ac8451a77aa093a958msarett */
78c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
88c8f22a3bba18edaad41d6ac8451a77aa093a958msarett#include "SkCodec.h"
98c8f22a3bba18edaad41d6ac8451a77aa093a958msarett#include "SkImageInfo.h"
108c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
118c8f22a3bba18edaad41d6ac8451a77aa093a958msarett#include "gif_lib.h"
128c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
138c8f22a3bba18edaad41d6ac8451a77aa093a958msarett/*
148c8f22a3bba18edaad41d6ac8451a77aa093a958msarett *
158c8f22a3bba18edaad41d6ac8451a77aa093a958msarett * This class implements the decoding for gif images
168c8f22a3bba18edaad41d6ac8451a77aa093a958msarett *
178c8f22a3bba18edaad41d6ac8451a77aa093a958msarett */
188c8f22a3bba18edaad41d6ac8451a77aa093a958msarettclass SkGifCodec : public SkCodec {
198c8f22a3bba18edaad41d6ac8451a77aa093a958msarettpublic:
208c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
218c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    /*
228c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Checks the start of the stream to see if the image is a gif
238c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     */
248c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    static bool IsGif(SkStream*);
258c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
268c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    /*
278c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Assumes IsGif was called and returned true
288c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Creates a gif decoder
298c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Reads enough of the stream to determine the image format
308c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     */
318c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    static SkCodec* NewFromStream(SkStream*);
328c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
338c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
348c8f22a3bba18edaad41d6ac8451a77aa093a958msarettprotected:
358c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
368c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    /*
37438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * Read enough of the stream to initialize the SkGifCodec.
38438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * Returns a bool representing success or failure.
39438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     *
40438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * @param codecOut
41438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * If it returned true, and codecOut was not NULL,
42438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * codecOut will be set to a new SkGifCodec.
43438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     *
44438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * @param gifOut
45438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * If it returned true, and codecOut was NULL,
46438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * gifOut must be non-NULL and gifOut will be set to a new
47438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * GifFileType pointer.
48438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     *
49438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * @param stream
50438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * Deleted on failure.
51438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * codecOut will take ownership of it in the case where we created a codec.
52438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     * Ownership is unchanged when we returned a gifOut.
53438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     *
54438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett     */
55438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    static bool ReadHeader(SkStream* stream, SkCodec** codecOut, GifFileType** gifOut);
56438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett
57438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    /*
588c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Initiates the gif decode
598c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     */
608c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&,
618c8f22a3bba18edaad41d6ac8451a77aa093a958msarett            SkPMColor*, int32_t*) override;
628c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
638c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    SkEncodedFormat onGetEncodedFormat() const override {
648c8f22a3bba18edaad41d6ac8451a77aa093a958msarett        return kGIF_SkEncodedFormat;
658c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    }
668c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
678c8f22a3bba18edaad41d6ac8451a77aa093a958msarettprivate:
688c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
698c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    /*
708c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * This function cleans up the gif object after the decode completes
718c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * It is used in a SkAutoTCallIProc template
728c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     */
73438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    static void CloseGif(GifFileType* gif);
748c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
758c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    /*
768c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Frees any extension data used in the decode
778c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Used in a SkAutoTCallVProc
788c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     */
798c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    static void FreeExtension(SavedImage* image);
808c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
818c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    /*
828c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Creates an instance of the decoder
838c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * Called only by NewFromStream
848c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     *
858c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * @param srcInfo contains the source width and height
868c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * @param stream the stream of image data
878c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     * @param gif pointer to library type that manages gif decode
888c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     *            takes ownership
898c8f22a3bba18edaad41d6ac8451a77aa093a958msarett     */
908c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    SkGifCodec(const SkImageInfo& srcInfo, SkStream* stream, GifFileType* gif);
918c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
92438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    SkAutoTCallVProc<GifFileType, CloseGif> fGif; // owned
938c8f22a3bba18edaad41d6ac8451a77aa093a958msarett
948c8f22a3bba18edaad41d6ac8451a77aa093a958msarett    typedef SkCodec INHERITED;
958c8f22a3bba18edaad41d6ac8451a77aa093a958msarett};
96