41 dataBlockIsZero (
false), fresh (
false), finished (
false),
42 currentBit (0), lastBit (0), lastByteIndex (0),
43 codeSize (0), setCodeSize (0), maxCode (0), maxCodeSize (0),
44 firstcode (0), oldcode (0), clearCode (0), endCode (0)
46 int imageWidth, imageHeight;
47 if (! getSizeFromHeader (imageWidth, imageHeight))
51 if (in.
read (buf, 3) != 3)
54 int numColours = 2 << (buf[0] & 7);
57 if ((buf[0] & 0x80) != 0)
58 readPalette (numColours);
62 if (input.read (buf, 1) != 1 || buf[0] ==
';')
67 if (readExtension (transparent))
76 if (input.read (buf, 9) == 9)
81 numColours = 2 << (buf[8] & 7);
83 if ((buf[8] & 0x80) != 0)
84 if (! readPalette (numColours))
88 imageWidth, imageHeight, transparent >= 0);
90 image.getProperties()->set (
"originalImageHadAlpha", transparent >= 0);
92 readImage ((buf[8] & 0x40) != 0, transparent);
105 bool dataBlockIsZero, fresh, finished;
106 int currentBit, lastBit, lastByteIndex;
107 int codeSize, setCodeSize;
108 int maxCode, maxCodeSize;
109 int firstcode, oldcode;
110 int clearCode, endCode;
111 enum { maxGifCode = 1 << 12 };
112 int table [2] [maxGifCode];
113 int stack [2 * maxGifCode];
116 bool getSizeFromHeader (
int& w,
int& h)
121 if (input.
read (b, 6) == 6
122 && (
strncmp (
"GIF87a", b, 6) == 0
123 ||
strncmp (
"GIF89a", b, 6) == 0))
125 if (input.
read (b, 4) == 4)
129 return w > 0 && h > 0;
136 bool readPalette (
const int numCols)
138 for (
int i = 0; i < numCols; ++i)
143 palette[i].
setARGB (0xff, rgb[0], rgb[1], rgb[2]);
150 int readDataBlock (
uint8*
const dest)
153 if (input.
read (&n, 1) == 1)
155 dataBlockIsZero = (n == 0);
157 if (dataBlockIsZero || (input.
read (dest, n) == n))
164 int readExtension (
int& transparent)
167 if (input.
read (&type, 1) != 1)
175 n = readDataBlock (b);
185 n = readDataBlock (b);
195 for (i = 0; i < clearCode; ++i)
201 for (; i < maxGifCode; ++i)
208 void initialise (
const int inputCodeSize)
210 setCodeSize = inputCodeSize;
211 codeSize = setCodeSize + 1;
212 clearCode = 1 << setCodeSize;
213 endCode = clearCode + 1;
214 maxCodeSize = 2 * clearCode;
215 maxCode = clearCode + 2;
232 firstcode = oldcode = getCode (codeSize,
false);
234 if (firstcode != clearCode)
244 while ((code = getCode (codeSize,
false)) >= 0)
246 if (code == clearCode)
249 codeSize = setCodeSize + 1;
250 maxCodeSize = 2 * clearCode;
251 maxCode = clearCode + 2;
253 firstcode = oldcode = getCode (codeSize,
false);
256 else if (code == endCode)
264 while ((n = readDataBlock (buf)) > 0)
271 const int incode = code;
279 while (code >= clearCode)
281 *sp++ = table[1][code];
282 if (code == table[0][code])
285 code = table[0][code];
288 *sp++ = firstcode = table[1][code];
290 if ((code = maxCode) < maxGifCode)
292 table[0][code] = oldcode;
293 table[1][code] = firstcode;
296 if (maxCode >= maxCodeSize && maxCodeSize < maxGifCode)
312 int getCode (
const int codeSize_,
const bool shouldInitialise)
314 if (shouldInitialise)
322 if ((currentBit + codeSize_) >= lastBit)
327 buffer[0] = buffer [
jmax (0, lastByteIndex - 2)];
328 buffer[1] = buffer [
jmax (0, lastByteIndex - 1)];
330 const int n = readDataBlock (buffer + 2);
335 lastByteIndex = 2 + n;
336 currentBit = (currentBit - lastBit) + 16;
337 lastBit = (2 + n) * 8 ;
343 for (
int j = 0; j < codeSize_; ++j)
345 result |= ((buffer[i >> 3] & (1 << (i & 7))) != 0) << j;
349 currentBit += codeSize_;
353 bool readImage (
const int interlace,
const int transparent)
356 if (input.
read (&c, 1) != 1)
361 if (transparent >= 0)
362 palette [transparent].
setARGB (0, 0, 0, 0);
364 int xpos = 0, ypos = 0, yStep = 8, pass = 0;
368 const bool hasAlpha = image.hasAlphaChannel();
372 const int index = readLZWByte();
379 ((
PixelRGB*) p)->set (palette [index]);
383 if (++xpos == destData.width)
391 while (ypos >= destData.height)
395 case 1: ypos = 4; yStep = 8;
break;
396 case 2: ypos = 2; yStep = 4;
break;
397 case 3: ypos = 1; yStep = 2;
break;
398 default:
return true;
404 if (++ypos >= destData.height)