mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-02 11:46:35 +00:00
9044a24097
Use get() and use_count() instead. Add #define NO_POINTERHOLDER_DEPRECATION to remove deprecation markers for these only. This commit also removes all deprecated PointerHolder API calls from qpdf's code except in PointerHolder's test suite, which must continue to test the deprecated APIs.
123 lines
3.3 KiB
C++
123 lines
3.3 KiB
C++
#include <qpdf/Pl_TIFFPredictor.hh>
|
|
#include <qpdf/QTC.hh>
|
|
#include <qpdf/BitStream.hh>
|
|
#include <qpdf/BitWriter.hh>
|
|
#include <stdexcept>
|
|
#include <vector>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
|
|
Pl_TIFFPredictor::Pl_TIFFPredictor(char const* identifier, Pipeline* next,
|
|
action_e action, unsigned int columns,
|
|
unsigned int samples_per_pixel,
|
|
unsigned int bits_per_sample) :
|
|
Pipeline(identifier, next),
|
|
action(action),
|
|
columns(columns),
|
|
samples_per_pixel(samples_per_pixel),
|
|
bits_per_sample(bits_per_sample),
|
|
pos(0)
|
|
{
|
|
if (samples_per_pixel < 1)
|
|
{
|
|
throw std::runtime_error(
|
|
"TIFFPredictor created with invalid samples_per_pixel");
|
|
}
|
|
if ((bits_per_sample < 1) ||
|
|
(bits_per_sample > (8 * (sizeof(unsigned long long)))))
|
|
{
|
|
throw std::runtime_error(
|
|
"TIFFPredictor created with invalid bits_per_sample");
|
|
}
|
|
unsigned long long bpr =
|
|
((columns * bits_per_sample * samples_per_pixel) + 7) / 8;
|
|
if ((bpr == 0) || (bpr > (UINT_MAX - 1)))
|
|
{
|
|
throw std::runtime_error(
|
|
"TIFFPredictor created with invalid columns value");
|
|
}
|
|
this->bytes_per_row = bpr & UINT_MAX;
|
|
this->cur_row = PointerHolder<unsigned char>(
|
|
true, new unsigned char[this->bytes_per_row]);
|
|
memset(this->cur_row.get(), 0, this->bytes_per_row);
|
|
}
|
|
|
|
Pl_TIFFPredictor::~Pl_TIFFPredictor()
|
|
{
|
|
}
|
|
|
|
void
|
|
Pl_TIFFPredictor::write(unsigned char* data, size_t len)
|
|
{
|
|
size_t left = this->bytes_per_row - this->pos;
|
|
size_t offset = 0;
|
|
while (len >= left)
|
|
{
|
|
// finish off current row
|
|
memcpy(this->cur_row.get() + this->pos, data + offset, left);
|
|
offset += left;
|
|
len -= left;
|
|
|
|
processRow();
|
|
|
|
// Prepare for next row
|
|
memset(this->cur_row.get(), 0, this->bytes_per_row);
|
|
left = this->bytes_per_row;
|
|
this->pos = 0;
|
|
}
|
|
if (len)
|
|
{
|
|
memcpy(this->cur_row.get() + this->pos, data + offset, len);
|
|
}
|
|
this->pos += len;
|
|
}
|
|
|
|
void
|
|
Pl_TIFFPredictor::processRow()
|
|
{
|
|
QTC::TC("libtests", "Pl_TIFFPredictor processRow",
|
|
(action == a_decode ? 0 : 1));
|
|
BitWriter bw(this->getNext());
|
|
BitStream in(this->cur_row.get(), this->bytes_per_row);
|
|
std::vector<long long> prev;
|
|
for (unsigned int i = 0; i < this->samples_per_pixel; ++i)
|
|
{
|
|
long long sample = in.getBitsSigned(this->bits_per_sample);
|
|
bw.writeBitsSigned(sample, this->bits_per_sample);
|
|
prev.push_back(sample);
|
|
}
|
|
for (unsigned int col = 1; col < this->columns; ++col)
|
|
{
|
|
for (unsigned int i = 0; i < this->samples_per_pixel; ++i)
|
|
{
|
|
long long sample = in.getBitsSigned(this->bits_per_sample);
|
|
long long new_sample = sample;
|
|
if (action == a_encode)
|
|
{
|
|
new_sample -= prev[i];
|
|
prev[i] = sample;
|
|
}
|
|
else
|
|
{
|
|
new_sample += prev[i];
|
|
prev[i] = new_sample;
|
|
}
|
|
bw.writeBitsSigned(new_sample, this->bits_per_sample);
|
|
}
|
|
}
|
|
bw.flush();
|
|
}
|
|
|
|
void
|
|
Pl_TIFFPredictor::finish()
|
|
{
|
|
if (this->pos)
|
|
{
|
|
// write partial row
|
|
processRow();
|
|
}
|
|
this->pos = 0;
|
|
memset(this->cur_row.get(), 0, this->bytes_per_row);
|
|
getNext()->finish();
|
|
}
|