Skip to content

Commit

Permalink
#1765 enable YUVA rendering
Browse files Browse the repository at this point in the history
also ensure the codec self-tests have the metadata needed for decoding 'jpega'
  • Loading branch information
totaam committed Nov 28, 2024
1 parent 8ff7082 commit bf65d16
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 150 deletions.
5 changes: 2 additions & 3 deletions xpra/client/gui/window_backing_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ def paint_pillow(self, coding: str, img_data, x: int, y: int, width: int, height

def paint_spng(self, img_data, x: int, y: int, width: int, height: int,
options: typedict, callbacks: PaintCallbacks) -> None:
rgba, rgb_format, iwidth, iheight = self.spng_decoder.decompress(img_data)
rgba, rgb_format, iwidth, iheight = self.spng_decoder.decompress(img_data, options)
rowstride = iwidth * len(rgb_format)
self.ui_paint_rgb("png", rgb_format, rgba,
x, y, iwidth, iheight, width, height, rowstride, options, callbacks)
Expand All @@ -538,8 +538,7 @@ def paint_webp(self, img_data, x: int, y: int, width: int, height: int,
self.paint_pillow("webp", img_data, x, y, width, height, options, callbacks)
return
if WEBP_YUV:
has_alpha = options.boolget("has_alpha")
img = self.webp_decoder.decompress_to_yuv(img_data, options, has_alpha)
img = self.webp_decoder.decompress_to_yuv(img_data, options)
self.paint_image_wrapper("webp", img, x, y, width, height, options, callbacks)
return
img = self.webp_decoder.decompress_to_rgb(img_data, options)
Expand Down
6 changes: 2 additions & 4 deletions xpra/codecs/avif/decoder.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,11 @@ def decompress(data: bytes, options: typedict, yuv=False) -> ImageWrapper:


def selftest(full=False) -> None:
w, h = (24, 16) #hard coded size of test data
from xpra.codecs.checks import TEST_PICTURES
for size, samples in TEST_PICTURES["avif"].items():
w, h = size
for bdata in samples:
options = typedict()
img = decompress(bdata, options)
for bdata, options in samples:
img = decompress(bdata, typedict(options))
assert img.get_width()==w and img.get_height()==h
assert len(img.get_pixels())>0
#print("compressed data(%s)=%s" % (has_alpha, binascii.hexlify(r)))
35 changes: 27 additions & 8 deletions xpra/codecs/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import struct
import binascii
from typing import Any, TypeAlias
from collections.abc import Callable, Sequence, Iterable

from xpra.common import roundup
Expand All @@ -21,8 +22,12 @@
TEST_LIMIT_W, TEST_LIMIT_H = 8192, 8192


def unhex(s: str) -> bytes:
return binascii.unhexlify(s.replace(" ", "").replace("\n", "").replace("\r", ""))
def unhexlify(s: str) -> bytes:
return binascii.unhexlify(s.replace(" ", "").replace("\n", ""))


def unhex(s: str) -> tuple[bytes, dict[str, Any]]:
return unhexlify(s), {}


DEFAULT_TEST_SIZE = 128, 128
Expand All @@ -39,8 +44,10 @@ def unhex(s: str) -> bytes:
}


TEST_DATA: TypeAlias = Sequence[tuple[bytes, dict[str, Any]]]

# this test data was generated using a 24x16 blank image as input
TEST_COMPRESSED_DATA: dict[str, dict[str, dict[tuple[int, int], Sequence[bytes]]]] = {
TEST_COMPRESSED_DATA: dict[str, dict[str, dict[tuple[int, int], TEST_DATA]]] = {
"h264": {
"YUV420P": {
(24, 16): (
Expand Down Expand Up @@ -203,7 +210,7 @@ def unhex(s: str) -> bytes:
},
}

TEST_PICTURES: dict[str, dict[tuple[int, int], Sequence[bytes]]] = {
TEST_PICTURES: dict[str, dict[tuple[int, int], TEST_DATA]] = {
"png": {
(32, 32): (
unhex("89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af40000002849444154785eedd08100000000c3a0f9531fe4855061c0800103060c183060c0800103060cbc0f0c102000013337932a0000000049454e44ae426082"),
Expand Down Expand Up @@ -231,6 +238,18 @@ def unhex(s: str) -> bytes:
unhex("ffd8ffe000104a46494600010100000100010000ffdb004300100b0c0e0c0a100e0d0e1211101318281a181616183123251d283a333d3c3933383740485c4e404457453738506d51575f626768673e4d71797064785c656763ffdb0043011112121815182f1a1a2f634238426363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363ffc00011080080008003012200021101031101ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00f40a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2800a28a2803fffd9"),
)
},
"jpega": {
(32, 32): (
(
unhexlify("ffd8ffe000104a46494600010100000100010000ffdb004300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb004301ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00011080020002003012200021101031101ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00651451400514514005145140051451401fffd9ffd8ffe000104a46494600010100000100010000ffdb004300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0000b080020002001011100ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffda0008010100003f006514514514514514514514515fffd9"),
{"quality": 0, "alpha-offset": 642},
),
(
unhexlify("ffd8ffe000104a46494600010100000100010000ffdb00430001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101ffdb00430101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101ffc00011080020002003011100021101031101ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00fe3fe800a002800a002800a002800a002800a002800a002800a002800a00ffd9ffd8ffe000104a46494600010100000100010000ffdb00430001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101ffc0000b080020002001011100ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffda0008010100003f00fe3fe8a28a28a28a28a28a28a28affd9"),
{"quality": 100, "alpha-offset": 655},
),
)
},
"webp": {
(32, 32): (
unhex("524946465c00000057454250565038580a000000100000001f00001f0000414c50480f00000001071011110012c2ffef7a44ff530f005650382026000000d002009d012a200020003ed162aa4fa825a3a2280801001a096900003da3a000fef39d800000"),
Expand Down Expand Up @@ -336,10 +355,10 @@ def testdecoder(decoder_module, full: bool) -> Sequence[str]:


def testdecoding(decoder_module, encoding: str, full: bool) -> None:
test_data_set: dict[str, dict[tuple[int, int], Sequence[bytes]]] | None = TEST_COMPRESSED_DATA.get(encoding)
test_data_set: dict[str, dict[tuple[int, int], TEST_DATA]] | None = TEST_COMPRESSED_DATA.get(encoding)
for cs in decoder_module.get_input_colorspaces(encoding):
min_w, min_h = decoder_module.get_min_size(encoding)
test_data: dict[tuple[int, int], Sequence[bytes]] = {}
test_data: dict[tuple[int, int], TEST_DATA] = {}
if test_data_set:
test_data = test_data_set.get(cs, {})
elif encoding in TEST_PICTURES:
Expand All @@ -361,10 +380,10 @@ def testdecoding(decoder_module, encoding: str, full: bool) -> None:
try:
if frames:
log(f"{decoder_module.get_type()}: testing {encoding} / {cs} with {len(frames)} frames of size {w}x{h}")
for i, data in enumerate(frames):
for i, (data, options) in enumerate(frames):
try:
log(f"frame {i+1} is {len(data or ()):5} bytes")
image = decoder.decompress_image(data, typedict())
image = decoder.decompress_image(data, typedict(options))
if image is None:
raise RuntimeError(f"failed to decode test data for encoding {encoding!r} with colorspace {cs!r}")
if image.get_width()!=w:
Expand Down
Loading

0 comments on commit bf65d16

Please sign in to comment.