47{
48
49
50
51 int err;
52 GifFileType* gifFile = DGifOpen(device(),
doInput, &err);
53 if (!gifFile) {
54 qWarning() << "Received error code" << err;
55 return false;
56 }
57
58
59 *image = QImage(gifFile->SWidth, gifFile->SHeight, QImage::Format_Indexed8);
60
61 GifRecordType recordType;
63
64 int i, row, imageNum = 0, topRow, width, height;
65 int transColor = -1;
66 do
67 {
68 DGifGetRecordType(gifFile, &recordType);
69 switch (recordType)
70 {
71 case IMAGE_DESC_RECORD_TYPE:
72 if (DGifGetImageDesc(gifFile) == GIF_ERROR)
73 {
74 qWarning("QGIFLibHandler::read: error %d", gifFile->Error);
75 return false;
76 }
77 topRow = gifFile->Image.Top;
78 width = gifFile->Image.Width;
79 height = gifFile->Image.Height;
80
81 if (gifFile->Image.Left + width > gifFile->SWidth ||
82 gifFile->Image.Top + height > gifFile->SHeight)
83 {
84 qWarning("Image %d is not confined to screen dimension, aborted.", imageNum);
85 return false;
86 }
87
88
89
90 image->fill(gifFile->SBackGroundColor);
91
92
93 if (gifFile->Image.Interlace)
94 {
95
96 for (i = 0; i < 4; i++)
99 {
100 if (DGifGetLine(gifFile, image->scanLine(row), width) == GIF_ERROR)
101 {
102 qWarning("QGIFLibHandler::read: error %d", gifFile->Error);
103 return false;
104 }
105
106
107
108
109 }
110 }
111 else
112 {
113 for (row = 0; row < height; row++)
114 {
115 if (DGifGetLine(gifFile, image->scanLine(row), width) == GIF_ERROR)
116 {
117 qWarning("QGIFLibHandler::read: error %d", gifFile->Error);
118 return false;
119 }
120
121
122
123
124 }
125 }
126 break;
127 case EXTENSION_RECORD_TYPE:
128 {
129 int extCode;
130 GifByteType* extData;
131
132 if (DGifGetExtension(gifFile, &extCode, &extData) == GIF_ERROR)
133 {
134 qWarning("QGIFLibHandler::read: error %d", gifFile->Error);
135 return false;
136 }
137 while (extData != NULL)
138 {
139 int len = extData[0];
140 switch (extCode)
141 {
142 case GRAPHICS_EXT_FUNC_CODE:
143
144
145
146
147
148
149 if (extData[1] & 0x01)
150 {
151 transColor = extData[3];
152
154
155 }
156 break;
157 case COMMENT_EXT_FUNC_CODE:
158 {
159 QByteArray comment((char*)(extData + 1), len);
160
161 image->setText("Description", comment);
162 }
163 break;
164 case PLAINTEXT_EXT_FUNC_CODE:
165 break;
166 }
167 if (DGifGetExtensionNext(gifFile, &extData) == GIF_ERROR)
168 {
169 qWarning("QGIFLibHandler::read: error %d", gifFile->Error);
170 return false;
171 }
172 }
173 }
174 break;
175 case TERMINATE_RECORD_TYPE:
176 break;
177 default:
178 break;
179 }
180 }
181 while (recordType != TERMINATE_RECORD_TYPE);
182
183
185 ? gifFile->Image.ColorMap
186 : gifFile->SColorMap);
187 if (!ColorMap)
188 {
189 qWarning("QGIFLibHandler::read: Image does not have a colormap");
190 return false;
191 }
193 image->setColorCount(ccount);
194 for (i = 0; i < ccount; ++i)
195 {
196 GifColorType gifColor =
ColorMap->Colors[i];
197 QRgb color = gifColor.Blue | (gifColor.Green << 8) | (gifColor.Red << 16);
198
199
200 if (i != transColor)
201 color |= 0xff << 24;
202
203 image->setColor(i, color);
204 }
205
206 return true;
207}
int doInput(GifFileType *gif, GifByteType *data, int i)
static const int InterlacedOffset[]
static const int InterlacedJumps[]