function gif (options) {
  if (is.object(options)) {
    if (is.defined(options.reuse)) {
      this._setBooleanOption('gifReuse', options.reuse);
    }
    if (is.defined(options.progressive)) {
      this._setBooleanOption('gifProgressive', options.progressive);
    }
    const colours = options.colours || options.colors;
    if (is.defined(colours)) {
      if (is.integer(colours) && is.inRange(colours, 2, 256)) {
        this.options.gifBitdepth = bitdepthFromColourCount(colours);
      } else {
        throw is.invalidParameterError('colours', 'integer between 2 and 256', colours);
      }
    }
    if (is.defined(options.effort)) {
      if (is.number(options.effort) && is.inRange(options.effort, 1, 10)) {
        this.options.gifEffort = options.effort;
      } else {
        throw is.invalidParameterError('effort', 'integer between 1 and 10', options.effort);
      }
    }
    if (is.defined(options.dither)) {
      if (is.number(options.dither) && is.inRange(options.dither, 0, 1)) {
        this.options.gifDither = options.dither;
      } else {
        throw is.invalidParameterError('dither', 'number between 0.0 and 1.0', options.dither);
      }
    }
    if (is.defined(options.interFrameMaxError)) {
      if (is.number(options.interFrameMaxError) && is.inRange(options.interFrameMaxError, 0, 32)) {
        this.options.gifInterFrameMaxError = options.interFrameMaxError;
      } else {
        throw is.invalidParameterError('interFrameMaxError', 'number between 0.0 and 32.0', options.interFrameMaxError);
      }
    }
    if (is.defined(options.interPaletteMaxError)) {
      if (is.number(options.interPaletteMaxError) && is.inRange(options.interPaletteMaxError, 0, 256)) {
        this.options.gifInterPaletteMaxError = options.interPaletteMaxError;
      } else {
        throw is.invalidParameterError('interPaletteMaxError', 'number between 0.0 and 256.0', options.interPaletteMaxError);
      }
    }
  }
  trySetAnimationOptions(options, this.options);
  return this._updateFormatOut('gif', options);
}
Use these GIF options for the output image.

The first entry in the palette is reserved for transparency.

The palette of the input image will be re-used if possible.

@since 0.30.0

@example
// Convert PNG to GIF
await sharp(pngBuffer)
  .gif()
  .toBuffer();

@example
// Convert animated WebP to animated GIF
await sharp('animated.webp', { animated: true })
  .toFile('animated.gif');

@example
// Create a 128x128, cropped, non-dithered, animated thumbnail of an animated GIF
const out = await sharp('in.gif', { animated: true })
  .resize({ width: 128, height: 128 })
  .gif({ dither: 0 })
  .toBuffer();

@example
// Lossy file size reduction of animated GIF
await sharp('in.gif', { animated: true })
  .gif({ interFrameMaxError: 8 })
  .toFile('optim.gif');

@param {Object} [options] - output options
@param {boolean} [options.reuse=true] - re-use existing palette, otherwise generate new (slow)
@param {boolean} [options.progressive=false] - use progressive (interlace) scan
@param {number} [options.colours=256] - maximum number of palette entries, including transparency, between 2 and 256
@param {number} [options.colors=256] - alternative spelling of `options.colours`
@param {number} [options.effort=7] - CPU effort, between 1 (fastest) and 10 (slowest)
@param {number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, between 0 (least) and 1 (most)
@param {number} [options.interFrameMaxError=0] - maximum inter-frame error for transparency, between 0 (lossless) and 32
@param {number} [options.interPaletteMaxError=3] - maximum inter-palette error for palette reuse, between 0 and 256
@param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
@param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds)
@param {boolean} [options.force=true] - force GIF output, otherwise attempt to use input format
@returns {Sharp}
@throws {Error} Invalid options