Plateworks DesqueezeFrameworkPlateworks DesqueezeShow a photo from an anamorphic lens at its correct shape in Lightroom, with one tag in the DNG and no change to a pixel.OverviewAn anamorphic lens squeezes the width of each photo. Plateworks Desqueeze is a Mac tool that sets the DefaultScale tag in every DNG of one folder. Lightroom and Camera Raw read the tag and stretch the photo when they show it. The tag works only in a DNG, so the tool converts Sony ARW files to DNG first.The tool has three front ends, and all three do the same work:A window. Drop a folder on it, select the squeeze factor of the lens, and click the run button.A command line tool, desqueeze.An MCP server, desqueeze-mcp, for an MCP client such as Claude Code.DesqueezeCore is the Swift module that holds every rule. Each front end collects input, calls the core, and shows what the core returns. Three external programs do the file work: exiftool reads and writes the tags, dnglab converts ARW files, and Adobe DNG Converter is an optional backup for the photos that dnglab cannot match.The tool is open source under the MIT license. The window has a download, and Getting started says what it holds. The command line tool and the MCP server are a build from source. The download and the build were tested on macOS 27.2 only, and the build with Xcode 27 only.The tool collects nothing, and Privacy says what each part of it loads and saves.Where to startTo use the tool, start with Getting started. Before the first run on photos that matter, read What happens to your files.To change the code, start with Architecture, then read Safety rules for code.To add your camera, read How the match works, then Adding a camera.TopicsFor a photographerGetting startedGet the tool, and make a first run on a copy of a folder.Using the windowDrop a folder, select the squeeze factor of the lens, and run.Using the command line toolScan a folder, see what a run would do, run, and remove, with desqueeze.Using it from Claude CodeGive the tool to an MCP client, so a model can scan a folder and set the stretch for you.What happens to your filesWhat the tool does to each file, what it sends to the Trash, and how to undo a run.Cameras and lensesWhich photos get a DNG that renders as Adobe’s does, and what happens to every other photo.TroubleshootingWhat each note and each message means, what to do, and how to make a report for a bug.PrivacyDesqueeze collects nothing.For a contributorArchitectureOne core, three front ends and three external programs, and the path of one run through them.How the match worksWhy a DNG from dnglab renders darker than Adobe’s, the nine tags that close the gap, and how each value was measured.Adding a cameraMeasure what Adobe DNG Converter writes for another Sony camera, add its row to the match table, and prove the row with the drift check.Safety rules for codeThe rules that a change must not break, why each one exists, and the test that guards it.TestingThe three test suites, the fixtures, what skips, and the rules that keep a test from a real photo and from the real Trash.The JSON reportsEvery key of the scan report and of the run report, and every kind of note, for a tool that you write on top.Scan and snapshotenum FolderChoiceWhat counts as a folder when a person drops one, chooses one, or names one at launch (design, section 5).enum FolderScanLists the top level of a folder, and decides which ARW files are pending. It reads no tag.struct FolderContentsThe files at the top level of one folder that a scan looks at.struct FolderScannerMakes the FolderSnapshot of a folder: the lists of FolderScan, the tag of each DNG, and the backup state. It changes no file.struct FolderSnapshotEverything a front end and the job need to know about one folder.struct DNGFileOne DNG in the folder, with what the scan learned about it.Factor and tagstruct SqueezeFactorA horizontal stretch factor for the DNG DefaultScale tag.struct ScaleThe two numbers of the DefaultScale tag: horizontal stretch, then vertical stretch.protocol ScaleTaggingReads and writes the DefaultScale tag. DesqueezeJob depends on this protocol, so its tests need no exiftool.struct ScaleTagThe exiftool implementation.struct TagRowOne row of the folder read: a DNG and its current tag.enum TagErrorA read or a write of a tag that failed, with the reason as text.protocol BackupHandlingThe backup that exiftool leaves beside a file it wrote: <name>_original.struct FileBackupsThe real BackupHandling. It discards a file with the function that its caller gives: the Trash for the app, and a folder of its own for a test.Converters and the matchprotocol RawConverterConverts one raw file to a DNG beside it.struct RawConvertersThe converters that are installed, each optional, and the reader of the facts that choose between them (design 13).struct DnglabConverterConverts with dnglab, then writes the tags that make the DNG render as Adobe DNG Converter’s does (design 13.2 to 13.4).struct AdobeConverterConverts with Adobe DNG Converter, the optional backup (design 13.3).struct ConversionWhat a conversion made.enum ConvertErrorWhy a conversion failed, and the file that it left behind.enum ConverterOutputThe output of a conversion, <base>.dng, the names of the files that can be beside it while a conversion works, and what a converter asks the disk about them.struct ExclusiveRenameGives a file a new name, and fails when anything has that name (design 13.3, step 5).struct ARWFactsThe five facts about one ARW that decide which converter takes it, and what the match writes (design 13.4).protocol ARWFactsReadingReads the facts. DesqueezeJob depends on this protocol, so its tests need no exiftool.struct ARWFactsReaderThe exiftool implementation.enum AdobeMatchThe tags that make a dnglab DNG render as Adobe DNG Converter’s does, and the rule for when they can (design 13.2 to 13.4). Pure: no file access.enum ConverterChoiceWhich converters get one ARW, and in which order (design 13.4). Pure: the run and the dry run both ask here, so the two cannot disagree.enum ConverterKindThe two converters, by the names that the JSON gives them (design 13.6).The job, the plan and the summarystruct DesqueezeJobOne run over a folder (design, section 4.3).struct FolderLockOne run in a folder at a time (design 13.9).enum TagDecisionWhat a run does with one DNG.struct RunPlanWhat a run would do, file by file. Made by DesqueezeJob.plan.struct RunSummaryThe counts and the notes of one run.struct FileNoteOne line for the result list: a file and what happened to it.struct RunProgressOne completed step of a run: how many steps are complete, how many the run has, and the file of this step. A conversion is one step, the tag of a DNG is one, and so is each ARW that the run handles when it moves the originals (design 14.3).class CancelFlagSet from the main thread, read from the job’s thread.class InterruptWatcherSets a flag at a signal, so a run stops after its current file.The originals, on requestenum OriginalDecisionWhat the run does with one original: the ARW of a conversion that this run made (design 14.2).enum OriginalStateWhether an ARW is still the file that was converted (design 14.2, line 4).struct FileRecordWhat the disk says about one file: whether it is a regular file, its size, its modification date, and its file number.enum DNGCheckThe check of a DNG, directly before its original moves to the Trash (design 14.2, line 5): <base>.dng is a regular file with bytes, it names the ARW in OriginalRawFileName, and its DefaultScale is the chosen factor.struct OriginalCheckTagsThe two tags that the check of a DNG reads before its original moves (design 14.2, line 5). ScaleTagging.readOriginalCheck gives them.Reportsstruct DesqueezeOperationsThe three things a front end does with a folder: scan, run, and remove. Each returns a report that is ready to print.struct ScanReportWhat a scan found, in the JSON shape of design 12.1, with the dnglab key of design 13.6.struct RunReportThe result of a run or of a dry run, in the JSON shape of design 12.1, with the two counts of design 13.6 and the two keys of design 14.3.struct ErrorReportWhat a front end prints as JSON when it can give no report.enum ReportJSONTurns a report into JSON text.Front-end textenum FolderTextThe words and the counts that a front end shows about a folder (design, sections 5 and 7).enum ConverterTextThe sentences about who converts, made once. The help of the tool and the descriptions of the MCP server say them, so no front end words them again (design 13.5). The advice line about a missing converter is made at FolderText.converterAdvice.enum DesqueezeVersionThe version of Desqueeze. The one place that holds the number for the command line tools. project.yml holds the same number for the app, and a test keeps the two equal.Process and toolsprotocol ProcessRunnerStarts a program with arguments and waits for it. No shell is involved, so a path with spaces is one argument.struct SystemProcessRunnerThe real runner. It starts each program with Process.struct LoggingProcessRunnerRuns each program through another runner, and writes what happened to a sink: the command line, the exit code, and the raw output. For --verbose.struct ProcessResultWhat a program that ran and exited gave: its exit code and its output.struct ProcessSignalErrorA program that a signal ended, for example kill or a crash.struct ToolLocatorFinds the three external tools: exiftool, dnglab, and Adobe DNG Converter. Holds no path that is specific to one Mac.