kodi
GifHelper.h
1 /*
2  * Copyright (C) 2014 Team Kodi
3  * http://kodi.tv
4  *
5  * This Program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2, or (at your option)
8  * any later version.
9  *
10  * This Program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with XBMC; see the file COPYING. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #pragma once
22 
23 #include <gif_lib.h>
24 #ifndef CONTINUE_EXT_FUNC_CODE
25 #define CONTINUE_EXT_FUNC_CODE 0
26 #endif
27 
28 #ifndef DISPOSAL_UNSPECIFIED
29 #define DISPOSAL_UNSPECIFIED 0
30 #endif
31 
32 #ifndef DISPOSE_DO_NOT
33 #define DISPOSE_DO_NOT 1
34 #endif
35 
36 #ifndef DISPOSE_BACKGROUND
37 #define DISPOSE_BACKGROUND 2
38 #endif
39 
40 #ifndef DISPOSE_PREVIOUS
41 #define DISPOSE_PREVIOUS 3
42 #endif
43 
44 #include <vector>
45 #include <string>
46 #include <memory>
47 #include "SimpleFS.h"
48 
49 #pragma pack(1)
50 struct GifColor
51 {
52  uint8_t b, g, r, a;
53 };
54 #pragma pack()
55 
56 class CFile;
57 
58 class GifFrame
59 {
60  friend class GifHelper;
61 public:
62 
63  GifFrame() = default;
64  virtual ~GifFrame() = default;
65 
66  std::vector<uint8_t> m_pImage;
67  unsigned int m_delay = 0;
68 
69 private:
70  unsigned int m_top = 0;
71  unsigned int m_left = 0;
72  unsigned int m_disposal = 0;
73  unsigned int m_height = 0;
74  unsigned int m_width = 0;
75  std::vector<GifColor> m_palette;
76 };
77 
78 
79 
80 class GifHelper
81 {
82  friend class GifFrame;
83 
84  typedef std::shared_ptr<GifFrame> FramePtr;
85 
86 public:
87  GifHelper() = default;
88  virtual ~GifHelper();
89 
90  bool LoadGif(const std::string& file);
91 
92  std::vector<FramePtr>& GetFrames() { return m_frames; }
93  unsigned int GetPitch() const { return m_pitch; }
94  unsigned int GetNumLoops() const { return m_loops; }
95  unsigned int GetWidth() const { return m_width; }
96  unsigned int GetHeight() const { return m_height; }
97 
98 private:
99  std::vector<FramePtr> m_frames;
100  unsigned int m_imageSize = 0;
101  unsigned int m_pitch = 0;
102  unsigned int m_loops = 0;
103  unsigned int m_numFrames = 0;
104 
105  std::string m_filename;
106  GifFileType* m_gif = nullptr;
107  std::vector<GifColor> m_globalPalette;
108  std::vector<uint8_t> m_pTemplate;
109  CFile m_gifFile;
110 
111  unsigned int m_width;
112  unsigned int m_height;
113 
114  bool Open(GifFileType *& gif, void * dataPtr, InputFunc readFunc);
115  void Close(GifFileType * gif);
116 
117  const char* Reason(int reason);
118 
119  bool LoadGifMetaData(const std::string& file);
120  bool Slurp(GifFileType* gif);
121  void InitTemplateAndColormap();
122  bool LoadGifMetaData(GifFileType* gif);
123  static void ConvertColorTable(std::vector<GifColor> &dest, ColorMapObject* src, unsigned int size);
124  bool GcbToFrame(GifFrame &frame, unsigned int imgIdx);
125  int ExtractFrames(unsigned int count);
126  void ClearFrameAreaToTransparency(unsigned char* dest, const GifFrame &frame);
127  void ConstructFrame(GifFrame &frame, const unsigned char* src) const;
128  bool PrepareTemplate(GifFrame &frame);
129  void Release();
130 
131 #if GIFLIB_MAJOR != 5
132  /*
133  taken from giflib 5.1.0
134  */
135  const char* GifErrorString(int ErrorCode)
136  {
137  const char *Err;
138 
139  switch (ErrorCode) {
140  case E_GIF_ERR_OPEN_FAILED:
141  Err = "Failed to open given file";
142  break;
143  case E_GIF_ERR_WRITE_FAILED:
144  Err = "Failed to write to given file";
145  break;
146  case E_GIF_ERR_HAS_SCRN_DSCR:
147  Err = "Screen descriptor has already been set";
148  break;
149  case E_GIF_ERR_HAS_IMAG_DSCR:
150  Err = "Image descriptor is still active";
151  break;
152  case E_GIF_ERR_NO_COLOR_MAP:
153  Err = "Neither global nor local color map";
154  break;
155  case E_GIF_ERR_DATA_TOO_BIG:
156  Err = "Number of pixels bigger than width * height";
157  break;
158  case E_GIF_ERR_NOT_ENOUGH_MEM:
159  Err = "Failed to allocate required memory";
160  break;
161  case E_GIF_ERR_DISK_IS_FULL:
162  Err = "Write failed (disk full?)";
163  break;
164  case E_GIF_ERR_CLOSE_FAILED:
165  Err = "Failed to close given file";
166  break;
167  case E_GIF_ERR_NOT_WRITEABLE:
168  Err = "Given file was not opened for write";
169  break;
170  case D_GIF_ERR_OPEN_FAILED:
171  Err = "Failed to open given file";
172  break;
173  case D_GIF_ERR_READ_FAILED:
174  Err = "Failed to read from given file";
175  break;
176  case D_GIF_ERR_NOT_GIF_FILE:
177  Err = "Data is not in GIF format";
178  break;
179  case D_GIF_ERR_NO_SCRN_DSCR:
180  Err = "No screen descriptor detected";
181  break;
182  case D_GIF_ERR_NO_IMAG_DSCR:
183  Err = "No Image Descriptor detected";
184  break;
185  case D_GIF_ERR_NO_COLOR_MAP:
186  Err = "Neither global nor local color map";
187  break;
188  case D_GIF_ERR_WRONG_RECORD:
189  Err = "Wrong record type detected";
190  break;
191  case D_GIF_ERR_DATA_TOO_BIG:
192  Err = "Number of pixels bigger than width * height";
193  break;
194  case D_GIF_ERR_NOT_ENOUGH_MEM:
195  Err = "Failed to allocate required memory";
196  break;
197  case D_GIF_ERR_CLOSE_FAILED:
198  Err = "Failed to close given file";
199  break;
200  case D_GIF_ERR_NOT_READABLE:
201  Err = "Given file was not opened for read";
202  break;
203  case D_GIF_ERR_IMAGE_DEFECT:
204  Err = "Image is defective, decoding aborted";
205  break;
206  case D_GIF_ERR_EOF_TOO_SOON:
207  Err = "Image EOF detected before image complete";
208  break;
209  default:
210  Err = NULL;
211  break;
212  }
213  return Err;
214  }
215 #endif
216 };
Definition: GifHelper.h:58
Definition: SimpleFS.h:27
Definition: GifHelper.h:50
Definition: GifHelper.h:80