2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../core/juce_StandardHeader.h"
28 namespace zlibNamespace
30 #if JUCE_INCLUDE_ZLIB_CODE
33 #include "zlib/zlib.h"
42 #include "juce_GZIPCompressorOutputStream.h"
44 //==============================================================================
45 class GZIPCompressorOutputStream::GZIPCompressorHelper
48 GZIPCompressorHelper (const int compressionLevel
, const int windowBits
)
51 compLevel (compressionLevel
),
54 streamIsValid (false),
58 using namespace zlibNamespace
;
61 streamIsValid
= (deflateInit2 (&stream
, compLevel
, Z_DEFLATED
,
62 windowBits
!= 0 ? windowBits
: MAX_WBITS
,
63 8, strategy
) == Z_OK
);
66 ~GZIPCompressorHelper()
68 using namespace zlibNamespace
;
73 bool needsInput() const noexcept
78 void setInput (const uint8
* const newData
, const int size
) noexcept
84 int doNextBlock (uint8
* const dest
, const int destSize
) noexcept
86 using namespace zlibNamespace
;
89 stream
.next_in
= const_cast <uint8
*> (data
);
90 stream
.next_out
= dest
;
91 stream
.avail_in
= dataSize
;
92 stream
.avail_out
= destSize
;
94 const int result
= setParams
? deflateParams (&stream
, compLevel
, strategy
)
95 : deflate (&stream
, shouldFinish
? Z_FINISH
: Z_NO_FLUSH
);
103 // Deliberate fall-through..
105 data
+= dataSize
- stream
.avail_in
;
106 dataSize
= stream
.avail_in
;
108 return destSize
- stream
.avail_out
;
118 enum { gzipCompBufferSize
= 32768 };
121 zlibNamespace::z_stream stream
;
123 int dataSize
, compLevel
, strategy
;
124 bool setParams
, streamIsValid
;
127 bool finished
, shouldFinish
;
130 //==============================================================================
131 GZIPCompressorOutputStream::GZIPCompressorOutputStream (OutputStream
* const destStream_
,
132 int compressionLevel
,
133 const bool deleteDestStream
,
134 const int windowBits
)
135 : destStream (destStream_
, deleteDestStream
),
136 buffer ((size_t) GZIPCompressorHelper::gzipCompBufferSize
)
138 if (compressionLevel
< 1 || compressionLevel
> 9)
139 compressionLevel
= -1;
141 helper
= new GZIPCompressorHelper (compressionLevel
, windowBits
);
144 GZIPCompressorOutputStream::~GZIPCompressorOutputStream()
149 //==============================================================================
150 void GZIPCompressorOutputStream::flushInternal()
152 if (! helper
->finished
)
154 helper
->shouldFinish
= true;
156 while (! helper
->finished
)
163 void GZIPCompressorOutputStream::flush()
168 bool GZIPCompressorOutputStream::write (const void* destBuffer
, int howMany
)
170 if (! helper
->finished
)
172 helper
->setInput (static_cast <const uint8
*> (destBuffer
), howMany
);
174 while (! helper
->needsInput())
184 bool GZIPCompressorOutputStream::doNextBlock()
186 const int len
= helper
->doNextBlock (buffer
, (int) GZIPCompressorHelper::gzipCompBufferSize
);
187 return len
<= 0 || destStream
->write (buffer
, len
);
190 int64
GZIPCompressorOutputStream::getPosition()
192 return destStream
->getPosition();
195 bool GZIPCompressorOutputStream::setPosition (int64
/*newPosition*/)
197 jassertfalse
; // can't do it!