1 /* 2 For general Scribus (>=1.3.2) copyright and licensing information please refer 3 to the COPYING file provided with the program. Following this notice may exist 4 a copyright and/or license notice that predates the release of Scribus 1.3.2 5 for which a new license (GPL+exception) is in place. 6 */ 7 8 /* Code inspired by cairo and adapted for Scribus by Jean Ghali */ 9 10 #include "scstreamfilter_flate.h" 11 12 #include <cstdlib> 13 #include <zlib.h> 14 15 #include <QDataStream> 16 17 #define BUFFER_SIZE 16384 18 struct ScFlateEncodeFilterData 19 { 20 z_stream zlib_stream; 21 unsigned char input_buffer [BUFFER_SIZE]; 22 unsigned char output_buffer[BUFFER_SIZE]; 23 }; 24 ScFlateEncodeFilter(QDataStream * stream)25ScFlateEncodeFilter::ScFlateEncodeFilter(QDataStream* stream) 26 : ScStreamFilter(stream) 27 { 28 m_filterData = nullptr; 29 m_openedFilter = false; 30 } 31 ScFlateEncodeFilter(ScStreamFilter * filter)32ScFlateEncodeFilter::ScFlateEncodeFilter(ScStreamFilter* filter) 33 : ScStreamFilter(filter) 34 { 35 m_filterData = nullptr; 36 m_openedFilter = false; 37 } 38 ~ScFlateEncodeFilter()39ScFlateEncodeFilter::~ScFlateEncodeFilter() 40 { 41 if (m_filterData && m_openedFilter) 42 closeFilter(); 43 freeData(); 44 } 45 freeData()46void ScFlateEncodeFilter::freeData() 47 { 48 if (m_filterData) 49 free (m_filterData); 50 m_filterData = nullptr; 51 } 52 openFilter()53bool ScFlateEncodeFilter::openFilter() 54 { 55 freeData(); 56 57 m_filterData = (ScFlateEncodeFilterData*) malloc(sizeof(ScFlateEncodeFilterData)); 58 if (m_filterData == nullptr) 59 return false; 60 61 m_filterData->zlib_stream.zalloc = Z_NULL; 62 m_filterData->zlib_stream.zfree = Z_NULL; 63 m_filterData->zlib_stream.opaque = Z_NULL; 64 65 if (deflateInit (&m_filterData->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK) 66 { 67 freeData(); 68 return false; 69 } 70 71 m_filterData->zlib_stream.next_in = m_filterData->input_buffer; 72 m_filterData->zlib_stream.avail_in = 0; 73 m_filterData->zlib_stream.next_out = m_filterData->output_buffer; 74 m_filterData->zlib_stream.avail_out = BUFFER_SIZE; 75 76 m_openedFilter = ScStreamFilter::openFilter(); 77 return m_openedFilter; 78 } closeFilter()79bool ScFlateEncodeFilter::closeFilter() 80 { 81 bool closeSucceed = writeDeflate(true); 82 deflateEnd (&m_filterData->zlib_stream); 83 m_openedFilter = false; 84 closeSucceed &= ScStreamFilter::closeFilter(); 85 return closeSucceed; 86 } 87 writeData(const char * data,int dataLen)88bool ScFlateEncodeFilter::writeData(const char* data, int dataLen) 89 { 90 bool deflateSuccess = true; 91 unsigned int count; 92 const unsigned char *p = (const unsigned char *) data; 93 94 if (!m_filterData) 95 return false; 96 97 while (dataLen) { 98 count = dataLen; 99 if (count > BUFFER_SIZE - m_filterData->zlib_stream.avail_in) 100 count = BUFFER_SIZE - m_filterData->zlib_stream.avail_in; 101 memcpy (m_filterData->input_buffer + m_filterData->zlib_stream.avail_in, p, count); 102 p += count; 103 m_filterData->zlib_stream.avail_in += count; 104 dataLen -= count; 105 106 if (m_filterData->zlib_stream.avail_in == BUFFER_SIZE) 107 deflateSuccess &= writeDeflate(false); 108 } 109 110 return deflateSuccess; 111 } 112 writeDeflate(bool flush)113bool ScFlateEncodeFilter::writeDeflate(bool flush) 114 { 115 int ret; 116 bool deflateSuccess = true; 117 bool finished; 118 119 do { 120 ret = deflate (&m_filterData->zlib_stream, flush ? Z_FINISH : Z_NO_FLUSH); 121 if (flush || m_filterData->zlib_stream.avail_out == 0) 122 { 123 deflateSuccess &= writeDataInternal((const char*) m_filterData->output_buffer, BUFFER_SIZE - m_filterData->zlib_stream.avail_out); 124 m_filterData->zlib_stream.next_out = m_filterData->output_buffer; 125 m_filterData->zlib_stream.avail_out = BUFFER_SIZE; 126 } 127 128 finished = true; 129 if (m_filterData->zlib_stream.avail_in != 0) 130 finished = false; 131 if (flush && ret != Z_STREAM_END) 132 finished = false; 133 134 } while (!finished); 135 136 m_filterData->zlib_stream.next_in = m_filterData->input_buffer; 137 return deflateSuccess; 138 } 139