Allocate stream compression buffer.

This commit is contained in:
Michael R Sweet 2025-02-16 13:20:51 -05:00
parent 44827bac1a
commit 492a4f51b2
No known key found for this signature in database
GPG Key ID: BE67C75EC81F3244
3 changed files with 46 additions and 20 deletions

View File

@ -205,7 +205,7 @@ pdfioObjCreateStream(
obj->pdf->current_obj = obj; obj->pdf->current_obj = obj;
// Return the new stream... // Return the new stream...
return (_pdfioStreamCreate(obj, length_obj, filter)); return (_pdfioStreamCreate(obj, length_obj, 0, filter));
} }

View File

@ -313,8 +313,9 @@ struct _pdfio_stream_s // Stream
z_stream flate; // Flate filter state z_stream flate; // Flate filter state
_pdfio_predictor_t predictor; // Predictor function, if any _pdfio_predictor_t predictor; // Predictor function, if any
size_t pbpixel, // Size of a pixel in bytes size_t pbpixel, // Size of a pixel in bytes
pbsize; // Predictor buffer size, if any pbsize, // Predictor buffer size, if any
unsigned char cbuffer[4096], // Compressed data buffer cbsize; // Compressed data buffer size
unsigned char *cbuffer, // Compressed data buffer
*prbuffer, // Raw buffer (previous line), as needed *prbuffer, // Raw buffer (previous line), as needed
*psbuffer; // PNG filter buffer, as needed *psbuffer; // PNG filter buffer, as needed
_pdfio_crypto_cb_t crypto_cb; // Encryption/descryption callback, if any _pdfio_crypto_cb_t crypto_cb; // Encryption/descryption callback, if any
@ -384,7 +385,7 @@ extern void *_pdfioObjGetExtension(pdfio_obj_t *obj) _PDFIO_INTERNAL;
extern bool _pdfioObjLoad(pdfio_obj_t *obj) _PDFIO_INTERNAL; extern bool _pdfioObjLoad(pdfio_obj_t *obj) _PDFIO_INTERNAL;
extern void _pdfioObjSetExtension(pdfio_obj_t *obj, void *data, _pdfio_extfree_t datafree) _PDFIO_INTERNAL; extern void _pdfioObjSetExtension(pdfio_obj_t *obj, void *data, _pdfio_extfree_t datafree) _PDFIO_INTERNAL;
extern pdfio_stream_t *_pdfioStreamCreate(pdfio_obj_t *obj, pdfio_obj_t *length_obj, pdfio_filter_t compression) _PDFIO_INTERNAL; extern pdfio_stream_t *_pdfioStreamCreate(pdfio_obj_t *obj, pdfio_obj_t *length_obj, size_t cbsize, pdfio_filter_t compression) _PDFIO_INTERNAL;
extern pdfio_stream_t *_pdfioStreamOpen(pdfio_obj_t *obj, bool decode) _PDFIO_INTERNAL; extern pdfio_stream_t *_pdfioStreamOpen(pdfio_obj_t *obj, bool decode) _PDFIO_INTERNAL;
extern bool _pdfioStringIsAllocated(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL; extern bool _pdfioStringIsAllocated(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;

View File

@ -50,7 +50,7 @@ pdfioStreamClose(pdfio_stream_t *st) // I - Stream
while ((status = deflate(&st->flate, Z_FINISH)) != Z_STREAM_END) while ((status = deflate(&st->flate, Z_FINISH)) != Z_STREAM_END)
{ {
size_t bytes = sizeof(st->cbuffer) - st->flate.avail_out, size_t bytes = st->cbsize - st->flate.avail_out,
// Bytes to write // Bytes to write
outbytes; // Actual bytes written outbytes; // Actual bytes written
@ -89,13 +89,13 @@ pdfioStreamClose(pdfio_stream_t *st) // I - Stream
} }
st->flate.next_out = (Bytef *)st->cbuffer + bytes; st->flate.next_out = (Bytef *)st->cbuffer + bytes;
st->flate.avail_out = (uInt)(sizeof(st->cbuffer) - bytes); st->flate.avail_out = (uInt)(st->cbsize - bytes);
} }
if (st->flate.avail_out < (uInt)sizeof(st->cbuffer)) if (st->flate.avail_out < (uInt)st->cbsize)
{ {
// Write any residuals... // Write any residuals...
size_t bytes = sizeof(st->cbuffer) - st->flate.avail_out; size_t bytes = st->cbsize - st->flate.avail_out;
// Bytes to write // Bytes to write
if (st->crypto_cb) if (st->crypto_cb)
@ -172,6 +172,7 @@ pdfioStreamClose(pdfio_stream_t *st) // I - Stream
st->pdf->current_obj = NULL; st->pdf->current_obj = NULL;
free(st->cbuffer);
free(st->prbuffer); free(st->prbuffer);
free(st->psbuffer); free(st->psbuffer);
free(st); free(st);
@ -190,6 +191,7 @@ pdfio_stream_t * // O - Stream or `NULL` on error
_pdfioStreamCreate( _pdfioStreamCreate(
pdfio_obj_t *obj, // I - Object pdfio_obj_t *obj, // I - Object
pdfio_obj_t *length_obj, // I - Length object, if any pdfio_obj_t *length_obj, // I - Length object, if any
size_t cbsize, // I - Size of compression buffer
pdfio_filter_t compression) // I - Compression to apply pdfio_filter_t compression) // I - Compression to apply
{ {
pdfio_stream_t *st; // Stream pdfio_stream_t *st; // Stream
@ -302,8 +304,21 @@ _pdfioStreamCreate(
else else
st->predictor = _PDFIO_PREDICTOR_NONE; st->predictor = _PDFIO_PREDICTOR_NONE;
if (cbsize == 0)
cbsize = 4096;
st->cbsize = cbsize;
if ((st->cbuffer = malloc(cbsize)) == NULL)
{
_pdfioFileError(st->pdf, "Unable to allocate %lu bytes for Flate output buffer: %s", (unsigned long)cbsize, strerror(errno));
free(st->prbuffer);
free(st->psbuffer);
free(st);
return (NULL);
}
st->flate.next_out = (Bytef *)st->cbuffer; st->flate.next_out = (Bytef *)st->cbuffer;
st->flate.avail_out = (uInt)sizeof(st->cbuffer); st->flate.avail_out = (uInt)cbsize;
if ((status = deflateInit(&(st->flate), 9)) != Z_OK) if ((status = deflateInit(&(st->flate), 9)) != Z_OK)
{ {
@ -567,11 +582,21 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
else else
st->predictor = _PDFIO_PREDICTOR_NONE; st->predictor = _PDFIO_PREDICTOR_NONE;
st->cbsize = 4096;
if ((st->cbuffer = malloc(st->cbsize)) == NULL)
{
_pdfioFileError(st->pdf, "Unable to allocate %lu bytes for Flate compression buffer.", (unsigned long)st->cbsize);
free(st->prbuffer);
free(st->psbuffer);
free(st);
return (NULL);
}
PDFIO_DEBUG("_pdfioStreamOpen: pos=%ld\n", (long)_pdfioFileTell(st->pdf)); PDFIO_DEBUG("_pdfioStreamOpen: pos=%ld\n", (long)_pdfioFileTell(st->pdf));
if (sizeof(st->cbuffer) > st->remaining) if (st->cbsize > st->remaining)
rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->remaining); rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->remaining);
else else
rbytes = _pdfioFileRead(st->pdf, st->cbuffer, sizeof(st->cbuffer)); rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->cbsize);
if (rbytes <= 0) if (rbytes <= 0)
{ {
@ -1045,10 +1070,10 @@ stream_read(pdfio_stream_t *st, // I - Stream
if (st->flate.avail_in == 0) if (st->flate.avail_in == 0)
{ {
// Read more from the file... // Read more from the file...
if (sizeof(st->cbuffer) > st->remaining) if (st->cbsize > st->remaining)
rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->remaining); rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->remaining);
else else
rbytes = _pdfioFileRead(st->pdf, st->cbuffer, sizeof(st->cbuffer)); rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->cbsize);
if (rbytes <= 0) if (rbytes <= 0)
return (-1); // End of file... return (-1); // End of file...
@ -1101,10 +1126,10 @@ stream_read(pdfio_stream_t *st, // I - Stream
if (st->flate.avail_in == 0) if (st->flate.avail_in == 0)
{ {
// Read more from the file... // Read more from the file...
if (sizeof(st->cbuffer) > st->remaining) if (st->cbsize > st->remaining)
rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->remaining); rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->remaining);
else else
rbytes = _pdfioFileRead(st->pdf, st->cbuffer, sizeof(st->cbuffer)); rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->cbsize);
if (rbytes <= 0) if (rbytes <= 0)
return (-1); // End of file... return (-1); // End of file...
@ -1171,10 +1196,10 @@ stream_read(pdfio_stream_t *st, // I - Stream
if (st->flate.avail_in == 0) if (st->flate.avail_in == 0)
{ {
// Read more from the file... // Read more from the file...
if (sizeof(st->cbuffer) > st->remaining) if (st->cbsize > st->remaining)
rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->remaining); rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->remaining);
else else
rbytes = _pdfioFileRead(st->pdf, st->cbuffer, sizeof(st->cbuffer)); rbytes = _pdfioFileRead(st->pdf, st->cbuffer, st->cbsize);
if (rbytes <= 0) if (rbytes <= 0)
return (-1); // End of file... return (-1); // End of file...
@ -1278,10 +1303,10 @@ stream_write(pdfio_stream_t *st, // I - Stream
while (st->flate.avail_in > 0) while (st->flate.avail_in > 0)
{ {
if (st->flate.avail_out < (sizeof(st->cbuffer) / 8)) if (st->flate.avail_out < (st->cbsize / 8))
{ {
// Flush the compression buffer... // Flush the compression buffer...
size_t cbytes = sizeof(st->cbuffer) - st->flate.avail_out, size_t cbytes = st->cbsize - st->flate.avail_out,
outbytes; outbytes;
if (st->crypto_cb) if (st->crypto_cb)
@ -1310,7 +1335,7 @@ stream_write(pdfio_stream_t *st, // I - Stream
} }
st->flate.next_out = (Bytef *)st->cbuffer + cbytes; st->flate.next_out = (Bytef *)st->cbuffer + cbytes;
st->flate.avail_out = (uInt)(sizeof(st->cbuffer) - cbytes); st->flate.avail_out = (uInt)(st->cbsize - cbytes);
} }
// Deflate what we can this time... // Deflate what we can this time...