static pixel_format choose_pixel_format(convert_params& params, const crn_comp_params& comp_params, const mipmapped_texture& src_tex, texture_type tex_type) {
  const pixel_format src_fmt = src_tex.get_format();
  const texture_file_types::format src_file_type = src_tex.get_source_file_type();
  const bool is_normal_map = (tex_type == cTextureTypeNormalMap);

  if (params.m_always_use_source_pixel_format)
    return src_fmt;

  // Attempt to choose a reasonable/sane output pixel format.
  if (params.m_dst_file_type == texture_file_types::cFormatCRN) {
    if (is_normal_map) {
      if (pixel_format_helpers::is_dxt(src_fmt))
        return src_fmt;
      else
        return PIXEL_FMT_DXT5_AGBR;
    }
  } else if (params.m_dst_file_type == texture_file_types::cFormatKTX) {
    if ((src_file_type != texture_file_types::cFormatCRN) && (src_file_type != texture_file_types::cFormatKTX) && (src_file_type != texture_file_types::cFormatDDS)) {
      if (is_normal_map) {
        return pixel_format_helpers::has_alpha(src_fmt) ? PIXEL_FMT_A8R8G8B8 : PIXEL_FMT_R8G8B8;
      } else if (pixel_format_helpers::is_grayscale(src_fmt)) {
        if (pixel_format_helpers::has_alpha(src_fmt))
          return PIXEL_FMT_ETC2A;
        else
          return PIXEL_FMT_ETC1;
      } else if (pixel_format_helpers::has_alpha(src_fmt))
        return PIXEL_FMT_ETC2A;
      else
        return PIXEL_FMT_ETC1;
    }
  } else if (params.m_dst_file_type == texture_file_types::cFormatDDS) {
    if ((src_file_type != texture_file_types::cFormatCRN) && (src_file_type != texture_file_types::cFormatKTX) && (src_file_type != texture_file_types::cFormatDDS)) {
      if (is_normal_map) {
        return PIXEL_FMT_DXT5_AGBR;
      } else if (pixel_format_helpers::is_grayscale(src_fmt)) {
        if (pixel_format_helpers::has_alpha(src_fmt))
          return comp_params.get_flag(cCRNCompFlagDXT1AForTransparency) ? PIXEL_FMT_DXT1A : PIXEL_FMT_DXT5;
        else
          return PIXEL_FMT_DXT1;
      } else if (pixel_format_helpers::has_alpha(src_fmt))
        return comp_params.get_flag(cCRNCompFlagDXT1AForTransparency) ? PIXEL_FMT_DXT1A : PIXEL_FMT_DXT5;
      else
        return PIXEL_FMT_DXT1;
    }
  } else {
    // Destination is a regular image format.
    if (pixel_format_helpers::is_grayscale(src_fmt)) {
      if (pixel_format_helpers::has_alpha(src_fmt))
        return PIXEL_FMT_A8L8;
      else
        return PIXEL_FMT_L8;
    } else if (pixel_format_helpers::has_alpha(src_fmt))
      return PIXEL_FMT_A8R8G8B8;
    else
      return PIXEL_FMT_R8G8B8;
  }

  return src_fmt;
}
static void print_comp_params(const crn_comp_params& comp_params) {
  console::debug("\nTexture conversion compression parameters:");
  console::debug("          Desired bitrate: %3.3f", comp_params.m_target_bitrate);
  console::debug("              CRN Quality: %i", comp_params.m_quality_level);
  console::debug("CRN C endpoints/selectors: %u %u", comp_params.m_crn_color_endpoint_palette_size, comp_params.m_crn_color_selector_palette_size);
  console::debug("CRN A endpoints/selectors: %u %u", comp_params.m_crn_alpha_endpoint_palette_size, comp_params.m_crn_alpha_selector_palette_size);
  console::debug("     DXT both block types: %u, Alpha threshold: %u", comp_params.get_flag(cCRNCompFlagUseBothBlockTypes), comp_params.m_dxt1a_alpha_threshold);
  console::debug("  DXT compression quality: %s", crn_get_dxt_quality_string(comp_params.m_dxt_quality));
  console::debug("               Perceptual: %u, Large Blocks: %u", comp_params.get_flag(cCRNCompFlagPerceptual), comp_params.get_flag(cCRNCompFlagHierarchical));
  console::debug("               Compressor: %s", get_dxt_compressor_name(comp_params.m_dxt_compressor_type));
  console::debug(" Disable endpoint caching: %u", comp_params.get_flag(cCRNCompFlagDisableEndpointCaching));
  console::debug("       Grayscale sampling: %u", comp_params.get_flag(cCRNCompFlagGrayscaleSampling));
  console::debug("       Max helper threads: %u", comp_params.m_num_helper_threads);
  console::debug("");
}
static bool write_compressed_texture(
    mipmapped_texture& work_tex, convert_params& params, crn_comp_params& comp_params, pixel_format dst_format, progress_params& progress_state, bool perceptual, convert_stats& stats) {
  comp_params.m_file_type = (params.m_dst_file_type == texture_file_types::cFormatCRN) ? cCRNFileTypeCRN : cCRNFileTypeDDS;

  comp_params.m_pProgress_func = crn_progress_callback;
  comp_params.m_pProgress_func_data = &progress_state;
  comp_params.set_flag(cCRNCompFlagPerceptual, perceptual);

  crn_format crn_fmt = pixel_format_helpers::convert_pixel_format_to_best_crn_format(dst_format);
  comp_params.m_format = crn_fmt;

  console::message("Writing %s texture to file: \"%s\"", crn_get_format_string(crn_fmt), params.m_dst_filename.get_ptr());

  uint32 actual_quality_level;
  float actual_bitrate;
  bool status = work_tex.write_to_file(params.m_dst_filename.get_ptr(), params.m_dst_file_type, &comp_params, &actual_quality_level, &actual_bitrate);
  if (!status)
    return convert_error(params, "Failed writing output file!");

  if (!params.m_no_stats) {
    if (!stats.init(params.m_pInput_texture->get_source_filename().get_ptr(), params.m_dst_filename.get_ptr(), *params.m_pIntermediate_texture, params.m_dst_file_type, params.m_lzma_stats)) {
      console::warning("Unable to compute output statistics for file: %s", params.m_pInput_texture->get_source_filename().get_ptr());
    }
  }

  return true;
}
Exemple #4
0
      bool init(const crn_comp_params &params)
      {
         m_comp_params = params;

         m_pack_params.init(params);

         crn_format basic_crn_fmt = crnd::crnd_get_fundamental_dxt_format(params.m_format);
         pixel_format basic_pixel_fmt = pixel_format_helpers::convert_crn_format_to_pixel_format(basic_crn_fmt);

         if ((params.get_flag(cCRNCompFlagDXT1AForTransparency)) && (basic_pixel_fmt == PIXEL_FMT_DXT1))
            basic_pixel_fmt = PIXEL_FMT_DXT1A;

         if (!m_image.init(pixel_format_helpers::get_dxt_format(basic_pixel_fmt), cDXTBlockSize, cDXTBlockSize, false))
            return false;

         return true;
      }
static bool convert_and_write_normal_texture(mipmapped_texture& work_tex, convert_params& params, const crn_comp_params& comp_params, pixel_format dst_format, progress_params& progress_state, bool formats_differ, bool perceptual, convert_stats& stats) {
  if (formats_differ) {
    dxt_image::pack_params pack_params;

    pack_params.m_perceptual = perceptual;
    pack_params.m_compressor = comp_params.m_dxt_compressor_type;
    pack_params.m_pProgress_callback = dxt_progress_callback_func;
    pack_params.m_pProgress_callback_user_data_ptr = &progress_state;
    pack_params.m_dxt1a_alpha_threshold = comp_params.m_dxt1a_alpha_threshold;
    pack_params.m_quality = comp_params.m_dxt_quality;
    pack_params.m_endpoint_caching = !comp_params.get_flag(cCRNCompFlagDisableEndpointCaching);
    pack_params.m_grayscale_sampling = comp_params.get_flag(cCRNCompFlagGrayscaleSampling);
    if ((!comp_params.get_flag(cCRNCompFlagUseBothBlockTypes)) && (!comp_params.get_flag(cCRNCompFlagDXT1AForTransparency)))
      pack_params.m_use_both_block_types = false;

    pack_params.m_num_helper_threads = comp_params.m_num_helper_threads;
    pack_params.m_use_transparent_indices_for_black = comp_params.get_flag(cCRNCompFlagUseTransparentIndicesForBlack);

    console::info("Converting texture format from %s to %s", pixel_format_helpers::get_pixel_format_string(work_tex.get_format()), pixel_format_helpers::get_pixel_format_string(dst_format));

    timer tm;
    tm.start();

    bool status = work_tex.convert(dst_format, pack_params);

    double t = tm.get_elapsed_secs();

    console::info("");

    if (!status) {
      if (progress_state.m_canceled) {
        params.m_canceled = true;
        return false;
      } else {
        return convert_error(params, "Failed converting texture to output format!");
      }
    }

    console::info("Texture format conversion took %3.3fs", t);
  }

  if (params.m_write_mipmaps_to_multiple_files) {
    for (uint f = 0; f < work_tex.get_num_faces(); f++) {
      for (uint l = 0; l < work_tex.get_num_levels(); l++) {
        dynamic_string filename(params.m_dst_filename.get_ptr());

        dynamic_string drv, dir, fn, ext;
        if (!file_utils::split_path(params.m_dst_filename.get_ptr(), &drv, &dir, &fn, &ext))
          return false;

        fn += dynamic_string(cVarArg, "_face%u_mip%u", f, l).get_ptr();
        filename = drv + dir + fn + ext;

        mip_level* pLevel = work_tex.get_level(f, l);

        face_vec face(1);
        face[0].push_back(crnlib_new<mip_level>(*pLevel));

        mipmapped_texture new_tex;
        new_tex.assign(face);

        console::info("Writing texture face %u mip level %u to file %s", f, l, filename.get_ptr());

        if (!new_tex.write_to_file(filename.get_ptr(), params.m_dst_file_type, NULL, NULL, NULL))
          return convert_error(params, "Failed writing output file!");
      }
    }
  } else {
    console::message("Writing texture to file: \"%s\"", params.m_dst_filename.get_ptr());

    if (params.m_dst_stream) {
      if (!work_tex.write_to_stream(params.m_dst_stream, params.m_dst_file_type, NULL, NULL, NULL)) {
        return convert_error(params, "Failed writing output stream!");
	  }
	}
	else if (!work_tex.write_to_file(params.m_dst_filename.get_ptr(), params.m_dst_file_type, NULL, NULL, NULL)) {
      return convert_error(params, "Failed writing output file!");
    }

    if (!params.m_no_stats) {
      if (!stats.init(params.m_pInput_texture->get_source_filename().get_ptr(), params.m_dst_filename.get_ptr(), *params.m_pIntermediate_texture, params.m_dst_file_type, params.m_lzma_stats)) {
        console::warning("Unable to compute output statistics for file: %s", params.m_pInput_texture->get_source_filename().get_ptr());
      }
    }
  }

  return true;
}
      static pixel_format choose_pixel_format(convert_params& params, const crn_comp_params &comp_params, const dds_texture& src_tex, texture_type tex_type)
      {
         if (params.m_use_source_format)
            return src_tex.get_format();

         const bool is_normal_map = (tex_type == cTextureTypeNormalMap);

         if (params.m_dst_file_type == texture_file_types::cFormatCRN)
         {
            if (is_normal_map)
            {
               switch (src_tex.get_format())
               {
                  case PIXEL_FMT_DXN:
                  case PIXEL_FMT_3DC:
                  case PIXEL_FMT_DXT5_xGBR:
                  case PIXEL_FMT_DXT5_AGBR:
                  case PIXEL_FMT_DXT5_xGxR:
                     return src_tex.get_format();
                  default:
                     return PIXEL_FMT_DXT5_AGBR;
               }
            }
         }
         else if (params.m_dst_file_type == texture_file_types::cFormatDDS)
         {
            if (src_tex.get_source_file_type() != texture_file_types::cFormatCRN)
            {
               if (is_normal_map)
               {
                  switch (src_tex.get_format())
                  {
                     case PIXEL_FMT_DXN:
                     case PIXEL_FMT_3DC:
                     case PIXEL_FMT_DXT5_xGBR:
                     case PIXEL_FMT_DXT5_AGBR:
                     case PIXEL_FMT_DXT5_xGxR:
                        return src_tex.get_format();
                     default:
                        return PIXEL_FMT_DXT5_AGBR;
                  }
               }
               else if (pixel_format_helpers::is_grayscale(src_tex.get_format()))
               {
                  if (pixel_format_helpers::has_alpha(src_tex.get_format()))
                     return comp_params.get_flag(cCRNCompFlagDXT1AForTransparency) ? PIXEL_FMT_DXT1A : PIXEL_FMT_DXT5;
                  else
                     return PIXEL_FMT_DXT1;
               }
               else if (pixel_format_helpers::has_alpha(src_tex.get_format()))
                  return comp_params.get_flag(cCRNCompFlagDXT1AForTransparency) ? PIXEL_FMT_DXT1A : PIXEL_FMT_DXT5;
               else
                  return PIXEL_FMT_DXT1;
            }
         }
         else
         {
            // A regular image format.
            if (pixel_format_helpers::is_grayscale(src_tex.get_format()))
            {
               if (pixel_format_helpers::has_alpha(src_tex.get_format()))
                  return PIXEL_FMT_A8L8;
               else
                  return PIXEL_FMT_L8;
            }
            else if (pixel_format_helpers::has_alpha(src_tex.get_format()))
               return PIXEL_FMT_A8R8G8B8;
            else
               return PIXEL_FMT_R8G8B8;
         }

         return src_tex.get_format();
      }