1 #include <QtCore> // for qWarning()
9 #define CHUNK_SIZE 1024
11 Compressor::Compressor(QIODevice
* device
, int compression
) : device_(device
)
13 zlib_stream_
= (z_stream
*) malloc(sizeof(z_stream
));
14 zlib_stream_
->zalloc
= Z_NULL
;
15 zlib_stream_
->zfree
= Z_NULL
;
16 zlib_stream_
->opaque
= Z_NULL
;
17 int result
= deflateInit(zlib_stream_
, compression
);
18 Q_ASSERT(result
== Z_OK
);
20 connect(device
, SIGNAL(aboutToClose()), this, SLOT(flush()));
24 Compressor::~Compressor()
29 void Compressor::flush()
35 write(QByteArray(),true);
36 int result
= deflateEnd(zlib_stream_
);
38 qWarning("compressor.c: deflateEnd failed (%d)", result
);
43 int Compressor::write(const QByteArray
& input
)
45 return write(input
,false);
48 int Compressor::write(const QByteArray
& input
, bool flush
)
51 zlib_stream_
->avail_in
= input
.size();
52 zlib_stream_
->next_in
= (Bytef
*) input
.data();
56 int output_position
= 0;
58 output
.resize(output_position
+ CHUNK_SIZE
);
59 zlib_stream_
->avail_out
= CHUNK_SIZE
;
60 zlib_stream_
->next_out
= (Bytef
*) (output
.data() + output_position
);
61 result
= deflate(zlib_stream_
,(flush
? Z_FINISH
: Z_NO_FLUSH
));
62 if (result
== Z_STREAM_ERROR
) {
63 qWarning("compressor.cpp: Error ('%s')", zlib_stream_
->msg
);
66 output_position
+= CHUNK_SIZE
;
68 while (zlib_stream_
->avail_out
== 0);
69 if (zlib_stream_
->avail_in
!= 0) {
70 qWarning("Compressor: avail_in != 0");
72 output_position
-= zlib_stream_
->avail_out
;
77 output
.resize(output_position
+ CHUNK_SIZE
);
78 zlib_stream_
->avail_out
= CHUNK_SIZE
;
79 zlib_stream_
->next_out
= (Bytef
*) (output
.data() + output_position
);
80 result
= deflate(zlib_stream_
,Z_SYNC_FLUSH
);
81 if (result
== Z_STREAM_ERROR
) {
82 qWarning("compressor.cpp: Error ('%s')", zlib_stream_
->msg
);
85 output_position
+= CHUNK_SIZE
;
87 while (zlib_stream_
->avail_out
== 0);
88 output_position
-= zlib_stream_
->avail_out
;
90 output
.resize(output_position
);
92 // Write the compressed data
93 device_
->write(output
);
97 // -----------------------------------------------------------------------------
99 Decompressor::Decompressor(QIODevice
* device
) : device_(device
)
101 zlib_stream_
= (z_stream
*) malloc(sizeof(z_stream
));
102 zlib_stream_
->zalloc
= Z_NULL
;
103 zlib_stream_
->zfree
= Z_NULL
;
104 zlib_stream_
->opaque
= Z_NULL
;
105 int result
= inflateInit(zlib_stream_
);
106 Q_ASSERT(result
== Z_OK
);
108 connect(device
, SIGNAL(aboutToClose()), this, SLOT(flush()));
112 Decompressor::~Decompressor()
117 void Decompressor::flush()
123 write(QByteArray(),true);
124 int result
= inflateEnd(zlib_stream_
);
126 qWarning("compressor.c: inflateEnd failed (%d)", result
);
131 int Decompressor::write(const QByteArray
& input
)
133 return write(input
,false);
136 int Decompressor::write(const QByteArray
& input
, bool flush
)
139 zlib_stream_
->avail_in
= input
.size();
140 zlib_stream_
->next_in
= (Bytef
*) input
.data();
144 int output_position
= 0;
146 output
.resize(output_position
+ CHUNK_SIZE
);
147 zlib_stream_
->avail_out
= CHUNK_SIZE
;
148 zlib_stream_
->next_out
= (Bytef
*) (output
.data() + output_position
);
149 result
= inflate(zlib_stream_
,(flush
? Z_FINISH
: Z_NO_FLUSH
));
150 if (result
== Z_STREAM_ERROR
) {
151 qWarning("compressor.cpp: Error ('%s')", zlib_stream_
->msg
);
154 output_position
+= CHUNK_SIZE
;
156 while (zlib_stream_
->avail_out
== 0);
157 //Q_ASSERT(zlib_stream_->avail_in == 0);
158 if (zlib_stream_
->avail_in
!= 0) {
159 qWarning() << "Decompressor: Unexpected state: avail_in=" << zlib_stream_
->avail_in
<< ",avail_out=" << zlib_stream_
->avail_out
<< ",result=" << result
;
160 return Z_STREAM_ERROR
; // FIXME: Should probably return 'result'
162 output_position
-= zlib_stream_
->avail_out
;
167 output
.resize(output_position
+ CHUNK_SIZE
);
168 zlib_stream_
->avail_out
= CHUNK_SIZE
;
169 zlib_stream_
->next_out
= (Bytef
*) (output
.data() + output_position
);
170 result
= inflate(zlib_stream_
,Z_SYNC_FLUSH
);
171 if (result
== Z_STREAM_ERROR
) {
172 qWarning("compressor.cpp: Error ('%s')", zlib_stream_
->msg
);
175 output_position
+= CHUNK_SIZE
;
177 while (zlib_stream_
->avail_out
== 0);
178 output_position
-= zlib_stream_
->avail_out
;
180 output
.resize(output_position
);
182 // Write the compressed data
183 device_
->write(output
);