Merge commit 'de5f92937857cccc45080c59c6236561416e5ece' into libraw-copylib
Upgrade LibRaw to 0.21.2.
This commit is contained in:
@@ -1,3 +1,25 @@
|
||||
2023-12-19 Alex Tutubalin <lexa@lexa.ru>
|
||||
|
||||
LibRaw 0.21.2-Release
|
||||
|
||||
* New compile-defined limit LIBRAW_MAX_PROFILE_SIZE_MB:
|
||||
limits allocation/read size for embedded color profile (default: 256Mb)
|
||||
|
||||
* Embedded color profile allocation/read size: limited by input file size.
|
||||
|
||||
* Multiple fixes (mostly inspired by oss-fuzz) to improve library stability and/or input checks.
|
||||
|
||||
* raw-identify: use fallback if PATH_MAX not available
|
||||
|
||||
* Disabled color conversion for Canon 16-bit thumbnails
|
||||
|
||||
* docs/changelog: explained the case when no thumbnail is found in specific file
|
||||
|
||||
* swapXX renamed to libraw_swapXX to avoid name conflict
|
||||
|
||||
* better striped thumbnails handling
|
||||
|
||||
|
||||
2023-01-05 Alex Tutubalin <lexa@lexa.ru>
|
||||
LibRaw 0.21.1-Release
|
||||
* fixed typo in panasonic metadata parser
|
||||
@@ -52,7 +74,11 @@
|
||||
|
||||
Notes:
|
||||
- Only TIFF-based and CR3 files are parsed for thumbnail list, other formats will have
|
||||
thumbcount = 1 (or 0 if no thumbnail found in file).
|
||||
thumbcount = 1.
|
||||
|
||||
- If no thumbnails are found in file: thumbcount will be set to 1 and
|
||||
thumblist[0] will be initialized with data from thumbnail fields,
|
||||
so LibRaw::unpack_thumb_ex(0) will do the same as LibRaw::unpack_thumb()
|
||||
|
||||
- Thumbnail image size may be unknown (not recorded in metadata), in this case twidth and theight are zero.
|
||||
Usually small(er) thumbnails will always have twidth/theight filled, while largest one may have these fields set to zero.
|
||||
|
||||
@@ -427,6 +427,12 @@
|
||||
<dd>Thumbnail data offset in file</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
Note: even if no thumbnails were found in TIFF/CR3 structure, the
|
||||
thumbcount field will be initialized to 1 and thumblist[0] will be
|
||||
initialized to thumbnail data from the thumbnail data, so
|
||||
LibRaw::unpack_thumb_ex(0) will do the same as LibRaw::unpack_thumb().
|
||||
</p>
|
||||
<p><a name="libraw_lensinfo_t"></a></p>
|
||||
<h3>Structure libraw_lensinfo_t: parsed lens data</h3>
|
||||
|
||||
@@ -24,6 +24,10 @@ it under the terms of the one of two licenses as you choose:
|
||||
#define LIBRAW_MAX_ALLOC_MB_DEFAULT 2048L
|
||||
#endif
|
||||
|
||||
#ifndef LIBRAW_MAX_PROFILE_SIZE_MB
|
||||
#define LIBRAW_MAX_PROFILE_SIZE_MB 256LL
|
||||
#endif
|
||||
|
||||
#ifndef LIBRAW_MAX_NONDNG_RAW_FILE_SIZE
|
||||
#define LIBRAW_MAX_NONDNG_RAW_FILE_SIZE 2147483647ULL
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@ it under the terms of the one of two licenses as you choose:
|
||||
|
||||
#define LIBRAW_MAJOR_VERSION 0
|
||||
#define LIBRAW_MINOR_VERSION 21
|
||||
#define LIBRAW_PATCH_VERSION 1
|
||||
#define LIBRAW_PATCH_VERSION 2
|
||||
#define LIBRAW_VERSION_TAIL Release
|
||||
|
||||
#define LIBRAW_SHLIB_CURRENT 23
|
||||
|
||||
@@ -40,7 +40,11 @@ it under the terms of the one of two licenses as you choose:
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
#ifndef MAX_PATH
|
||||
#ifdef PATH_MAX
|
||||
#define MAX_PATH PATH_MAX
|
||||
#else
|
||||
#define MAX_PATH 4096
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -577,6 +577,9 @@ void LibRaw::lossless_jpeg_load_raw()
|
||||
i = jidx / (cr2_slice[1] * raw_height);
|
||||
if ((j = i >= cr2_slice[0]))
|
||||
i = cr2_slice[0];
|
||||
if(!cr2_slice[1+j])
|
||||
throw LIBRAW_EXCEPTION_IO_CORRUPT;
|
||||
|
||||
jidx -= i * (cr2_slice[1] * raw_height);
|
||||
row = jidx / cr2_slice[1 + j];
|
||||
col = jidx % cr2_slice[1 + j] + i * cr2_slice[1];
|
||||
@@ -609,10 +612,16 @@ void LibRaw::canon_sraw_load_raw()
|
||||
int saved_w = width, saved_h = height;
|
||||
char *cp;
|
||||
|
||||
if(!image)
|
||||
throw LIBRAW_EXCEPTION_IO_CORRUPT;
|
||||
|
||||
if (!ljpeg_start(&jh, 0) || jh.clrs < 4)
|
||||
return;
|
||||
jwide = (jh.wide >>= 1) * jh.clrs;
|
||||
|
||||
if (jwide < 32 || jwide > 65535)
|
||||
throw LIBRAW_EXCEPTION_IO_CORRUPT;
|
||||
|
||||
if (load_flags & 256)
|
||||
{
|
||||
width = raw_width;
|
||||
@@ -1170,6 +1179,8 @@ void LibRaw::panasonic_load_raw()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (load_flags >= 0x4000)
|
||||
throw LIBRAW_EXCEPTION_IO_CORRUPT;
|
||||
for (row = 0; row < raw_height; row++)
|
||||
{
|
||||
checkCancel();
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
void LibRaw::sony_arq_load_raw()
|
||||
{
|
||||
int row, col;
|
||||
if (imgdata.idata.filters || imgdata.idata.colors < 3)
|
||||
throw LIBRAW_EXCEPTION_IO_CORRUPT;
|
||||
|
||||
read_shorts(imgdata.rawdata.raw_image,
|
||||
imgdata.sizes.raw_width * imgdata.sizes.raw_height * 4);
|
||||
libraw_internal_data.internal_data.input->seek(
|
||||
|
||||
@@ -556,7 +556,7 @@ _forceinline
|
||||
#else
|
||||
inline
|
||||
#endif
|
||||
void swap24(uchar *data, int len)
|
||||
void libraw_swap24(uchar *data, int len)
|
||||
{
|
||||
for (int i = 0; i < len - 2; i += 3)
|
||||
{
|
||||
@@ -572,7 +572,7 @@ _forceinline
|
||||
#else
|
||||
inline
|
||||
#endif
|
||||
void swap32(uchar *data, int len)
|
||||
void libraw_swap32(uchar *data, int len)
|
||||
{
|
||||
unsigned *d = (unsigned*)data;
|
||||
for (int i = 0; i < len / 4; i++)
|
||||
@@ -646,9 +646,9 @@ void LibRaw::uncompressed_fp_dng_load_raw()
|
||||
if (bytesps == 2 && difford)
|
||||
libraw_swab(dst, fullrowbytes);
|
||||
else if (bytesps == 3 && (libraw_internal_data.unpacker_data.order == 0x4949)) // II-16bit
|
||||
swap24(dst, fullrowbytes);
|
||||
libraw_swap24(dst, fullrowbytes);
|
||||
if (bytesps == 4 && difford)
|
||||
swap32(dst, fullrowbytes);
|
||||
libraw_swap32(dst, fullrowbytes);
|
||||
|
||||
float lmax = expandFloats(
|
||||
dst,
|
||||
|
||||
@@ -352,10 +352,17 @@ int LibRaw::phase_one_correct()
|
||||
{ /* Quadrant linearization */
|
||||
ushort lc[2][2][16], ref[16];
|
||||
int qr, qc;
|
||||
bool baddiv = false;
|
||||
for (qr = 0; qr < 2; qr++)
|
||||
for (qc = 0; qc < 2; qc++)
|
||||
for (i = 0; i < 16; i++)
|
||||
lc[qr][qc][i] = get4();
|
||||
for (qc = 0; qc < 2; qc++)
|
||||
{
|
||||
for (i = 0; i < 16; i++)
|
||||
lc[qr][qc][i] = get4();
|
||||
if (lc[qr][qc][15] == 0)
|
||||
baddiv = true;
|
||||
}
|
||||
if(baddiv)
|
||||
continue;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
int v = 0;
|
||||
|
||||
@@ -266,8 +266,9 @@ int LibRaw::unpack_thumb(void)
|
||||
tiff_ifd[pifd].strip_byte_counts_count)
|
||||
{
|
||||
// We found it, calculate final size
|
||||
unsigned total_size = 0;
|
||||
for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count; i++)
|
||||
INT64 total_size = 0;
|
||||
for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count
|
||||
&& i < tiff_ifd[pifd].strip_offsets_count; i++)
|
||||
total_size += tiff_ifd[pifd].strip_byte_counts[i];
|
||||
if (total_size != (unsigned)t_length) // recalculate colors
|
||||
{
|
||||
@@ -284,15 +285,15 @@ int LibRaw::unpack_thumb(void)
|
||||
|
||||
char *dest = T.thumb;
|
||||
INT64 pos = ID.input->tell();
|
||||
INT64 remain = T.tlength;
|
||||
|
||||
for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count &&
|
||||
i < tiff_ifd[pifd].strip_offsets_count;
|
||||
i++)
|
||||
{
|
||||
int remain = T.tlength;
|
||||
int sz = tiff_ifd[pifd].strip_byte_counts[i];
|
||||
int off = tiff_ifd[pifd].strip_offsets[i];
|
||||
if (off >= 0 && off + sz <= ID.input->size() && sz <= remain)
|
||||
INT64 off = tiff_ifd[pifd].strip_offsets[i];
|
||||
if (off >= 0 && off + sz <= ID.input->size() && sz > 0 && INT64(sz) <= remain)
|
||||
{
|
||||
ID.input->seek(off, SEEK_SET);
|
||||
ID.input->read(dest, sz, 1);
|
||||
@@ -332,13 +333,13 @@ int LibRaw::unpack_thumb(void)
|
||||
int o_bps = (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS) ? 2 : 1;
|
||||
int o_length = T.twidth * T.theight * t_colors * o_bps;
|
||||
int i_length = T.twidth * T.theight * t_colors * 2;
|
||||
if (!T.tlength)
|
||||
T.tlength = o_length;
|
||||
THUMB_SIZE_CHECKTNZ(o_length);
|
||||
|
||||
THUMB_SIZE_CHECKTNZ(o_length);
|
||||
THUMB_SIZE_CHECKTNZ(i_length);
|
||||
THUMB_SIZE_CHECKTNZ(T.tlength);
|
||||
|
||||
ushort *t_thumb = (ushort *)calloc(i_length, 1);
|
||||
if (!t_thumb)
|
||||
throw LIBRAW_EXCEPTION_ALLOC;
|
||||
ID.input->read(t_thumb, 1, i_length);
|
||||
if ((libraw_internal_data.unpacker_data.order == 0x4949) ==
|
||||
(ntohs(0x1234) == 0x1234))
|
||||
@@ -350,14 +351,18 @@ int LibRaw::unpack_thumb(void)
|
||||
{
|
||||
T.thumb = (char *)t_thumb;
|
||||
T.tformat = LIBRAW_THUMBNAIL_BITMAP16;
|
||||
T.tlength = i_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
T.thumb = (char *)malloc(o_length);
|
||||
if (!T.thumb)
|
||||
throw LIBRAW_EXCEPTION_ALLOC;
|
||||
for (int i = 0; i < o_length; i++)
|
||||
T.thumb[i] = t_thumb[i] >> 8;
|
||||
free(t_thumb);
|
||||
T.tformat = LIBRAW_THUMBNAIL_BITMAP;
|
||||
T.tlength = o_length;
|
||||
}
|
||||
SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
|
||||
return 0;
|
||||
|
||||
@@ -265,6 +265,10 @@ void LibRaw::xtrans_interpolate(int passes)
|
||||
{
|
||||
rix = &rgb[0][row - top][col - left];
|
||||
int h = fcol(row, col + 1);
|
||||
|
||||
if (h == 1) // Incorrect pattern
|
||||
break;
|
||||
|
||||
float diff[6];
|
||||
memset(diff, 0, sizeof diff);
|
||||
for (int i = 1, d = 0; d < 6; d++, i ^= LIBRAW_AHD_TILE ^ 1, h ^= 2)
|
||||
|
||||
@@ -460,7 +460,7 @@ int LibRaw_buffer_datastream::scanf_one(const char *fmt, void *val)
|
||||
if (scanf_res > 0)
|
||||
{
|
||||
int xcnt = 0;
|
||||
while (streampos < streamsize)
|
||||
while (streampos < streamsize-1)
|
||||
{
|
||||
streampos++;
|
||||
xcnt++;
|
||||
|
||||
@@ -132,7 +132,7 @@ void LibRaw::parseAdobeRAFMakernote()
|
||||
}
|
||||
|
||||
#define CHECKSPACE(s) \
|
||||
if (posPrivateMknBuf + (s) > PrivateMknLength) \
|
||||
if (INT64(posPrivateMknBuf) + INT64(s) > INT64(PrivateMknLength)) \
|
||||
{ \
|
||||
free(PrivateMknBuf); \
|
||||
return; \
|
||||
@@ -209,7 +209,7 @@ void LibRaw::parseAdobeRAFMakernote()
|
||||
PrivateOrder = sget2(PrivateMknBuf);
|
||||
unsigned s, l;
|
||||
s = ifd_start = sget4(PrivateMknBuf +2)+6;
|
||||
CHECKSPACE(ifd_start+4);
|
||||
CHECKSPACE(INT64(ifd_start)+4LL);
|
||||
l = ifd_len = sget4(PrivateMknBuf +ifd_start);
|
||||
CHECKSPACE_ABS3(ifd_start, ifd_len, 4);
|
||||
|
||||
@@ -767,7 +767,7 @@ void LibRaw::parseAdobeRAFMakernote()
|
||||
|
||||
if (wb_section_offset)
|
||||
{
|
||||
CHECKSPACE(wb_section_offset + 12);
|
||||
CHECKSPACE(INT64(wb_section_offset) + 12LL);
|
||||
}
|
||||
|
||||
if (wb_section_offset &&
|
||||
|
||||
@@ -39,6 +39,7 @@ void LibRaw::wavelet_denoise()
|
||||
static const float noise[] = {0.8002f, 0.2735f, 0.1202f, 0.0585f,
|
||||
0.0291f, 0.0152f, 0.0080f, 0.0044f};
|
||||
|
||||
if (iwidth < 65 || iheight < 65) return;
|
||||
|
||||
while (maximum << scale < 0x10000)
|
||||
scale++;
|
||||
@@ -135,6 +136,9 @@ void LibRaw::wavelet_denoise()
|
||||
static const float noise[] = {0.8002, 0.2735, 0.1202, 0.0585,
|
||||
0.0291, 0.0152, 0.0080, 0.0044};
|
||||
|
||||
if (iwidth < 65 || iheight < 65)
|
||||
return;
|
||||
|
||||
while (maximum << scale < 0x10000)
|
||||
scale++;
|
||||
maximum <<= --scale;
|
||||
@@ -324,6 +328,9 @@ void LibRaw::recover_highlights()
|
||||
|
||||
grow = pow(2.0, 4 - highlight);
|
||||
FORC(unsigned(colors)) hsat[c] = 32000 * pre_mul[c];
|
||||
FORC(unsigned(colors))
|
||||
if(hsat[c]<1)
|
||||
return;
|
||||
for (kc = 0, c = 1; c < (unsigned)colors; c++)
|
||||
if (pre_mul[kc] < pre_mul[c])
|
||||
kc = c;
|
||||
|
||||
@@ -43,6 +43,8 @@ void LibRaw::raw2image_start()
|
||||
|
||||
// adjust for half mode!
|
||||
IO.shrink =
|
||||
!imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image &&
|
||||
!imgdata.rawdata.float4_image && !imgdata.rawdata.float3_image &&
|
||||
P1.filters &&
|
||||
(O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1)));
|
||||
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
|
||||
#define _ARR_SZ(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
static const int _tagtype_dataunit_bytes [19] = {
|
||||
1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4, 2, 8, 8, 8, 8
|
||||
static const int _tagtype_dataunit_bytes [20] = {
|
||||
1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4, 2, 8, 8, 8, 8, 8
|
||||
};
|
||||
|
||||
libraw_static_table_t LibRaw::tagtype_dataunit_bytes(_tagtype_dataunit_bytes, _ARR_SZ(_tagtype_dataunit_bytes));
|
||||
|
||||
int libraw_tagtype_dataunit_bytes(int tagtype)
|
||||
{
|
||||
return _tagtype_dataunit_bytes[((unsigned)tagtype <= _ARR_SZ(_tagtype_dataunit_bytes)) ? tagtype : 0];
|
||||
return _tagtype_dataunit_bytes[((unsigned)tagtype < _ARR_SZ(_tagtype_dataunit_bytes)) ? tagtype : 0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,8 +37,11 @@ void LibRaw::cubic_spline(const int *x_, const int *y_, const int len)
|
||||
}
|
||||
for (i = len - 1; i > 0; i--)
|
||||
{
|
||||
b[i] = (y[i] - y[i - 1]) / (x[i] - x[i - 1]);
|
||||
d[i - 1] = x[i] - x[i - 1];
|
||||
float _div = x[i] - x[i - 1];
|
||||
if (fabs(_div) < 1.0e-15)
|
||||
_div = 1;
|
||||
b[i] = (y[i] - y[i - 1]) / _div;
|
||||
d[i - 1] = _div;
|
||||
}
|
||||
for (i = 1; i < len - 1; i++)
|
||||
{
|
||||
|
||||
@@ -482,7 +482,10 @@ int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
|
||||
// Fuji layout files: either DNG or unpacked_load_raw should be used
|
||||
if (libraw_internal_data.internal_output_params.fuji_width || libraw_internal_data.unpacker_data.fuji_layout)
|
||||
{
|
||||
if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw)
|
||||
if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw
|
||||
&& load_raw != &LibRaw::unpacked_load_raw_FujiDBP
|
||||
&& load_raw != &LibRaw::unpacked_load_raw_fuji_f700s20
|
||||
)
|
||||
return LIBRAW_FILE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@@ -1200,9 +1203,15 @@ int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
|
||||
{
|
||||
if (C.profile)
|
||||
free(C.profile);
|
||||
C.profile = malloc(C.profile_length);
|
||||
ID.input->seek(ID.profile_offset, SEEK_SET);
|
||||
ID.input->read(C.profile, C.profile_length, 1);
|
||||
INT64 profile_sz = MIN(INT64(C.profile_length), ID.input->size() - ID.profile_offset);
|
||||
if (profile_sz > 0LL && profile_sz < LIBRAW_MAX_PROFILE_SIZE_MB * 1024LL * 1024LL)
|
||||
{
|
||||
C.profile = malloc(size_t(profile_sz));
|
||||
ID.input->seek(ID.profile_offset, SEEK_SET);
|
||||
ID.input->read(C.profile, size_t(profile_sz), 1);
|
||||
}
|
||||
else
|
||||
C.profile = NULL;
|
||||
}
|
||||
|
||||
SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
|
||||
|
||||
@@ -127,26 +127,36 @@ void LibRaw::kodak_thumb_loader()
|
||||
int(*t_hist)[LIBRAW_HISTOGRAM_SIZE] =
|
||||
(int(*)[LIBRAW_HISTOGRAM_SIZE])calloc(sizeof(*t_hist), 4);
|
||||
|
||||
float out[3], out_cam[3][4] = {{2.81761312f, -1.98369181f, 0.166078627f, 0},
|
||||
{-0.111855984f, 1.73688626f, -0.625030339f, 0},
|
||||
{-0.0379119813f, -0.891268849f, 1.92918086f, 0}};
|
||||
|
||||
for (img = imgdata.image[0], row = 0; row < S.height; row++)
|
||||
for (col = 0; col < S.width; col++, img += 4)
|
||||
{
|
||||
out[0] = out[1] = out[2] = 0;
|
||||
int c;
|
||||
for (c = 0; c < 3; c++)
|
||||
if (imgdata.idata.maker_index == LIBRAW_CAMERAMAKER_Canon) // Skip color conversion for canon PPM tiffs
|
||||
{
|
||||
for (img = imgdata.image[0], row = 0; row < S.height; row++)
|
||||
for (col = 0; col < S.width; col++, img += 4)
|
||||
for (int c = 0; c < P1.colors; c++)
|
||||
t_hist[c][img[c] >> 3]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
float out[3], out_cam[3][4] = {{2.81761312f, -1.98369181f, 0.166078627f, 0},
|
||||
{-0.111855984f, 1.73688626f, -0.625030339f, 0},
|
||||
{-0.0379119813f, -0.891268849f, 1.92918086f, 0}};
|
||||
|
||||
for (img = imgdata.image[0], row = 0; row < S.height; row++)
|
||||
for (col = 0; col < S.width; col++, img += 4)
|
||||
{
|
||||
out[0] += out_cam[0][c] * img[c];
|
||||
out[1] += out_cam[1][c] * img[c];
|
||||
out[2] += out_cam[2][c] * img[c];
|
||||
out[0] = out[1] = out[2] = 0;
|
||||
int c;
|
||||
for (c = 0; c < 3; c++)
|
||||
{
|
||||
out[0] += out_cam[0][c] * img[c];
|
||||
out[1] += out_cam[1][c] * img[c];
|
||||
out[2] += out_cam[2][c] * img[c];
|
||||
}
|
||||
for (c = 0; c < 3; c++)
|
||||
img[c] = CLIP((int)out[c]);
|
||||
for (c = 0; c < P1.colors; c++)
|
||||
t_hist[c][img[c] >> 3]++;
|
||||
}
|
||||
for (c = 0; c < 3; c++)
|
||||
img[c] = CLIP((int)out[c]);
|
||||
for (c = 0; c < P1.colors; c++)
|
||||
t_hist[c][img[c] >> 3]++;
|
||||
}
|
||||
}
|
||||
|
||||
// from gamma_lut
|
||||
int(*save_hist)[LIBRAW_HISTOGRAM_SIZE] =
|
||||
|
||||
Reference in New Issue
Block a user