Fixed issue, where raw cropped Fuji X-Pro3 could not be loaded correctly. This would result in a Segmentation Fault.
With these changes the program should read the correct dimensions from the file's metadata, and load the image accordingly.
This commit is contained in:
Dániel Battyányi 2023-08-30 22:17:16 +02:00
parent a56c11570f
commit 23e2f0cca5
No known key found for this signature in database
GPG Key ID: 7125B147DC00233A
3 changed files with 66 additions and 7 deletions

View File

@ -7113,8 +7113,8 @@ void CLASS apply_tiff()
(unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 && // RT
ns && ((ns > os && (ties = 1)) ||
(ns == os && shot_select == ties++))) {
raw_width = tiff_ifd[i].width;
raw_height = tiff_ifd[i].height;
raw_width = read_crop.complete ? read_crop.width : tiff_ifd[i].width;
raw_height = read_crop.complete ? read_crop.height : tiff_ifd[i].height;
tiff_bps = tiff_ifd[i].bps;
tiff_compress = tiff_ifd[i].comp;
data_offset = tiff_ifd[i].offset;
@ -7647,37 +7647,62 @@ void CLASS parse_fuji (int offset)
fseek (ifp, offset, SEEK_SET);
entries = get4();
int read_crop_c = 0;
bool read_crop_dimensions = false;
if (entries > 255) return;
while (entries--) {
tag = get2();
len = get2();
save = ftell(ifp);
// tag 0x100 = 256 RawImageFullSize
if (tag == 0x100) {
raw_height = get2();
raw_width = get2();
} else if (tag == 0x121) {
height = get2();
if ((width = get2()) == 4284) width += 3;
// tag 0x130 = 304 FujiLayout
} else if (tag == 0x130) {
fuji_layout = fgetc(ifp) >> 7;
fuji_width = !(fgetc(ifp) & 8);
// tag 0x131 = 305 XTransLayout
} else if (tag == 0x131) {
filters = 9;
FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
} else if (tag == 0x2ff0) {
FORC4 cam_mul[c ^ 1] = get2();
} else if (tag == 0xc000 && len > 20000) {
} else if (tag == 0xc000 && len > 20000 && !read_crop_dimensions) {
c = order;
order = 0x4949;
while ((tag = get4()) > raw_width);
width = tag;
height = get4();
order = c;
// RawImageCroppedSize 0x111 = 273 (including borders)
} else if (tag == 0x111) {
height = raw_height = read_crop.height = get2();
width = raw_width = read_crop.width = get2();
read_crop_dimensions = true;
read_crop_c += 2;
// RawImageTopLeft 0x110 = 272 (top margin first, then left margin)
} else if (tag == 0x110){
read_crop.top_margin = get2();
read_crop.left_margin = get2();
read_crop_c += 2;
}
// 0x112 = 274 unknown tag
// 0x113 = 275 unknown tag
// 0x115 = 277 RawImageAspectRatio
// 0x141 = 321 unknown tag
// 0x9650 = 38480 RawExposureBias
// 0x9651 = 38481 unknown tag
// 0x17f8 = 6136 unknown tag
fseek (ifp, save+len, SEEK_SET);
}
height <<= fuji_layout;
width >>= fuji_layout;
read_crop.complete = read_crop_c == 4;
}
int CLASS parse_jpeg (int offset)
@ -10133,8 +10158,17 @@ canon_a5:
width = raw_width = 6016;
height = raw_height = 4014;
} else if (!strcmp(model, "X-Pro3") || !strcmp(model, "X-T3") || !strcmp(model, "X-T30") || !strcmp(model, "X-T4") || !strcmp(model, "X100V") || !strcmp(model, "X-S10")) {
width = raw_width = 6384;
height = raw_height = 4182;
constexpr std::uint_fast16_t x_width = 6384, x_height = 4182;
is_cropped = read_crop.complete && (x_width - raw_width > is_cropped_margin || x_height - raw_height > is_cropped_margin);
if (!is_cropped) {
width = raw_width = x_width;
height = raw_height = x_height;
}
// due to this (mainly raw_width and raw_height) not beimg read from the file, a segmentation fault occurs, when trying to read the raw image
// the following data should be read from the exif data, and passed to the corresponding variables:
// RAF - RawImageCroppedSize ------- Test image: 4992x3328
// raw_width = 4992;
// raw_height = 3328;
} else if (!strcmp(model, "DBP for GX680")) { // Special case for #4204
width = raw_width = 5504;
height = raw_height = 3856;

View File

@ -76,6 +76,22 @@ public:
}
protected:
// stores the cropdata read from the file
struct CropData {
std::uint_fast16_t width,
height,
top_margin,
left_margin;
bool complete = false;
} read_crop;
/*
If the difference between the read dimension (width /height)
and the constant dimension (eg.: from cameraconstants)
is greater than this amount,
then the file should be considered raw cropped (for fuji cropped raw)
*/
static constexpr std::uint_fast16_t is_cropped_margin = 500;
bool is_cropped = false;
int exif_base, ciff_base, ciff_len;
rtengine::IMFILE *ifp;
FILE *ofp;

View File

@ -560,6 +560,13 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
raw_crop_cc = true;
int lm, tm, w, h;
cc->get_rawCrop(raw_width, raw_height, lm, tm, w, h);
is_cropped = read_crop.complete && (raw_width - read_crop.width > is_cropped_margin || raw_height - read_crop.height > is_cropped_margin);
if (is_cropped){
left_margin = read_crop.left_margin;
top_margin = read_crop.top_margin;
tm = 0;
lm = 0;
}
if (isXtrans()) {
shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6));
@ -569,8 +576,10 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
}
}
left_margin = lm;
top_margin = tm;
if (!is_cropped) {
left_margin = lm;
top_margin = tm;
}
if (w < 0) {
iwidth += w;