Esempio n. 1
0
static SquashStatus
squash_lz4_compress_buffer_unsafe (SquashCodec* codec,
                                   size_t* compressed_size,
                                   uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)],
                                   size_t uncompressed_size,
                                   const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)],
                                   SquashOptions* options) {
  int level = squash_codec_get_option_int_index (codec, options, SQUASH_LZ4_OPT_LEVEL);

#if INT_MAX < SIZE_MAX
  if (SQUASH_UNLIKELY(INT_MAX < uncompressed_size) ||
      SQUASH_UNLIKELY(INT_MAX < *compressed_size))
    return squash_error (SQUASH_RANGE);
#endif

  assert (*compressed_size >= LZ4_COMPRESSBOUND(uncompressed_size));

  int lz4_r;

  if (level == 7) {
    lz4_r = LZ4_compress ((char*) uncompressed,
                          (char*) compressed,
                          (int) uncompressed_size);
  } else if (level < 7) {
    lz4_r = LZ4_compress_fast ((const char*) uncompressed,
                               (char*) compressed,
                               (int) uncompressed_size,
                               (int) *compressed_size,
                               squash_lz4_level_to_fast_mode (level));
  } else {
    lz4_r = LZ4_compressHC2 ((char*) uncompressed,
                             (char*) compressed,
                             (int) uncompressed_size,
                             squash_lz4_level_to_hc_level (level));
  }

#if SIZE_MAX < INT_MAX
  if (SQUASH_UNLIKELY(SIZE_MAX < lz4_r))
    return squash_error (SQUASH_RANGE);
#endif

  *compressed_size = lz4_r;

  return (lz4_r == 0) ? SQUASH_BUFFER_FULL : SQUASH_OK;
}
Esempio n. 2
0
size_t lz4Compress(std::shared_ptr<uint8_t> src, size_t uncompressedBytes,
                   std::shared_ptr<uint8_t>& dst,
                   uint32_t compressionLevel)
{
  if (uncompressedBytes > size_t(LZ4_MAX_INPUT_SIZE))
    throw std::runtime_error("Input data too big for LZ4 (max LZ4_MAX_INPUT_SIZE)");
  int const inputSize = static_cast<int>(uncompressedBytes);
  int const upperBound = LZ4_compressBound(inputSize);
  if (upperBound < 0)
    throw std::runtime_error("Input data too big for LZ4 (max LZ4_MAX_INPUT_SIZE)");
  dst.reset(new uint8_t[size_t(upperBound)], nonstd::DeleteArray<uint8_t>());

  if (compressionLevel > 17)
    compressionLevel = 17;
  else if (compressionLevel < 1)
    compressionLevel = 1;

  int compressedBytes = 0;
  switch (compressionLevel) {
  case 1:
    compressedBytes = LZ4_compress((const char*)src.get(),
                                   (char*)dst.get(),
                                   inputSize);
    break;
  default:
    // compression level 0 is default mode which seems to equal level 9 and HC
    compressedBytes = LZ4_compressHC2((const char*)src.get(),
                                      (char*)dst.get(),
                                      inputSize,
                                      compressionLevel - 1);
    break;
  }

  assert(compressedBytes >= 0);
  if (compressedBytes <= 0)
    throw std::runtime_error(std::string("LZ4_compress[HC] failed, returned value: ") +
      SysTools::ToString(compressedBytes));
  return compressedBytes;
}
Esempio n. 3
0
bool JobTicket::DoJob(const wxRect &rect)
{
    unsigned char *bit_array[10];
    for(int i=0 ; i < 10 ; i++)
        bit_array[i] = 0;

    wxRect ncrect(rect);

    bit_array[0] = level0_bits;
    level0_bits = NULL;

    if(!bit_array[0]) {
        //  Grab a copy of the level0 chart bits
        // we could alternately subsample grabbing leveln chart bits
        // directly here to speed things up...
        ChartBase *pchart;
        int index;
    
        if(ChartData){
            index =  ChartData->FinddbIndex( m_ChartPath );
            pchart = ChartData->OpenChartFromDBAndLock(index, FULL_INIT );

            if(pchart && ChartData->IsChartLocked( index )){
                ChartBaseBSB *pBSBChart = dynamic_cast<ChartBaseBSB*>( pchart );
                if( pBSBChart ) {
                    bit_array[0] = (unsigned char *) malloc( ncrect.width * ncrect.height * 4 );
                    pBSBChart->GetChartBits( ncrect, bit_array[0], 1 );
                }
                ChartData->UnLockCacheChart(index);
            }
            else
                bit_array[0] = NULL;
        }
    }
    
    //OK, got the bits?
    int ssize, dim;
    if(!bit_array[0] )
        return false;
    
    //  Fill in the rest of the private uncompressed array
    dim = g_GLOptions.m_iTextureDimension;
    dim /= 2;
    for( int i = 1 ; i < g_mipmap_max_level+1 ; i++ ){
        size_t nmalloc = wxMax(dim * dim * 3, 4*4*3);
        bit_array[i] = (unsigned char *) malloc( nmalloc );
        MipMap_24( 2*dim, 2*dim, bit_array[i - 1], bit_array[i] );
        dim /= 2;
    }
        
    int texture_level = 0;
    for( int level = level_min_request; level < g_mipmap_max_level+1 ; level++ ){
        int dim = TextureDim(level);
        int size = TextureTileSize(level, true);
        unsigned char *tex_data = (unsigned char*)malloc(size);
        if(g_raster_format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) {
            // color range fit is worse quality but twice as fast
            int flags = squish::kDxt1 | squish::kColourRangeFit;
            
            if( g_GLOptions.m_bTextureCompressionCaching) {
                /* use slower cluster fit since we are building the cache for
                 * better quality, this takes roughly 25% longer and uses about
                 * 10% more disk space (result doesn't compress as well with lz4) */
                flags = squish::kDxt1 | squish::kColourClusterFit;
            }
            
            OCPNStopWatch sww;
            squish::CompressImageRGBpow2_Flatten_Throttle_Abort( bit_array[level], dim, dim, tex_data, flags,
                                                                 true, b_throttle ? throttle_func : 0, &sww, b_abort );
            
        } else if(g_raster_format == GL_ETC1_RGB8_OES) 
            CompressDataETC(bit_array[level], dim, size, tex_data, b_abort);
        else if(g_raster_format == GL_COMPRESSED_RGB_FXT1_3DFX) {
            if(!CompressUsingGPU(bit_array[level], dim, size, tex_data, texture_level, binplace)) {
                b_abort = true;
                break;
            }

            if(binplace)
                g_tex_mem_used += size;

            texture_level++;
        }
        comp_bits_array[level] = tex_data;
            
        if(b_abort){
            for( int i = 0; i < g_mipmap_max_level+1; i++ ){
                free( bit_array[i] );
                bit_array[i] = 0;
            }
            return false;
        }
    }
        
    //  All done with the uncompressed data in the thread
    for( int i = 0; i < g_mipmap_max_level+1; i++ ) {
        free( bit_array[i] );
        bit_array[i] = 0;
    }

    if(b_throttle)
        wxThread::Sleep(1);
    
    if(b_abort)
        return false;

    if(bpost_zip_compress) {
            
        int max_compressed_size = LZ4_COMPRESSBOUND(g_tile_size);
        for(int level = level_min_request; level < g_mipmap_max_level+1 ; level++){
            if(b_abort)
                return false;

            unsigned char *compressed_data = (unsigned char *)malloc(max_compressed_size);
            int csize = TextureTileSize(level, true);

            char *src = (char *)comp_bits_array[level];
            int compressed_size = LZ4_compressHC2( src, (char *)compressed_data, csize, 4);
            // shrink buffer to actual size.
            // This will greatly reduce ram usage, ratio usually 10:1
            // there might be a more efficient way than realloc...
            compressed_data = (unsigned char*)realloc(compressed_data, compressed_size);
            compcomp_bits_array[level] = compressed_data;
            compcomp_size_array[level] = compressed_size;
        }
    }

    return true;
}