Exemple #1
0
CCompressionProcessor::EStatus CZipCompressor::Finish(
    char* out_buf, size_t  out_size,
    /* out */      size_t* out_avail)
{
    *out_avail = 0;
    if ( !out_size ) {
        return eStatus_Overflow;
    }
    LIMIT_SIZE_PARAM_U(out_size);

    // Default behavior on empty data -- don't write header/footer
    if ( !GetProcessedSize()  &&  !F_ISSET(fAllowEmptyData) ) {
        return eStatus_EndOfData;
    }

    // Write gzip file header if not done yet
    size_t header_len = 0;
    if ( F_ISSET(fWriteGZipFormat)  &&  m_NeedWriteHeader ) {
        header_len = s_WriteGZipHeader(out_buf, out_size, &m_FileInfo);
        if (!header_len) {
            SetError(-1, "Cannot write gzip header");
            return eStatus_Overflow;
        }
        // IncreaseOutputSize()
        // -- will be called below, and it will count 'header_len'
        m_NeedWriteHeader = false;
    }

    // Finish compression
    STREAM->next_in   = 0;
    STREAM->avail_in  = 0;
    STREAM->next_out  = (unsigned char*)out_buf + header_len;
    STREAM->avail_out = (unsigned int)(out_size - header_len);

    int errcode = deflate(STREAM, Z_FINISH);
    SetError(errcode, zError(errcode));
    *out_avail = out_size - STREAM->avail_out;
    IncreaseOutputSize((unsigned long)(*out_avail));

    switch (errcode) {
    case Z_OK:
        return eStatus_Overflow;
    case Z_STREAM_END:
        // Write .gz file footer
        if ( F_ISSET(fWriteGZipFormat) ) {
            size_t footer_len =
                s_WriteGZipFooter(out_buf + *out_avail, STREAM->avail_out,
                                  GetProcessedSize(), m_CRC32);
            if ( !footer_len ) {
                SetError(-1, "Cannot write gzip footer");
                return eStatus_Overflow;
            }
            IncreaseOutputSize((unsigned long)footer_len);
            *out_avail += footer_len;
        }
        return eStatus_EndOfData;
    }
    ERR_COMPRESS(66, FormatErrorMessage("CZipCompressor::Finish", GetProcessedSize()));
    return eStatus_Error;
}
Exemple #2
0
CCompressionProcessor::EStatus CZipCompressor::Process(
    const char* in_buf,  size_t  in_len,
    char*       out_buf, size_t  out_size,
    /* out */            size_t* in_avail,
    /* out */            size_t* out_avail)
{
    *out_avail = 0;
    if (in_len > kMax_UInt) {
        SetError(Z_STREAM_ERROR, "size of the source buffer is too big");
        ERR_COMPRESS(61, FormatErrorMessage("CZipCompressor::Process", GetProcessedSize()));
        return eStatus_Error;
    }
    if ( !out_size ) {
        return eStatus_Overflow;
    }
    LIMIT_SIZE_PARAM_U(out_size);

    size_t header_len = 0;

    // Write gzip file header
    if ( F_ISSET(fWriteGZipFormat)  &&  m_NeedWriteHeader ) {
        header_len = s_WriteGZipHeader(out_buf, out_size, &m_FileInfo);
        if (!header_len) {
            SetError(-1, "Cannot write gzip header");
            ERR_COMPRESS(62, FormatErrorMessage("CZipCompressor::Process", GetProcessedSize()));
            return eStatus_Error;
        }
        m_NeedWriteHeader = false;
    }
    STREAM->next_in   = (unsigned char*)const_cast<char*>(in_buf);
    STREAM->avail_in  = (unsigned int)in_len;
    STREAM->next_out  = (unsigned char*)out_buf + header_len;
    STREAM->avail_out = (unsigned int)(out_size - header_len);

    int errcode = deflate(STREAM, Z_NO_FLUSH);
    SetError(errcode, zError(errcode));
    *in_avail  = STREAM->avail_in;
    *out_avail = out_size - STREAM->avail_out;
    IncreaseProcessedSize((unsigned long)(in_len - *in_avail));
    IncreaseOutputSize((unsigned long)(*out_avail));

    // If we writing in gzip file format
    if ( F_ISSET(fWriteGZipFormat) ) {
        // Update the CRC32 for processed data
        m_CRC32 = crc32(m_CRC32, (unsigned char*)in_buf,
                        (unsigned int)(in_len - *in_avail));
    }
    if ( errcode == Z_OK ) {
        return eStatus_Success;
    }
    ERR_COMPRESS(63, FormatErrorMessage("CZipCompressor::Process", GetProcessedSize()));
    return eStatus_Error;
}
float SpectrumAnalyst::GetProcessedValue(float freq0, float freq1) const
{
   float bin0, bin1, binwidth;

   if (mAlg == Spectrum) {
      bin0 = freq0 * mWindowSize / mRate;
      bin1 = freq1 * mWindowSize / mRate;
   } else {
      bin0 = freq0 * mRate;
      bin1 = freq1 * mRate;
   }
   binwidth = bin1 - bin0;

   float value = float(0.0);

   if (binwidth < 1.0) {
      float binmid = (bin0 + bin1) / 2.0;
      int ibin = (int)(binmid) - 1;
      if (ibin < 1)
         ibin = 1;
      if (ibin >= GetProcessedSize() - 3)
         ibin = std::max(0, GetProcessedSize() - 4);

      value = CubicInterpolate(mProcessed[ibin],
                               mProcessed[ibin + 1],
                               mProcessed[ibin + 2],
                               mProcessed[ibin + 3], binmid - ibin);

   } else {
      if (bin0 < 0)
         bin0 = 0;
      if (bin1 >= GetProcessedSize())
         bin1 = GetProcessedSize() - 1;

      if ((int)(bin1) > (int)(bin0))
         value += mProcessed[(int)(bin0)] * ((int)(bin0) + 1 - bin0);
      bin0 = 1 + (int)(bin0);
      while (bin0 < (int)(bin1)) {
         value += mProcessed[(int)(bin0)];
         bin0 += 1.0;
      }
      value += mProcessed[(int)(bin1)] * (bin1 - (int)(bin1));

      value /= binwidth;
   }

   return value;
}
Exemple #4
0
CCompressionProcessor::EStatus CZipCompressor::Flush(
    char* out_buf, size_t  out_size,
    /* out */      size_t* out_avail)
{
    *out_avail = 0;
    if ( !out_size ) {
        return eStatus_Overflow;
    }
    LIMIT_SIZE_PARAM_U(out_size);

    STREAM->next_in   = 0;
    STREAM->avail_in  = 0;
    STREAM->next_out  = (unsigned char*)out_buf;
    STREAM->avail_out = (unsigned int)out_size;

    int errcode = deflate(STREAM, Z_SYNC_FLUSH);
    SetError(errcode, zError(errcode));
    *out_avail = out_size - STREAM->avail_out;
    IncreaseOutputSize((unsigned long)(*out_avail));

    if ( errcode == Z_OK  ||  errcode == Z_BUF_ERROR ) {
        if ( STREAM->avail_out == 0) {
            return eStatus_Overflow;
        }
        return eStatus_Success;
    }
    ERR_COMPRESS(64, FormatErrorMessage("CZipCompressor::Flush", GetProcessedSize()));
    return eStatus_Error;
}
Exemple #5
0
CCompressionProcessor::EStatus CZipCompressor::Init(void)
{
    if ( IsBusy() ) {
        // Abnormal previous session termination
        End();
    }
    // Initialize members
    Reset();
    SetBusy();

    m_CRC32 = 0;
    m_NeedWriteHeader = true;
    m_Cache.erase();

    // Initialize the compressor stream structure
    memset(STREAM, 0, sizeof(z_stream));
    // Create a compressor stream
    int errcode = deflateInit2_(STREAM, GetLevel(), Z_DEFLATED,
                                F_ISSET(fWriteGZipFormat) ? -m_WindowBits :
                                m_WindowBits,
                                m_MemLevel, m_Strategy,
                                ZLIB_VERSION, (int)sizeof(z_stream));
    SetError(errcode, zError(errcode));
    if ( errcode == Z_OK ) {
        return eStatus_Success;
    }
    ERR_COMPRESS(60, FormatErrorMessage("CZipCompressor::Init", GetProcessedSize()));
    return eStatus_Error;
}
Exemple #6
0
CCompressionProcessor::EStatus CZipDecompressor::Init(void)
{
    // Initialize members
    Reset();
    SetBusy();
    m_NeedCheckHeader = true;
    m_IsGZ = false;
    m_SkipInput = 0;
    m_Cache.erase();
    m_Cache.reserve(kMaxHeaderSize);

    // Initialize the compressor stream structure
    memset(STREAM, 0, sizeof(z_stream));
    // Create a compressor stream
    int errcode = inflateInit2_(STREAM, m_WindowBits,
                                ZLIB_VERSION, (int)sizeof(z_stream));

    SetError(errcode, zError(errcode));

    if ( errcode == Z_OK ) {
        return eStatus_Success;
    }
    ERR_COMPRESS(68, FormatErrorMessage("CZipDecompressor::Init", GetProcessedSize()));
    return eStatus_Error;
}
float SpectrumAnalyst::FindPeak(float xPos, float *pY) const
{
   float bestpeak = 0.0f;
   float bestValue = 0.0;
   if (GetProcessedSize() > 1) {
      bool up = (mProcessed[1] > mProcessed[0]);
      float bestdist = 1000000;
      for (int bin = 3; bin < GetProcessedSize() - 1; bin++) {
         bool nowUp = mProcessed[bin] > mProcessed[bin - 1];
         if (!nowUp && up) {
            // Local maximum.  Find actual value by cubic interpolation
            int leftbin = bin - 2;
            /*
            if (leftbin < 1)
               leftbin = 1;
               */
            float valueAtMax = 0.0;
            float max = leftbin + CubicMaximize(mProcessed[leftbin],
                                                mProcessed[leftbin + 1],
                                                mProcessed[leftbin + 2],
                                                mProcessed[leftbin + 3],
                                                &valueAtMax);

            float thispeak;
            if (mAlg == Spectrum)
               thispeak = max * mRate / mWindowSize;
            else
               thispeak = max / mRate;

            if (fabs(thispeak - xPos) < bestdist) {
               bestpeak = thispeak;
               bestdist = fabs(thispeak - xPos);
               bestValue = valueAtMax;
               // Should this test come after the enclosing if?
               if (thispeak > xPos)
                  break;
            }
         }
         up = nowUp;
      }
   }

   if (pY)
      *pY = bestValue;
   return bestpeak;
}
Exemple #8
0
CCompressionProcessor::EStatus CZipDecompressor::End(int abandon)
{
    int errcode = inflateEnd(STREAM);
    SetBusy(false);
    if ( abandon ||
            m_DecompressMode == eMode_TransparentRead   ||
            errcode == Z_OK ) {
        return eStatus_Success;
    }
    ERR_COMPRESS(71, FormatErrorMessage("CZipDecompressor::End", GetProcessedSize()));
    return eStatus_Error;
}
Exemple #9
0
CCompressionProcessor::EStatus CZipCompressor::End(int abandon)
{
    int errcode = deflateEnd(STREAM);
    SetBusy(false);
    if (abandon) {
        // Ignore result of deflateEnd(), because it can return an error code for empty data
        return eStatus_Success;
    }
    SetError(errcode, zError(errcode));
    if ( errcode == Z_OK ) {
        return eStatus_Success;
    }
    ERR_COMPRESS(67, FormatErrorMessage("CZipCompressor::End", GetProcessedSize()));
    return eStatus_Error;
}
Exemple #10
0
CCompressionProcessor::EStatus CZipDecompressor::Finish(
    char*   out_buf,
    size_t  out_size,
    size_t* out_avail)
{
    if (m_DecompressMode == eMode_TransparentRead) {
        return eStatus_EndOfData;
    }
    // Do not check here on eMode_Unknown. It will be processed below.
    size_t in_avail;
    // Process only if we have some data -- otherwise zlib return error
    CCompressionProcessor::EStatus status = eStatus_Success;
    if ( GetProcessedSize() || m_Cache.size() ) {
        status = Process(0, 0, out_buf, out_size, &in_avail, out_avail);
    }
    if (status == eStatus_Success  &&  *out_avail == 0) {
        // Possible case with .gz files only (check on concatenated files)
        return eStatus_EndOfData;
    }
    return status;
}
Exemple #11
0
CCompressionProcessor::EStatus CZipDecompressor::Process(
    const char* in_buf,  size_t  in_len,
    char*       out_buf, size_t  out_size,
    /* out */            size_t* in_avail,
    /* out */            size_t* out_avail)
{
    *out_avail = 0;
    if (in_len > kMax_UInt) {
        SetError(Z_STREAM_ERROR, "size of the source buffer is too big");
        ERR_COMPRESS(69, FormatErrorMessage("CZipDecompressor::Process", GetProcessedSize()));
        return eStatus_Error;
    }
    if ( !out_size ) {
        return eStatus_Overflow;
    }
    LIMIT_SIZE_PARAM_U(out_size);

    // By default we consider that data is compressed
    if ( m_DecompressMode == eMode_Unknown  &&
            !F_ISSET(fAllowTransparentRead) ) {
        m_DecompressMode = eMode_Decompress;
    }

    char*  x_in_buf = const_cast<char*>(in_buf);
    size_t x_in_len = in_len;

    // If data is compressed, or the read mode is undefined yet
    if ( m_DecompressMode != eMode_TransparentRead ) {

        // Need to skip some bytes from input stream?
        // (in case of concatenated .gz files only)
        if ( m_SkipInput ) {
            // Skip from cache if present
            if ( m_Cache.size() ) {
                size_t n = min(m_Cache.size(), m_SkipInput);
                m_Cache.erase(0, n);
                m_SkipInput -= n;
                IncreaseProcessedSize((unsigned long)n);
            }
            // And/or from input stream also
            if ( m_SkipInput ) {
                size_t n = min(x_in_len, m_SkipInput);
                x_in_buf += n;
                x_in_len -= n;
                m_SkipInput -= n;
                IncreaseProcessedSize((unsigned long)n);
                if ( m_SkipInput ) {
                    // Data block is very small... and was skipped.
                    *in_avail  = x_in_len;
                    *out_avail = 0;
                    return eStatus_Success;
                }
            }
        }

        bool   from_cache   = false;
        size_t old_avail_in = 0;

        // Check file header
        if ( F_ISSET(fCheckFileHeader) ) {
            size_t header_len = 0;
            if ( m_NeedCheckHeader ) {
                if (!x_in_buf  &&  !m_Cache.size()) {
                    // Possible Flush(), but we should refill the cache
                    // to perform header check -- so, just ignore.
                    *in_avail  = 0;
                    *out_avail = 0;
                    return eStatus_Success;
                }
                if (x_in_buf  &&  m_Cache.size() < kMaxHeaderSize) {
                    size_t n = min(kMaxHeaderSize - m_Cache.size(), x_in_len);
                    m_Cache.append(x_in_buf, n);
                    x_in_buf += n;
                    x_in_len -= n;
                    if (m_Cache.size() < kMaxHeaderSize) {
                        // Data block is very small and was fully cached.
                        *in_avail  = 0;
                        *out_avail = 0;
                        return eStatus_Success;
                    }
                }
                // Check gzip header in the buffer
                header_len = s_CheckGZipHeader(m_Cache.data(), m_Cache.size());
                _ASSERT(header_len < kMaxHeaderSize);

                // If gzip header found, skip it
                if ( header_len ) {
                    m_Cache.erase(0, header_len);
                    IncreaseProcessedSize((unsigned long)header_len);
                    m_DecompressMode = eMode_Decompress;
                    m_IsGZ = true;
                }
                // Reinit decompression stream
                inflateEnd(STREAM);
                int errcode = inflateInit2_(STREAM,
                                            m_IsGZ ? -m_WindowBits : m_WindowBits,
                                            ZLIB_VERSION,
                                            (int)sizeof(z_stream));
                SetError(errcode, zError(errcode));
                if ( errcode != Z_OK ) {
                    return eStatus_Error;
                }
                // Already skipped, or we don't have header here
                m_NeedCheckHeader = false;
            }
        }

        // Prepare STREAM for decompressing
        if ( m_Cache.size() ) {
            // Possible, we have some unprocessed data in the cache
            STREAM->next_in   = (unsigned char*)(m_Cache.data());
            STREAM->avail_in  = (unsigned int)m_Cache.size();
            STREAM->next_out  = (unsigned char*)out_buf;
            STREAM->avail_out = (unsigned int)out_size;
            from_cache        = true;
            old_avail_in      = STREAM->avail_in; // = m_Cache.size()
        } else {
            STREAM->next_in   = (unsigned char*)x_in_buf;
            STREAM->avail_in  = (unsigned int)x_in_len;
            STREAM->next_out  = (unsigned char*)out_buf;
            STREAM->avail_out = (unsigned int)out_size;
        }

        // Try to decompress data
        int errcode = inflate(STREAM, Z_SYNC_FLUSH);

        if ( m_DecompressMode == eMode_Unknown ) {
            // The flag fAllowTransparentRead is set
            _ASSERT(F_ISSET(fAllowTransparentRead));
            // Determine decompression mode for following operations
            if (errcode == Z_OK  ||  errcode == Z_STREAM_END) {
                m_DecompressMode = eMode_Decompress;
            } else {
                m_DecompressMode = eMode_TransparentRead;
            }
        }
        if ( m_DecompressMode == eMode_Decompress ) {
            SetError(errcode, zError(errcode));

            // Concatenated file? Try to process next .gz chunk, if present
            if ((errcode == Z_STREAM_END)  &&  m_IsGZ) {
                // Skip .gz file footer (8 bytes)
                if (STREAM->avail_in < 8) {
                    m_SkipInput = 8 - STREAM->avail_in;
                    STREAM->avail_in = 0;
                } else {
                    STREAM->avail_in -= 8;
                }
                if ( F_ISSET(fAllowConcatenatedGZip) ) {
                    m_NeedCheckHeader = true;
                    errcode = Z_OK;
                }
            }
            // Update count of processed data
            if ( from_cache ) {
                m_Cache.erase(0, old_avail_in - STREAM->avail_in);
                *in_avail = x_in_len;
                IncreaseProcessedSize((unsigned long)(old_avail_in - STREAM->avail_in));
            } else {
                *in_avail = STREAM->avail_in;
                IncreaseProcessedSize((unsigned long)(x_in_len - *in_avail));
                x_in_len = *in_avail;
            }
            // In case of concatenated .gz files:
            // Possible, we already skipped some bytes from cache,
            // and it should be empty now. If needed, try to skip some
            // bytes from the input stream also.
            if ( m_SkipInput ) {
                _ASSERT(m_Cache.size() == 0);
                size_t n = min(x_in_len, m_SkipInput);
                if ( n ) {
                    x_in_len -= n;
                    m_SkipInput -= n;
                    *in_avail = x_in_len;
                    IncreaseProcessedSize((unsigned long)n);
                }
            }
            *out_avail = out_size - STREAM->avail_out;
            IncreaseOutputSize((unsigned long)(*out_avail));

            // Analyze decompressor status
            switch (errcode) {
            case Z_OK:
                if ( from_cache  &&
                        STREAM->avail_in > 0  &&  *out_avail == 0) {
                    return m_NeedCheckHeader ? eStatus_Repeat : eStatus_Overflow;
                }
                return eStatus_Success;
            case Z_STREAM_END:
                return eStatus_EndOfData;
            }
            ERR_COMPRESS(70, FormatErrorMessage("CZipDecompressor::Process", GetProcessedSize()));
            return eStatus_Error;
        }
        /* else: eMode_ThansparentRead (see below) */
    }

    // Transparent read

    _ASSERT(m_DecompressMode == eMode_TransparentRead);
    size_t total = 0;
    if ( m_Cache.size() ) {
        total = min(m_Cache.size(), out_size);
        memcpy(out_buf, m_Cache.data(), total);
        m_Cache.erase(0, total);
        out_size -= total;
    }
    if (x_in_len  &&  out_size)  {
        size_t n = min(x_in_len, out_size);
        memcpy(out_buf + total, x_in_buf, n);
        total += n;
        x_in_len -= n;
    }
    *in_avail  = x_in_len;
    *out_avail = total;
    IncreaseProcessedSize((unsigned long)total);
    IncreaseOutputSize((unsigned long)total);
    return eStatus_Success;
}