Since DNG 1.3, a file can carry processing steps as opcodes: lens distortion and
vignetting corrections, bad pixel repair, gain maps and so on. They sit in the tags
OpcodeList1, OpcodeList2 and OpcodeList3 of the
raw image directory, applied at three stages described on the
raw data page. This page follows the DNG
specification and Adobe’s DNG SDK.
Opcode list
An opcode list is always big-endian, whatever the byte order of the file.
| Field | Type | Meaning |
|---|---|---|
| Count | LONG | Number of opcodes |
| Opcodes | varies | One after another, applied in order |
Each opcode:
| Field | Type | Meaning |
|---|---|---|
| Opcode ID | LONG | Which opcode (below) |
| DNG version | LONG | The DNG version that defined it, as four bytes, such as 01 03 00 00 |
| Flags | LONG | Bit 0 (1): optional, a reader may skip it if it does not know it. Bit 1 (2): may be skipped when making a quick preview. |
| Parameter bytes | LONG | Size of the parameters that follow |
| Parameters | varies | Depends on the opcode |
A reader that meets an unknown opcode skips it with the parameter size if it is optional, and otherwise must give up on processing the image.
Opcode IDs
| ID | Opcode | Does |
|---|---|---|
| 1 | WarpRectilinear | Corrects lens distortion and lateral chromatic aberration of a normal lens |
| 2 | WarpFisheye | Unwraps a fisheye lens to a rectilinear image |
| 3 | FixVignetteRadial | Corrects radial vignetting |
| 4 | FixBadPixelsConstant | Replaces pixels that hold a given constant value |
| 5 | FixBadPixelsList | Replaces listed bad pixels and rectangles |
| 6 | TrimBounds | Crops the image |
| 7 | MapTable | Maps values through a lookup table |
| 8 | MapPolynomial | Maps values through a polynomial |
| 9 | GainMap | Multiplies by a smoothly varying gain, such as a lens shading map |
| 10 | DeltaPerRow | Adds a value to each row |
| 11 | DeltaPerColumn | Adds a value to each column |
| 12 | ScalePerRow | Multiplies each row by a value |
| 13 | ScalePerColumn | Multiplies each column by a value |
| 14 | WarpRectilinear2 | A later form of WarpRectilinear with more coefficients (DNG 1.6) |
Opcodes 1 to 13 date from DNG 1.3. The parameters of WarpRectilinear2 are not given here, as they were not confirmed from a public source.
Area specification
Opcodes 7 to 13 start their parameters with an area: which pixels and planes they act on.
| Field | Type | Meaning |
|---|---|---|
| Top | LONG | First row |
| Left | LONG | First column |
| Bottom | LONG | Row after the last |
| Right | LONG | Column after the last |
| Plane | LONG | First plane |
| Planes | LONG | Number of planes, at least 1 |
| RowPitch | LONG | Act on every n-th row, at least 1 |
| ColPitch | LONG | Act on every n-th column, at least 1 |
The pitches let one opcode act on a single colour of a Bayer pattern, for example pitch 2 starting at row 0 and column 1.
Lens corrections
Centres are normalised: 0.0 to 1.0 across the image, with 0.5, 0.5 the middle.
| Opcode | Parameters, in order |
|---|---|
| 1 WarpRectilinear | Planes (LONG, 1 or one per colour plane); for each plane 6 DOUBLE: radial kr0–kr3 and tangential kt0, kt1; then centre x and y (DOUBLE) |
| 2 WarpFisheye | Planes (LONG); for each plane 4 DOUBLE: radial kr0–kr3; then centre x and y (DOUBLE) |
| 3 FixVignetteRadial | 5 DOUBLE: k0–k4; then centre x and y (DOUBLE). The gain at normalised distance r is 1 + k0r² + k1r⁴ + k2r⁶ + k3r⁸ + k4r¹⁰. |
For the warps, a destination pixel at normalised radius r maps to a source radius r × (kr0 + kr1r² + kr2r⁴ + kr3r⁶), with the tangential terms added for WarpRectilinear. The centre values must lie between 0 and 1.
Bad pixels and trimming
| Opcode | Parameters, in order |
|---|---|
| 4 FixBadPixelsConstant | Constant (LONG): the value that marks a bad pixel; BayerPhase (LONG): position of the Bayer pattern (0 to 3). 8 bytes. |
| 5 FixBadPixelsList | BayerPhase (LONG); point count (LONG); rectangle count (LONG); each point as row, column (2 LONG); each rectangle as top, left, bottom, right (4 LONG). 12 + 8 × points + 16 × rectangles bytes. |
| 6 TrimBounds | Top, left, bottom, right (4 LONG): the area to keep. |
The bad pixel opcodes act on single-plane 16-bit CFA data, so they belong in
OpcodeList1.
Value mapping
| Opcode | Parameters after the area |
|---|---|
| 7 MapTable | Table size (LONG, 1 to 65536); entries (SHORT each). Each 16-bit value v becomes entry v (the last entry if v is beyond the table). |
| 8 MapPolynomial | Degree (LONG); degree + 1 coefficients (DOUBLE), constant term first. |
| 9 GainMap | Points down and across (2 LONG); spacing down and across (2 DOUBLE); origin down and across (2 DOUBLE); map planes (LONG); then the gains (FLOAT), row by row, column by column, with the planes innermost. |
| 10 DeltaPerRow | Count (LONG, one per row of the area at its row pitch); values (FLOAT), added. |
| 11 DeltaPerColumn | Count (LONG, one per column at the column pitch); values (FLOAT), added. |
| 12 ScalePerRow | Count (LONG); values (FLOAT), multiplied. |
| 13 ScalePerColumn | Count (LONG); values (FLOAT), multiplied. |
Gain map positions are in normalised image coordinates: point i down is at
origin + i × spacing. Gains between points are interpolated linearly in
both directions, and positions outside the map use the nearest edge. A map with a
single point in a direction is constant in that direction.
A list
00 00 00 01 count: 1 opcode
00 00 00 06 ID 6, TrimBounds
01 03 00 00 DNG 1.3.0.0
00 00 00 01 flags: optional
00 00 00 10 16 bytes of parameters
00 00 00 08 00 00 00 08 00 00 0F A8 00 00 17 78 top 8, left 8, bottom 4008, right 6008