docs: def _populate_cparams(self, img_array, mct=None, cratios=None, psnr=None,
                            cinema2k=None, cinema4k=None, irreversible=None,
                            cbsize=None, eph=None, grid_offset=None, modesw=None,
                            numres=None, prog=None, psizes=None, sop=None,
                            subsam=None, tilesize=None, colorspace=None):
          """Directs processing of write method arguments.
  
          Parameters
          ----------
          img_array : ndarray
              Image data to be written to file.
          kwargs : dictionary
              Non-image keyword inputs provided to write method.
          """
          other_args = (mct, cratios, psnr, irreversible, cbsize, eph,
                        grid_offset, modesw, numres, prog, psizes, sop, subsam)
          if (((cinema2k is not None or cinema4k is not None) and
               (not all([arg is None for arg in other_args])))):
              msg = ("Cannot specify cinema2k/cinema4k along with any other "
                     "options.")
              raise IOError(msg)
  
          if cratios is not None and psnr is not None:
              msg = "Cannot specify cratios and psnr options together."
              raise IOError(msg)
  
          if version.openjpeg_version_tuple[0] == 1:
              cparams = opj.set_default_encoder_parameters()
          else:
              cparams = opj2.set_default_encoder_parameters()
  
          outfile = self.filename.encode()
          num_pad_bytes = opj2.PATH_LEN - len(outfile)
          outfile += b'0' * num_pad_bytes
          cparams.outfile = outfile
  
          if self.filename[-4:].endswith(('.jp2', '.JP2')):
              cparams.codec_fmt = opj2.CODEC_JP2
          else:
              cparams.codec_fmt = opj2.CODEC_J2K
  
          # Set defaults to lossless to begin.
          cparams.tcp_rates[0] = 0
          cparams.tcp_numlayers = 1
          cparams.cp_disto_alloc = 1
  
          cparams.irreversible = 1 if irreversible else 0
  
          if cinema2k is not None:
              self._cparams = cparams
              self._set_cinema_params('cinema2k', cinema2k)
              return
  
          if cinema4k is not None:
              self._cparams = cparams
              self._set_cinema_params('cinema4k', cinema4k)
              return
  
          if cbsize is not None:
              cparams.cblockw_init = cbsize[1]
              cparams.cblockh_init = cbsize[0]
  
          if cratios is not None:
              cparams.tcp_numlayers = len(cratios)
              for j, cratio in enumerate(cratios):
                  cparams.tcp_rates[j] = cratio
              cparams.cp_disto_alloc = 1
  
          cparams.csty |= 0x02 if sop else 0
          cparams.csty |= 0x04 if eph else 0
  
          if grid_offset is not None:
              cparams.image_offset_x0 = grid_offset[1]
              cparams.image_offset_y0 = grid_offset[0]
  
          if modesw is not None:
              for shift in range(6):
                  power_of_two = 1 << shift
                  if modesw & power_of_two:
                      cparams.mode |= power_of_two
  
          if numres is not None:
              cparams.numresolution = numres
  
          if prog is not None:
              cparams.prog_order = core.PROGRESSION_ORDER[prog.upper()]
  
          if psnr is not None:
              cparams.tcp_numlayers = len(psnr)
              for j, snr_layer in enumerate(psnr):
                  cparams.tcp_distoratio[j] = snr_layer
              cparams.cp_fixed_quality = 1
  
          if psizes is not None:
              for j, (prch, prcw) in enumerate(psizes):
                  cparams.prcw_init[j] = prcw
                  cparams.prch_init[j] = prch
              cparams.csty |= 0x01
              cparams.res_spec = len(psizes)
  
          if subsam is not None:
              cparams.subsampling_dy = subsam[0]
              cparams.subsampling_dx = subsam[1]
  
          if tilesize is not None:
              cparams.cp_tdx = tilesize[1]
              cparams.cp_tdy = tilesize[0]
              cparams.tile_size_on = opj2.TRUE
  
          if mct is None:
              # If the multi component transform was not specified, we infer
              # that it should be used if the color space is RGB.
              cparams.tcp_mct = 1 if self._colorspace == opj2.CLRSPC_SRGB else 0
          else:
              if self._colorspace == opj2.CLRSPC_GRAY:
                  msg = ("Cannot specify usage of the multi component transform "
                         "if the colorspace is gray.")
                  raise IOError(msg)
              cparams.tcp_mct = 1 if mct else 0
  
          self._validate_compression_params(img_array, cparams, colorspace)
  
          self._cparams = cparams