40struct instance_record;
48struct rest_server_context;
56 static constexpr std::string_view
dicom =
"application/dicom";
57 static constexpr std::string_view
dicom_json =
"application/dicom+json";
58 static constexpr std::string_view
dicom_xml =
"application/dicom+xml";
59 static constexpr std::string_view
octet_stream =
"application/octet-stream";
60 static constexpr std::string_view
jpeg =
"image/jpeg";
61 static constexpr std::string_view
png =
"image/png";
62 static constexpr std::string_view
jphc =
"image/jphc";
81 -> std::vector<accept_info>;
89[[nodiscard]]
auto is_acceptable(
const std::vector<accept_info>& accept_infos,
112 void add_part(std::vector<uint8_t> data,
113 std::optional<std::string_view> content_type = std::nullopt);
122 std::vector<uint8_t> data,
123 std::string_view location,
124 std::optional<std::string_view> content_type = std::nullopt);
130 [[nodiscard]]
auto build()
const -> std::string;
142 [[nodiscard]]
auto boundary()
const -> std::string_view;
148 [[nodiscard]]
auto empty()
const noexcept -> bool;
154 [[nodiscard]]
auto size()
const noexcept -> size_t;
183 bool include_bulk_data =
false,
184 std::string_view bulk_data_uri_prefix =
"") -> std::string;
191[[nodiscard]]
auto vr_to_string(uint16_t vr_code) -> std::string;
249 [[nodiscard]]
bool success() const noexcept {
return !
error.has_value(); }
250 [[nodiscard]]
explicit operator bool() const noexcept {
return success(); }
259 [[nodiscard]]
static auto parse(std::string_view content_type,
260 std::string_view body) -> parse_result;
268 -> std::optional<std::string>;
275 [[nodiscard]]
static auto extract_type(std::string_view content_type)
276 -> std::optional<std::string>;
285 -> std::vector<std::pair<std::string, std::string>>;
328 [[nodiscard]]
explicit operator bool() const noexcept {
return valid; }
332 return {
false, std::move(
code), std::move(message)};
344 std::optional<std::string_view> target_study_uid = std::nullopt)
345 -> validation_result;
354 const store_response& response,
355 std::string_view base_url) -> std::string;
370 std::string_view patient_id,
371 std::string_view patient_name) -> std::string;
381 std::string_view study_uid) -> std::string;
392 std::string_view series_uid,
393 std::string_view study_uid) -> std::string;
435 -> std::vector<uint32_t>;
445 std::span<const uint8_t> pixel_data,
446 uint32_t frame_number,
447 size_t frame_size) -> std::vector<uint8_t>;
501 std::string_view query_string,
502 std::string_view accept_header) -> rendered_params;
514 std::vector<uint8_t> d, std::string_view mime_type) {
515 return {std::move(d), std::string(mime_type),
true,
""};
519 return {{},
"",
false, std::move(msg)};
537 std::span<const uint8_t> pixel_data,
540 uint16_t bits_stored,
542 double window_center,
544 double rescale_slope = 1.0,
545 double rescale_intercept = 0.0) -> std::vector<uint8_t>;
554 std::string_view file_path,
555 const rendered_params& params) -> rendered_result;
Builder for multipart MIME responses.
auto build() const -> std::string
Build the complete multipart response body.
auto boundary() const -> std::string_view
Get the boundary string.
std::vector< part > parts_
auto content_type_header() const -> std::string
Get the Content-Type header value for this multipart response.
void add_part(std::vector< uint8_t > data, std::optional< std::string_view > content_type=std::nullopt)
Add a part to the multipart response.
static auto generate_boundary() -> std::string
Generate a unique boundary string.
auto empty() const noexcept -> bool
Check if any parts have been added.
void add_part_with_location(std::vector< uint8_t > data, std::string_view location, std::optional< std::string_view > content_type=std::nullopt)
Add a part with location header.
multipart_builder(std::string_view content_type=media_type::dicom)
Construct a multipart builder.
auto size() const noexcept -> size_t
Get the number of parts.
std::string default_content_type_
Parser for multipart/related request bodies.
static auto extract_type(std::string_view content_type) -> std::optional< std::string >
Extract type parameter from Content-Type header.
static auto extract_boundary(std::string_view content_type) -> std::optional< std::string >
Extract boundary from Content-Type header.
static auto parse_part_headers(std::string_view header_section) -> std::vector< std::pair< std::string, std::string > >
Parse headers from a part's header section.
static auto parse(std::string_view content_type, std::string_view body) -> parse_result
Parse a multipart/related request body.
auto study_record_to_dicom_json(const storage::study_record &record, std::string_view patient_id, std::string_view patient_name) -> std::string
Convert a study record to DicomJSON format for QIDO-RS response.
auto extract_frame(std::span< const uint8_t > pixel_data, uint32_t frame_number, size_t frame_size) -> std::vector< uint8_t >
Extract a single frame from pixel data.
auto parse_accept_header(std::string_view accept_header) -> std::vector< accept_info >
Parse Accept header into structured format.
auto series_record_to_dicom_json(const storage::series_record &record, std::string_view study_uid) -> std::string
Convert a series record to DicomJSON format for QIDO-RS response.
auto is_acceptable(const std::vector< accept_info > &accept_infos, std::string_view media_type) -> bool
Check if a media type is acceptable based on Accept header.
auto parse_rendered_params(std::string_view query_string, std::string_view accept_header) -> rendered_params
Parse rendered image parameters from HTTP request.
rendered_format
Rendered image output format.
@ jpeg
JPEG format (default)
@ jphc
HTJ2K format (image/jphc)
auto build_store_response_json(const store_response &response, std::string_view base_url) -> std::string
Build STOW-RS response in DicomJSON format.
auto dataset_to_dicom_json(const core::dicom_dataset &dataset, bool include_bulk_data=false, std::string_view bulk_data_uri_prefix="") -> std::string
Convert a DICOM dataset to DicomJSON format.
auto validate_instance(const core::dicom_dataset &dataset, std::optional< std::string_view > target_study_uid=std::nullopt) -> validation_result
Validate a DICOM instance for STOW-RS storage.
auto is_bulk_data_tag(uint32_t tag) -> bool
Check if a DICOM tag contains bulk data.
auto parse_frame_numbers(std::string_view frame_list) -> std::vector< uint32_t >
Parse frame numbers from URL path.
auto parse_instance_query_params(const std::string &url_params) -> storage::instance_query
Parse QIDO-RS instance query parameters from HTTP request.
auto instance_record_to_dicom_json(const storage::instance_record &record, std::string_view series_uid, std::string_view study_uid) -> std::string
Convert an instance record to DicomJSON format for QIDO-RS response.
auto apply_window_level(std::span< const uint8_t > pixel_data, uint16_t width, uint16_t height, uint16_t bits_stored, bool is_signed, double window_center, double window_width, double rescale_slope=1.0, double rescale_intercept=0.0) -> std::vector< uint8_t >
Apply window/level transformation to pixel data.
auto vr_to_string(uint16_t vr_code) -> std::string
Convert a VR type code to DicomJSON VR string.
auto parse_series_query_params(const std::string &url_params) -> storage::series_query
Parse QIDO-RS series query parameters from HTTP request.
auto render_dicom_image(std::string_view file_path, const rendered_params ¶ms) -> rendered_result
Render a DICOM image to JPEG or PNG.
auto parse_study_query_params(const std::string &url_params) -> storage::study_query
Parse QIDO-RS query parameters from HTTP request.
Instance record from the database.
Series record from the database.
Study record from the database.
Parsed Accept header information.
std::string transfer_syntax
std::vector< uint8_t > data
std::string message
Human-readable error message.
std::string code
Error code (e.g., "INVALID_BOUNDARY")
Parse result - either parts or error.
std::optional< parse_error > error
Error if parsing failed.
bool success() const noexcept
std::vector< multipart_part > parts
Parsed parts (empty on error)
Parsed part from multipart request.
std::string content_id
Content-ID header (optional)
std::string content_type
Content-Type of this part.
std::vector< uint8_t > data
Binary data of this part.
std::string content_location
Content-Location header (optional)
Parameters for rendered image requests.
uint16_t viewport_width
Output viewport width (0 = original size)
std::optional< double > window_center
Window center (default: auto from DICOM or calculated)
std::optional< double > window_width
Window width (default: auto from DICOM or calculated)
uint32_t frame
Frame number for multi-frame images (1-based, default 1)
int quality
JPEG quality (1-100, default 75)
bool burn_annotations
Annotation (burned-in or removed)
std::optional< std::string > presentation_state_uid
Presentation state SOP Instance UID (optional)
uint16_t viewport_height
Output viewport height (0 = original size)
Result of rendered image operation.
bool success
Operation succeeded.
std::string error_message
Error message if failed.
std::vector< uint8_t > data
Encoded image data.
std::string content_type
MIME type (image/jpeg or image/png)
static rendered_result ok(std::vector< uint8_t > d, std::string_view mime_type)
static rendered_result error(std::string msg)
STOW-RS store result for a single instance.
bool success
Whether storage succeeded.
std::optional< std::string > error_code
Error code if failed.
std::string sop_class_uid
SOP Class UID of the instance.
std::optional< std::string > error_message
Error message if failed.
std::string retrieve_url
URL to retrieve the stored instance.
std::string sop_instance_uid
SOP Instance UID of the instance.
STOW-RS overall store response.
std::vector< store_instance_result > referenced_instances
Successfully stored.
bool all_success() const noexcept
std::vector< store_instance_result > failed_instances
Failed to store.
bool partial_success() const noexcept
bool all_failed() const noexcept
Validation result for DICOM instance.
static validation_result ok()
std::string error_code
Error code if invalid.
static validation_result error(std::string code, std::string message)
bool valid
Whether validation passed.
std::string error_message
Error message if invalid.