Skip to content

Commit

Permalink
Support compression
Browse files Browse the repository at this point in the history
  • Loading branch information
attah committed Jan 27, 2024
1 parent 0a92748 commit a4880af
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ippdecode: bytestream.o ippmsg.o ippattr.o ippdecode.o
$(CXX) $^ -o $@

ippclient: ippmsg.o ippattr.o ippprintjob.o printparameters.o ippclient.o curlrequester.o minimime.o pdf2printable.o ppm2pwg.o baselinify.o bytestream.o
$(CXX) $^ $(shell pkg-config --libs poppler-glib) -ljpeg -lcurl -o $@
$(CXX) $^ $(shell pkg-config --libs poppler-glib) -ljpeg -lcurl -lz -o $@

minimime: minimime_main.o minimime.o bytestream.o
$(CXX) $^ -o $@
Expand Down
76 changes: 62 additions & 14 deletions lib/curlrequester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ void CurlRequester::doRun()
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &buf);
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, write_callback);

CURLcode res = curl_easy_perform(_curl);

_result = res;
_result = curl_easy_perform(_curl);
_resultMsg = buf;
});
}
Expand Down Expand Up @@ -75,6 +73,7 @@ bool CurlIppPosterBase::write(const void* data, size_t size)
memcpy(_data, data, size);
_size = size;
_offset = 0;
_compression = _nextCompression;
_canRead.unlock();
return true;
}
Expand Down Expand Up @@ -103,24 +102,70 @@ size_t CurlIppPosterBase::requestWrite(char* dest, size_t size)
if(!_reading)
{
_canRead.lock();
if(_done)
{
return 0;
}
_reading = true;
}

size_t actualSize = std::min(size, (_size - _offset));
size_t remaining = (_size - _offset);
size_t bytesWritten = 0;

memcpy(dest, (_data+_offset), actualSize);
_offset += actualSize;
if(_compression != Compression::None)
{
_zstrm.next_out = (Bytef*)dest;
_zstrm.avail_out = size;
_zstrm.next_in = (_data + _offset);
_zstrm.avail_in = remaining;
deflate(&_zstrm, _done ? Z_FINISH : Z_NO_FLUSH);
_offset += (remaining - _zstrm.avail_in);
bytesWritten = size - _zstrm.avail_out;
}
else // No compression = memcpy
{
bytesWritten = std::min(size, remaining);
memcpy(dest, (_data+_offset), bytesWritten);
_offset += bytesWritten;
}

if(_offset == _size)
if(!_done)
{
_reading = false;
_canWrite.unlock();
if(_offset == _size)
{ // End of input
_reading = false;
_canWrite.unlock();
}
if(bytesWritten == 0)
{ // Compression produced no output this time,
// we'll most likely have gone to write mode,
// keep waiting.
return requestWrite(dest, size);
}
}
return actualSize;

return bytesWritten;
}

void CurlIppPosterBase::setCompression(Compression compression)
{
if(_nextCompression != Compression::None)
{
throw std::logic_error("unsetting/changing compression");
}
_nextCompression = compression;

_zstrm.zalloc = Z_NULL;
_zstrm.zfree = Z_NULL;
_zstrm.opaque = Z_NULL;

int level = 11;
if(compression == Compression::Deflate)
{
level *= -1;
}
else if(compression == Compression::Gzip)
{
level += 16;
}

deflateInit2(&_zstrm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, level, 7, Z_DEFAULT_STRATEGY);
}

CurlIppPosterBase::CurlIppPosterBase(std::string addr, bool ignoreSslErrors, bool verbose)
Expand All @@ -146,6 +191,9 @@ CURLcode CurlIppPosterBase::await(Bytestream* data)
}

_done = true;
_data = Array<uint8_t>(0);
_size = 0;
_offset = 0;
_canRead.unlock();
return CurlRequester::await(data);
}
Expand Down
13 changes: 13 additions & 0 deletions lib/curlrequester.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@
#endif

#include <curl/curl.h>
#include <zlib.h>
#include "lthread.h"
#include <array.h>
#include <bytestream.h>
#include <mutex>

enum class Compression
{
None = 0,
Deflate,
Gzip
};

class CurlRequester
{
public:
Expand Down Expand Up @@ -64,6 +72,9 @@ class CurlRequester
CURL* _curl;
struct curl_slist* _opts = NULL;

z_stream _zstrm;
Compression _nextCompression = Compression::None;
Compression _compression = Compression::None;
LThread _worker;
};

Expand All @@ -76,6 +87,8 @@ class CurlIppPosterBase : public CurlRequester
bool give(Bytestream& bts);
size_t requestWrite(char* dest, size_t size);

void setCompression(Compression compression);

static size_t trampoline(char* dest, size_t size, size_t nmemb, void* userp)
{
CurlIppPosterBase* cid = (CurlIppPosterBase*)userp;
Expand Down
32 changes: 27 additions & 5 deletions lib/ippprintjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ Error IppPrintJob::finalize(std::string inputFormat, int pages)
return Error("Failed to determine traget format");
}

if(MiniMime::isPrinterRaster(targetFormat))
{
List<std::string> compressionSupported = compression.getSupported();
if(compressionSupported.contains("gzip"))
{
compression.set("gzip");
}
else if(compressionSupported.contains("deflate"))
{
compression.set("deflate");
}
}

if(!printParams.setPaperSize(media.get(printParams.paperSizeName)))
{
return Error("Invalid paper size name");
Expand Down Expand Up @@ -437,12 +450,21 @@ Error IppPrintJob::doPrint(std::string addr, std::string inFile, ConvertFun conv
CurlIppStreamer cr(addr, true, verbose);
cr.write((char*)(hdr.raw()), hdr.size());

if(compression.get() == "gzip")
{
cr.setCompression(Compression::Gzip);
}
else if(compression.get() == "deflate")
{
cr.setCompression(Compression::Deflate);
}

WriteFun writeFun([&cr](unsigned char const* buf, unsigned int len) -> bool
{
if(len == 0)
return true;
return cr.write((const char*)buf, len);
});
{
if(len == 0)
return true;
return cr.write((const char*)buf, len);
});

ProgressFun progressFun([verbose](size_t page, size_t total) -> void
{
Expand Down
1 change: 1 addition & 0 deletions lib/ippprintjob.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class IppPrintJob
ChoiceSetting<std::string> scaling = ChoiceSetting<std::string>(&_printerAttrs, &jobAttrs, IppMsg::Keyword, "print-scaling");

ChoiceSetting<std::string> documentFormat = ChoiceSetting<std::string>(&_printerAttrs, &opAttrs, IppMsg::MimeMediaType, "document-format");
ChoiceSetting<std::string> compression = ChoiceSetting<std::string>(&_printerAttrs, &opAttrs, IppMsg::Keyword, "compression");

ChoiceSetting<std::string> mediaType = ChoiceSetting<std::string>(&_printerAttrs, &jobAttrs, IppMsg::Keyword, "media-type", "media-col");
ChoiceSetting<std::string> mediaSource = ChoiceSetting<std::string>(&_printerAttrs, &jobAttrs, IppMsg::Keyword, "media-source", "media-col");
Expand Down
2 changes: 1 addition & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
LDFLAGS = -ldl -Wl,--export-dynamic -lcurl -ljpeg $(shell pkg-config --libs poppler-glib)
LDFLAGS = -ldl -Wl,--export-dynamic -lcurl -ljpeg $(shell pkg-config --libs poppler-glib) -lz
CXXFLAGS = -std=c++17 -g -pedantic -Wall -Werror -Wextra -I ../lib -I ../bytestream \
$(shell pkg-config --cflags poppler-glib)
TEST_INCLUDES = -I ../lib -I ../bytestream/minitest -I ../bytestream/minitest/tests
Expand Down

0 comments on commit a4880af

Please sign in to comment.