PDA

View Full Version : LZW (.Z files, uncompress/compress in linux) library?



falconium
17th April 2011, 05:16
Hi,

Does anyone know about a library for handling LZW compressed files?
ZLIB/Quazip doesn't handle these, as that is only good for deflate method.

My aim is to uncompress files from *.z files, so compression is not needed.

Thanks!

falconium
17th April 2011, 22:46
I have successfully found a wrapper for GZIP using LZW compression, but I could only manage to compile it as a console application the way you can see it in the included files.
If I want to add the same source and header to my GUI application, it doesn't find <iostream>. I don't know why, since it is able to compile as console application in a different project.
Does anyone know why it fails to compile as GUI?

I think that an expert could make a QT-compliant wrapper easily from it. I failed to do this, since I'm a newbie, and the compile error is:

In file included from ..\NESA\gzstream.c:29:
..\NESA/gzstream.h:34:20: error: iostream: No such file or directory
..\NESA/gzstream.h:35:19: error: fstream: No such file or directory
In file included from ..\NESA\gzstream.c:29:
..\NESA/gzstream.h:46: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'gzstreambuf'
..\NESA/gzstream.h:75: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'gzstreambase'
..\NESA/gzstream.h:93: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'igzstream'
..\NESA/gzstream.h:104: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'ogzstream'
...etc...

The only difference between .pro files is:

Console project:

QT += core
QT -= gui
TARGET = gzstream
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app

GUI project:

QT += core gui xml
TARGET = NESA
TEMPLATE = app

The working combination is here (so others can also use it to uncompress .z files), but somehow it adds additional line breaks for some reason:

gzstream.h:


// ================================================== ==========================
// gzstream, C++ iostream classes wrapping the zlib compression library.
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ================================================== ==========================
//
// File : gzstream.h
// Revision : $Revision: 1.5 $
// Revision_date : $Date: 2002/04/26 23:30:15 $
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
//
// Standard streambuf implementation following Nicolai Josuttis, "The
// Standard C++ Library".
// ================================================== ==========================

#ifndef GZSTREAM_H
#define GZSTREAM_H 1

// standard C++ with new header file names and std:: namespace
#include <iostream>
#include <fstream>
#include <../../../gzip/zip/zlib.h>

#ifdef GZSTREAM_NAMESPACE
namespace GZSTREAM_NAMESPACE {
#endif

// ----------------------------------------------------------------------------
// Internal classes to implement gzstream. See below for user classes.
// ----------------------------------------------------------------------------

class gzstreambuf : public std::streambuf {
private:
static const int bufferSize = 47+256; // size of data buff
// totals 512 bytes under g++ for igzstream at the end.

gzFile file; // file handle for compressed file
char buffer[bufferSize]; // data buffer
char opened; // open/close state of stream
int mode; // I/O mode

int flush_buffer();
public:
gzstreambuf() : opened(0) {
setp( buffer, buffer + (bufferSize-1));
setg( buffer + 4, // beginning of putback area
buffer + 4, // read position
buffer + 4); // end position
// ASSERT: both input & output capabilities will not be used together
}
int is_open() { return opened; }
gzstreambuf* open( const char* name, int open_mode);
gzstreambuf* close();
~gzstreambuf() { close(); }

virtual int overflow( int c = EOF);
virtual int underflow();
virtual int sync();
};

class gzstreambase : virtual public std::ios {
protected:
gzstreambuf buf;
public:
gzstreambase() { init(&buf); }
gzstreambase( const char* name, int open_mode);
~gzstreambase();
void open( const char* name, int open_mode);
void close();
gzstreambuf* rdbuf() { return &buf; }
};

// ----------------------------------------------------------------------------
// User classes. Use igzstream and ogzstream analogously to ifstream and
// ofstream respectively. They read and write files based on the gz*
// function interface of the zlib. Files are compatible with gzip compression.
// ----------------------------------------------------------------------------

class igzstream : public gzstreambase, public std::istream {
public:
igzstream() : std::istream( &buf) {}
igzstream( const char* name, int open_mode = std::ios::in)
: gzstreambase( name, open_mode), std::istream( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::in) {
gzstreambase::open( name, open_mode);
}
};

class ogzstream : public gzstreambase, public std::ostream {
public:
ogzstream() : std::ostream( &buf) {}
ogzstream( const char* name, int mode = std::ios::out)
: gzstreambase( name, mode), std::ostream( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::out) {
gzstreambase::open( name, open_mode);
}
};

#ifdef GZSTREAM_NAMESPACE
} // namespace GZSTREAM_NAMESPACE
#endif

#endif // GZSTREAM_H
// ================================================== ==========================
// EOF //



gzstream.c:


// ================================================== ==========================
// gzstream, C++ iostream classes wrapping the zlib compression library.
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ================================================== ==========================
//
// File : gzstream.C
// Revision : $Revision: 1.7 $
// Revision_date : $Date: 2003/01/08 14:41:27 $
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
//
// Standard streambuf implementation following Nicolai Josuttis, "The
// Standard C++ Library".
// ================================================== ==========================

#include <gzstream.h>
#include <iostream>
#include <string.h> // for memcpy

#ifdef GZSTREAM_NAMESPACE
namespace GZSTREAM_NAMESPACE {
#endif

// ----------------------------------------------------------------------------
// Internal classes to implement gzstream. See header file for user classes.
// ----------------------------------------------------------------------------

// --------------------------------------
// class gzstreambuf:
// --------------------------------------

gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {
if ( is_open())
return (gzstreambuf*)0;
mode = open_mode;
// no append nor read/write mode
if ((mode & std::ios::ate) || (mode & std::ios::app)
|| ((mode & std::ios::in) && (mode & std::ios::out)))
return (gzstreambuf*)0;
char fmode[10];
char* fmodeptr = fmode;
if ( mode & std::ios::in)
*fmodeptr++ = 'r';
else if ( mode & std::ios::out)
*fmodeptr++ = 'w';
*fmodeptr++ = 'b';
*fmodeptr = '\0';
file = gzopen( name, fmode);
if (file == 0)
return (gzstreambuf*)0;
opened = 1;
return this;
}

gzstreambuf * gzstreambuf::close() {
if ( is_open()) {
sync();
opened = 0;
if ( gzclose( file) == Z_OK)
return this;
}
return (gzstreambuf*)0;
}

int gzstreambuf::underflow() { // used for input buffer only
if ( gptr() && ( gptr() < egptr()))
return * reinterpret_cast<unsigned char *>( gptr());

if ( ! (mode & std::ios::in) || ! opened)
return EOF;
// Josuttis' implementation of inbuf
int n_putback = gptr() - eback();
if ( n_putback > 4)
n_putback = 4;
memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);

int num = gzread( file, buffer+4, bufferSize-4);
if (num <= 0) // ERROR or EOF
return EOF;

// reset buffer pointers
setg( buffer + (4 - n_putback), // beginning of putback area
buffer + 4, // read position
buffer + 4 + num); // end of buffer

// return next character
return * reinterpret_cast<unsigned char *>( gptr());
}

int gzstreambuf::flush_buffer() {
// Separate the writing of the buffer from overflow() and
// sync() operation.
int w = pptr() - pbase();
if ( gzwrite( file, pbase(), w) != w)
return EOF;
pbump( -w);
return w;
}

int gzstreambuf::overflow( int c) { // used for output buffer only
if ( ! ( mode & std::ios::out) || ! opened)
return EOF;
if (c != EOF) {
*pptr() = c;
pbump(1);
}
if ( flush_buffer() == EOF)
return EOF;
return c;
}

int gzstreambuf::sync() {
// Changed to use flush_buffer() instead of overflow( EOF)
// which caused improper behavior with std::endl and flush(),
// bug reported by Vincent Ricard.
if ( pptr() && pptr() > pbase()) {
if ( flush_buffer() == EOF)
return -1;
}
return 0;
}

// --------------------------------------
// class gzstreambase:
// --------------------------------------

gzstreambase::gzstreambase( const char* name, int mode) {
init( &buf);
open( name, mode);
}

gzstreambase::~gzstreambase() {
buf.close();
}

void gzstreambase::open( const char* name, int open_mode) {
if ( ! buf.open( name, open_mode))
clear( rdstate() | std::ios::badbit);
}

void gzstreambase::close() {
if ( buf.is_open())
if ( ! buf.close())
clear( rdstate() | std::ios::badbit);
}

#ifdef GZSTREAM_NAMESPACE
} // namespace GZSTREAM_NAMESPACE
#endif

// ================================================== ==========================
// EOF //


main.c:


// ================================================== ==========================
// gzstream, C++ iostream classes wrapping the zlib compression library.
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ================================================== ==========================
//
// File : test_gunzip.C
// Revision : $Revision: 1.3 $
// Revision_date : $Date: 2001/10/04 15:09:28 $
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
//
// Short test program reading a file, uncompressing it, and writing it.
// ================================================== ==========================

#include <gzstream.h>
#include <iostream>
#include <fstream>
#include <stdlib.h>

int main( int argc, char*argv[]) {
if ( argc != 3) {
std::cerr << "Usage: " << argv[0] <<" <in-file> <out-file>\n";
return EXIT_FAILURE;
}
// check alternate way of opening file
igzstream in2;
in2.open( argv[1]);
if ( ! in2.good()) {
std::cerr << "ERROR: Opening file `" << argv[1] << "' failed.\n";
return EXIT_FAILURE;
}
in2.close();
if ( ! in2.good()) {
std::cerr << "ERROR: Closing file `" << argv[1] << "' failed.\n";
return EXIT_FAILURE;
}
// now use the shorter way with the constructor to open the same file
igzstream in( argv[1]);
if ( ! in.good()) {
std::cerr << "ERROR: Opening file `" << argv[1] << "' failed.\n";
return EXIT_FAILURE;
}
std::ofstream out( argv[2]);
if ( ! out.good()) {
std::cerr << "ERROR: Opening file `" << argv[2] << "' failed.\n";
return EXIT_FAILURE;
}
char c;
while ( in.get(c))
out << c;
in.close();
out.close();
if ( ! in.eof()) {
std::cerr << "ERROR: Reading file `" << argv[1] << "' failed.\n";
return EXIT_FAILURE;
}
if ( ! out.good()) {
std::cerr << "ERROR: Writing file `" << argv[2] << "' failed.\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

// ================================================== ==========================
// EOF


Project file:

#-------------------------------------------------
#
# Project created by QtCreator 2011-04-17T03:53:26
#
#-------------------------------------------------

QT += core

QT -= gui

TARGET = gzstream
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app


SOURCES += test_gunzip.C \
gzstream.C

HEADERS += \
gzstream.h


Added after 4 minutes:

ZLIB is also needed for this wrapper, so maybe ZLIB does support .Z files too, not just deflation in .ZIP files, but yet I'm too weak to find out how I could use it without a wrapper.

Added after 9 minutes:

Is there something (e.g. a switch) included in its makefile of the original project which why it is able to use <iostream>?


# ================================================== ==========================
# gzstream, C++ iostream classes wrapping the zlib compression library.
# Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# ================================================== ==========================
#
# File : Makefile
# Revision : $Revision: 1.3 $
# Revision_date : $Date: 2001/10/04 15:09:28 $
# Author(s) : Deepak Bandyopadhyay, Lutz Kettner
#
# ================================================== ==========================

# ----------------------------------------------------------------------------
# adapt these settings to your need:
# add '-DGZSTREAM_NAMESPACE=name' to CPPFLAGS to place the classes
# in its own namespace. Note, this macro needs to be set while creating
# the library as well while compiling applications based on it.
# As an alternative, gzstream.C and gzstream.h can be edited.
# ----------------------------------------------------------------------------

# CXX = CC -n32 -LANG:std # for SGI Irix 6.5, MIPSpro CC version 7.30
CXX = g++ # for Linux RedHat 6.1, g++ version 2.95.2

CPPFLAGS = -I. -O
LDFLAGS = -L. -lgzstream -lz
AR = ar cr

# ----------------------------------------------------------------------------
# plain simple rules to make and cleanup the library:
# make default; compiles the library
# make test; compiles and executes test. O.K. message marks success.
# make clean; removes temporary files
# make cleanall; removes temporary files, the library, and programs
# ----------------------------------------------------------------------------

default: libgzstream.a

test: test_gzip test_gunzip
./test_gzip COPYING.LIB gz.tmp.gz
gunzip gz.tmp.gz
diff COPYING.LIB gz.tmp
gzip gz.tmp
./test_gunzip gz.tmp.gz gz.tmp
diff COPYING.LIB gz.tmp
rm gz.tmp.gz gz.tmp
# *** O.K. Test finished successfully. ***

gzstream.o : gzstream.C gzstream.h
${CXX} ${CPPFLAGS} -c -o gzstream.o gzstream.C

test_gzip.o : test_gzip.C gzstream.h
${CXX} ${CPPFLAGS} -c -o test_gzip.o test_gzip.C

test_gunzip.o : test_gunzip.C gzstream.h
${CXX} ${CPPFLAGS} -c -o test_gunzip.o test_gunzip.C

libgzstream.a : gzstream.o
${AR} libgzstream.a gzstream.o

test_gzip : test_gzip.o libgzstream.a
${CXX} -o test_gzip test_gzip.o ${LDFLAGS}

test_gunzip : test_gunzip.o libgzstream.a
${CXX} -o test_gunzip test_gunzip.o ${LDFLAGS}

clean :
rm *.o

cleanall :
rm *.o libgzstream.a test_gzip test_gunzip

# ================================================== ==========================
# EOF

squidge
17th April 2011, 22:53
Your trying to include a C++ header file from a C project.

Try changing your project to a C++ project and trying again.

(GCC detects this via the file extension, so you should rename your .c to .cpp or pass the appropriate options if you wish to keep the same file extension)

The original makefile specifies that the .c files should be compiled with the C++ compiler.

falconium
17th April 2011, 23:07
YEeeeees! Thank you very much, squidge!!!
Changing the extension from .C to .CPP did the trick! I owe you one!