static lzham_compress_status_t create_init_params(lzcompressor::init_params &params, const lzham_compress_params *pParams)
 {
    if ((pParams->m_dict_size_log2 < CLZBase::cMinDictSizeLog2) || (pParams->m_dict_size_log2 > CLZBase::cMaxDictSizeLog2))
       return LZHAM_COMP_STATUS_INVALID_PARAMETER;
    
    if (pParams->m_cpucache_total_lines)
    {
       if (!math::is_power_of_2(pParams->m_cpucache_line_size))
       {
          return LZHAM_COMP_STATUS_INVALID_PARAMETER;
       }
    }
       
    params.m_dict_size_log2 = pParams->m_dict_size_log2;
    params.m_max_helper_threads = LZHAM_MIN(LZHAM_MAX_HELPER_THREADS, pParams->m_max_helper_threads);
    params.m_num_cachelines = pParams->m_cpucache_total_lines;
    params.m_cacheline_size = pParams->m_cpucache_line_size;
    params.m_lzham_compress_flags = pParams->m_compress_flags;
    
    switch (pParams->m_level)
    {
       case LZHAM_COMP_LEVEL_FASTEST:   params.m_compression_level = cCompressionLevelFastest; break;
       case LZHAM_COMP_LEVEL_FASTER:    params.m_compression_level = cCompressionLevelFaster; break;
       case LZHAM_COMP_LEVEL_DEFAULT:   params.m_compression_level = cCompressionLevelDefault; break;
       case LZHAM_COMP_LEVEL_BETTER:    params.m_compression_level = cCompressionLevelBetter; break;
       case LZHAM_COMP_LEVEL_UBER:      params.m_compression_level = cCompressionLevelUber; break;
       default:
          return LZHAM_COMP_STATUS_INVALID_PARAMETER;
    };
 
    return LZHAM_COMP_STATUS_SUCCESS;
 }
   bool generate_huffman_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret, code_size_histogram &code_size_hist)
   {
      if ((!num_syms) || (num_syms > cHuffmanMaxSupportedSyms))
         return false;
                  
      huffman_work_tables& state = *static_cast<huffman_work_tables*>(pContext);;
            
      uint max_freq = 0;
      uint total_freq = 0;
      
      uint num_used_syms = 0;
      for (uint i = 0; i < num_syms; i++)
      {
         uint freq = pFreq[i];
         
         if (!freq)
            pCodesizes[i] = 0;
         else
         {
            total_freq += freq;
            max_freq = math::maximum(max_freq, freq);
            
            sym_freq& sf = state.syms0[num_used_syms];
            sf.m_left = (uint16)i;
            sf.m_right = cUINT16_MAX;
            sf.m_freq = freq;
            num_used_syms++;
         }            
      }
      
      total_freq_ret = total_freq;

      if (num_used_syms == 1)
      {
         pCodesizes[state.syms0[0].m_left] = 1;
         return true;
      }

      sym_freq* syms = radix_sort_syms(num_used_syms, state.syms0, state.syms1);
      
      int x[cHuffmanMaxSupportedSyms];
      for (uint i = 0; i < num_used_syms; i++)
         x[i] = syms[i].m_freq;
      
      calculate_minimum_redundancy(x, num_used_syms);
      
      uint max_len = 0;
      for (uint i = 0; i < num_used_syms; i++)
      {
         uint len = x[i];
         max_len = math::maximum(len, max_len);
         code_size_hist.m_num_codes[LZHAM_MIN(len, (uint)code_size_histogram::cMaxUnlimitedHuffCodeSize)]++;
         pCodesizes[syms[i].m_left] = static_cast<uint8>(len);
      }
      max_code_size = max_len;
                  
      return true;
   }
int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args)
{
   if (!sizeOfBuffer)
      return 0;

   int c = vsnprintf(buffer, sizeOfBuffer, format, args);

   buffer[sizeOfBuffer - 1] = '\0';

   if (c < 0)
      return sizeOfBuffer - 1;

   return LZHAM_MIN(c, (int)sizeOfBuffer - 1);
}
int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...)
{
   if (!sizeOfBuffer)
      return 0;

   va_list args;
   va_start(args, format);
   int c = vsnprintf(buffer, sizeOfBuffer, format, args);
   va_end(args);

   buffer[sizeOfBuffer - 1] = '\0';

   if (c < 0)
      return sizeOfBuffer - 1;

   return LZHAM_MIN(c, (int)sizeOfBuffer - 1);
}
   lzham_compress_status_t lzham_lib_compress(
      lzham_compress_state_ptr p,
      const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, 
      lzham_uint8 *pOut_buf, size_t *pOut_buf_size,
      lzham_bool no_more_input_bytes_flag)
   {
      lzham_compress_state *pState = static_cast<lzham_compress_state*>(p);

      if ((!pState) || (!pState->m_params.m_dict_size_log2) || (pState->m_status >= LZHAM_COMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE) || (!pIn_buf_size) || (!pOut_buf_size))
      {
         return LZHAM_COMP_STATUS_INVALID_PARAMETER;
      }
      
      if ((*pIn_buf_size) && (!pIn_buf))
      {
         return LZHAM_COMP_STATUS_INVALID_PARAMETER;
      }
      
      if ((!*pOut_buf_size) || (!pOut_buf))
      {
         return LZHAM_COMP_STATUS_INVALID_PARAMETER;
      }
      
      byte_vec &comp_data = pState->m_compressor.get_compressed_data();
      if (pState->m_comp_data_ofs < comp_data.size())
      {
         *pIn_buf_size = 0;
         *pOut_buf_size = LZHAM_MIN(comp_data.size() - pState->m_comp_data_ofs, *pOut_buf_size);
                  
         memcpy(pOut_buf, comp_data.get_ptr() + pState->m_comp_data_ofs, *pOut_buf_size);
         
         pState->m_comp_data_ofs += *pOut_buf_size;
         
         pState->m_status = LZHAM_COMP_STATUS_NOT_FINISHED;
         return pState->m_status;
      }
      
      comp_data.try_resize(0);
      pState->m_comp_data_ofs = 0;
      
      if (pState->m_flushed_compressor)
      {
         if ((*pIn_buf_size) || (!no_more_input_bytes_flag))
         {
            pState->m_status = LZHAM_COMP_STATUS_INVALID_PARAMETER;
            return pState->m_status;
         }
         
         *pIn_buf_size = 0;
         *pOut_buf_size = 0;
         
         pState->m_status = LZHAM_COMP_STATUS_SUCCESS;
         return pState->m_status;
      }
      
      const size_t cMaxBytesToPutPerIteration = 4*1024*1024;
      size_t bytes_to_put = LZHAM_MIN(cMaxBytesToPutPerIteration, *pIn_buf_size);
      const bool consumed_entire_input_buf = (bytes_to_put == *pIn_buf_size);

      if (bytes_to_put)
      {
         if (!pState->m_compressor.put_bytes(pIn_buf, (uint)bytes_to_put))
         {
            *pIn_buf_size = 0;
            *pOut_buf_size = 0;
            
            pState->m_status = LZHAM_COMP_STATUS_FAILED;
            return pState->m_status;
         }
      }
      
      if ((consumed_entire_input_buf) && (no_more_input_bytes_flag) && (!pState->m_flushed_compressor))
      {
         if (!pState->m_compressor.put_bytes(NULL, 0))
         {
            *pIn_buf_size = 0;
            *pOut_buf_size = 0;

            pState->m_status = LZHAM_COMP_STATUS_FAILED;
            return pState->m_status;
         }  
         pState->m_flushed_compressor = true;  
      }
                  
      *pIn_buf_size = bytes_to_put;
      
      *pOut_buf_size = LZHAM_MIN(comp_data.size() - pState->m_comp_data_ofs, *pOut_buf_size);   
      if (*pOut_buf_size)
      {
         memcpy(pOut_buf, comp_data.get_ptr() + pState->m_comp_data_ofs, *pOut_buf_size);

         pState->m_comp_data_ofs += *pOut_buf_size;
      }
      
      if ((no_more_input_bytes_flag) && (pState->m_flushed_compressor) && (pState->m_comp_data_ofs >= comp_data.size()))
         pState->m_status = LZHAM_COMP_STATUS_SUCCESS;
      else if ((consumed_entire_input_buf) && (!no_more_input_bytes_flag) && (pState->m_comp_data_ofs >= comp_data.size()))
         pState->m_status = LZHAM_COMP_STATUS_NEEDS_MORE_INPUT;
      else
         pState->m_status = LZHAM_COMP_STATUS_NOT_FINISHED;
      
      return pState->m_status;  
   }      
Exemple #6
0
   lzham_compress_status_t LZHAM_CDECL lzham_lib_compress2(
      lzham_compress_state_ptr p,
      const lzham_uint8 *pIn_buf, size_t *pIn_buf_size,
      lzham_uint8 *pOut_buf, size_t *pOut_buf_size,
      lzham_flush_t flush_type)
   {
      lzham_compress_state *pState = static_cast<lzham_compress_state*>(p);

      if ((!pState) || (!pState->m_params.m_dict_size_log2) || (pState->m_status >= LZHAM_COMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE) || (!pIn_buf_size) || (!pOut_buf_size))
         return LZHAM_COMP_STATUS_INVALID_PARAMETER;

      if ((*pIn_buf_size) && (!pIn_buf))
         return LZHAM_COMP_STATUS_INVALID_PARAMETER;

      if ((!*pOut_buf_size) || (!pOut_buf))
         return LZHAM_COMP_STATUS_INVALID_PARAMETER;

      byte_vec &comp_data = pState->m_compressor.get_compressed_data();
      size_t num_bytes_written_to_out_buf = 0;
      if (pState->m_comp_data_ofs < comp_data.size())
      {
         size_t n = LZHAM_MIN(comp_data.size() - pState->m_comp_data_ofs, *pOut_buf_size);

         memcpy(pOut_buf, comp_data.get_ptr() + pState->m_comp_data_ofs, n);

         pState->m_comp_data_ofs += n;

         const bool has_no_more_output = (pState->m_comp_data_ofs >= comp_data.size());
         if (has_no_more_output)
         {
            pOut_buf += n;
            *pOut_buf_size -= n;
            num_bytes_written_to_out_buf += n;
         }
         else
         {
            *pIn_buf_size = 0;
            *pOut_buf_size = n;
            pState->m_status = LZHAM_COMP_STATUS_HAS_MORE_OUTPUT;
            return pState->m_status;
         }
      }

      comp_data.try_resize(0);
      pState->m_comp_data_ofs = 0;

      if (pState->m_finished_compression)
      {
         if ((*pIn_buf_size) || (flush_type != LZHAM_FINISH))
         {
            pState->m_status = LZHAM_COMP_STATUS_INVALID_PARAMETER;
            return pState->m_status;
         }

         *pIn_buf_size = 0;
         *pOut_buf_size = num_bytes_written_to_out_buf;

         pState->m_status = LZHAM_COMP_STATUS_SUCCESS;
         return pState->m_status;
      }

      const size_t cMaxBytesToPutPerIteration = 4*1024*1024;
      size_t bytes_to_put = LZHAM_MIN(cMaxBytesToPutPerIteration, *pIn_buf_size);
      const bool consumed_entire_input_buf = (bytes_to_put == *pIn_buf_size);

      if (bytes_to_put)
      {
         if (!pState->m_compressor.put_bytes(pIn_buf, (uint)bytes_to_put))
         {
            *pIn_buf_size = 0;
            *pOut_buf_size = num_bytes_written_to_out_buf;
            pState->m_status = LZHAM_COMP_STATUS_FAILED;
            return pState->m_status;
         }
      }

      if ((consumed_entire_input_buf) && (flush_type != LZHAM_NO_FLUSH))
      {
         if ((flush_type == LZHAM_SYNC_FLUSH) || (flush_type == LZHAM_FULL_FLUSH) || (flush_type == LZHAM_TABLE_FLUSH))
         {
            if (!pState->m_compressor.flush(flush_type))
            {
               *pIn_buf_size = 0;
               *pOut_buf_size = num_bytes_written_to_out_buf;
               pState->m_status = LZHAM_COMP_STATUS_FAILED;
               return pState->m_status;
            }
         }
         else if (!pState->m_finished_compression)
         {
            if (!pState->m_compressor.put_bytes(NULL, 0))
            {
               *pIn_buf_size = 0;
               *pOut_buf_size = num_bytes_written_to_out_buf;
               pState->m_status = LZHAM_COMP_STATUS_FAILED;
               return pState->m_status;
            }
            pState->m_finished_compression = true;
         }
      }

      size_t num_comp_bytes_to_output = LZHAM_MIN(comp_data.size() - pState->m_comp_data_ofs, *pOut_buf_size);
      if (num_comp_bytes_to_output)
      {
         memcpy(pOut_buf, comp_data.get_ptr() + pState->m_comp_data_ofs, num_comp_bytes_to_output);

         pState->m_comp_data_ofs += num_comp_bytes_to_output;
      }

      *pIn_buf_size = bytes_to_put;
      *pOut_buf_size = num_bytes_written_to_out_buf + num_comp_bytes_to_output;

      const bool has_no_more_output = (pState->m_comp_data_ofs >= comp_data.size());
      if ((has_no_more_output) && (flush_type == LZHAM_FINISH) && (pState->m_finished_compression))
         pState->m_status = LZHAM_COMP_STATUS_SUCCESS;
      else if ((has_no_more_output) && (consumed_entire_input_buf) && (flush_type == LZHAM_NO_FLUSH))
         pState->m_status = LZHAM_COMP_STATUS_NEEDS_MORE_INPUT;
      else
         pState->m_status = has_no_more_output ? LZHAM_COMP_STATUS_NOT_FINISHED : LZHAM_COMP_STATUS_HAS_MORE_OUTPUT;

      return pState->m_status;
   }