/frames/{frame} now validates the frame as a positive 1-based integer and
returns 400 for invalid values. The frame number is threaded through
doWadoRs into addFileToBuffer, where it is sliced out of uncompressed Pixel
Data using NumberOfFrames, Rows, Columns, SamplesPerPixel and BitsAllocated.
- add src/dimse/frameExtractor.ts (native frame slicing)
- add src/dimse/errors.ts (status-bearing HttpError types)
- reject compressed/encapsulated frames with 415 instead of full pixel data
- keep JPEG conversion on /rendered and /thumbnail only
- log frame requests with jpegRendererUsed=false
- add frame extraction and validation tests
Replace the hand-built metadata subset in parseMeta with a VR-aware
DICOM-to-DICOM-JSON converter. Window Center/Width, Rescale Intercept/Slope
are only emitted when the source element exists; multi-values are preserved
in source order. VOI/LUT, Presentation LUT and Pixel Padding tags are
preserved and Pixel Data is excluded.
- add src/dimse/dicomJson.ts (dictionary-aware converter)
- rewrite src/dimse/parseMeta.ts to use the converter
- add synthetic non-PHI DICOM writer and metadata tests
- add npm test script (node:test + ts-node) and skipLibCheck