Commit 661db7435145279ae81c87c837c4de263991ab8f
Committed by
GitHub
Merge pull request #1481 from m-holger/pl_dct
Refactor `Pl_DCT` buffer management to use `std::string` and simplify…
Showing
2 changed files
with
20 additions
and
28 deletions
include/qpdf/Pl_DCT.hh
| ... | ... | @@ -22,7 +22,6 @@ |
| 22 | 22 | |
| 23 | 23 | #include <qpdf/Pipeline.hh> |
| 24 | 24 | |
| 25 | -#include <qpdf/Pl_Buffer.hh> | |
| 26 | 25 | #include <cstddef> |
| 27 | 26 | #include <functional> |
| 28 | 27 | |
| ... | ... | @@ -88,9 +87,9 @@ class QPDF_DLL_CLASS Pl_DCT: public Pipeline |
| 88 | 87 | |
| 89 | 88 | private: |
| 90 | 89 | QPDF_DLL_PRIVATE |
| 91 | - void compress(void* cinfo, Buffer*); | |
| 90 | + void compress(void* cinfo); | |
| 92 | 91 | QPDF_DLL_PRIVATE |
| 93 | - void decompress(void* cinfo, Buffer*); | |
| 92 | + void decompress(void* cinfo); | |
| 94 | 93 | |
| 95 | 94 | enum action_e { a_compress, a_decompress }; |
| 96 | 95 | ... | ... |
libqpdf/Pl_DCT.cc
| ... | ... | @@ -84,7 +84,6 @@ class Pl_DCT::Members |
| 84 | 84 | J_COLOR_SPACE color_space, |
| 85 | 85 | CompressConfig* config_callback) : |
| 86 | 86 | action(a_compress), |
| 87 | - buf("DCT uncompressed image"), | |
| 88 | 87 | image_width(image_width), |
| 89 | 88 | image_height(image_height), |
| 90 | 89 | components(components), |
| ... | ... | @@ -95,8 +94,7 @@ class Pl_DCT::Members |
| 95 | 94 | |
| 96 | 95 | // For decompression |
| 97 | 96 | Members() : |
| 98 | - action(a_decompress), | |
| 99 | - buf("DCT compressed image") | |
| 97 | + action(a_decompress) | |
| 100 | 98 | { |
| 101 | 99 | } |
| 102 | 100 | |
| ... | ... | @@ -105,7 +103,7 @@ class Pl_DCT::Members |
| 105 | 103 | ~Members() = default; |
| 106 | 104 | |
| 107 | 105 | action_e action; |
| 108 | - Pl_Buffer buf; | |
| 106 | + std::string buf; | |
| 109 | 107 | |
| 110 | 108 | // Used for compression |
| 111 | 109 | JDIMENSION image_width{0}; |
| ... | ... | @@ -163,21 +161,17 @@ Pl_DCT::~Pl_DCT() = default; |
| 163 | 161 | void |
| 164 | 162 | Pl_DCT::write(unsigned char const* data, size_t len) |
| 165 | 163 | { |
| 166 | - m->buf.write(data, len); | |
| 164 | + if (len > 0) { | |
| 165 | + m->buf.append(reinterpret_cast<char const*>(data), len); | |
| 166 | + } | |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | void |
| 170 | 170 | Pl_DCT::finish() |
| 171 | 171 | { |
| 172 | - m->buf.finish(); | |
| 173 | - | |
| 174 | - // Using a std::shared_ptr<Buffer> here and passing it into compress and decompress causes a | |
| 175 | - // memory leak with setjmp/longjmp. Just use a pointer and delete it. | |
| 176 | - Buffer* b = m->buf.getBuffer(); | |
| 177 | - if (b->getSize() == 0) { | |
| 172 | + if (m->buf.empty()) { | |
| 178 | 173 | // Special case: empty data will never succeed and probably means we're calling finish a |
| 179 | 174 | // second time from an exception handler. |
| 180 | - delete b; | |
| 181 | 175 | next()->finish(); |
| 182 | 176 | return; |
| 183 | 177 | } |
| ... | ... | @@ -198,9 +192,9 @@ Pl_DCT::finish() |
| 198 | 192 | if (setjmp(jerr.jmpbuf) == 0) { |
| 199 | 193 | try { |
| 200 | 194 | if (m->action == a_compress) { |
| 201 | - compress(reinterpret_cast<void*>(&cinfo_compress), b); | |
| 195 | + compress(reinterpret_cast<void*>(&cinfo_compress)); | |
| 202 | 196 | } else { |
| 203 | - decompress(reinterpret_cast<void*>(&cinfo_decompress), b); | |
| 197 | + decompress(reinterpret_cast<void*>(&cinfo_decompress)); | |
| 204 | 198 | } |
| 205 | 199 | } catch (std::exception& e) { |
| 206 | 200 | // Convert an exception back to a longjmp so we can ensure that the right cleanup |
| ... | ... | @@ -211,7 +205,6 @@ Pl_DCT::finish() |
| 211 | 205 | } else { |
| 212 | 206 | error = true; |
| 213 | 207 | } |
| 214 | - delete b; | |
| 215 | 208 | |
| 216 | 209 | if (m->action == a_compress) { |
| 217 | 210 | jpeg_destroy_compress(&cinfo_compress); |
| ... | ... | @@ -312,7 +305,7 @@ term_buffer_source(j_decompress_ptr) |
| 312 | 305 | } |
| 313 | 306 | |
| 314 | 307 | static void |
| 315 | -jpeg_buffer_src(j_decompress_ptr cinfo, Buffer* buffer) | |
| 308 | +jpeg_buffer_src(j_decompress_ptr cinfo, std::string& buffer) | |
| 316 | 309 | { |
| 317 | 310 | cinfo->src = reinterpret_cast<jpeg_source_mgr*>( |
| 318 | 311 | // line-break |
| ... | ... | @@ -325,12 +318,12 @@ jpeg_buffer_src(j_decompress_ptr cinfo, Buffer* buffer) |
| 325 | 318 | src->skip_input_data = skip_buffer_input_data; |
| 326 | 319 | src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ |
| 327 | 320 | src->term_source = term_buffer_source; |
| 328 | - src->bytes_in_buffer = buffer->getSize(); | |
| 329 | - src->next_input_byte = buffer->getBuffer(); | |
| 321 | + src->bytes_in_buffer = buffer.size(); | |
| 322 | + src->next_input_byte = reinterpret_cast<unsigned char*>(buffer.data()); | |
| 330 | 323 | } |
| 331 | 324 | |
| 332 | 325 | void |
| 333 | -Pl_DCT::compress(void* cinfo_p, Buffer* b) | |
| 326 | +Pl_DCT::compress(void* cinfo_p) | |
| 334 | 327 | { |
| 335 | 328 | auto* cinfo = reinterpret_cast<jpeg_compress_struct*>(cinfo_p); |
| 336 | 329 | |
| ... | ... | @@ -361,13 +354,13 @@ Pl_DCT::compress(void* cinfo_p, Buffer* b) |
| 361 | 354 | unsigned int width = cinfo->image_width * QIntC::to_uint(cinfo->input_components); |
| 362 | 355 | size_t expected_size = QIntC::to_size(cinfo->image_height) * |
| 363 | 356 | QIntC::to_size(cinfo->image_width) * QIntC::to_size(cinfo->input_components); |
| 364 | - if (b->getSize() != expected_size) { | |
| 357 | + if (m->buf.size() != expected_size) { | |
| 365 | 358 | throw std::runtime_error( |
| 366 | - "Pl_DCT: image buffer size = " + std::to_string(b->getSize()) + | |
| 359 | + "Pl_DCT: image buffer size = " + std::to_string(m->buf.size()) + | |
| 367 | 360 | "; expected size = " + std::to_string(expected_size)); |
| 368 | 361 | } |
| 369 | 362 | JSAMPROW row_pointer[1]; |
| 370 | - unsigned char* buffer = b->getBuffer(); | |
| 363 | + auto buffer = reinterpret_cast<unsigned char*>(m->buf.data()); | |
| 371 | 364 | while (cinfo->next_scanline < cinfo->image_height) { |
| 372 | 365 | // We already verified that the buffer is big enough. |
| 373 | 366 | row_pointer[0] = &buffer[cinfo->next_scanline * width]; |
| ... | ... | @@ -378,7 +371,7 @@ Pl_DCT::compress(void* cinfo_p, Buffer* b) |
| 378 | 371 | } |
| 379 | 372 | |
| 380 | 373 | void |
| 381 | -Pl_DCT::decompress(void* cinfo_p, Buffer* b) | |
| 374 | +Pl_DCT::decompress(void* cinfo_p) | |
| 382 | 375 | { |
| 383 | 376 | auto* cinfo = reinterpret_cast<jpeg_decompress_struct*>(cinfo_p); |
| 384 | 377 | |
| ... | ... | @@ -395,10 +388,10 @@ Pl_DCT::decompress(void* cinfo_p, Buffer* b) |
| 395 | 388 | cinfo->mem->max_memory_to_use = memory_limit; |
| 396 | 389 | } |
| 397 | 390 | |
| 398 | - jpeg_buffer_src(cinfo, b); | |
| 391 | + jpeg_buffer_src(cinfo, m->buf); | |
| 399 | 392 | |
| 400 | 393 | (void)jpeg_read_header(cinfo, TRUE); |
| 401 | - (void)jpeg_calc_output_dimensions(cinfo); | |
| 394 | + jpeg_calc_output_dimensions(cinfo); | |
| 402 | 395 | unsigned int width = cinfo->output_width * QIntC::to_uint(cinfo->output_components); |
| 403 | 396 | if (memory_limit > 0 && |
| 404 | 397 | width > (static_cast<unsigned long>(memory_limit) / (20U * cinfo->output_height))) { | ... | ... |