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