Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* always close the (de)compressor after we have finished using it!
* decompress without holding the gil

git-svn-id: https://xpra.org/svn/Xpra/trunk@14989 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Feb 6, 2017
1 parent a0506a8 commit 7970c2a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 32 deletions.
53 changes: 32 additions & 21 deletions src/xpra/codecs/jpeg/decoder.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,20 @@ def decompress(data, int width, int height, options={}):
log.error("Error: failed to instantiate a JPEG decompressor")
return None

def close():
r = tjDestroy(decompressor)
if r:
log.error("Error: failed to destroy the JPEG decompressor, code %i:", r)
log.error(" %s", get_error_str())

cdef int r, w, h, subsamp, cs
r = tjDecompressHeader3(decompressor,
<const unsigned char *> buf, buf_len,
&w, &h, &subsamp, &cs)
if r:
log.error("Error: failed to decompress JPEG header")
log.error(" %s", get_error_str())
close()
return None
assert w==width and h==height, "invalid picture dimensions: %ix%i, expected %ix%i" % (w, h, width, height)
subsamp_str = "YUV%sP" % TJSAMP_STR.get(subsamp, subsamp)
Expand All @@ -135,29 +142,33 @@ def decompress(data, int width, int height, options={}):
cdef int strides[3]
cdef int i, stride
cdef MemBuf membuf
cdef int flags = 0 #TJFLAG_BOTTOMUP
pystrides = []
pyplanes = []
for i in range(3):
stride = tjPlaneWidth(i, w, subsamp)
assert stride>0, "cannot get stride - out of bounds?"
strides[i] = roundup(stride, 4)
plane_sizes[i] = tjPlaneSizeYUV(i, w, strides[i], h, subsamp)
assert plane_sizes[i]>0, "cannot get plane size - out of bounds?"
membuf = getbuf(plane_sizes[i]) #add padding?
planes[i] = <unsigned char*> membuf.get_mem()
#python objects for each plane:
pystrides.append(strides[i])
pyplanes.append(memoryview(membuf))
#log("jpeg strides: %s, plane sizes=%s", pystrides, [int(plane_sizes[i]) for i in range(3)])
cdef int flags = 0 #TJFLAG_BOTTOMUP
r = tjDecompressToYUVPlanes(decompressor,
buf, buf_len,
planes, width, strides, height, flags)
if r:
log.error("Error: failed to decompress %s JPEG data", subsamp_str)
log.error(" %s", get_error_str())
log.error(" width=%i, strides=%s, height=%s", width, pystrides, height)
return None
try:
for i in range(3):
stride = tjPlaneWidth(i, w, subsamp)
assert stride>0, "cannot get stride - out of bounds?"
strides[i] = roundup(stride, 4)
plane_sizes[i] = tjPlaneSizeYUV(i, w, strides[i], h, subsamp)
assert plane_sizes[i]>0, "cannot get plane size - out of bounds?"
membuf = getbuf(plane_sizes[i]) #add padding?
planes[i] = <unsigned char*> membuf.get_mem()
#python objects for each plane:
pystrides.append(strides[i])
pyplanes.append(memoryview(membuf))
#log("jpeg strides: %s, plane sizes=%s", pystrides, [int(plane_sizes[i]) for i in range(3)])
with nogil:
r = tjDecompressToYUVPlanes(decompressor,
buf, buf_len,
planes, width, strides, height, flags)
if r:
log.error("Error: failed to decompress %s JPEG data", subsamp_str)
log.error(" %s", get_error_str())
log.error(" width=%i, strides=%s, height=%s", width, pystrides, height)
return None
finally:
close()
return ImageWrapper(0, 0, w, h, pyplanes, subsamp_str, 24, pystrides, ImageWrapper._3_PLANES)

def selftest(full=False):
Expand Down
28 changes: 17 additions & 11 deletions src/xpra/codecs/jpeg/encoder.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,23 @@ def encode(image, int quality=50, int speed=50, options={}):
cdef unsigned long out_size = 0
cdef int r
log("jpeg: encode with subsampling=%s for pixel format=%s with quality=%s", TJSAMP_STR.get(subsamp, subsamp), pfstr, quality)
with nogil:
r = tjCompress2(compressor, buf,
width, stride, height, tjpf, &out,
&out_size, subsamp, quality, flags)
if r!=0:
log.error("Error: failed to compress jpeg image, code %i:", r)
log.error(" %s", get_error_str())
log.error(" width=%i, stride=%i, height=%i", width, stride, height)
log.error(" pixel format=%s, quality=%i", pfstr, quality)
return None
assert out_size>0 and out!=NULL, "jpeg compression produced no data"
try:
with nogil:
r = tjCompress2(compressor, buf,
width, stride, height, tjpf, &out,
&out_size, subsamp, quality, flags)
if r!=0:
log.error("Error: failed to compress jpeg image, code %i:", r)
log.error(" %s", get_error_str())
log.error(" width=%i, stride=%i, height=%i", width, stride, height)
log.error(" pixel format=%s, quality=%i", pfstr, quality)
return None
assert out_size>0 and out!=NULL, "jpeg compression produced no data"
finally:
r = tjDestroy(compressor)
if r:
log.error("Error: failed to destroy the JPEG compressor, code %i:", r)
log.error(" %s", get_error_str())
cdata = makebuf(out, out_size)
client_options = {}
return "jpeg", Compressed("jpeg", memoryview(cdata), False), client_options, width, height, 0, 24
Expand Down

0 comments on commit 7970c2a

Please sign in to comment.