diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 82c72a53b..0ac579149 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -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; diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index aadc0b969..33e3eb7b1 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -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; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 8478d56ab..370666018 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -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;