DIAGRAM EDITION  the stages in plain languageReference edition →

Stage 14 of 16

The fast route: the same map, lighter work

Fast mode traces a picture in a fraction of the time the full engine takes. It keeps the parts that make the drawing correct — shapes that share their borders exactly, and edges placed to a fraction of a pixel — and swaps every slow search for a quick, single-pass version. This page follows that route from the file to the finished SVG, and explains how the speed-up round made it faster again while changing what it draws in one place only: the picture's outer frame, now written as the exact rectangle it is. A later fix to the curve step changed a few more drawings: a curve that turns sharply back on itself no longer swallows the outline it belongs to.

Two routes through the same machine

The full engine, called Quality, spends its time searching. It weighs every possible colour against the evidence before accepting it, merges bands of a colour fade two at a time and re-checks after each merge, moves every edge of the picture at once until a re-drawing matches the pixels, and tries many ways of drawing each outline before picking the cheapest.

Fast mode answers the same questions in one pass each. It shares the middle of the pipeline with Quality unchanged — the map in which every border is stored once, the step that moves each border point onto the true edge, the symmetry check, and the writer that produces the file — and replaces the rest.

QUALITY FAST evidence-weighed palette regions, fades merged in pairs every edge moved at once best of many curve choices one-pass colour count tidy regions, rebuild fades skipped Potrace-style curves shared: border map, edge placement, symmetry shared: write the SVG edges go straight to the curve step
Where the two routes part. Thinly outlined boxes are Quality's own stages; copper boxes are Fast mode's replacements; the two tall boxes with a heavy outline are the same code in both. Fast mode also leaves out two tidy-up steps after the curves (repairing outlines that cross themselves, and making a shape that repeats, like the dots of an ellipsis, exactly identical each time).

Colours from the flat middles of shapes

The first job is deciding which colours — "inks" — the picture is made of. Fast mode sorts every pixel into one of a few tens of thousands of small colour boxes and counts them. But a box earns an ink only through its flat pixels: pixels whose four neighbours, left, right, above and below, fall in the same box.

Copper dot: a flat pixel. All four of its neighbours are the same colour as it is. Only flat pixels vote for an ink. The grey rim never has one. An anti-aliased edge is one pixel wide: every rim pixel touches the shape on one side and the background on the other, so a blend between two inks can never become an ink of its own.
Flat pixels. A filled region of any size has plenty of them; the blurry rim between two regions has none. That single rule does most of the work the full engine's careful evidence tests do.

The boxes are then taken busiest first. A box joins an existing ink when its colour is almost the same, or close and right next to one of that ink's boxes — one ink spread over neighbouring boxes by noise. Otherwise it starts an ink of its own. Lines too thin to have any flat pixel, such as small text, get a second chance from pixels that have at least one matching neighbour, unless their colour is simply a blend of two other inks. Finally every pixel gets its ink: most straight from a table built once per box, and only the in-between pixels by looking at their neighbours.

Counting in stretches, not pixel by pixel

Logos are mostly large areas of one colour. Read along any row and the colour stays the same for long stretches — "runs" — before it changes. On the large test images a pixel continues its left neighbour's colour almost every time, so most of the latest round's speed comes from one idea used over and over: do the work once per run, not once per pixel.

One row of sixteen pixels… …is three runs. 5 × background 6 × ink 5 × background The colour box is worked out once per run; a whole run's pixels are added up in one go.
Runs. At 2048 pixels across, the runs of the finished region map are about a quarter of a percent of the pixels. The border map, the region clean-up and the fade rebuilding below all read the picture as runs.

Why splitting the counting over many cores changes nothing

A big image is cut into horizontal bands, and each processor core counts its own band. At the end the band totals are added together. That sounds harmless, but for a computer it usually is not: adding the same numbers in a different order can give a result that differs in the last digit, because each addition rounds. A tracer that wants the same output on every machine has to care about that last digit.

band 1 band 2 band 3 band 4 core 1 counts core 2 counts core 3 counts core 4 counts one total exactly the total one core would reach, to the last bit
Order-free sums. For the colour sums the palette keeps, the order of addition provably cannot matter on an ordinary 8-bit image.

Here it provably does not matter. Every colour in an ordinary 8-bit image is a whole number of very small, equal steps, and the running totals the palette keeps are wide enough to hold every sum of up to about four million of them — a 2048 × 2048 image — without rounding anything. A sum that never rounds is the exact answer, whatever order the numbers arrive in. The code checks this condition on every value it reads; an image that has been resized in between (whose colours are averages, not whole steps) fails the check and is counted the slow way, one row after another, so the answer is still the same. The technical page gives the short proof.

Tidying the regions

Once every pixel has an ink, pixels of one ink that touch form a region. Before the border map is built, five quick passes tidy them:

  • Slivers — thin strips along an edge that are only a blend of the two regions either side go back to whichever of the two they mostly are.
  • Rims — the grey outline around small text, itself a strip between two inks, is split between the letter and the paper.
  • Near-identical inks — a patch whose ink the eye cannot tell from its larger neighbour's joins it.
  • Speckles — regions below a size that grows with the picture are given to the neighbour they share the longest border with, so no hole is left.
  • Faces — what remains is numbered, one number per connected region. Fast mode keeps those numbers in 16 bits, which leaves room for 65,534 regions. A picture with more than that first has its smallest regions merged, each into the neighbour it shares the most border with, until the rest fit, so every region is still one connected patch of one ink. It used to lump every region past the limit into the first one, whatever its colour. No real picture tried so far reaches the limit in Fast mode; a fine checkerboard does, and is the test.

All five now work on the runs. The pixel labels are read once, when the runs are made, and written once, at the end. In between, everything the passes need — a region's size, whether it has an inside at all, the length of its border with each neighbour — is read off the runs. On a 2048-pixel image the whole tidy-up went from 76.2 milliseconds to 3.86.

Putting smooth fades back together

A smooth colour fade has no flat colour, so the ink-finding step turns it into bands, and each band would get a border of its own. Neighbouring regions whose inks are only a small step apart are grouped, each group gets one gradient fitted to it, and the gradient is kept when it explains the pixels about as well as the bands did.

The latest round added a shortcut that is a proof, not a guess: two regions that touch always have different inks, so if no two different inks in the whole picture are close enough to be steps of one fade, nothing could ever be grouped — and the pass stops before looking at a single pixel. That settled 5 of the 7 large test images outright. On a picture with so many regions that the smallest had to be merged (above), the shortcut stands aside and the full pass decides.

The shared middle

From here Fast mode runs the same code as Quality: the border map, the step that moves each border point onto the true edge, and the symmetry check. All three got faster for both modes: the map's borders are read off runs, and the edge placement, which looks at each point on its own, now measures many points at once on different cores while the symmetry check runs beside it. Only the whole-picture adjustment that Quality runs next is left out.

Drawing the curves the Potrace way

For the curves, Fast mode follows the classic method of Potrace, a well-known tracer from 2003, restated for points that already sit at their true positions between the pixels rather than on the pixel corners Potrace starts from. Each shared border is fitted once, so the two regions either side draw exactly the same curve.

1. measured points 2. fewest straight sides 3. corners and curves corner stays sharp 4. merged curves two lines and one curve
The four steps. (1) The border points, already placed between the pixels. (2) The fewest straight sides that stay within half a pixel of every point. (3) Each corner of that outline is either kept sharp — where rounding it would miss the points — or rounded into a curve fitted to the points around it. (4) Runs of smooth curves bending one way are merged wherever a single curve says the same thing.

Two rules keep that last merge safe. A piece of curve that turns sharply back on itself — a U-turn — is always kept as its own curve, never merged with its neighbours. And a closed outline is never collapsed into a single curve: it always comes back as two curves or more. Before a fix in October 2026, one U-turn piece could make the merge lose track of the whole stretch, which then came back as its last piece alone; on a closed outline that left one curve closed on itself, and the shape was not drawn. In everyday Fast mode the fix changed 9 of the 402 icons of the quality check at its smaller size and 3 at its larger one, and the Visa logo of the Simple Icons set, traced at 512 pixels, came out closer to the original.

Whether a corner stays sharp is decided by distance: if the rounded curve would miss the border points by more than a tenth of a pixel, and by more than twice what the two straight sides miss them by, the corner is kept. Until October 2026 the limit was a quarter of a pixel. Lowering it made Fast both closer and smaller at once: a sharp corner takes four numbers where the curve that rounded it took six, and on drawn icons the sharp corner is usually what the artist drew. On the quality check's small icons the colour error fell by 1.5 % and the number count by 4.3 %; on the larger ones the count fell by 1.6 % with the error unchanged.

Before those steps, a closed outline that is really a circle or an ellipse is recognised as one and written with three or five numbers instead of a chain of curves; and a border between two nearly identical colours is fitted more loosely, because a small misplacement there is invisible. Borders are fitted on all cores at once, each on its own.

The picture's outer border is not fitted at all. When one region runs all the way round the edge of the picture — a background colour, or the clear ground of a transparent icon — its outline is exactly the picture's rectangle, so Fast mode now writes it as four straight lines. Fitting it used to be the slowest single job on most pictures, and it left a small cut across one corner: a wasted curve on two icons in three.

The search for the fewest straight sides, where most of this step's time went, got three shortcuts that give exactly the same outline. It stops working out the cost of sides that already need more pieces than the best way found so far; it jumps over straight runs of the pixel grid, where the outcome is known in advance; and on very long borders it works out which sides are allowed on all cores at once, then chooses among them in the usual order. The circle and ellipse check stopped computing a score that nothing read, and now starts its search for an ellipse from one good guess instead of five. Together, the curve step became two to five times faster, the most on the largest pictures.

The outer frame is the one change here that alters the drawing on purpose, and only on pictures with a coloured background: a transparent icon's clear ground is not drawn, so there it only saves time. The single starting guess for ellipses changed no file in the test sets, but unlike the other shortcuts it is not proven to give the same answer, so the quality check judged it instead.

Faster, with the drawing held fixed

Every change the speed-up round made to the steps described above was made with the output held fixed (the outer-frame change in the curve step, described just above, is the one deliberate exception, and the ellipse starting guess was judged rather than proven; the later U-turn fix was a correction, not a speed-up, and the quality check judged it too). Each rewritten step keeps the code it replaced as a reference, the tests compare the two on random and awkward inputs, and the finished SVG files were compared byte for byte across hundreds of test images in both modes. Measured per image on a busy development machine, so the milliseconds are approximate:

StepImage sizeBeforeAfter
Finding the inks2048 px47.7 ms7.1 ms
Finding the inks128 px1.85 ms0.40 ms
Tidying the regions2048 px76.2 ms3.86 ms
Tidying the regions128 px0.50 ms0.09 ms
Fades, border map, edge placement2048 px42 ms13 ms
The same, plus transparency, on a transparent image2048 px130 ms21 ms
The same128 px1.8 ms1.2 ms
Drawing the curves2048 px26.3 ms5.4 ms
Drawing the curves128 px1.00 ms0.46 ms

The curve rows come from one run of all the changes together; the others measure each step's own work against its own earlier run. Measured the same way, the whole trace before the curves went from 161.5 ms to 31.0 ms on a 2048 px picture, and from 4.3 ms to 2.5 ms on a 128 px icon.

The shared middle is shared: Quality mode gained the border map and edge placement speed-ups too.

Writing the file

The last step is Quality's own writer, with one difference: Fast mode does not make repeated, near-identical shapes exactly identical. For a transparent picture, the check for shapes that fade from solid to see-through now skips every shape where a fade is mathematically impossible — too small, or completely solid inside — instead of testing every shape against the whole picture. The writer's page has the details.

A third route: Balanced

Between Fast and Quality there is a large gap in time and a large gap in closeness, and the two are not spread evenly over Quality's stages. On small icons, almost all of Fast's error sits within one pixel of an edge: it is about where the borders are, not about colour. Two of Quality's stages fix that. One fits every outline by trying many ways of drawing it, and costs twenty to thirty times Fast's whole trace. The other moves every border point at once until a redrawing matches the pixels, and it is cheap at the start: most of what it buys comes in its first few rounds.

Balanced is Fast with the first eight rounds of that edge placement added, and a curve fit that follows the points a quarter more closely. It keeps Fast's flat fills and leaves the expensive outline search to Quality. On the quality check's small icons it closes about three fifths of the distance from Fast to Quality, and at 512 pixels two fifths to a half; on a set of 21 logos and emoji at 512 and 1024 pixels its median error is close to Quality's. It costs two to three times Fast's work, a tenth of Quality's or less.

Why eight rounds. When Balanced was first built, on the edge placement of version 0.2.5, four rounds were the sweet spot. The edge placement was then rewritten to take better-judged steps, and the count was measured again: the colour error still levels off after four, but on the new version more rounds also leave a smoother edge for the curve fit, so the drawing uses fewer numbers and turns less. Eight rounds bring the number count back to Fast's for about a seventh more time than four.

It has a price besides time: its outlines turn more along their length than Fast's, because the finer fit follows more of the small wobble in the measured edge. Fitting with Fast's own looseness after the same eight rounds avoids that, with fewer numbers than Fast, and still gains about two thirds as much; the measurements are on the technical page.

On pictures larger than 1024 pixels on their longer side, Balanced simply runs Fast. At 2048 pixels the extra steps still helped a little — about 5 % on typical logos — but they cost a third more numbers and nearly three times the work, and the rest of what separates Fast from Quality there is the way gradients are filled, which no edge placement can fix.