aaaaaa123456789 / libplum

Image-handling library that allows reading and writing common image file formats
The Unlicense
11 stars 6 forks source link

Factor out `has_alpha` from `get_true_color_depth` #2

Closed Rangi42 closed 2 years ago

Rangi42 commented 2 years ago
static bool has_alpha(const struct plum_image * image) {
  size_t count;
  const void * colordata;
  if (image -> palette) {
    count = image -> max_palette_index + 1;
    colordata = image -> palette;
  } else {
    count = (size_t) image -> width * image -> height * image -> frames;
    colordata = image -> data;
  }
  switch (image -> color_format & PLUM_COLOR_MASK) {
    case PLUM_COLOR_32: {
      const uint32_t * color = colordata;
      if (image -> color_format & PLUM_ALPHA_INVERT) {
        while (count --) if (*(color ++) < 0xff000000u) return true;
      } else
        while (count --) if (*(color ++) >= 0x1000000u) return true;
    } break;
    case PLUM_COLOR_64: {
      const uint64_t * color = colordata;
      if (image -> color_format & PLUM_ALPHA_INVERT) {
        while (count --) if (*(color ++) < 0xffff000000000000u) return true;
      } else
        while (count --) if (*(color ++) >= 0x1000000000000u) return true;
    } break;
    case PLUM_COLOR_16: {
      const uint16_t * color = colordata;
      if (image -> color_format & PLUM_ALPHA_INVERT) {
        while (count --) if (*(color ++) < 0x8000u) return true;
      } else
        while (count --) if (*(color ++) >= 0x7fff) return true;
    } break;
    case PLUM_COLOR_32X: {
      const uint32_t * color = colordata;
      if (image -> color_format & PLUM_ALPHA_INVERT) {
        while (count --) if (*(color ++) < 0xc0000000u) return true;
      } else
        while (count --) if (*(color ++) >= 0x40000000u) return true;
    }
  }
  return false;
}

uint32_t get_true_color_depth (const struct plum_image * image) {
  uint8_t red, green, blue, alpha;
  switch (image -> color_format & PLUM_COLOR_MASK) {
    case PLUM_COLOR_32:
      red = green = blue = alpha = 8;
      break;
    case PLUM_COLOR_64:
      red = green = blue = alpha = 16;
      break;
    case PLUM_COLOR_16:
      red = green = blue = 5;
      alpha = 1;
      break;
    case PLUM_COLOR_32X:
      red = green = blue = 10;
      alpha = 2;
  }
  const struct plum_metadata * colorinfo = plum_find_metadata(image, PLUM_METADATA_COLOR_DEPTH);
  if (colorinfo) {
    unsigned char * data = colorinfo -> data;
    if (*data || data[1] || data[2]) {
      if (*data) red = *data;
      if (data[1]) green = data[1];
      if (data[2]) blue = data[2];
    } else if ((colorinfo -> size >= 5) && data[4])
      red = green = blue = data[4];
    if ((colorinfo -> size >= 4) && data[3]) alpha = data[3];
  }
  if (!has_alpha(image) alpha = 0;
  if (red > 16) red = 16;
  if (green > 16) green = 16;
  if (blue > 16) blue = 16;
  if (alpha > 16) alpha = 16;
  return ((uint32_t) red) | ((uint32_t) green << 8) | ((uint32_t) blue << 16) | ((uint32_t) alpha << 24);
}
aaaaaa123456789 commented 2 years ago

Did it in a slightly different way in b687248.