def _write_openjpeg(self, img_array, verbose=False):
        """
        Write JPEG 2000 file using OpenJPEG 1.5 interface.
        """
        if img_array.ndim == 2:
            # Force the image to be 3D.  Just makes things easier later on.
            img_array = img_array.reshape(img_array.shape[0],
                                          img_array.shape[1],
                                          1)

        self._populate_comptparms(img_array)

        with ExitStack() as stack:
            image = opj.image_create(self._comptparms, self._colorspace)
            stack.callback(opj.image_destroy, image)

            numrows, numcols, numlayers = img_array.shape

            # set image offset and reference grid
            image.contents.x0 = self._cparams.image_offset_x0
            image.contents.y0 = self._cparams.image_offset_y0
            image.contents.x1 = (image.contents.x0 +
                                 (numcols - 1) * self._cparams.subsampling_dx +
                                 1)
            image.contents.y1 = (image.contents.y0 +
                                 (numrows - 1) * self._cparams.subsampling_dy +
                                 1)

            # Stage the image data to the openjpeg data structure.
            for k in range(0, numlayers):
                layer = np.ascontiguousarray(img_array[:, :, k],
                                             dtype=np.int32)
                dest = image.contents.comps[k].data
                src = layer.ctypes.data
                ctypes.memmove(dest, src, layer.nbytes)

            cinfo = opj.create_compress(self._cparams.codec_fmt)
            stack.callback(opj.destroy_compress, cinfo)

            # Setup the info, warning, and error handlers.
            # Always use the warning and error handler.  Use of an info
            # handler is optional.
            event_mgr = opj.EventMgrType()
            _info_handler = _INFO_CALLBACK if verbose else None
            event_mgr.info_handler = _info_handler
            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.setup_encoder(cinfo, ctypes.byref(self._cparams), image)

            cio = opj.cio_open(cinfo)
            stack.callback(opj.cio_close, cio)

            if not opj.encode(cinfo, cio, image):
                raise IOError("Encode error.")

            pos = opj.cio_tell(cio)

            blob = ctypes.string_at(cio.contents.buffer, pos)
            fptr = open(self.filename, 'wb')
            stack.callback(fptr.close)
            fptr.write(blob)

        self.parse()
Write JPEG 2000 file using OpenJPEG 1.5 interface.