ecere: gfx/gui: support P/NaCl platform. add new Pepper interface driver for targetin...
[sdk] / ecere / src / gfx / bitmaps / GIFFormat.ec
1 namespace gfx::bitmaps;
2
3 import "Display"
4
5 #if !defined(__EMSCRIPTEN__) && !defined(__pnacl__)
6
7 #include "gif_lib.h"
8
9 static int ReadData(GifFileType * gifFile, GifByteType * bytes, int size)
10 {
11    File f = gifFile->UserData;
12    return f.Read(bytes, 1, size);
13 }
14
15 /*static int WriteData(GifFileType * gifFile, GifByteType * bytes, int size)
16 {
17    File f = gifFile->UserData;
18    return f.Write(bytes, 1, size);
19 }
20 */
21 static const char * extensions[] = { "gif", null };
22
23 class GIFFormat : BitmapFormat
24 {
25    class_property(extensions) = extensions;
26
27    bool Load(Bitmap bitmap, File f)
28    {
29       bool result = false;
30
31 #if GIFLIB_MAJOR >= 5
32       GifFileType * gifFile = DGifOpen(f, ReadData, null);
33 #else
34       GifFileType * gifFile = DGifOpen(f, ReadData);
35 #endif
36       if(gifFile)
37       {
38          DGifSlurp(gifFile);
39          if(bitmap.Allocate(null, gifFile->SWidth, gifFile->SHeight, 0, pixelFormat888, false))
40          {
41             uint y;
42             ColorAlpha * picture = (ColorAlpha *)bitmap.picture;
43             int transparent = -1;
44             struct SavedImage * image = &gifFile->SavedImages[0];
45             int c;
46             ColorMapObject * colorMap = gifFile->SColorMap;
47
48             if(!colorMap) colorMap = gifFile->Image.ColorMap;
49
50             for(c = 0; c<image->ExtensionBlockCount; c++)
51             {
52                ExtensionBlock * block = &image->ExtensionBlocks[c];
53                if(block->Function == 249)
54                {
55                   if(block->Bytes[0])
56                      transparent = (byte)block->Bytes[3];
57                }
58             }
59             if(colorMap)
60             {
61                int colorCount = colorMap->ColorCount;
62                if(!gifFile->Image.Interlace)
63                {
64                   for(y = 0; y < gifFile->SHeight; y++)
65                   {
66                      uint x;
67                      for(x = 0; x < gifFile->SWidth; x++)
68                      {
69                         byte index = image->RasterBits[y*gifFile->SWidth+x];
70                         if(index == transparent || index >= colorCount)
71                            picture[y * bitmap.stride + x] = 0; //&= 0xFFFFFF;
72                         else
73                            picture[y * bitmap.stride + x] = ColorAlpha { 255, {
74                               colorMap->Colors[index].Red,
75                               colorMap->Colors[index].Green,
76                               colorMap->Colors[index].Blue } };
77                      }
78                   }
79                }
80                else
81                {
82                   int startline[4] = {0, 4, 2, 1};
83                   int offset[4] = {8, 8, 4, 2};
84                   int group;
85                   uint i;
86                   for(group=0,i=0;group<4;group++)
87                   {
88                      uint y;
89                      for(y = startline[group]; y < gifFile->SHeight; y += offset[group], i++)
90                      {
91                         uint x;
92                         for(x = 0; x < gifFile->SWidth; x++)
93                         {
94                            byte index = image->RasterBits[i*gifFile->SWidth+x];
95                            if(index == transparent)
96                               picture[y * bitmap.stride + x] = 0;// &= 0xFFFFFF;
97                            else
98                               picture[y * bitmap.stride + x] = ColorAlpha { 255, {
99                                  colorMap->Colors[index].Red,
100                                  colorMap->Colors[index].Green,
101                                  colorMap->Colors[index].Blue } };
102                         }
103                      }
104                   }
105                }
106                bitmap.transparent = (transparent != -1) ? true : false;
107                result = true;
108             }
109          }
110 #if GIFLIB_MAJOR >= 5
111          DGifCloseFile(gifFile, null);
112 #else
113          DGifCloseFile(gifFile);
114 #endif
115       }
116
117       if(!result)
118          bitmap.Free();
119       return result;
120    }
121
122    bool Save(Bitmap bitmap, const char * filename, void * options)
123    {
124       bool result = false;
125       return result;
126    }
127
128    ColorAlpha * LoadPalette(const char * fileName, const char * type)
129    {
130       ColorAlpha * result = null;
131       return result;
132    }
133 }
134
135 #endif // !defined(__EMSCRIPTEN__)