Skip to content

Commit eca78e1

Browse files
committed
#1765 simplify decoder interface
use options typedict for flags and pixel format
1 parent d6d153f commit eca78e1

File tree

5 files changed

+34
-29
lines changed

5 files changed

+34
-29
lines changed

tests/unittests/unit/codecs/color_range_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ def verify_rgb(self, enc_name: str, encoding: str, image: ImageWrapper, enc_opti
175175
# print(f"testing {fmt} rgb decoding using {decompress_to_rgb}")
176176
if not decompress_to_rgb:
177177
continue
178-
rimage = decompress_to_rgb(self.rgb_format, data)
178+
dec_options = typedict({"rgb_format": self.rgb_format})
179+
rimage = decompress_to_rgb(data, dec_options)
179180
tolerance = enc_options["tolerance"]
180181
if dec_name == "dec_jpeg":
181182
tolerance += 1

xpra/client/gui/window_backing_base.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -506,17 +506,10 @@ def nv_decode(self, encoding: str, img_data, width: int, height: int, options: t
506506

507507
def do_paint_jpeg(self, encoding: str, img_data, x: int, y: int, width: int, height: int,
508508
options: typedict, callbacks: PaintCallbacks) -> None:
509-
alpha_offset = options.intget("alpha-offset", 0)
510509
img = self.nv_decode(encoding, img_data, width, height, options)
511510
if img is None:
512-
if encoding == "jpeg":
513-
rgb_format = "BGRX"
514-
elif encoding == "jpega":
515-
rgb_format = "BGRA"
516-
else:
517-
raise ValueError(f"invalid encoding {encoding!r}")
518511
assert self.jpeg_decoder is not None
519-
img = self.jpeg_decoder.decompress_to_rgb(rgb_format, img_data, alpha_offset)
512+
img = self.jpeg_decoder.decompress_to_rgb(img_data, options)
520513
self.paint_image_wrapper(encoding, img, x, y, width, height, options, callbacks)
521514

522515
def paint_avif(self, img_data, x: int, y: int, width: int, height: int,
@@ -549,9 +542,7 @@ def paint_webp(self, img_data, x: int, y: int, width: int, height: int,
549542
img = self.webp_decoder.decompress_to_yuv(img_data, options, has_alpha)
550543
self.paint_image_wrapper("webp", img, x, y, width, height, options, callbacks)
551544
return
552-
rgb_format = options.strget("rgb_format", "BGRX")
553-
has_alpha = options.boolget("has_alpha", False)
554-
img = self.webp_decoder.decompress_to_rgb(rgb_format, img_data, has_alpha)
545+
img = self.webp_decoder.decompress_to_rgb(img_data, options)
555546
self.paint_image_wrapper("webp", img, x, y, width, height, options, callbacks)
556547

557548
def paint_rgb(self, rgb_format: str, raw_data, x: int, y: int, width: int, height: int, rowstride: int,

xpra/codecs/jpeg/decoder.pyx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,11 @@ def decompress_to_yuv(data: bytes, options: typedict, unsigned char nplanes=3) -
228228
return ImageWrapper(0, 0, w, h, pyplanes, pixel_format, 24, pystrides, planes=ImageWrapper.PLANAR_3)
229229

230230

231-
def decompress_to_rgb(rgb_format: str, data: bytes, unsigned long alpha_offset=0) -> ImageWrapper:
231+
def decompress_to_rgb(data: bytes, options: typedict) -> ImageWrapper:
232+
cdef unsigned int alpha_offset = options.intget("alpha-offset", 0)
233+
rgb_format = "BGRA" if alpha_offset else "BGRX"
234+
235+
rgb_format = options.strget("rgb_format", "BGRX")
232236
assert rgb_format in TJPF_VAL
233237
cdef TJPF pixel_format = TJPF_VAL[rgb_format]
234238

@@ -337,7 +341,7 @@ def selftest(full=False) -> None:
337341
log("jpeg selftest")
338342

339343
def test_rgbx(bdata):
340-
return decompress_to_rgb("RGBX", bdata)
344+
return decompress_to_rgb(bdata, typedict())
341345

342346
def test_yuv(bdata):
343347
return decompress_to_yuv(bdata, typedict())

xpra/codecs/webp/decoder.pyx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,11 @@ cdef inline int roundup(int n, int m):
175175
return (n + m - 1) & ~(m - 1)
176176

177177

178-
def decompress_to_rgb(rgb_format: str, data: bytes, has_alpha: bool=True) -> ImageWrapper:
178+
def decompress_to_rgb(data: bytes, options: typedict) -> ImageWrapper:
179+
cdef int has_alpha = options.boolget("has_alpha", False)
180+
rgb_format = options.strget("rgb_format", "BGRA" if has_alpha else "BGRX")
179181
if rgb_format not in ("RGBX", "RGBA", "BGRA", "BGRX", "RGB", "BGR"):
180-
raise ValueError(f"unsupported rgb format {rgb_format}")
182+
raise ValueError(f"unsupported rgb format {rgb_format!r}")
181183
cdef WebPDecoderConfig config
182184
config.options.use_threads = 1
183185
WebPInitDecoderConfig(&config)
@@ -236,7 +238,7 @@ class WebpImageWrapper(ImageWrapper):
236238
free(<void *> buf)
237239

238240

239-
def decompress_to_yuv(data: bytes, options: typedict, has_alpha=False) -> WebpImageWrapper:
241+
def decompress_to_yuv(data: bytes, options: typedict) -> WebpImageWrapper:
240242
"""
241243
This returns a WebpBufferWrapper, you MUST call free() on it
242244
once the pixel buffer can be freed.
@@ -248,6 +250,7 @@ def decompress_to_yuv(data: bytes, options: typedict, has_alpha=False) -> WebpIm
248250
log("webp decompress_to_yuv found features: width=%4i, height=%4i, has_alpha=%-5s", config.input.width, config.input.height, bool(config.input.has_alpha))
249251

250252
config.output.colorspace = MODE_YUV
253+
cdef int has_alpha = options.boolget("has_alpha", False)
251254
cdef int alpha = has_alpha and config.input.has_alpha
252255
if alpha:
253256
log.warn("Warning: webp YUVA colorspace not supported yet")
@@ -325,14 +328,20 @@ def selftest(full=False) -> None:
325328
for size, samples in TEST_PICTURES["webp"].items():
326329
w, h = size
327330
for bdata in samples:
328-
for alpha in (True, False):
329-
rgb_format = "BGRA" if alpha else "BGRX"
330-
img = decompress_to_rgb(rgb_format, bdata, alpha)
331-
assert img.get_width()==w and img.get_height()==h and (img.get_pixel_format().find("A")>=0) == alpha
331+
for alpha in (False, True):
332+
options = typedict({"has_alpha": alpha})
333+
img = decompress_to_rgb(bdata, options)
334+
iw = img.get_width()
335+
ih = img.get_height()
336+
pf = img.get_pixel_format()
337+
got_alpha = pf.find("A") >= 0
338+
assert iw==w and ih==h, f"expected {w}x{h} but got {iw}x{ih}"
339+
if not alpha:
340+
assert not got_alpha, f"expected {alpha=}, got {pf}"
332341
assert len(img.get_pixels())>0
333342
img.free()
334343

335-
img = decompress_to_yuv(bdata, typedict(), False)
344+
img = decompress_to_yuv(bdata, typedict())
336345
assert img.get_width()==w and img.get_height()==h and (img.get_pixel_format() == "YUV420P")
337346
assert len(img.get_pixels())>0
338347
img.free()

xpra/opengl/backing.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@
9393

9494
CURSOR_IDLE_TIMEOUT: int = envint("XPRA_CURSOR_IDLE_TIMEOUT", 6)
9595

96+
PLANAR_FORMATS = (
97+
"YUV420P", "YUV422P", "YUV444P", "NV12", "YUV444P16",
98+
"GBRP", "GBRP16",
99+
)
100+
96101
PIXEL_FORMAT_TO_CONSTANT: dict[str, IntConstant] = {
97102
"r210": GL_BGRA,
98103
"R210": GL_RGBA,
@@ -1137,13 +1142,8 @@ def paint_nvdec(gl_context) -> None:
11371142
return
11381143
if JPEG_YUV and width >= 2 and height >= 2 and encoding == "jpeg":
11391144
img = self.jpeg_decoder.decompress_to_yuv(img_data, options)
1140-
elif encoding == "jpeg":
1141-
img = self.jpeg_decoder.decompress_to_rgb("BGRX", img_data)
1142-
elif encoding == "jpega":
1143-
alpha_offset = options.intget("alpha-offset", 0)
1144-
img = self.jpeg_decoder.decompress_to_rgb("BGRA", img_data, alpha_offset)
11451145
else:
1146-
raise ValueError(f"invalid encoding {encoding}")
1146+
img = self.jpeg_decoder.decompress_to_rgb(img_data, options)
11471147
self.paint_image_wrapper(encoding, img, x, y, width, height, options, callbacks)
11481148

11491149
def cuda_buffer_to_pbo(self, gl_context, cuda_buffer, rowstride: int, src_y: int, height: int, stream):
@@ -1403,7 +1403,7 @@ def paint_planar(self, context, shader: str, encoding: str, img,
14031403
x: int, y: int, enc_width: int, enc_height: int, width: int, height: int,
14041404
options: typedict, callbacks: PaintCallbacks) -> None:
14051405
pixel_format = img.get_pixel_format()
1406-
if pixel_format not in ("YUV420P", "YUV422P", "YUV444P", "GBRP", "NV12", "GBRP16", "YUV444P16"):
1406+
if pixel_format not in PLANAR_FORMATS:
14071407
img.free()
14081408
raise ValueError(f"the GL backing does not handle pixel format {pixel_format!r} yet!")
14091409
if not context:

0 commit comments

Comments
 (0)