Files
pqAutomationApp/UniTAP/libs/lib_dscl/dscl.py

195 lines
7.4 KiB
Python
Raw Normal View History

2026-04-16 16:51:05 +08:00
import os
from typing import Optional
from .dscl_types import *
from UniTAP.libs.lib_uicl.uicl_types import UICL_Image, UICL_ImageParameters
from UniTAP.libs.lib_helper import OS_Requirements, lib_method_wrapper
DSCL_CURRENT_VERSION = 1
DSCL = OS_Requirements("DSCL").get_lib()
DSCL_PATH = OS_Requirements("DSCL").get_path_to_lib()
DSC_TOOLS_FOLDER = os.path.dirname(DSCL_PATH)
def from_cstr(src_str):
try:
return src_str.value.decode('cp1252')
except BaseException:
return src_str.value.decode('utf-8')
class DSCLError(Exception):
def __init__(self, message, errors=None):
super().__init__(message)
self.errors = errors
def DSCL_GetRequiredBufferSize(image_to_encode: DSCL_Image):
_DSCL_GetRequiredBufferSize = lib_method_wrapper(DSCL.DSCL_GetRequiredBufferSize,
[POINTER(DSCL_Image)],
c_uint64)
return _DSCL_GetRequiredBufferSize(byref(image_to_encode))
def DSCL_GetRequiredBufferSizeFromPPS(pps: DSCL_PPS):
_DSCL_GetRequiredBufferSizeFromPPS = lib_method_wrapper(DSCL.DSCL_GetRequiredBufferSizeFromPPS,
[POINTER(DSCL_PPS)],
c_uint64)
return _DSCL_GetRequiredBufferSizeFromPPS(byref(pps))
def DSCL_Encode(image: UICL_Image, pps: DSCL_PPS) -> DSCL_Image:
_DSCL_Encode = lib_method_wrapper(DSCL.DSCL_Encode,
[POINTER(UICL_Image), POINTER(DSCL_PPS), POINTER(DSCL_Image),
POINTER(DSCL_EncoderConfig), c_char_p, c_int],
DSCL_RESULT)
max_enc_image_size = DSCL_GetRequiredBufferSizeFromPPS(pps)
if max_enc_image_size <= 132:
raise DSCLError("Failed to calculate buffer size for DSC encoding!")
encoded_image = DSCL_Image()
encoded_image.DataPtr = (c_uint8 * max_enc_image_size)()
encoded_image.DataSize = max_enc_image_size
_log_struct = DSCL_EncoderConfig()
_log_string_size = 65536
_log_string = create_string_buffer(_log_string_size)
result = _DSCL_Encode(byref(image), byref(pps), byref(encoded_image), byref(_log_struct),
_log_string, _log_string_size)
log = str(from_cstr(_log_string))
if result < DSCL_SUCCESS:
raise DSCLError(f"Encoding finished with error: {result}. Error log: {log}", result)
return encoded_image
def DSCL_Decode(encoded_image: DSCL_Image, decode_simple422_to_444: Optional[bool] = False) -> UICL_Image:
_DSCL_Decode = lib_method_wrapper(DSCL.DSCL_Decode,
[POINTER(DSCL_Image), POINTER(UICL_Image),
POINTER(DSCL_DecoderConfig)],
DSCL_RESULT)
decoded_image = UICL_Image()
decoded_image.Parameters = UICL_ImageParameters()
decoded_image.DataPtr = POINTER(c_uint8)()
decoded_image.DataSize = 0
decoder_config = DSCL_DecoderConfig()
decoder_config.decodeSimple422to444 = False if decode_simple422_to_444 is None else decode_simple422_to_444
result = _DSCL_Decode(byref(encoded_image), byref(decoded_image), byref(decoder_config))
if result < DSCL_SUCCESS:
raise DSCLError(f"Decoding failed with error code: {result}", result)
return decoded_image
def DSCL_ResultToString(result):
_DSCL_ResultToString = lib_method_wrapper(DSCL.DSCL_ResultToString,
[DSCL_RESULT, c_char_p, c_uint64],
c_uint64)
_error_string = create_string_buffer(1024)
_DSCL_ResultToString(result, _error_string, 1024)
return from_cstr(_error_string)
def DSCL_CalculateDSCCRC(image: DSCL_Image):
_DSCL_CalculateDSCCRC = lib_method_wrapper(DSCL.DSCL_CalculateDSCCRC,
[POINTER(DSCL_Image), POINTER(DSCL_CRC16)],
c_uint64)
crc_value = DSCL_CRC16()
result = _DSCL_CalculateDSCCRC(byref(image), byref(crc_value))
if result < DSCL_SUCCESS:
raise DSCLError(f"Calculate DSC CRC: Failed to calculate CRC", result)
return crc_value
def DSCL_ExtractPPSFromData(data):
_DSCL_ExtractPPSFromData = lib_method_wrapper(DSCL.DSCL_ExtractPPSFromData,
[POINTER(c_uint8), c_uint64, POINTER(DSCL_PPS)],
c_uint64)
_pps = DSCL_PPS()
_size = len(data)
_data = (c_uint8 * _size)(*data)
result = _DSCL_ExtractPPSFromData(_data, _size, byref(_pps))
if result < DSCL_SUCCESS:
raise DSCLError(f"Cannot extract PPS from data. Code: {result}")
return _pps
def DSCL_ExtractPPS(image: DSCL_Image):
_DSCL_ExtractPPS = lib_method_wrapper(DSCL.DSCL_ExtractPPS,
[POINTER(DSCL_Image), POINTER(DSCL_PPS)],
c_uint64)
_pps = DSCL_PPS()
result = _DSCL_ExtractPPS(byref(image), byref(_pps))
if result < DSCL_SUCCESS:
raise DSCLError(f"Cannot extract PPS from DSCL Image. Code: {result}")
return _pps
def DSCL_VerifyPPS(image: DSCL_Image):
_DSCL_VerifyPPS = lib_method_wrapper(DSCL.DSCL_VerifyPPS,
[POINTER(DSCL_Image), c_char_p, c_uint64],
c_bool)
_error_string = create_string_buffer(1024)
return _DSCL_VerifyPPS(byref(image), _error_string, 1024)
def DSCL_GeneratePPS(decoded_image_parameters: UICL_ImageParameters,
is_simple_422: bool, is_block_prediction_enabled: bool, bits_per_pixel: int,
horizontal_slice_count: int, vertical_slice_count: int, buffer_bit_depth: int,
dsc_version: DSCL_DscVersion) -> DSCL_PPS:
_DSCL_GeneratePPS = lib_method_wrapper(DSCL.DSCL_GeneratePPS,
[POINTER(DSCL_PPS), POINTER(UICL_ImageParameters), c_bool, c_bool,
c_uint16, c_uint16, c_uint16, c_uint8, DSCL_DscVersion],
c_bool)
_pps = DSCL_PPS()
result = _DSCL_GeneratePPS(byref(_pps), byref(decoded_image_parameters), is_simple_422,
is_block_prediction_enabled, bits_per_pixel, horizontal_slice_count,
vertical_slice_count, buffer_bit_depth, dsc_version)
if result < DSCL_SUCCESS:
raise DSCLError(f"Cannot generate PPS. Error code {result}")
return _pps
def DSCL_LoadFromFile(file_name: str) -> DSCL_RESULT:
_DSCL_LoadFromFile = lib_method_wrapper(DSCL.DSCL_LoadFromFile,
[c_char_p, POINTER(DSCL_Image)],
DSCL_Image)
image = DSCL_Image()
image.DataPtr = POINTER(c_uint8)()
image.DataSize = 0
result = _DSCL_LoadFromFile(c_char_p(file_name.encode('utf-8')), byref(image))
if result < DSCL_SUCCESS:
raise DSCLError(f"Cannot load image from file. Error code {result}.")
return result
def DSCL_FreeImage(image: DSCL_Image) -> DSCL_RESULT:
_DSCL_FreeImage = lib_method_wrapper(DSCL.DSCL_FreeImage,
[POINTER(POINTER(DSCL_Image))],
c_uint64)
result = _DSCL_FreeImage(byref(byref(image)))
return result