Measure, Validate, Capabilities
and the error codes
Plan sizes without rendering, check a request before using it, discover what the installed build supports, and handle every failure by its stable code.
measure
Exact geometry without an image
measure takes the same request as generate (minus the output destination members) and runs the encoder and the layout, but renders nothing. Use it to size a layout, to pick a module size that meets a physical requirement, or to find out why a symbol would not fit — cheaply, and without touching the file system.
Chilkat.JsonObject req = new Chilkat.JsonObject();
req.UpdateString("payload.text", "https://www.chilkatsoft.com/some/long/url?with=parameters");
req.UpdateString("render.units", "mm");
req.UpdateNumber("render.moduleSize", "0.4");
req.UpdateInt("render.dpi", 203); // a 203-dpi label printer
req.UpdateInt("render.maxWidth", 40); // the label is 40 mm wide
Chilkat.JsonObject res = new Chilkat.JsonObject();
Chilkat.Formats fmt = new Chilkat.Formats();
if (!fmt.QrCode("measure", req, res)) { Console.WriteLine(fmt.LastErrorText); return; }
if (res.BoolOf("fits")) {
Console.WriteLine("version " + res.IntOf("symbols[0].selectedEncoding.version")
+ ", pitch " + res.IntOf("measurements[0].pitch") + " px"
+ ", " + res.StringOf("measurements[0].physicalWidth") + " mm wide");
} else {
Console.WriteLine("does not fit: " + res.StringOf("reasons[0].message"));
}req = chilkat2.JsonObject()
req.UpdateString("payload.text", "https://www.chilkatsoft.com/some/long/url?with=parameters")
req.UpdateString("render.units", "mm")
req.UpdateNumber("render.moduleSize", "0.4")
req.UpdateInt("render.dpi", 203) # a 203-dpi label printer
req.UpdateInt("render.maxWidth", 40) # the label is 40 mm wide
res = chilkat2.JsonObject()
fmt = chilkat2.Formats()
if not fmt.QrCode("measure", req, res):
print(fmt.LastErrorText); exit()
if res.BoolOf("fits"):
print("version", res.IntOf("symbols[0].selectedEncoding.version"),
"pitch", res.IntOf("measurements[0].pitch"), "px,",
res.StringOf("measurements[0].physicalWidth"), "mm wide")
else:
print("does not fit:", res.StringOf("reasons[0].message"))Formats, have the same methods and the same JSON requests in every supported language: C, C++, C#, VB.NET, Java, Objective-C, Swift, Python, PHP, Perl, Ruby, Node.js, Electron, React Native, Dart / Flutter, Go, Rust, Zig, Delphi, C++Builder, Free Pascal / Lazarus, Classic ASP, VB6, VBScript, FoxPro, DataFlex, PowerBuilder, Xojo, Xbase++, PureBasic, AutoIt, B4A / B4J, LabVIEW, SQL Server and Tcl. See Chilkat Downloads for Every Language.The measure response
| Member | Meaning |
|---|---|
fits | true when every symbol satisfies the constraints. |
symbols[] | As for generate (present when the payload could be encoded). |
measurements[] | One entry per symbol: fits, noFitReason, units, dpi, pitch, requestedPitch, pitchAdjusted, moduleSize (actual, in units), canvasWidth/canvasHeight, physicalWidth/physicalHeight, rotation, symbolX/symbolY/symbolWidth/symbolHeight, quietZonePx, paddingPx, textBandPx, text, textScale. |
reasons[] | When something does not fit: { "code": "noFit" | "capacityExceeded", "path", "message", "symbolIndex" }. A payload too large for any version is a completed fits: false measurement, not a failure. |
{
"fits": false,
"symbols": [ { "symbology": "qr", "selectedEncoding": { "version": 5, ... }, ... } ],
"measurements": [ { "index": 0, "fits": false, "noFitReason": "exceedsMaxWidth", "units": "mm", "dpi": 203, "pitch": 3, ... } ],
"reasons": [ { "code": "noFit", "path": "/render", "message": "exceedsMaxWidth", "symbolIndex": 0 } ],
"errors": [], "warnings": []
}measure and generate always agree: the measurements[] of a generate response describe the image that was delivered, pixel for pixel.validate
Examine a request without producing output
validate answers "is this request good?" at a chosen depth. It takes the generate request members plus a target and a validation.scope. Request-level mistakes (unknown options, wrong types, out-of-range values) still fail the call; content findings about an admissible request are returned with true and a verdict.
| Member | Values | Default | Notes |
|---|---|---|---|
target | "symbol" | required | "payload" (structured payload validation) is reserved. |
validation.scope | "definition" · "capacity" · "layout" | "definition" | definition: is the symbology/payload/encoding admissible? capacity: additionally, does the payload fit? layout: additionally, does it fit the render constraints? render is admitted only for the layout scope. |
{ "target": "symbol", "validation": { "scope": "capacity" },
"payload": { "text": "...3000 characters..." }, "encoding": { "qr": { "errorCorrection": "H" } } }{
"validationStatus": "invalid",
"subject": { "target": "symbol", "symbology": "qr", "scope": "capacity", "payloadBytes": 3000 },
"findings": [ { "code": "capacityExceeded", "path": "/payload", "severity": "error",
"message": "the payload does not fit any admitted QR version at the selected error-correction level" } ],
"checks": [ { "name": "definition", "status": "passed" }, { "name": "capacity", "status": "failed" } ],
"errors": [], "warnings": []
}validationStatus is valid only when every check up to the requested scope passed; a definite violation makes it invalid. checks[] lists each scope with passed, failed or notApplicable (a later scope is not examined after an earlier one fails).
capabilities
What does this build support?
capabilities needs no request (an empty object is fine) and returns a description of the installed implementation. Optional filters narrow the arrays: symbology, operation, payloadType. Everything reported as available is accepted by the other operations, and everything else is rejected with unsupportedFeature or optionNotApplicable — so an application can feature-detect instead of guessing.
{
"productVersion": "11.7.0",
"symbologies": [
{ "id": "qr", "family": "qr", "available": true, "generate": true, "read": false, "detect": false,
"structuredAppend": { "generate": true, "maxSymbols": 16 }, "hri": false,
"quietZone": { "left": 4, "top": 4, "right": 4, "bottom": 4 },
"encoding": { "version": { "min": 1, "max": 40 }, "errorCorrection": [ "auto", "L", "M", "Q", "H" ],
"boostErrorCorrection": true, "mask": { "min": 0, "max": 7 },
"modes": [ "auto", "numeric", "alphanumeric", "byte" ], "eci": [ "none", 26 ], "charsets": [ "utf-8" ] },
"render": { "moduleShape": [ "square" ], "finderStyle": [ "standard" ], "logo": false, "text": true } },
{ "id": "code128", "family": "linear", "available": false, "reason": "notImplemented" }, ...
],
"operations": [ { "name": "generate", "available": true }, { "name": "measure", "available": true },
{ "name": "validate", "available": true, "targets": [ "symbol" ], "scopes": [ "definition", "capacity", "layout" ] },
{ "name": "capabilities", "available": true }, { "name": "read", "available": false, "reason": "notImplemented" }, ... ],
"payloadTypes": [ { "type": "text", "available": true, "generate": true }, { "type": "binary", "available": true, "generate": true }, ... ],
"imageFormats": [ ... ], "render": { ... },
"dependencies": { "verifyReadback": { "available": false, "reason": "readerNotImplemented" } },
"limits": { "timeoutMs": { "default": 10000, "max": 600000 }, "maxPixels": { "default": 16777216, "max": 67108864, "maxAxis": 32768 } },
"errors": [], "warnings": []
}Chilkat.JsonObject caps = new Chilkat.JsonObject();
Chilkat.JsonObject filter = new Chilkat.JsonObject();
filter.UpdateString("symbology", "dataMatrix");
fmt.Barcode("capabilities", filter, caps);
bool haveDataMatrix = caps.SizeOfArray("symbologies") > 0 && caps.BoolOf("symbologies[0].available");caps = chilkat2.JsonObject()
filt = chilkat2.JsonObject()
filt.UpdateString("symbology", "dataMatrix")
fmt.Barcode("capabilities", filt, caps)
haveDataMatrix = caps.SizeOfArray("symbologies") > 0 and caps.BoolOf("symbologies[0].available")limits
Time and memory safety
Two limits protect the host application from pathological requests. Both have sensible defaults and are reported by capabilities.
| Member | Range | Default | Notes |
|---|---|---|---|
limits.timeoutMs | 1–600,000 | 10,000 | A deadline for the whole operation, checked at the engine's internal checkpoints (per mask evaluation, per row, per output). On expiry the call fails with code timeout and the response carries "stopReason": "timeout"; no partial image is ever returned. |
limits.maxPixels | 1–67,108,864 | 16,777,216 (4096²) | The largest canvas area (after rotation) that may be rendered; each side is also capped at 32,768 px. A larger symbol is a no-fit (exceedsPixelLimit). |
{ "payload": { "text": "..." }, "render": { "moduleSize": 40 }, "limits": { "timeoutMs": 2000, "maxPixels": 4000000 } }Errors and warnings
Every failure has a stable code
When a method returns false, the response holds exactly one errors[] entry: { "code", "path", "message" }. path is a JSON Pointer into the request (/encoding/qr/version; ~ and / in names are escaped as ~0 and ~1), or empty for execution failures. Messages are bounded and never echo payload content. LastErrorText has the full diagnostic log.
Request-rejection codes
| Code | Meaning | Example |
|---|---|---|
missingOption | A required member is absent. | Barcode without symbology; payload without text. |
nullNotAllowed | A member is JSON null. | "encoding": null |
wrongType | Wrong JSON type, including non-integer tokens for integers. | "version": "3", "version": 3.0, "timeoutMs": 007 |
invalidNumber | A number that is not finite. | "dpi": 1e400 |
outOfRange | A value outside its range or a string too long. | "mask": 8, a quiet zone below 4, "version": 41 |
invalidEnum | A string that is not one of the allowed tokens (tokens are case-sensitive). | "errorCorrection": "m", "rotation": 45, op "Generate" |
unknownOption | A member name that does not exist at that place. | "render": { "size": 4 } |
duplicateOption | The same member twice in one object. | |
conflictingOptions | Members that cannot be combined. | path with pathTemplate; return: "none" without a destination; mode: "numeric" for non-digits; minVersion > maxVersion |
unsupportedFeature | A defined feature that this build does not implement. | symbology: "dataMatrix", mode: "kanji", encoding.gs1, render.qr.logo, verifyReadback: true, op "read" |
optionNotApplicable | A valid member that does not apply to this symbology or operation. | encoding.code128 for QR; output.path under measure; charset with a binary payload |
Execution codes
| Code | Meaning |
|---|---|
capacityExceeded | The payload does not fit the admitted QR versions at the selected error-correction level (path /payload). |
noFit | The symbol does not fit the render constraints (path /render; the message names the reason, see Rendering). |
outputFailed | A destination exists (and overwrite is false), could not be checked, or could not be written. |
resourceLimit | Memory could not be allocated or the internal working-memory ceiling was reached. |
timeout | limits.timeoutMs expired. The response also carries stopReason. |
internalError | An unexpected inconsistency; please report it with LastErrorText. |
warnings[] is reserved for advisories about requests that completed; it is empty in v11.7.0.
if (!fmt.QrCode("generate", jsonIn, jsonOut)) {
string code = jsonOut.StringOf("errors[0].code");
string path = jsonOut.StringOf("errors[0].path");
if (code == "capacityExceeded") {
// too much data: lower the error-correction level or enable structured append
} else if (code == "noFit") {
// relax maxWidth/maxHeight or use shrinkToFit
} else {
Console.WriteLine(code + " at " + path + ": " + jsonOut.StringOf("errors[0].message"));
Console.WriteLine(fmt.LastErrorText);
}
}if (!fmt.QrCode("generate", jsonIn, jsonOut)) {
const char *code = jsonOut.stringOf("errors[0].code");
if (strcmp(code, "capacityExceeded") == 0) {
// too much data: lower the error-correction level or enable structured append
} else if (strcmp(code, "noFit") == 0) {
// relax maxWidth/maxHeight or use shrinkToFit
} else {
std::cout << code << " at " << jsonOut.stringOf("errors[0].path") << ": "
<< jsonOut.stringOf("errors[0].message") << "\r\n" << fmt.lastErrorText() << "\r\n";
}
}if not fmt.QrCode("generate", jsonIn, jsonOut):
code = jsonOut.StringOf("errors[0].code")
if code == "capacityExceeded":
pass # too much data: lower the error-correction level or enable structured append
elif code == "noFit":
pass # relax maxWidth/maxHeight or use shrinkToFit
else:
print(code, "at", jsonOut.StringOf("errors[0].path") + ":", jsonOut.StringOf("errors[0].message"))
print(fmt.LastErrorText)