Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Thema: Probleme mit "zlib" unter c++

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
20.08.2003, 14:22 Uhr
~cuser
Gast


beim dekomprimieren mit der inflate-funktion enstehen seqenzen mit diesen zeichen "ð­º" sowie zeilenunbrüche dazwischen. die gesamtlänge des zurückgegebenen ist ca. so groß wie die komprimierten daten.

bin ein "EXPERTE" in c++, ich hoffe mir kann trotzdem geholfen werden...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
20.08.2003, 14:24 Uhr
0xdeadbeef
Gott
(Operator)


Zeig mal den Code her.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
20.08.2003, 14:28 Uhr
~cuser
Gast


Hier der Code
noch ein bissl unsauber:

C++:
byte *compr ;
  uLong comprLen = PDFFontFileCompressed[2].Length();
  uLong uncomprLen = 1000;
  compr    = (byte*)calloc((uInt)comprLen+1, 1);
  uncompr  = (byte*)calloc((uInt)uncomprLen, 1);
  int err1, err2, err3;
  z_stream d_stream; /* decompression stream */
  int output;

  strcpy((char*)uncompr, "mist");
  memcpy(compr, PDFFontFileCompressed[2].c_str(), PDFFontFileCompressed[2].Length());

  d_stream.zalloc = (alloc_func)0;
  d_stream.zfree = (free_func)0;
  d_stream.opaque = (voidpf)0;
  d_stream.next_in  = compr;
  d_stream.avail_in = 0;
  d_stream.next_out = uncompr;

  err1 = inflateInit(&d_stream);
  
  while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
         d_stream.avail_in = d_stream.avail_out = 1;
         err2 = inflate(&d_stream, Z_FINISH);
         if (err2 == Z_STREAM_END) break;
  }
err3 = inflateEnd(&d_stream);



--edit: Pablo. [ cpp ] tags eingefügt --

Dieser Post wurde am 20.08.2003 um 14:31 Uhr von Pablo Yanez Trujillo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
20.08.2003, 14:32 Uhr
~cuser
Gast


hab noch was vergessen: deklaration von "uncompr" und auslesen is woanders. da dürfte der fehler aber nich sein.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
20.08.2003, 15:07 Uhr
virtual
Sexiest Bit alive
(Operator)


Zunächstmal ist der Code ziemlich ineffizient: Du machst euinen inflate Aufruf um jeweils ein 1 Byte zu extrahieren.
Der parameter Z_FINISH ist IMHO Unsinn:

Zitat:

If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much output as possible to the output buffer. The flushing behavior of inflate is not specified for values of the flush parameter other than Z_SYNC_FLUSH and Z_FINISH, but the current implementation actually flushes as much output as possible anyway.
inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed ; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster routine may be used for the single inflate() call.


Insbesondere der Fettgedruckte Teil scheint mir bei einem Byte ausgabepuffer nicht gegeben.
Tja, und dann noch ein Problem: Du ignorierst geflissentlich alle Fehler, die so auftreten können. inflateEnd hätte zB bereits den Fehler zurückliefern können, daß es Fehlergeschlagen ist, gleiches gilt für die anderen zlib Routinen.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
20.08.2003, 16:19 Uhr
~cuser
Gast


danke das du dich mit dem problem beschäftigst.

der code den ich geposted habe ist ein test-code mit zur fehlerfindung. er ist nicht sauber. die fehler die fehlerauswertung habe ich nicht geposted um den code nicht zu groß zu machen.

es wird aber kein fehler zurückgegeben. nach der ausführung des progis haben die fehler(ints) folgende werte.

err1 = 0; (keine fehler)
err2 = 1; (dekomp bis zum ende abgeschlossen)
err3 = 0; (kein fehler)

avail_out: habe ich schon verschiedene größen getestet. es ändert sich nix.

mfg cuser...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
20.08.2003, 16:25 Uhr
virtual
Sexiest Bit alive
(Operator)


Wart mal, bis ich @home bin, da habe ich ein wenig Code zu dem Thema rumliegen, der auch funktioniert. Poste ich dann mal. Wo machst Du das eigentlich ? Linux oder Windows?
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
20.08.2003, 16:28 Uhr
0xdeadbeef
Gott
(Operator)


ts, ts. Virtual, wenn schon Goffelsprech, dann auch @~.

~ sweet ~...
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 20.08.2003 um 16:28 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
20.08.2003, 16:32 Uhr
~cuser
Gast


Umgebung: win2000; bcb6e

wäre super wenn du mir helfen kannst...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
20.08.2003, 17:47 Uhr
virtual
Sexiest Bit alive
(Operator)


Leider ist der komplette Source etwas zu lang, um ihnim Forum zu posten. Ich poste mal die Auszüge, die meines Erachtens die für Dich wichtigen sind:

C++:
/** Wrapper class for the zlib uncompression functions.
* This is a small wrapper class for the low level function of the zlib to
* uncompress data. The usage of this class is fairly simple: the constructor
* expects two parameters that specify where to read the compressed data
* (a STL istream object) and which format to be used. After that \ref begin()
* must be called to start the uncompression. Then the uncompressed data can be
* get using \ref uncompress(). The uncompression is finalized calling \ref
* end().
*
* \note    If the input stream is noz capable of seeking, obey the following
*          restrictions:
*          The input must not consist of more than one data unit, and the
*            input must not comply to the format specified by RFC 1952.
*          In futires versions these restrictions might be dropped.
* \note     All methods sign errors by throwing \ref ZLibException.
*
* \sa ZLibCompressor, ZLibException
*/

class ZLibUncompressor
{
//    === CONSTANTS =============================================================
public:
    /** Status information.
     * These constants define the different states of \ref ZLibUncompressor.
     * -# The instance is in \c IDLE state right after construction or after
     *   \ref end() was called. The only valid action is to call \ref begin().
     * -# If in \c UNCOMPRESSING state the next valid actions are \ref
     *   uncompress() to extract more data from the compressed input or
     *   \ref end() to end uncompression.
     * -# if in \c ENDOFSTREAM state the next valid action is \ref end(),
     *    Since this state indicates the end of the current data unit.
     * -# If in \c ERROR state then something bad happened and the only valid
     *   action is \ref end() to end the uncompression and cleanup.
     * One may get the current status using \ref getState()
     */

    enum STATE
    {
        IDLE,
        UNCOMPRESSING,
        ENDOFSTREAM,
        ERROR
    };

//    === ATTRIBUTES ============================================================
private:
    /**    Internal buffer size.
     * This specifies the size of the buffer that temporarily keeps the data
     * when reading from input. A buffer of this size is assigned to
     * the \ref m_strmZ. The buffer is \ref m_pcBuffer.
     */

    static const size_t c_nBufferSize = 4096;

    /** Internal state.
     * This member contains the current status of the instance. It is one of
     * the \ref STATE constants.
     */

    STATE m_nState;
    
    /**    
     * Control structure for communication with the zlib. most of the zlib
     * function require a pointer to this structure, which contains information
     * where to read and where to write data.
     */
    
    z_stream m_strmZ;

    /** Control structuer for zlib.
     * This is a pointer to the input stream that contains the compressed
     * source data. It is set by the constructor.
     */

    std::istream* m_pstrmIn;

    /** Internal buffer.
     * This is the buffer that is temporarily used to store compressed input
     * data before reading it into the final destination buffer. The buffer
     * size is defined in \ref c_nBufferSize. A pointer to this buffer is
     * used in \ref m_strmZ.
     */

    Bytef m_pcBuffer[c_nBufferSize];

    /** RFC 1952 compliancy.
     * This flag indicates, whether the compressed input conforms to the RFC
     * 1952 and is compatible with the format written by gzip.If \c false, it
     * does not conform to that RFC and the zlib header is searched when
     * reading the input instead of the gzip header. The value of this flag
     * is set by the constructor.
     */

    bool m_bGZIPFormat;

    /** CRC checksum.
     * This contains the CRC of the data uncompressed so far. It is only
     * updated, if \ref m_bGZIPFormat is \c true
     */

    uint32_t m_nCRC32;

    ...
}
...


void
ZLibUncompressor::readFromStream()
{
    if (!m_pstrmIn->eof())
    {
        m_pstrmIn->read(reinterpret_cast<char*>(m_pcBuffer), c_nBufferSize);
        m_strmZ.next_in = m_pcBuffer;
        m_strmZ.avail_in = m_pstrmIn->gcount();

        if (!m_pstrmIn->eof() && !m_pstrmIn->good())
        {
            m_nState = ERROR;
            throw ZLibException("stream problem: cannot read");
        }
    }
}
    

// ----------------------------------------------------------------------------


void
ZLibUncompressor::readTrailer()
{
    uint32_t nCRC32;
    uint32_t nSize;

    m_pstrmIn->read(reinterpret_cast<char*>(&nCRC32), sizeof(nCRC32));
    m_pstrmIn->read(reinterpret_cast<char*>(&nSize), sizeof(nSize));

    try
    {
        
    if (!m_pstrmIn->good())
    {
        m_nState = ERROR;
        throw ZLibException("stream problem: cannot read");
    }
    if (nCRC32 != m_nCRC32)
    {
        m_nState = ERROR;
        throw ZLibException("CRC checksum incorrect");
    }
    if (nSize != m_strmZ.total_out)
    {
        m_nState = ERROR;
        throw ZLibException("size differs from expected size");
    }
    }
    catch (std::exception& ex)
    {
        std::cerr<<ex.what()<<std::endl;
        throw;
    }
    
}


// ----------------------------------------------------------------------------


void
ZLibUncompressor::begin()
{
    int nReturn = Z_OK;

    //
    // Check state
    //
    if (IDLE != m_nState)
        throw ZLibException("Bad sequence: not in IDLE state.");
    
    //
    // Init zlib
    //
    std::memset(&m_strmZ, 0, sizeof(m_strmZ));
    nReturn = inflateInit2(&m_strmZ, m_bGZIPFormat? -15:15);
    if (Z_OK != nReturn)
    {
        if (m_strmZ.msg)
            throw ZLibException(m_strmZ.msg);
        else
            throw ZLibException(nReturn);
    }
    m_nCRC32 = 0;
    m_strUnitName = "";
    m_nState = UNCOMPRESSING;

    //
    // fetch header information, if requested
    //
    if (m_bGZIPFormat)
    {
        readHeader();
    }

}

// ----------------------------------------------------------------------------


size_t
ZLibUncompressor::uncompress(
        char* p_pcOutput,
        size_t p_nLen)
{
    int nReturn = Z_OK;

    //
    // Check state
    //
    if (UNCOMPRESSING!=m_nState && ENDOFSTREAM!=m_nState)
        throw ZLibException("Bad sequence: neither UNCOMPRESSING "
                            "nor ENDOFSTREAM state.");

    //
    // Set up output buffer
    //
    m_strmZ.next_out = reinterpret_cast<Bytef*>(const_cast<char*>(p_pcOutput));
    m_strmZ.avail_out = p_nLen;

    //
    // Loop until everything is uncompressed or out buffer full
    //
    while (m_strmZ.avail_out>0 && ENDOFSTREAM!=m_nState)
    {
        //
        // If no input is available, get new
        //
        if (0==m_strmZ.avail_in)
        {
            if (m_pstrmIn->eof())
            {
                m_nState = ERROR;
                throw ZLibException("unexpected end of file");
            }
            readFromStream();
        }

        //
        // Decompress next portion, if not end of stream
        //
        if (ENDOFSTREAM != m_nState)
        {
            nReturn = inflate(&m_strmZ, Z_NO_FLUSH);
            if (Z_OK != nReturn)
            {    
                m_nState = nReturn==Z_STREAM_END? ENDOFSTREAM:ERROR;
                if (ERROR == m_nState)
                {
                    if (m_strmZ.msg)
                        throw ZLibException(m_strmZ.msg);
                    else
                        throw ZLibException(nReturn);
                }else
                {
                    m_pstrmIn->clear();
                }
            }        
        }
    }

    //
    // Update CRC, if requested
    //
    if (m_bGZIPFormat)
    {
        m_nCRC32 = crc32(m_nCRC32,
                         reinterpret_cast<Bytef*>(p_pcOutput),
                         p_nLen-m_strmZ.avail_out);
    }

    return p_nLen-m_strmZ.avail_out;
}


// ----------------------------------------------------------------------------


void
ZLibUncompressor::end()
{
    if (IDLE == m_nState)
        throw ZLibException("Bad sequence: in IDLE state.");

    //
    // seek to the real end of uncompressed data (we might fetched some    
    // bytes too much)
    //
    m_pstrmIn->seekg(-m_strmZ.avail_in, std::ios::cur);
    m_strmZ.next_in = NULL;
    m_strmZ.avail_in = 0;
    
    //
    // Check trailer (makes sense only in case that state is ENDOFSTREAM
    //
    try
    {
        if (ENDOFSTREAM==m_nState && m_bGZIPFormat)
        {
            readTrailer();
        }
    }
    catch (...)
    {
        inflateEnd(&m_strmZ);
        m_nState = IDLE;
        throw;
    }

    //
    // Finish decompression
    //
    int nReturn = inflateEnd(&m_strmZ);
    m_nState = IDLE;
    if (Z_OK != nReturn)
    {
        if (m_strmZ.msg)
            throw ZLibException(m_strmZ.msg);
        else
            throw ZLibException(nReturn);
    }

}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: