处理来自 python 的 C 断言

Handle C assertions from python

我使用以下 python 代码使用 GDCM 压缩 dicom 文件:

    import gdcm

    reader = gdcm.PixmapReader()
    reader.SetFileName(str(source))
    if not reader.Read():
        raise BaseException("Could not read (pixmap) %s" % source)
    image = reader.GetPixmap()
    change = gdcm.ImageChangeTransferSyntax()
    change.SetForce(False)
    change.SetCompressIconImage(False)
    transfer_syntax = gdcm.TransferSyntax(gdcm.TransferSyntax.JPEG2000Lossless)
    change.SetTransferSyntax(transfer_syntax)
    change.SetInput(image)
    if not change.Change():
        raise BaseException("Could not change the Transfer Syntax: ")
    ....

在行 change.Change() 中,GDCM 源代码中有一个断言可能会失败:

Assertion `((fragment_size + 1)/2 ) * 2 == ((image_height * image_width * numcomps * (bitsallocated/8) + 1)/ 2 )* 2' failed.

不幸的是,如果 GDCM 断言失败,python 进程将被终止。有没有办法处理这样的断言(在调用 change.Change() 之前没有检查 python 的条件)?

处理这个问题的一种方法是启动一个子进程来调用 C 库,然后如果子进程因为 C assert 语句而终止则引发异常。

在压缩 Dicom 之前,我不情愿地使用 pydicom 检查了 Dicom 的完整性:

def check_dicom(dicom_file):
    p = dicom.read_file(dicom_file)
    assert p.SamplesPerPixel in (1, 3)
    if p.BitsAllocated % 8 != 0:
        return False

    # assert( ((fragment_size + 1)/2 ) * 2 == ((image_height * image_width * numcomps * (bitsallocated/8) + 1)/ 2 )* 2 );
    left = ((len(p.PixelData) + 1)/2 ) * 2
    right = ((p.Rows * p.Columns * p.SamplesPerPixel * (p.BitsAllocated/8) + 1)/ 2 )* 2
    if left != right:
        raise BaseException("DICOM attributes are in conflict with pixel data size")
    return True