новые иконки в OpenBoard
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
OpenBoard/src/pdf-merger/FlateDecode.cpp

233 lines
5.3 KiB

/*
* Copyright (C) 2015-2022 Département de l'Instruction Publique (DIP-SEM)
*
* Copyright (C) 2013 Open Education Foundation
*
* Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
* l'Education Numérique en Afrique (GIP ENA)
*
* This file is part of OpenBoard.
*
* OpenBoard is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License,
* with a specific linking exception for the OpenSSL project's
* "OpenSSL" library (or with modified versions of it that use the
* same license as the "OpenSSL" library).
*
* OpenBoard 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include "FlateDecode.h"
#include "zlib.h"
#include "Utils.h"
#include <string.h>
#include "core/memcheck.h"
using namespace merge_lib;
#define ZLIB_MEM_DELTA 65535
#define ZLIB_CHECK_ERR(err,msg) \
if( err != Z_OK) {\
std::cout<<msg<<" ZLIB error:"<<err<<std::endl; \
}\
FlateDecode::FlateDecode():_predict(NULL)
{
}
FlateDecode::~FlateDecode()
{
if( _predict )
{
delete _predict;
}
}
void FlateDecode::initialize(Object * objectWithStream)
{
if( objectWithStream )
{
std::string head;
objectWithStream->getHeader(head);
if((int) head.find(FilterPredictor::DECODE_PARAM_TOKEN) != -1 )
{
_predict = new FilterPredictor();
_predict->initialize(objectWithStream);
}
}
}
/** @brief encode
*
* @todo:
document this function
*/
bool FlateDecode::encode(std::string &decoded)
{
z_stream stream;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
size_t out_len = 0;
unsigned char *out_p = NULL;
stream.next_out = out_p;
stream.avail_out = (uInt)out_len;
stream.next_in = (unsigned char*)decoded.c_str();
stream.avail_in = (uInt)decoded.size();
int err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
ZLIB_CHECK_ERR(err, "deflateInit");
if ( err != Z_OK )
{
return false;
}
bool toContinue = false;
int flush = Z_NO_FLUSH;
do
{
toContinue = false;
flush = (stream.avail_in == 0)?Z_FINISH:Z_NO_FLUSH;
if ( !stream.avail_out )
{
// increase the space
out_p = (unsigned char*)realloc(out_p,out_len + ZLIB_MEM_DELTA);
// init new memory
unsigned char *new_out_start = out_p + out_len;
memset(new_out_start,0,ZLIB_MEM_DELTA);
// Point next_out to the next unused byte
stream.next_out = new_out_start;
// Update the size of the buffer
stream.avail_out = (uInt)ZLIB_MEM_DELTA;
out_len += ZLIB_MEM_DELTA;
}
err = deflate(&stream,flush);
if ( err == Z_OK && stream.avail_out == 0 )
{
toContinue = true;
}
}
while ( toContinue || flush == Z_NO_FLUSH );
err = deflateEnd(&stream);
ZLIB_CHECK_ERR(err, "deflateEnd");
if( err != Z_OK )
{
free(out_p);
return false;
}
decoded = std::string((char*)out_p,stream.total_out);
free(out_p);
return true;
}
/** @brief decode
*
* @todo: document this function
*/
bool FlateDecode::decode(std::string & encoded)
{
z_stream stream;
//some initialization of ZLIB stuff
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
//trace_hex((char*)encoded.c_str(),encoded.size());
stream.next_in = (unsigned char*)encoded.c_str();
stream.avail_in = (uInt)encoded.size();
int err = inflateInit(&stream);
ZLIB_CHECK_ERR(err,"InflateInit");
if ( err != Z_OK )
{
return false;
}
unsigned char *out_p = NULL;
int out_len = 0;
stream.next_out = out_p;
stream.avail_out = out_len;
for (;;)
{
if ( !stream.avail_out)
{
// there is no more space for deallocation - increase the space
out_p = (unsigned char*)realloc(out_p,out_len + ZLIB_MEM_DELTA);
// init new memory
unsigned char *new_out_start = out_p + out_len;
memset(new_out_start,0,ZLIB_MEM_DELTA);
// Point next_out to the next unused byte
stream.next_out = new_out_start;
// Update the size of the uncompressed buffer
stream.avail_out = (uInt)ZLIB_MEM_DELTA;
out_len += ZLIB_MEM_DELTA;
}
err = inflate(&stream,Z_NO_FLUSH);
if ( err == Z_STREAM_END)
{
break;
}
ZLIB_CHECK_ERR(err,"Deflate");
if ( err != Z_OK )
{
if( out_p )
{
free(out_p);
}
return false;
}
}
err = inflateEnd(&stream);
ZLIB_CHECK_ERR(err,"InflateEnd");
if( err != Z_OK )
{
if( out_p )
{
free(out_p);
}
return false;
}
encoded = std::string((char*)out_p,stream.total_out);
free(out_p);
// trace_hex((char*)encoded.c_str(),encoded.size());
// if predictor exists for that object, then lets decode it
if( _predict )
{
_predict->decode(encoded);
}
return true;
}