bool wxGIFHandler::DoSaveFile(const wxImage& image, wxOutputStream *stream, bool WXUNUSED(verbose), bool first, int delayMilliSecs, bool loop, const wxRGB *pal, int palCount, int maskIndex) { const unsigned long colorcount = image.CountColours(256+1); bool ok = colorcount && (colorcount <= 256); if (!ok) { return false; } int width = image.GetWidth(); int height = image.GetHeight(); wxCHECK_MSG( width && height, false, wxS("can't save 0-sized file") ); int width_even = width + ((width % 2) ? 1 : 0); if (first) { ok = wxGIFHandler_WriteHeader(stream, width, height, loop, pal, palCount); } ok = ok && wxGIFHandler_WriteComment(stream, image.GetOption(wxIMAGE_OPTION_GIF_COMMENT)) && wxGIFHandler_WriteControl(stream, maskIndex, delayMilliSecs) && wxGIFHandler_WriteByte(stream, GIF_MARKER_SEP) && wxGIFHandler_WriteRect(stream, width, height); // local palette if (first) { // we already saved the (global) palette ok = ok && wxGIFHandler_WriteZero(stream); } else { const int bpp = wxGIFHandler_BitSize(palCount); wxUint8 b; b = 0x80; b |=(bpp - 1) << 5; b |=(bpp - 1); b &=~0x40; // clear interlaced ok = ok && wxGIFHandler_WriteByte(stream, b) && wxGIFHandler_WritePalette(stream, pal, palCount, bpp); } if (!ok) { return false; } if (!InitHashTable()) { wxLogError(_("Couldn't initialize GIF hash table.")); return false; } const wxUint8 *src = image.GetData(); wxScopedArray<wxUint8> eightBitData(width); SetupCompress(stream, 8); m_pixelCount = height * width_even; for (int y = 0; y < height; y++) { m_pixelCount -= width_even; for (int x = 0; x < width; x++) { wxRGB rgb; rgb.red = src[0]; rgb.green = src[1]; rgb.blue = src[2]; int index = wxGIFHandler_PaletteFind(rgb, pal, palCount); wxASSERT(index != wxNOT_FOUND); eightBitData[x] = (wxUint8)index; src+=3; } ok = CompressLine(stream, eightBitData.get(), width); if (!ok) { break; } } wxDELETE(m_hashTable); return ok; }