def test_minixml_4(): xml = """<?xml encoding="utf-8"?>\n<foo />\n""" got_xml = gdal.SerializeXMLTree(gdal.ParseXMLString(xml)) assert xml == got_xml, 'serialize xml tree failed.'
def parse_jp2_box(xml_tree, out_f, src_jp2file): if not (xml_tree[XML_TYPE_IDX] == gdal.CXT_Element and xml_tree[XML_VALUE_IDX] == 'JP2Box'): print('Not a JP2Box element') return False jp2box_name = get_attribute_val(xml_tree, 'name') if jp2box_name is None: print('Cannot find JP2Box.name attribute') return False if len(jp2box_name) != 4: print('Invalid JP2Box.name : %s' % jp2box_name) return False hex_binary_content = get_node_content( find_xml_node(xml_tree, 'BinaryContent', immediate_child=True)) decoded_content = find_xml_node(xml_tree, 'DecodedContent', immediate_child=True) decoded_geotiff = find_xml_node(xml_tree, 'DecodedGeoTIFF', immediate_child=True) text_content = get_node_content( find_xml_node(xml_tree, 'TextContent', immediate_child=True)) xml_content = find_xml_node(xml_tree, 'XMLContent', immediate_child=True) jp2box = find_xml_node(xml_tree, 'JP2Box', immediate_child=True) jp2codestream = find_xml_node(xml_tree, 'JP2KCodeStream', immediate_child=True) if hex_binary_content: if decoded_content or decoded_geotiff or text_content or xml_content or jp2box: print( 'BinaryContent found, and one of DecodedContent/DecodedGeoTIFF/TextContent/XMLContent/JP2Box. The latter will be ignored' ) if jp2box_name == 'uuid': uuid = get_node_content( find_xml_node(xml_tree, 'UUID', immediate_child=True)) if uuid is None: print('Cannot find JP2Box.UUID element') return False else: uuid = '' out_f.write( struct.pack( '>I' * 1, 8 + int(len(hex_binary_content) / 2) + int(len(uuid) / 2))) out_f.write(jp2box_name.encode('ascii')) write_hexstring_as_binary(uuid, out_f) write_hexstring_as_binary(hex_binary_content, out_f) elif decoded_content: if decoded_geotiff or text_content or xml_content or jp2box: print( 'DecodedContent found, and one of DecodedGeoTIFF/TextContent/XMLContent/JP2Box. The latter will be ignored' ) pos = out_f.tell() out_f.write(struct.pack('>I' * 1, 0)) out_f.write(jp2box_name.encode('ascii')) for child_idx in range(XML_FIRST_CHILD_IDX, len(decoded_content)): child = decoded_content[child_idx] if child[XML_TYPE_IDX] == gdal.CXT_Element and child[ XML_VALUE_IDX] == 'Field': if not parse_field(child, out_f, src_jp2file): return False new_pos = out_f.tell() out_f.seek(pos, 0) out_f.write(struct.pack('>I' * 1, new_pos - pos)) out_f.seek(new_pos, 0) elif text_content: if decoded_geotiff or xml_content or jp2box: print( 'TextContent found, and one of DecodedGeoTIFF/XMLContent/JP2Box. The latter will be ignored' ) out_f.write(struct.pack('>I' * 1, 8 + len(text_content))) out_f.write(jp2box_name.encode('ascii')) out_f.write(text_content.encode('latin1')) elif xml_content: if decoded_geotiff or jp2box: print( 'XMLContent found, and one of DecodedGeoTIFF/JP2Box. The latter will be ignored' ) serialized_xml_content = gdal.SerializeXMLTree( xml_content[XML_FIRST_CHILD_IDX]) out_f.write(struct.pack('>I' * 1, 8 + len(serialized_xml_content))) out_f.write(jp2box_name.encode('ascii')) out_f.write(serialized_xml_content.encode('latin1')) elif jp2box: if decoded_geotiff: print( 'JP2Box found, and one of DecodedGeoTIFF. The latter will be ignored' ) pos = out_f.tell() out_f.write(struct.pack('>I' * 1, 0)) out_f.write(jp2box_name.encode('ascii')) for child_idx in range(XML_FIRST_CHILD_IDX, len(xml_tree)): child = xml_tree[child_idx] if child[XML_TYPE_IDX] == gdal.CXT_Element and child[ XML_VALUE_IDX] == 'JP2Box': if not parse_jp2_box(child, out_f, src_jp2file): return False new_pos = out_f.tell() out_f.seek(pos, 0) out_f.write(struct.pack('>I' * 1, new_pos - pos)) out_f.seek(new_pos, 0) elif decoded_geotiff: serialized_xml_content = gdal.SerializeXMLTree( decoded_geotiff[XML_FIRST_CHILD_IDX]) vrt_ds = gdal.Open(serialized_xml_content) if vrt_ds is None: print('Cannot decode VRTDataset. Outputting empty content') binary_content = '' else: tmpfilename = '/vsimem/build_jp2_from_xml_tmp.tif' gdal.GetDriverByName('GTiff').CreateCopy(tmpfilename, vrt_ds) tif_f = gdal.VSIFOpenL(tmpfilename, 'rb') binary_content = gdal.VSIFReadL(1, 10000, tif_f) gdal.VSIFCloseL(tif_f) gdal.Unlink(tmpfilename) uuid = get_node_content( find_xml_node(xml_tree, 'UUID', immediate_child=True)) if uuid is None: uuid = 'B14BF8BD083D4B43A5AE8CD7D5A6CE03' out_f.write( struct.pack('>I' * 1, 8 + len(binary_content) + int(len(uuid) / 2))) out_f.write(jp2box_name.encode('ascii')) write_hexstring_as_binary(uuid, out_f) out_f.write(binary_content) elif jp2codestream: pos = out_f.tell() out_f.write(struct.pack('>I' * 1, 0)) out_f.write(jp2box_name.encode('ascii')) if not parse_jp2codestream(None, jp2codestream, out_f, src_jp2file): return False new_pos = out_f.tell() out_f.seek(pos, 0) out_f.write(struct.pack('>I' * 1, new_pos - pos)) out_f.seek(new_pos, 0) else: data_offset = get_attribute_val(xml_tree, 'data_offset') if data_offset is None: print('Cannot find JP2Box.data_offset attribute') return False data_offset = int(data_offset) data_length = get_attribute_val(xml_tree, 'data_length') if data_length is None: print('Cannot find JP2Box.data_length attribute') return False data_length = int(data_length) src_jp2file.seek(data_offset, 0) data = src_jp2file.read(data_length) out_f.write(struct.pack('>I' * 1, 8 + data_length)) out_f.write(jp2box_name.encode('ascii')) out_f.write(data) return True
def test_minixml_processing_instruction(): xml = """<?a b c d?>\n<foo />\n""" got_xml = gdal.SerializeXMLTree(gdal.ParseXMLString(xml)) assert xml == got_xml, 'serialize xml tree failed.'