<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _read_openjpeg(self, rlevel=0, verbose=False, area=None):
 """Read a JPEG 2000 image using libopenjpeg. Parameters rlevel : int, optional Factor by which to rlevel output resolution. Use -1 to get the lowest resolution thumbnail. verbose : bool, optional Print informational messages produced by the OpenJPEG library. area : tuple, optional Specifies decoding image area, (first_row, first_col, last_row, last_col) Returns ------- ndarray The image data. Raises ------ RuntimeError If the image has differing subsample factors. """

        self._subsampling_sanity_check()

        self._populate_dparams(rlevel)

        with ExitStack() as stack:
            try:
                self._dparams.decod_format = self._codec_format

                dinfo = opj.create_decompress(self._dparams.decod_format)

                event_mgr = opj.EventMgrType()
                handler = ctypes.cast(_INFO_CALLBACK, ctypes.c_void_p)
                event_mgr.info_handler = handler if self.verbose else None
                event_mgr.warning_handler = ctypes.cast(_WARNING_CALLBACK,
                                                        ctypes.c_void_p)
                event_mgr.error_handler = ctypes.cast(_ERROR_CALLBACK,
                                                      ctypes.c_void_p)
                opj.set_event_mgr(dinfo, ctypes.byref(event_mgr))

                opj.setup_decoder(dinfo, self._dparams)

                with open(self.filename, 'rb') as fptr:
                    src = fptr.read()
                cio = opj.cio_open(dinfo, src)

                raw_image = opj.decode(dinfo, cio)

                stack.callback(opj.image_destroy, raw_image)
                stack.callback(opj.destroy_decompress, dinfo)
                stack.callback(opj.cio_close, cio)

                image = self._extract_image(raw_image)

            except ValueError:
                opj2.check_error(0)

        if area is not None:
            x0, y0, x1, y1 = area
            extent = 2 ** rlevel

            area = [int(round(float(x) / extent + 2 ** -20)) for x in area]
            rows = slice(area[0], area[2], None)
            cols = slice(area[1], area[3], None)
            image = image[rows, cols]

        return image