1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef GIF_ENCODER_H
16 #define GIF_ENCODER_H
17 #include <vector>
18 #include "abs_image_encoder.h"
19 #include "plugin_class_base.h"
20 namespace OHOS {
21 namespace ImagePlugin {
22 
23 const int NUM_OF_RGB = 3;
24 const int DICTIONARY_SIZE = 8192;
25 
26 typedef struct ColorType {
27     uint8_t red;
28     uint8_t green;
29     uint8_t blue;
30 } ColorType;
31 
32 typedef struct ColorCoordinate {
33     uint8_t rgb[NUM_OF_RGB];
34     uint8_t newColorIndex;
35     long pixelNum;
36     struct ColorCoordinate *next;
37 } ColorCoordinate;
38 
39 typedef struct ColorSubdivMap {
40     uint8_t rgbMin[NUM_OF_RGB];
41     uint8_t rgbWidth[NUM_OF_RGB];
42     uint32_t colorNum;
43     long pixelNum;
44     ColorCoordinate *coordinate;
45 } ColorSubdivMap;
46 
47 class GifEncoder : public AbsImageEncoder, public OHOS::MultimediaPlugin::PluginClassBase {
48 public:
49     GifEncoder();
50     ~GifEncoder() override;
51     uint32_t StartEncode(OutputDataStream &outputStream, PlEncodeOptions &option) override;
52     uint32_t AddImage(Media::PixelMap &pixelMap) override;
53     uint32_t AddPicture(Media::Picture &picture) override;
54     uint32_t FinalizeEncode() override;
55     bool Write(const uint8_t* data, size_t data_size);
56 
57 private:
58     DISALLOW_COPY_AND_MOVE(GifEncoder);
59     uint32_t DoEncode();
60     uint32_t WriteFileInfo();
61     uint32_t WriteFrameInfo(int index);
62     uint32_t processFrame(int index);
63     uint32_t colorQuantize(int index, uint16_t width, uint16_t height,
64                            uint8_t *outputBuffer, ColorType *outputColorMap);
65     uint32_t separateRGB(int index, uint16_t width, uint16_t height,
66                          uint8_t *redBuffer, uint8_t *greenBuffer, uint8_t *blueBuffer);
67     uint32_t doColorQuantize(uint16_t width, uint16_t height,
68                              const uint8_t *redInput, const uint8_t *greenInput, const uint8_t *blueInput,
69                              uint8_t *outputBuffer, ColorType *outputColorMap);
70     uint32_t BuildColorSubdivMap(ColorSubdivMap *colorSubdivMap, uint32_t *colorSubdivMapSize);
71     int SortCmpRtn(const void *Entry1, const void *Entry2);
72     void InitDictionary();
73     int IsInDictionary(uint32_t Key);
74     void AddToDictionary(uint32_t Key, int Code);
75     uint32_t LZWEncodeFrame(uint8_t *outputBuffer, uint16_t width, uint16_t height);
76     uint32_t LZWEncode(uint8_t *buffer, int length);
77     uint32_t LZWWriteOut(int Code);
78     uint32_t LZWBufferOutput(int c);
79 
80 private:
81     OutputDataStream *outputStream_ {nullptr};
82     std::vector<Media::PixelMap*> pixelMaps_;
83     PlEncodeOptions encodeOpts_;
84     int lastCode_;
85     int eofCode_;
86     int runningCode_;
87     int clearCode_;
88     int runningBits_;
89     int maxCode_;
90     int crntShiftState_;
91     uint32_t crntShiftDWord_;
92     uint32_t dictionary_[DICTIONARY_SIZE];
93     uint8_t outputLZWBuffer_[256];
94 };
95 
96 } // namespace ImagePlugin
97 } // namespace OHOS
98 
99 #endif // GIF_ENCODER_H