size_t Crunch_CompressSingleImage(byte *stream, TexEncodeTask *t, int imagewidth, int imageheight, byte *imagedata) { crn_comp_params options; crn_uint32 quality_level = 0; crn_uint32 output_size = 0; float actual_bitrate = 0; byte *output_data; // set options options.clear(); options.m_width = imagewidth; options.m_height = imageheight; options.m_pImages[0][0] = (crn_uint32 *)imagedata; options.set_flag(cCRNCompFlagPerceptual, true); // crnlib non-perceptural mode looks worse if (t->image->datatype == IMAGE_GRAYSCALE) options.set_flag(cCRNCompFlagGrayscaleSampling, true); else options.set_flag(cCRNCompFlagGrayscaleSampling, false); options.set_flag(cCRNCompFlagUseBothBlockTypes, true); options.set_flag(cCRNCompFlagHierarchical, true); options.m_file_type = cCRNFileTypeDDS; options.m_quality_level = cCRNMaxQualityLevel; options.m_dxt1a_alpha_threshold = 128; options.m_dxt_quality = crnlib_speed[tex_profile]; options.m_dxt_compressor_type = crnlib_compressor_type; options.m_num_helper_threads = (tex_mode == TEXMODE_DROP_FILE) ? (numthreads - 1): 0; if (t->format->block == &B_DXT1) { options.m_format = cCRNFmtDXT1; if (t->image->hasAlpha) options.set_flag(cCRNCompFlagDXT1AForTransparency, true); else options.set_flag(cCRNCompFlagDXT1AForTransparency, false); } else if (t->format->block == &B_DXT2 || t->format->block == &B_DXT3) options.m_format = cCRNFmtDXT3; else if (t->format->block == &B_DXT4 || t->format->block == &B_DXT5) options.m_format = cCRNFmtDXT5; else { Warning("CrnLib: %s%s.dds - unsupported compression %s/%s", t->file->path.c_str(), t->file->name.c_str(), t->format->name, t->format->block->name); return 0; } // compress output_data = (byte *)crn_compress(options, output_size, &quality_level, &actual_bitrate); if (output_data) { output_size -= DDS_HEADER_SIZE; // crnlib generates data with DDS header memcpy(stream, output_data + DDS_HEADER_SIZE, output_size); crn_free_block(output_data); return output_size; } Warning("CrnLib : %s%s.dds - compressor failed", t->file->path.c_str(), t->file->name.c_str()); return 0; }
char *ImageUtils::compressImage(fipImage &image, bool generateMipmaps, int compressionQuality, size_t &compressedSize) { if (image.getBitsPerPixel() != 32) image.convertTo32Bits(); crn_comp_params params; crn_mipmap_params mipmaps; params.m_width = image.getWidth(); params.m_height = image.getHeight(); auto imgData = image.accessPixels(); // set the compression params params.m_format = crn_format::cCRNFmtDXT5; params.m_file_type = cCRNFileTypeDDS; params.m_alpha_component = 0; params.m_dxt_quality = (crn_dxt_quality)compressionQuality; params.set_flag(cCRNCompFlagPerceptual, false); params.m_pImages[0][0] = (crn_uint32*)imgData; // set the mipmaps params mipmaps.m_gamma_filtering = false; if (generateMipmaps) mipmaps.m_mode = cCRNMipModeGenerateMips; else mipmaps.m_mode = cCRNMipModeNoMips; uint32_t ddsSize = 0; char *compressedData = static_cast<char*>(crn_compress(params, mipmaps, ddsSize)); compressedSize = ddsSize; assert(compressedData != NULL); return (compressedData); }