Fixed issue #6312
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:
parent
a56c11570f
commit
23e2f0cca5
@ -7113,8 +7113,8 @@ void CLASS apply_tiff()
|
|||||||
(unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 && // RT
|
(unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 && // RT
|
||||||
ns && ((ns > os && (ties = 1)) ||
|
ns && ((ns > os && (ties = 1)) ||
|
||||||
(ns == os && shot_select == ties++))) {
|
(ns == os && shot_select == ties++))) {
|
||||||
raw_width = tiff_ifd[i].width;
|
raw_width = read_crop.complete ? read_crop.width : tiff_ifd[i].width;
|
||||||
raw_height = tiff_ifd[i].height;
|
raw_height = read_crop.complete ? read_crop.height : tiff_ifd[i].height;
|
||||||
tiff_bps = tiff_ifd[i].bps;
|
tiff_bps = tiff_ifd[i].bps;
|
||||||
tiff_compress = tiff_ifd[i].comp;
|
tiff_compress = tiff_ifd[i].comp;
|
||||||
data_offset = tiff_ifd[i].offset;
|
data_offset = tiff_ifd[i].offset;
|
||||||
@ -7647,37 +7647,62 @@ void CLASS parse_fuji (int offset)
|
|||||||
|
|
||||||
fseek (ifp, offset, SEEK_SET);
|
fseek (ifp, offset, SEEK_SET);
|
||||||
entries = get4();
|
entries = get4();
|
||||||
|
int read_crop_c = 0;
|
||||||
|
bool read_crop_dimensions = false;
|
||||||
if (entries > 255) return;
|
if (entries > 255) return;
|
||||||
while (entries--) {
|
while (entries--) {
|
||||||
tag = get2();
|
tag = get2();
|
||||||
len = get2();
|
len = get2();
|
||||||
save = ftell(ifp);
|
save = ftell(ifp);
|
||||||
|
// tag 0x100 = 256 RawImageFullSize
|
||||||
if (tag == 0x100) {
|
if (tag == 0x100) {
|
||||||
raw_height = get2();
|
raw_height = get2();
|
||||||
raw_width = get2();
|
raw_width = get2();
|
||||||
} else if (tag == 0x121) {
|
} else if (tag == 0x121) {
|
||||||
height = get2();
|
height = get2();
|
||||||
if ((width = get2()) == 4284) width += 3;
|
if ((width = get2()) == 4284) width += 3;
|
||||||
|
// tag 0x130 = 304 FujiLayout
|
||||||
} else if (tag == 0x130) {
|
} else if (tag == 0x130) {
|
||||||
fuji_layout = fgetc(ifp) >> 7;
|
fuji_layout = fgetc(ifp) >> 7;
|
||||||
fuji_width = !(fgetc(ifp) & 8);
|
fuji_width = !(fgetc(ifp) & 8);
|
||||||
|
// tag 0x131 = 305 XTransLayout
|
||||||
} else if (tag == 0x131) {
|
} else if (tag == 0x131) {
|
||||||
filters = 9;
|
filters = 9;
|
||||||
FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
|
FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
|
||||||
} else if (tag == 0x2ff0) {
|
} else if (tag == 0x2ff0) {
|
||||||
FORC4 cam_mul[c ^ 1] = get2();
|
FORC4 cam_mul[c ^ 1] = get2();
|
||||||
} else if (tag == 0xc000 && len > 20000) {
|
} else if (tag == 0xc000 && len > 20000 && !read_crop_dimensions) {
|
||||||
c = order;
|
c = order;
|
||||||
order = 0x4949;
|
order = 0x4949;
|
||||||
while ((tag = get4()) > raw_width);
|
while ((tag = get4()) > raw_width);
|
||||||
width = tag;
|
width = tag;
|
||||||
height = get4();
|
height = get4();
|
||||||
order = c;
|
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);
|
fseek (ifp, save+len, SEEK_SET);
|
||||||
}
|
}
|
||||||
height <<= fuji_layout;
|
height <<= fuji_layout;
|
||||||
width >>= fuji_layout;
|
width >>= fuji_layout;
|
||||||
|
read_crop.complete = read_crop_c == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CLASS parse_jpeg (int offset)
|
int CLASS parse_jpeg (int offset)
|
||||||
@ -10133,8 +10158,17 @@ canon_a5:
|
|||||||
width = raw_width = 6016;
|
width = raw_width = 6016;
|
||||||
height = raw_height = 4014;
|
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")) {
|
} 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;
|
constexpr std::uint_fast16_t x_width = 6384, x_height = 4182;
|
||||||
height = raw_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
|
} else if (!strcmp(model, "DBP for GX680")) { // Special case for #4204
|
||||||
width = raw_width = 5504;
|
width = raw_width = 5504;
|
||||||
height = raw_height = 3856;
|
height = raw_height = 3856;
|
||||||
|
@ -76,6 +76,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
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;
|
int exif_base, ciff_base, ciff_len;
|
||||||
rtengine::IMFILE *ifp;
|
rtengine::IMFILE *ifp;
|
||||||
FILE *ofp;
|
FILE *ofp;
|
||||||
|
@ -560,6 +560,13 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
|||||||
raw_crop_cc = true;
|
raw_crop_cc = true;
|
||||||
int lm, tm, w, h;
|
int lm, tm, w, h;
|
||||||
cc->get_rawCrop(raw_width, raw_height, 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()) {
|
if (isXtrans()) {
|
||||||
shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6));
|
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;
|
if (!is_cropped) {
|
||||||
top_margin = tm;
|
left_margin = lm;
|
||||||
|
top_margin = tm;
|
||||||
|
}
|
||||||
|
|
||||||
if (w < 0) {
|
if (w < 0) {
|
||||||
iwidth += w;
|
iwidth += w;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user