summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libjpeg/src/jmemmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/libjpeg/src/jmemmgr.c')
-rw-r--r--src/3rdparty/libjpeg/src/jmemmgr.c210
1 files changed, 160 insertions, 50 deletions
diff --git a/src/3rdparty/libjpeg/src/jmemmgr.c b/src/3rdparty/libjpeg/src/jmemmgr.c
index 70b8ec0c49..dca8f5c22c 100644
--- a/src/3rdparty/libjpeg/src/jmemmgr.c
+++ b/src/3rdparty/libjpeg/src/jmemmgr.c
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
- * Copyright (C) 2016, 2021, D. R. Commander.
+ * Copyright (C) 2016, 2021-2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -37,12 +37,6 @@
#endif
#include <limits.h>
-#ifndef NO_GETENV
-#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */
-extern char *getenv(const char *name);
-#endif
-#endif
-
LOCAL(size_t)
round_up_pow2(size_t a, size_t b)
@@ -74,10 +68,13 @@ round_up_pow2(size_t a, size_t b)
* There isn't any really portable way to determine the worst-case alignment
* requirement. This module assumes that the alignment requirement is
* multiples of ALIGN_SIZE.
- * By default, we define ALIGN_SIZE as sizeof(double). This is necessary on
- * some workstations (where doubles really do need 8-byte alignment) and will
- * work fine on nearly everything. If your machine has lesser alignment needs,
- * you can save a few bytes by making ALIGN_SIZE smaller.
+ * By default, we define ALIGN_SIZE as the maximum of sizeof(double) and
+ * sizeof(void *). This is necessary on some workstations (where doubles
+ * really do need 8-byte alignment) and will work fine on nearly everything.
+ * We use the maximum of sizeof(double) and sizeof(void *) since sizeof(double)
+ * may be insufficient, for example, on CHERI-enabled platforms with 16-byte
+ * pointers and a 16-byte alignment requirement. If your machine has lesser
+ * alignment needs, you can save a few bytes by making ALIGN_SIZE smaller.
* The only place I know of where this will NOT work is certain Macintosh
* 680x0 compilers that define double as a 10-byte IEEE extended float.
* Doing 10-byte alignment is counterproductive because longwords won't be
@@ -87,7 +84,7 @@ round_up_pow2(size_t a, size_t b)
#ifndef ALIGN_SIZE /* so can override from jconfig.h */
#ifndef WITH_SIMD
-#define ALIGN_SIZE sizeof(double)
+#define ALIGN_SIZE MAX(sizeof(void *), sizeof(double))
#else
#define ALIGN_SIZE 32 /* Most of the SIMD instructions we support require
16-byte (128-bit) alignment, but AVX2 requires
@@ -158,7 +155,9 @@ typedef my_memory_mgr *my_mem_ptr;
*/
struct jvirt_sarray_control {
- JSAMPARRAY mem_buffer; /* => the in-memory buffer */
+ JSAMPARRAY mem_buffer; /* => the in-memory buffer (if
+ cinfo->data_precision is 12, then this is
+ actually a J12SAMPARRAY) */
JDIMENSION rows_in_array; /* total virtual array height */
JDIMENSION samplesperrow; /* width of array (and of memory buffer) */
JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */
@@ -354,9 +353,10 @@ alloc_small(j_common_ptr cinfo, int pool_id, size_t sizeofobject)
* request is large enough that it may as well be passed directly to
* jpeg_get_large; the pool management just links everything together
* so that we can free it all on demand.
- * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
- * structures. The routines that create these structures (see below)
- * deliberately bunch rows together to ensure a large request size.
+ * Note: the major use of "large" objects is in
+ * JSAMPARRAY/J12SAMPARRAY/J16SAMPARRAY and JBLOCKARRAY structures. The
+ * routines that create these structures (see below) deliberately bunch rows
+ * together to ensure a large request size.
*/
METHODDEF(void *)
@@ -440,9 +440,22 @@ alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow,
JSAMPROW workspace;
JDIMENSION rowsperchunk, currow, i;
long ltemp;
+ J12SAMPARRAY result12;
+ J12SAMPROW workspace12;
+#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
+ J16SAMPARRAY result16;
+ J16SAMPROW workspace16;
+#endif
+ int data_precision = cinfo->is_decompressor ?
+ ((j_decompress_ptr)cinfo)->data_precision :
+ ((j_compress_ptr)cinfo)->data_precision;
+ size_t sample_size = data_precision == 16 ?
+ sizeof(J16SAMPLE) : (data_precision == 12 ?
+ sizeof(J12SAMPLE) :
+ sizeof(JSAMPLE));
/* Make sure each row is properly aligned */
- if ((ALIGN_SIZE % sizeof(JSAMPLE)) != 0)
+ if ((ALIGN_SIZE % sample_size) != 0)
out_of_memory(cinfo, 5); /* safety check */
if (samplesperrow > MAX_ALLOC_CHUNK) {
@@ -451,11 +464,11 @@ alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow,
out_of_memory(cinfo, 9);
}
samplesperrow = (JDIMENSION)round_up_pow2(samplesperrow, (2 * ALIGN_SIZE) /
- sizeof(JSAMPLE));
+ sample_size);
/* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK - sizeof(large_pool_hdr)) /
- ((long)samplesperrow * sizeof(JSAMPLE));
+ ((long)samplesperrow * (long)sample_size);
if (ltemp <= 0)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
if (ltemp < (long)numrows)
@@ -464,24 +477,68 @@ alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow,
rowsperchunk = numrows;
mem->last_rowsperchunk = rowsperchunk;
- /* Get space for row pointers (small object) */
- result = (JSAMPARRAY)alloc_small(cinfo, pool_id,
- (size_t)(numrows * sizeof(JSAMPROW)));
+ if (data_precision == 16) {
+#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
+ /* Get space for row pointers (small object) */
+ result16 = (J16SAMPARRAY)alloc_small(cinfo, pool_id,
+ (size_t)(numrows *
+ sizeof(J16SAMPROW)));
+
+ /* Get the rows themselves (large objects) */
+ currow = 0;
+ while (currow < numrows) {
+ rowsperchunk = MIN(rowsperchunk, numrows - currow);
+ workspace16 = (J16SAMPROW)alloc_large(cinfo, pool_id,
+ (size_t)((size_t)rowsperchunk * (size_t)samplesperrow * sample_size));
+ for (i = rowsperchunk; i > 0; i--) {
+ result16[currow++] = workspace16;
+ workspace16 += samplesperrow;
+ }
+ }
- /* Get the rows themselves (large objects) */
- currow = 0;
- while (currow < numrows) {
- rowsperchunk = MIN(rowsperchunk, numrows - currow);
- workspace = (JSAMPROW)alloc_large(cinfo, pool_id,
- (size_t)((size_t)rowsperchunk * (size_t)samplesperrow *
- sizeof(JSAMPLE)));
- for (i = rowsperchunk; i > 0; i--) {
- result[currow++] = workspace;
- workspace += samplesperrow;
+ return (JSAMPARRAY)result16;
+#else
+ ERREXIT1(cinfo, JERR_BAD_PRECISION, data_precision);
+ return NULL;
+#endif
+ } else if (data_precision == 12) {
+ /* Get space for row pointers (small object) */
+ result12 = (J12SAMPARRAY)alloc_small(cinfo, pool_id,
+ (size_t)(numrows *
+ sizeof(J12SAMPROW)));
+
+ /* Get the rows themselves (large objects) */
+ currow = 0;
+ while (currow < numrows) {
+ rowsperchunk = MIN(rowsperchunk, numrows - currow);
+ workspace12 = (J12SAMPROW)alloc_large(cinfo, pool_id,
+ (size_t)((size_t)rowsperchunk * (size_t)samplesperrow * sample_size));
+ for (i = rowsperchunk; i > 0; i--) {
+ result12[currow++] = workspace12;
+ workspace12 += samplesperrow;
+ }
}
- }
- return result;
+ return (JSAMPARRAY)result12;
+ } else {
+ /* Get space for row pointers (small object) */
+ result = (JSAMPARRAY)alloc_small(cinfo, pool_id,
+ (size_t)(numrows * sizeof(JSAMPROW)));
+
+ /* Get the rows themselves (large objects) */
+ currow = 0;
+ while (currow < numrows) {
+ rowsperchunk = MIN(rowsperchunk, numrows - currow);
+ workspace = (JSAMPROW)alloc_large(cinfo, pool_id,
+ (size_t)((size_t)rowsperchunk * (size_t)samplesperrow * sample_size));
+ for (i = rowsperchunk; i > 0; i--) {
+ result[currow++] = workspace;
+ workspace += samplesperrow;
+ }
+ }
+
+ return result;
+ }
}
@@ -643,6 +700,13 @@ realize_virt_arrays(j_common_ptr cinfo)
size_t minheights, max_minheights;
jvirt_sarray_ptr sptr;
jvirt_barray_ptr bptr;
+ int data_precision = cinfo->is_decompressor ?
+ ((j_decompress_ptr)cinfo)->data_precision :
+ ((j_compress_ptr)cinfo)->data_precision;
+ size_t sample_size = data_precision == 16 ?
+ sizeof(J16SAMPLE) : (data_precision == 12 ?
+ sizeof(J12SAMPLE) :
+ sizeof(JSAMPLE));
/* Compute the minimum space needed (maxaccess rows in each buffer)
* and the maximum space needed (full image height in each buffer).
@@ -653,10 +717,10 @@ realize_virt_arrays(j_common_ptr cinfo)
for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
if (sptr->mem_buffer == NULL) { /* if not realized yet */
size_t new_space = (long)sptr->rows_in_array *
- (long)sptr->samplesperrow * sizeof(JSAMPLE);
+ (long)sptr->samplesperrow * sample_size;
space_per_minheight += (long)sptr->maxaccess *
- (long)sptr->samplesperrow * sizeof(JSAMPLE);
+ (long)sptr->samplesperrow * sample_size;
if (SIZE_MAX - maximum_space < new_space)
out_of_memory(cinfo, 10);
maximum_space += new_space;
@@ -711,7 +775,7 @@ realize_virt_arrays(j_common_ptr cinfo)
jpeg_open_backing_store(cinfo, &sptr->b_s_info,
(long)sptr->rows_in_array *
(long)sptr->samplesperrow *
- (long)sizeof(JSAMPLE));
+ (long)sample_size);
sptr->b_s_open = TRUE;
}
sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
@@ -754,8 +818,15 @@ do_sarray_io(j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
/* Do backing store read or write of a virtual sample array */
{
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
-
- bytesperrow = (long)ptr->samplesperrow * sizeof(JSAMPLE);
+ int data_precision = cinfo->is_decompressor ?
+ ((j_decompress_ptr)cinfo)->data_precision :
+ ((j_compress_ptr)cinfo)->data_precision;
+ size_t sample_size = data_precision == 16 ?
+ sizeof(J16SAMPLE) : (data_precision == 12 ?
+ sizeof(J12SAMPLE) :
+ sizeof(JSAMPLE));
+
+ bytesperrow = (long)ptr->samplesperrow * (long)sample_size;
file_offset = ptr->cur_start_row * bytesperrow;
/* Loop to read or write each allocation chunk in mem_buffer */
for (i = 0; i < (long)ptr->rows_in_mem; i += ptr->rowsperchunk) {
@@ -769,14 +840,42 @@ do_sarray_io(j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
if (rows <= 0) /* this chunk might be past end of file! */
break;
byte_count = rows * bytesperrow;
- if (writing)
- (*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
- (void *)ptr->mem_buffer[i],
- file_offset, byte_count);
- else
- (*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
- (void *)ptr->mem_buffer[i],
- file_offset, byte_count);
+ if (data_precision == 16) {
+#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
+ J16SAMPARRAY mem_buffer16 = (J16SAMPARRAY)ptr->mem_buffer;
+
+ if (writing)
+ (*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
+ (void *)mem_buffer16[i],
+ file_offset, byte_count);
+ else
+ (*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
+ (void *)mem_buffer16[i],
+ file_offset, byte_count);
+#else
+ ERREXIT1(cinfo, JERR_BAD_PRECISION, data_precision);
+#endif
+ } else if (data_precision == 12) {
+ J12SAMPARRAY mem_buffer12 = (J12SAMPARRAY)ptr->mem_buffer;
+
+ if (writing)
+ (*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
+ (void *)mem_buffer12[i],
+ file_offset, byte_count);
+ else
+ (*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
+ (void *)mem_buffer12[i],
+ file_offset, byte_count);
+ } else {
+ if (writing)
+ (*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
+ (void *)ptr->mem_buffer[i],
+ file_offset, byte_count);
+ else
+ (*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
+ (void *)ptr->mem_buffer[i],
+ file_offset, byte_count);
+ }
file_offset += byte_count;
}
}
@@ -824,6 +923,13 @@ access_virt_sarray(j_common_ptr cinfo, jvirt_sarray_ptr ptr,
{
JDIMENSION end_row = start_row + num_rows;
JDIMENSION undef_row;
+ int data_precision = cinfo->is_decompressor ?
+ ((j_decompress_ptr)cinfo)->data_precision :
+ ((j_compress_ptr)cinfo)->data_precision;
+ size_t sample_size = data_precision == 16 ?
+ sizeof(J16SAMPLE) : (data_precision == 12 ?
+ sizeof(J12SAMPLE) :
+ sizeof(JSAMPLE));
/* debugging check */
if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
@@ -879,7 +985,7 @@ access_virt_sarray(j_common_ptr cinfo, jvirt_sarray_ptr ptr,
if (writable)
ptr->first_undef_row = end_row;
if (ptr->pre_zero) {
- size_t bytesperrow = (size_t)ptr->samplesperrow * sizeof(JSAMPLE);
+ size_t bytesperrow = (size_t)ptr->samplesperrow * sample_size;
undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
end_row -= ptr->cur_start_row;
while (undef_row < end_row) {
@@ -1162,12 +1268,16 @@ jinit_memory_mgr(j_common_ptr cinfo)
*/
#ifndef NO_GETENV
{
- char *memenv;
+ char memenv[30] = { 0 };
- if ((memenv = getenv("JPEGMEM")) != NULL) {
+ if (!GETENV_S(memenv, 30, "JPEGMEM") && strlen(memenv) > 0) {
char ch = 'x';
+#ifdef _MSC_VER
+ if (sscanf_s(memenv, "%ld%c", &max_to_use, &ch, 1) > 0) {
+#else
if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
+#endif
if (ch == 'm' || ch == 'M')
max_to_use *= 1000L;
mem->pub.max_memory_to_use = max_to_use * 1000L;