Skip to content

Latest commit

 

History

History
78 lines (52 loc) · 2.67 KB

LibGD.md

File metadata and controls

78 lines (52 loc) · 2.67 KB

LibGD

Overview

LibGD is the current contender. It isn't perfect for our needs but it's pretty good. It's also simple and well-written in plain C, so it's a lot more amenable to hacking than something like VIPS.

I have a fork of LibGD here.

Pros:

  • Designed for the server
  • Easily callable from scripting languages
  • Simple, clean C code
  • Has a large, established user base

Cons:

  • Documentation is out of date
  • Resizing is a bit of a mess

Resizing

GD has three different resizing "systems": classic, fixed-point and floating-point.

The latter two are accessible via the function 'gdImageScale()'. This resizes images according to a mode, which is set via the function gdImageSetInterpolationMethod().

Classic

The classic resizers are gdImageCopyResized() and gdImageCopyResampled().

gdImageCopyResized() is a simple non-interpolating resize (i.e. it just copyies the closest pixel when shrinking and enlarges the pixels when enlarging.) It is extremely fast but produces poor output.

gdImageCopyResampled() does some kind of averaging but I don't know which algorithm it uses. It is pretty fast with so-so image quality.

Fixed Point

The fixed point interpolations come from this Code Project class. They are accessed via gdImageScale() by setting the mode to one of:

GD_NEAREST_NEIGHBOUR
GD_BILINEAR_FIXED
GD_BICUBIC_FIXED

(Nearest Neighbour isn't technically a fixed-point algorithm, but it comes from the same source so I'm lumping it in with them.)

These are (IMHO) not very good. They use fixed-point arithmetic to avoid the overhead of floating-point math but are inefficient in other ways. They recompute the weights for each pixel rather than computing them once for each axis and reusing them. They also resize the entire image in one pass rather than doing horizontal and vertical separately, (probably) resulting in poor cache performance.

In addition, the code is hellishly complex.

Floating Point

These come from the Graphics Gems III example code. They are accessed via gdImageScale() and the remaining modes.

All of these work the same way: they generate an array of weights which are used to average the pixel values. The weights themselves are generated by a function which depends on the mode. The code is simple and generally efficient and I was able to get GD_BICUBIC to run significantly faster than GD_BICUBIC_FIXED with this bug fix.