static void unpack_argb(enum _openslide_jp2k_colorspace space,
                        opj_image_comp_t *comps,
                        uint32_t *dest,
                        int32_t w, int32_t h) {
  // TODO: too slow, and with duplicated code!

  int c0_sub_x = w / comps[0].w;
  int c1_sub_x = w / comps[1].w;
  int c2_sub_x = w / comps[2].w;
  int c0_sub_y = h / comps[0].h;
  int c1_sub_y = h / comps[1].h;
  int c2_sub_y = h / comps[2].h;

  int i = 0;

  switch (space) {
  case OPENSLIDE_JP2K_YCBCR:
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
        uint8_t c0 = comps[0].data[(y / c0_sub_y) * comps[0].w + (x / c0_sub_x)];
        uint8_t c1 = comps[1].data[(y / c1_sub_y) * comps[1].w + (x / c1_sub_x)];
        uint8_t c2 = comps[2].data[(y / c2_sub_y) * comps[2].w + (x / c2_sub_x)];

        write_pixel_ycbcr(dest + i, c0, c1, c2);
        i++;
      }
    }

    break;

  case OPENSLIDE_JP2K_RGB:
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
        uint8_t c0 = comps[0].data[(y / c0_sub_y) * comps[0].w + (x / c0_sub_x)];
        uint8_t c1 = comps[1].data[(y / c1_sub_y) * comps[1].w + (x / c1_sub_x)];
        uint8_t c2 = comps[2].data[(y / c2_sub_y) * comps[2].w + (x / c2_sub_x)];

        write_pixel_rgb(dest + i, c0, c1, c2);
        i++;
      }
    }
    break;
  }
}
static void copy_aperio_tile(uint16_t compression_mode,
			     opj_image_comp_t *comps,
			     uint32_t *dest,
			     int32_t w, int32_t h,
			     int c0_sub_x, int c0_sub_y,
			     int c1_sub_x, int c1_sub_y,
			     int c2_sub_x, int c2_sub_y) {
  // TODO: too slow, and with duplicated code!

  int i = 0;

  switch (compression_mode) {
  case APERIO_COMPRESSION_JP2K_YCBCR:
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
	uint8_t c0 = comps[0].data[(y / c0_sub_y) * comps[0].w + (x / c0_sub_x)];
	uint8_t c1 = comps[1].data[(y / c1_sub_y) * comps[1].w + (x / c1_sub_x)];
	uint8_t c2 = comps[2].data[(y / c2_sub_y) * comps[2].w + (x / c2_sub_x)];

	write_pixel_ycbcr(dest + i, c0, c1, c2);
	i++;
      }
    }

    break;

  case APERIO_COMPRESSION_JP2K_RGB:
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
	uint8_t c0 = comps[0].data[(y / c0_sub_y) * comps[0].w + (x / c0_sub_x)];
	uint8_t c1 = comps[1].data[(y / c1_sub_y) * comps[1].w + (x / c1_sub_x)];
	uint8_t c2 = comps[2].data[(y / c2_sub_y) * comps[2].w + (x / c2_sub_x)];

	write_pixel_rgb(dest + i, c0, c1, c2);
	i++;
      }
    }
    break;
  }
}