# Copyright 2023-2024 Amazon.com, Inc. or its affiliates.
# Copyright 2026-2026 General Atomics Integrated Intelligence, Inc.
import logging
from math import floor
from typing import List, Optional, Tuple
from aws.osml.formats.model_utils import sicd_parser, sicd_serializer
logger = logging.getLogger(__name__)
[docs]
class SICDUpdater:
"""
This class provides a means to perform common updates to a SICD XML metadata document.
"""
def __init__(self, xml_str: str):
"""
Construct a new instance of this class to manage a given set of SICD metadata.
:param xml_str: the SICD XML metadata to update
"""
self.xml_str = xml_str
if self.xml_str is not None and len(self.xml_str) > 0:
self.sicd = sicd_parser.from_string(self.xml_str)
# Here we're storing off the original first row/col to support the case where multiple chips are
# created from a SICD image that has already been chipped.
self.original_first_row = self.sicd.image_data.first_row
self.original_first_col = self.sicd.image_data.first_col
[docs]
def update_image_data_for_chip(self, chip_bounds: List[int], output_size: Optional[Tuple[int, int]]) -> None:
"""
This updates the SICD ImageData structure so that the FirstRow, FirstCol and NumRows, NumCols
elements match the new chip boundary.A sample of this XML structure is shown below::
<ImageData>
<NumRows>3859</NumRows>
<NumCols>6679</NumCols>
<FirstRow>0</FirstRow>
<FirstCol>0</FirstCol>
<FullImage>
<NumRows>3859</NumRows>
<NumCols>6679</NumCols>
</FullImage>
</ImageData>
:param chip_bounds: the [col, row, width, height] of the chip boundary
:param output_size: the [width, height] of the output chip
"""
if output_size is not None and (output_size[0] != chip_bounds[2] or output_size[1] != chip_bounds[3]):
raise ValueError("SICD chipping does not support scaling operations.")
self.sicd.image_data.first_row = floor(float(self.original_first_row)) + int(chip_bounds[1])
self.sicd.image_data.first_col = floor(float(self.original_first_col)) + int(chip_bounds[0])
self.sicd.image_data.num_rows = int(chip_bounds[3])
self.sicd.image_data.num_cols = int(chip_bounds[2])
[docs]
def encode_current_xml(self) -> str:
"""
Returns a copy of the current SICD metadata encoded in XML.
:return: xml encoded SICD metadata
"""
updated_xml = sicd_serializer.render(self.sicd)
return updated_xml