def decode(self, dst=None, pixfmt=TJPF_RGB): bpp = jpeg.tjPixelSize[pixfmt] if dst is None: if self.width is None: self.parse_header() sh = [self.height, self.width] if bpp > 1: sh.append(bpp) dst = numpy.zeros(sh, dtype=numpy.uint8) elif not hasattr(dst, "__array_interface__"): raise ValueError("dst should be numpy array or None") if len(dst.shape) < 2: raise ValueError("dst shape length should 2 or 3") if dst.nbytes < dst.shape[1] * dst.shape[0] * bpp: raise ValueError( "dst is too small to hold the requested pixel format") self._get_decompressor() n = self.lib_.tjDecompress2( self.decompressor.handle_, ffi.cast("unsigned char*", self.source.__array_interface__["data"][0]), self.source.nbytes, ffi.cast("unsigned char*", dst.__array_interface__["data"][0]), dst.shape[1], dst.strides[0], dst.shape[0], pixfmt, 0) if n: raise JPEGRuntimeError("tjDecompress2() failed with error " "%d and error string %s" % (n, self.get_last_error()), n) return dst
def parse_header(self): """Parses JPEG header. Fills self.width, self.height, self.subsampling. """ self._get_decompressor() whs = ffi.new("int[]", 3) whs_base = int(ffi.cast("size_t", whs)) whs_itemsize = int(ffi.sizeof("int")) n = self.lib_.tjDecompressHeader2( self.decompressor.handle_, ffi.cast("unsigned char*", self.source.__array_interface__["data"][0]), self.source.nbytes, ffi.cast("int*", whs_base), ffi.cast("int*", whs_base + whs_itemsize), ffi.cast("int*", whs_base + whs_itemsize + whs_itemsize)) if n: raise JPEGRuntimeError("tjDecompressHeader2() failed with error " "%d and error string %s" % (n, self.get_last_error()), n) self.width = int(whs[0]) self.height = int(whs[1]) self.subsampling = int(whs[2])