From 80f8b33f9bfcc1e271bf3e4c0addf1c2cdc95d26 Mon Sep 17 00:00:00 2001 From: maruncz Date: Fri, 1 Apr 2022 10:39:59 +0200 Subject: [PATCH 01/27] extract first frame from rawspeed --- src/common/imageio_rawspeed.cc | 107 +++++++++++++++++---------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/src/common/imageio_rawspeed.cc b/src/common/imageio_rawspeed.cc index 5a63fff5e8f1..b02f15c80da1 100644 --- a/src/common/imageio_rawspeed.cc +++ b/src/common/imageio_rawspeed.cc @@ -165,13 +165,13 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena d->decodeMetaData(meta); RawImage r = d->mRaw; - const auto errors = r->getErrors(); + const auto errors = r.get(0)->getErrors(); for(const auto &error : errors) fprintf(stderr, "[rawspeed] (%s) %s\n", img->filename, error.c_str()); - g_strlcpy(img->camera_maker, r->metadata.canonical_make.c_str(), sizeof(img->camera_maker)); - g_strlcpy(img->camera_model, r->metadata.canonical_model.c_str(), sizeof(img->camera_model)); - g_strlcpy(img->camera_alias, r->metadata.canonical_alias.c_str(), sizeof(img->camera_alias)); + g_strlcpy(img->camera_maker, r.metadata.canonical_make.c_str(), sizeof(img->camera_maker)); + g_strlcpy(img->camera_model, r.metadata.canonical_model.c_str(), sizeof(img->camera_model)); + g_strlcpy(img->camera_alias, r.metadata.canonical_alias.c_str(), sizeof(img->camera_alias)); dt_image_refresh_makermodel(img); // We used to partial match the Canon local rebrandings so lets pass on @@ -211,27 +211,27 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena }; for(uint32_t i = 0; i < (sizeof(legacy_aliases) / sizeof(legacy_aliases[1])); i++) - if(!strcmp(legacy_aliases[i].origname, r->metadata.model.c_str())) + if(!strcmp(legacy_aliases[i].origname, r.metadata.model.c_str())) { g_strlcpy(img->camera_legacy_makermodel, legacy_aliases[i].mungedname, sizeof(img->camera_legacy_makermodel)); break; } - img->raw_black_level = r->blackLevel; - img->raw_white_point = r->whitePoint; + img->raw_black_level = r.get(0)->blackLevel; + img->raw_white_point = r.get(0)->whitePoint; - if(r->blackLevelSeparate[0] == -1 - || r->blackLevelSeparate[1] == -1 - || r->blackLevelSeparate[2] == -1 - || r->blackLevelSeparate[3] == -1) + if(r.get(0)->blackLevelSeparate[0] == -1 + || r.get(0)->blackLevelSeparate[1] == -1 + || r.get(0)->blackLevelSeparate[2] == -1 + || r.get(0)->blackLevelSeparate[3] == -1) { - r->calculateBlackAreas(); + r.get(0)->calculateBlackAreas(); } for(uint8_t i = 0; i < 4; i++) - img->raw_black_level_separate[i] = r->blackLevelSeparate[i]; + img->raw_black_level_separate[i] = r.get(0)->blackLevelSeparate[i]; - if(r->blackLevel == -1) + if(r.get(0)->blackLevel == -1) { float black = 0.0f; for(uint8_t i = 0; i < 4; i++) @@ -255,9 +255,9 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena // Grab the WB for(int i = 0; i < 4; i++) - img->wb_coeffs[i] = r->metadata.wbCoeffs[i]; + img->wb_coeffs[i] = r.metadata.wbCoeffs[i]; - const int msize = r->metadata.colorMatrix.size(); + const int msize = r.metadata.colorMatrix.size(); // Grab the adobe coeff for(int k = 0; k < 4; k++) for(int i = 0; i < 3; i++) @@ -265,7 +265,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena const int idx = k*3 + i; if(idx < msize) img->adobe_XYZ_to_CAM[k][i] = - (float)r->metadata.colorMatrix[idx] / (float)ADOBE_COEFF_FACTOR; + (float)r.metadata.colorMatrix[idx] / (float)ADOBE_COEFF_FACTOR; else img->adobe_XYZ_to_CAM[k][i] = 0.0f; } @@ -276,7 +276,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena if (img->flags & DT_IMAGE_HAS_USERCROP) dt_exif_img_check_usercrop(img, filename); - if(r->getDataType() == TYPE_FLOAT32) + if(r.get(0)->getDataType() == TYPE_FLOAT32) { img->flags |= DT_IMAGE_HDR; @@ -286,30 +286,30 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena } img->buf_dsc.filters = 0u; - if(!r->isCFA) + if(!r.get(0)->isCFA) { const dt_imageio_retval_t ret = dt_imageio_open_rawspeed_sraw(img, r, mbuf); return ret; } - if((r->getDataType() != TYPE_USHORT16) && (r->getDataType() != TYPE_FLOAT32)) + if((r.get(0)->getDataType() != TYPE_USHORT16) && (r.get(0)->getDataType() != TYPE_FLOAT32)) return DT_IMAGEIO_FILE_CORRUPTED; - if((r->getBpp() != sizeof(uint16_t)) && (r->getBpp() != sizeof(float))) + if((r.get(0)->getBpp() != sizeof(uint16_t)) && (r.get(0)->getBpp() != sizeof(float))) return DT_IMAGEIO_FILE_CORRUPTED; - if((r->getDataType() == TYPE_USHORT16) && (r->getBpp() != sizeof(uint16_t))) + if((r.get(0)->getDataType() == TYPE_USHORT16) && (r.get(0)->getBpp() != sizeof(uint16_t))) return DT_IMAGEIO_FILE_CORRUPTED; - if((r->getDataType() == TYPE_FLOAT32) && (r->getBpp() != sizeof(float))) + if((r.get(0)->getDataType() == TYPE_FLOAT32) && (r.get(0)->getBpp() != sizeof(float))) return DT_IMAGEIO_FILE_CORRUPTED; - const float cpp = r->getCpp(); + const auto cpp = r.get(0)->getCpp(); if(cpp != 1) return DT_IMAGEIO_FILE_CORRUPTED; img->buf_dsc.channels = 1; - switch(r->getBpp()) + switch(r.get(0)->getBpp()) { case sizeof(uint16_t): img->buf_dsc.datatype = TYPE_UINT16; @@ -322,15 +322,15 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena } // dimensions of uncropped image - iPoint2D dimUncropped = r->getUncroppedDim(); + iPoint2D dimUncropped = r.get(0)->getUncroppedDim(); img->width = dimUncropped.x; img->height = dimUncropped.y; // dimensions of cropped image - iPoint2D dimCropped = r->dim; + iPoint2D dimCropped = r.get(0)->dim; // crop - Top,Left corner - iPoint2D cropTL = r->getCropOffset(); + iPoint2D cropTL = r.get(0)->getCropOffset(); img->crop_x = cropTL.x; img->crop_y = cropTL.y; @@ -339,12 +339,12 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena img->crop_width = cropBR.x; img->crop_height = cropBR.y; - img->fuji_rotation_pos = r->metadata.fujiRotationPos; - img->pixel_aspect_ratio = (float)r->metadata.pixelAspectRatio; + img->fuji_rotation_pos = r.metadata.fujiRotationPos; + img->pixel_aspect_ratio = (float)r.metadata.pixelAspectRatio; // as the X-Trans filters comments later on states, these are for // cropped image, so we need to uncrop them. - img->buf_dsc.filters = dt_rawspeed_crop_dcraw_filters(r->cfa.getDcrawFilter(), cropTL.x, cropTL.y); + img->buf_dsc.filters = dt_rawspeed_crop_dcraw_filters(r.get(0)->cfa.getDcrawFilter(), cropTL.x, cropTL.y); if(FILTERS_ARE_4BAYER(img->buf_dsc.filters)) img->flags |= DT_IMAGE_4BAYER; @@ -365,7 +365,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena for(int i = 0; i < 6; ++i) for(int j = 0; j < 6; ++j) { - img->buf_dsc.xtrans[j][i] = (uint8_t)r->cfa.getColorAt(i % 6, j % 6); + img->buf_dsc.xtrans[j][i] = (uint8_t)r.get(0)->cfa.getColorAt(i % 6, j % 6); } } } @@ -388,22 +388,23 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena * (from Klaus: r->pitch may differ from DT pitch (line to line spacing)) * else fallback to generic dt_imageio_flip_buffers() */ - const size_t bufSize_mipmap = (size_t)img->width * img->height * r->getBpp(); - const size_t bufSize_rawspeed = (size_t)r->pitch * dimUncropped.y; + const size_t bufSize_mipmap = (size_t)img->width * img->height * r.get(0)->getBpp(); + const size_t bufSize_rawspeed = (size_t)r.get(0)->pitch * dimUncropped.y; + if(bufSize_mipmap == bufSize_rawspeed) { - memcpy(buf, r->getDataUncropped(0, 0), bufSize_mipmap); + memcpy(buf, r.get(0)->getDataUncropped(0, 0), bufSize_mipmap); } else { - dt_imageio_flip_buffers((char *)buf, (char *)r->getDataUncropped(0, 0), r->getBpp(), dimUncropped.x, - dimUncropped.y, dimUncropped.x, dimUncropped.y, r->pitch, ORIENTATION_NONE); + dt_imageio_flip_buffers((char *)buf, (char *)r.get(0)->getDataUncropped(0, 0), r.get(0)->getBpp(), dimUncropped.x, + dimUncropped.y, dimUncropped.x, dimUncropped.y, r.get(0)->pitch, ORIENTATION_NONE); } // Check if the camera is missing samples - const Camera *cam = meta->getCamera(r->metadata.make.c_str(), - r->metadata.model.c_str(), - r->metadata.mode.c_str()); + const Camera *cam = meta->getCamera(r.metadata.make.c_str(), + r.metadata.model.c_str(), + r.metadata.mode.c_str()); if(cam && cam->supportStatus == Camera::SupportStatus::NoSamples) img->camera_missing_sample = TRUE; @@ -434,17 +435,17 @@ dt_imageio_retval_t dt_imageio_open_rawspeed_sraw(dt_image_t *img, RawImage r, d img->flags &= ~DT_IMAGE_LDR; img->flags &= ~DT_IMAGE_RAW; img->flags |= DT_IMAGE_S_RAW; - img->width = r->dim.x; - img->height = r->dim.y; + img->width = r.get(0)->dim.x; + img->height = r.get(0)->dim.y; // actually we want to store full floats here: img->buf_dsc.channels = 4; img->buf_dsc.datatype = TYPE_FLOAT; - if(r->getDataType() != TYPE_USHORT16 && r->getDataType() != TYPE_FLOAT32) + if(r.get(0)->getDataType() != TYPE_USHORT16 && r.get(0)->getDataType() != TYPE_FLOAT32) return DT_IMAGEIO_FILE_CORRUPTED; - const uint32_t cpp = r->getCpp(); + const uint32_t cpp = r.get(0)->getCpp(); if(cpp != 1 && cpp != 3 && cpp != 4) return DT_IMAGEIO_FILE_CORRUPTED; // if buf is NULL, we quit the fct here @@ -467,14 +468,14 @@ dt_imageio_retval_t dt_imageio_open_rawspeed_sraw(dt_image_t *img, RawImage r, d * we need to copy data from only channel to each of 3 channels */ - if(r->getDataType() == TYPE_USHORT16) + if(r.get(0)->getDataType() == TYPE_USHORT16) { #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) dt_omp_firstprivate(cpp) shared(r, img, buf) #endif for(int j = 0; j < img->height; j++) { - const uint16_t *in = (uint16_t *)r->getData(0, j); + const uint16_t *in = (uint16_t *)r.get(0)->getData(0, j); float *out = ((float *)buf) + (size_t)4 * j * img->width; for(int i = 0; i < img->width; i++, in += cpp, out += 4) @@ -493,7 +494,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed_sraw(dt_image_t *img, RawImage r, d #endif for(int j = 0; j < img->height; j++) { - const float *in = (float *)r->getData(0, j); + const float *in = (float *)r.get(0)->getData(0, j); float *out = ((float *)buf) + (size_t)4 * j * img->width; for(int i = 0; i < img->width; i++, in += cpp, out += 4) @@ -513,14 +514,14 @@ dt_imageio_retval_t dt_imageio_open_rawspeed_sraw(dt_image_t *img, RawImage r, d * just copy 3 ch to 3 ch */ - if(r->getDataType() == TYPE_USHORT16) + if(r.get(0)->getDataType() == TYPE_USHORT16) { #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) dt_omp_firstprivate(cpp) shared(r, img, buf) #endif for(int j = 0; j < img->height; j++) { - const uint16_t *in = (uint16_t *)r->getData(0, j); + const uint16_t *in = (uint16_t *)r.get(0)->getData(0, j); float *out = ((float *)buf) + (size_t)4 * j * img->width; for(int i = 0; i < img->width; i++, in += cpp, out += 4) @@ -539,7 +540,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed_sraw(dt_image_t *img, RawImage r, d #endif for(int j = 0; j < img->height; j++) { - const float *in = (float *)r->getData(0, j); + const float *in = (float *)r.get(0)->getData(0, j); float *out = ((float *)buf) + (size_t)4 * j * img->width; for(int i = 0; i < img->width; i++, in += cpp, out += 4) @@ -557,9 +558,9 @@ dt_imageio_retval_t dt_imageio_open_rawspeed_sraw(dt_image_t *img, RawImage r, d img->loader = LOADER_RAWSPEED; // Check if the camera is missing samples - const Camera *cam = meta->getCamera(r->metadata.make.c_str(), - r->metadata.model.c_str(), - r->metadata.mode.c_str()); + const Camera *cam = meta->getCamera(r.metadata.make.c_str(), + r.metadata.model.c_str(), + r.metadata.mode.c_str()); if(cam && cam->supportStatus == Camera::SupportStatus::NoSamples) img->camera_missing_sample = TRUE; From 6ced71827f15af5b678b76463eb568059fb054d9 Mon Sep 17 00:00:00 2001 From: maruncz Date: Sun, 3 Apr 2022 15:40:20 +0200 Subject: [PATCH 02/27] load all images - not working --- src/common/imageio_rawspeed.cc | 326 +++++++++++++++++++++++---------- src/develop/format.c | 2 +- src/develop/format.h | 2 + src/external/rawspeed | 2 +- 4 files changed, 233 insertions(+), 99 deletions(-) diff --git a/src/common/imageio_rawspeed.cc b/src/common/imageio_rawspeed.cc index b02f15c80da1..02c728674b39 100644 --- a/src/common/imageio_rawspeed.cc +++ b/src/common/imageio_rawspeed.cc @@ -132,6 +132,86 @@ static gboolean _ignore_image(const gchar *filename) return FALSE; } +static void load_image_metadata(const RawImage &r, dt_image_t *img) +{ + g_strlcpy(img->camera_maker, r.metadata.canonical_make.c_str(), sizeof(img->camera_maker)); + g_strlcpy(img->camera_model, r.metadata.canonical_model.c_str(), sizeof(img->camera_model)); + g_strlcpy(img->camera_alias, r.metadata.canonical_alias.c_str(), sizeof(img->camera_alias)); + dt_image_refresh_makermodel(img); + + // We used to partial match the Canon local rebrandings so lets pass on + // the value just in those cases to be able to fix old history stacks + static const struct + { + const char *mungedname; + const char *origname; + } legacy_aliases[] = { + { "Canon EOS", "Canon EOS REBEL SL1" }, + { "Canon EOS", "Canon EOS Kiss X7" }, + { "Canon EOS", "Canon EOS DIGITAL REBEL XT" }, + { "Canon EOS", "Canon EOS Kiss Digital N" }, + { "Canon EOS", "Canon EOS 350D" }, + { "Canon EOS", "Canon EOS DIGITAL REBEL XSi" }, + { "Canon EOS", "Canon EOS Kiss Digital X2" }, + { "Canon EOS", "Canon EOS Kiss X2" }, + { "Canon EOS", "Canon EOS REBEL T5i" }, + { "Canon EOS", "Canon EOS Kiss X7i" }, + { "Canon EOS", "Canon EOS Rebel T6i" }, + { "Canon EOS", "Canon EOS Kiss X8i" }, + { "Canon EOS", "Canon EOS Rebel T6s" }, + { "Canon EOS", "Canon EOS 8000D" }, + { "Canon EOS", "Canon EOS REBEL T1i" }, + { "Canon EOS", "Canon EOS Kiss X3" }, + { "Canon EOS", "Canon EOS REBEL T2i" }, + { "Canon EOS", "Canon EOS Kiss X4" }, + { "Canon EOS REBEL T3", "Canon EOS REBEL T3i" }, + { "Canon EOS", "Canon EOS Kiss X5" }, + { "Canon EOS", "Canon EOS REBEL T4i" }, + { "Canon EOS", "Canon EOS Kiss X6i" }, + { "Canon EOS", "Canon EOS DIGITAL REBEL XS" }, + { "Canon EOS", "Canon EOS Kiss Digital F" }, + { "Canon EOS", "Canon EOS REBEL T5" }, + { "Canon EOS", "Canon EOS Kiss X70" }, + { "Canon EOS", "Canon EOS DIGITAL REBEL XTi" }, + { "Canon EOS", "Canon EOS Kiss Digital X" }, + }; + + for(uint32_t i = 0; i < (sizeof(legacy_aliases) / sizeof(legacy_aliases[1])); i++) + { + if(!strcmp(legacy_aliases[i].origname, r.metadata.model.c_str())) + { + g_strlcpy(img->camera_legacy_makermodel, legacy_aliases[i].mungedname, sizeof(img->camera_legacy_makermodel)); + break; + } + } + + // Grab the WB + for(int i = 0; i < 4; i++) img->wb_coeffs[i] = r.metadata.wbCoeffs[i]; + + const int msize = r.metadata.colorMatrix.size(); + // Grab the adobe coeff + for(int k = 0; k < 4; k++) + for(int i = 0; i < 3; i++) + { + const int idx = k * 3 + i; + if(idx < msize) + img->adobe_XYZ_to_CAM[k][i] = (float)r.metadata.colorMatrix[idx] / (float)ADOBE_COEFF_FACTOR; + else + img->adobe_XYZ_to_CAM[k][i] = 0.0f; + } + + // FIXME: grab r->metadata.colorMatrix. + + img->fuji_rotation_pos = r.metadata.fujiRotationPos; + img->pixel_aspect_ratio = (float)r.metadata.pixelAspectRatio; + + + // Check if the camera is missing samples + const Camera *cam = meta->getCamera(r.metadata.make.c_str(), r.metadata.model.c_str(), r.metadata.mode.c_str()); + + if(cam && cam->supportStatus == Camera::SupportStatus::NoSamples) img->camera_missing_sample = TRUE; +} + dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filename, dt_mipmap_buffer_t *mbuf) { @@ -141,21 +221,18 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena char filen[PATH_MAX] = { 0 }; snprintf(filen, sizeof(filen), "%s", filename); - FileReader f(filen); - - std::unique_ptr d; - std::unique_ptr m; + FileReader file(filen); try { dt_rawspeed_load_meta(); dt_pthread_mutex_lock(&darktable.readFile_mutex); - m = f.readFile(); + auto m = file.readFile(); dt_pthread_mutex_unlock(&darktable.readFile_mutex); RawParser t(*m.get()); - d = t.getDecoder(meta); + auto d = t.getDecoder(meta); if(!d.get()) return DT_IMAGEIO_FILE_CORRUPTED; @@ -164,72 +241,86 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena d->decodeRaw(); d->decodeMetaData(meta); RawImage r = d->mRaw; + bool isMultiFrame{false}; - const auto errors = r.get(0)->getErrors(); - for(const auto &error : errors) - fprintf(stderr, "[rawspeed] (%s) %s\n", img->filename, error.c_str()); - - g_strlcpy(img->camera_maker, r.metadata.canonical_make.c_str(), sizeof(img->camera_maker)); - g_strlcpy(img->camera_model, r.metadata.canonical_model.c_str(), sizeof(img->camera_model)); - g_strlcpy(img->camera_alias, r.metadata.canonical_alias.c_str(), sizeof(img->camera_alias)); - dt_image_refresh_makermodel(img); - - // We used to partial match the Canon local rebrandings so lets pass on - // the value just in those cases to be able to fix old history stacks - static const struct { - const char *mungedname; - const char *origname; - } legacy_aliases[] = { - {"Canon EOS","Canon EOS REBEL SL1"}, - {"Canon EOS","Canon EOS Kiss X7"}, - {"Canon EOS","Canon EOS DIGITAL REBEL XT"}, - {"Canon EOS","Canon EOS Kiss Digital N"}, - {"Canon EOS","Canon EOS 350D"}, - {"Canon EOS","Canon EOS DIGITAL REBEL XSi"}, - {"Canon EOS","Canon EOS Kiss Digital X2"}, - {"Canon EOS","Canon EOS Kiss X2"}, - {"Canon EOS","Canon EOS REBEL T5i"}, - {"Canon EOS","Canon EOS Kiss X7i"}, - {"Canon EOS","Canon EOS Rebel T6i"}, - {"Canon EOS","Canon EOS Kiss X8i"}, - {"Canon EOS","Canon EOS Rebel T6s"}, - {"Canon EOS","Canon EOS 8000D"}, - {"Canon EOS","Canon EOS REBEL T1i"}, - {"Canon EOS","Canon EOS Kiss X3"}, - {"Canon EOS","Canon EOS REBEL T2i"}, - {"Canon EOS","Canon EOS Kiss X4"}, - {"Canon EOS REBEL T3","Canon EOS REBEL T3i"}, - {"Canon EOS","Canon EOS Kiss X5"}, - {"Canon EOS","Canon EOS REBEL T4i"}, - {"Canon EOS","Canon EOS Kiss X6i"}, - {"Canon EOS","Canon EOS DIGITAL REBEL XS"}, - {"Canon EOS","Canon EOS Kiss Digital F"}, - {"Canon EOS","Canon EOS REBEL T5"}, - {"Canon EOS","Canon EOS Kiss X70"}, - {"Canon EOS","Canon EOS DIGITAL REBEL XTi"}, - {"Canon EOS","Canon EOS Kiss Digital X"}, - }; - - for(uint32_t i = 0; i < (sizeof(legacy_aliases) / sizeof(legacy_aliases[1])); i++) - if(!strcmp(legacy_aliases[i].origname, r.metadata.model.c_str())) + /* free auto pointers on spot */ + d.reset(); + m.reset(); + + + for(const auto &frame : r) + { + const auto errors = frame->getErrors(); + for(const auto &error : errors) { - g_strlcpy(img->camera_legacy_makermodel, legacy_aliases[i].mungedname, sizeof(img->camera_legacy_makermodel)); - break; + fprintf(stderr, "[rawspeed] (%s) %s\n", img->filename, error.c_str()); + } + } + + // Get DefaultUserCrop + if(img->flags & DT_IMAGE_HAS_USERCROP) dt_exif_img_check_usercrop(img, filename); + + load_image_metadata(r, img); + + if(r.size() > 1) + { + auto isCFA = r.get(0)->isCFA; + for(const auto &f : r) + { + if(f->isCFA != isCFA) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent CFA flag across frames\n", img->filename); + return DT_IMAGEIO_FILE_CORRUPTED; + } } + isMultiFrame = isCFA; + } img->raw_black_level = r.get(0)->blackLevel; img->raw_white_point = r.get(0)->whitePoint; + if(isMultiFrame) + { + for(size_t i=0;i< r.size();++i) + { + if(r.get(i)->blackLevel != img->raw_black_level) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent black levels across frames\n", img->filename); + } + if(static_cast(r.get(i)->whitePoint) != img->raw_white_point) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent white points across frames\n", img->filename); + } + } + } - if(r.get(0)->blackLevelSeparate[0] == -1 - || r.get(0)->blackLevelSeparate[1] == -1 - || r.get(0)->blackLevelSeparate[2] == -1 - || r.get(0)->blackLevelSeparate[3] == -1) + for(const auto &f : r) { - r.get(0)->calculateBlackAreas(); + if(f->blackLevelSeparate[0] == -1 + || f->blackLevelSeparate[1] == -1 + || f->blackLevelSeparate[2] == -1 + || f->blackLevelSeparate[3] == -1) + { + f->calculateBlackAreas(); + } } for(uint8_t i = 0; i < 4; i++) + { img->raw_black_level_separate[i] = r.get(0)->blackLevelSeparate[i]; + } + if(isMultiFrame) + { + for(const auto &f : r) + { + for(uint8_t i = 0; i < 4; i++) + { + if(img->raw_black_level_separate[i] != f->blackLevelSeparate[i]) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent separate black levels across frames\n", img->filename); + } + } + } + } if(r.get(0)->blackLevel == -1) { @@ -249,32 +340,20 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena * ??? */ - /* free auto pointers on spot */ - d.reset(); - m.reset(); - - // Grab the WB - for(int i = 0; i < 4; i++) - img->wb_coeffs[i] = r.metadata.wbCoeffs[i]; - const int msize = r.metadata.colorMatrix.size(); - // Grab the adobe coeff - for(int k = 0; k < 4; k++) - for(int i = 0; i < 3; i++) + if(isMultiFrame) + { + auto type = r.get(0)->getDataType(); + for(const auto &f : r) { - const int idx = k*3 + i; - if(idx < msize) - img->adobe_XYZ_to_CAM[k][i] = - (float)r.metadata.colorMatrix[idx] / (float)ADOBE_COEFF_FACTOR; - else - img->adobe_XYZ_to_CAM[k][i] = 0.0f; + if(f->getDataType() != type) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent data types across frames\n", img->filename); + return DT_IMAGEIO_FILE_CORRUPTED; + } } + } - // FIXME: grab r->metadata.colorMatrix. - - // Get DefaultUserCrop - if (img->flags & DT_IMAGE_HAS_USERCROP) - dt_exif_img_check_usercrop(img, filename); if(r.get(0)->getDataType() == TYPE_FLOAT32) { @@ -285,6 +364,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena for(int k = 0; k < 4; k++) img->buf_dsc.processed_maximum[k] = 1.0f; } + // we don't support multiframe foll color images now img->buf_dsc.filters = 0u; if(!r.get(0)->isCFA) { @@ -292,6 +372,20 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena return ret; } + if(isMultiFrame) + { + auto bpp = r.get(0)->getBpp(); + for(const auto &f : r) + { + if(f->getBpp() != bpp) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent bit depth across frames\n", img->filename); + return DT_IMAGEIO_FILE_CORRUPTED; + } + } + } + + //all frames should have data type and bit depth consistent, so we only check first frame if((r.get(0)->getDataType() != TYPE_USHORT16) && (r.get(0)->getDataType() != TYPE_FLOAT32)) return DT_IMAGEIO_FILE_CORRUPTED; @@ -308,6 +402,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena if(cpp != 1) return DT_IMAGEIO_FILE_CORRUPTED; img->buf_dsc.channels = 1; + img->buf_dsc.frames = r.size(); switch(r.get(0)->getBpp()) { @@ -326,6 +421,18 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena img->width = dimUncropped.x; img->height = dimUncropped.y; + if(isMultiFrame) + { + for(const auto &f : r) + { + if((img->width != f->getUncroppedDim().x) || (img->height != f->getUncroppedDim().y)) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent uncropped dimensions across frames\n", img->filename); + return DT_IMAGEIO_FILE_CORRUPTED; + } + } + } + // dimensions of cropped image iPoint2D dimCropped = r.get(0)->dim; @@ -339,8 +446,23 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena img->crop_width = cropBR.x; img->crop_height = cropBR.y; - img->fuji_rotation_pos = r.metadata.fujiRotationPos; - img->pixel_aspect_ratio = (float)r.metadata.pixelAspectRatio; + if(isMultiFrame) + { + for(const auto &f : r) + { + if(dimCropped != f->dim) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent cropped dimensions across frames\n", img->filename); + return DT_IMAGEIO_FILE_CORRUPTED; + } + if(cropTL != f->getCropOffset()) + { + fprintf(stderr, "[rawspeed] (%s) inconsistent crop offset across frames\n", img->filename); + return DT_IMAGEIO_FILE_CORRUPTED; + } + } + } + // as the X-Trans filters comments later on states, these are for // cropped image, so we need to uncrop them. @@ -388,26 +510,36 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena * (from Klaus: r->pitch may differ from DT pitch (line to line spacing)) * else fallback to generic dt_imageio_flip_buffers() */ - const size_t bufSize_mipmap = (size_t)img->width * img->height * r.get(0)->getBpp(); - const size_t bufSize_rawspeed = (size_t)r.get(0)->pitch * dimUncropped.y; - - if(bufSize_mipmap == bufSize_rawspeed) + if(isMultiFrame) { - memcpy(buf, r.get(0)->getDataUncropped(0, 0), bufSize_mipmap); + const size_t bufSize_mipmap = (size_t)img->width * img->height * img->buf_dsc.frames * r.get(0)->getBpp(); + const size_t bufSize_rawspeed = (size_t)r.get(0)->pitch * dimUncropped.y * r.size(); + const size_t frame_size = bufSize_mipmap / r.size(); + printf("size mipmap: %lu\n size raw: %lu\nsize frame: %lu\n",bufSize_mipmap,bufSize_rawspeed,frame_size); + for(size_t i = 0; i < r.size(); ++i) + { + dt_imageio_flip_buffers(((char *)buf) + (i * frame_size), (char *)r.get(i)->getDataUncropped(0, 0), + r.get(i)->getBpp(), dimUncropped.x, dimUncropped.y, dimUncropped.x, dimUncropped.y, + r.get(i)->pitch, ORIENTATION_NONE); + } } else { - dt_imageio_flip_buffers((char *)buf, (char *)r.get(0)->getDataUncropped(0, 0), r.get(0)->getBpp(), dimUncropped.x, - dimUncropped.y, dimUncropped.x, dimUncropped.y, r.get(0)->pitch, ORIENTATION_NONE); + const size_t bufSize_mipmap = (size_t)img->width * img->height * r.get(0)->getBpp(); + const size_t bufSize_rawspeed = (size_t)r.get(0)->pitch * dimUncropped.y; + if(bufSize_mipmap == bufSize_rawspeed) + { + memcpy(buf, r.get(0)->getDataUncropped(0, 0), bufSize_mipmap); + } + else + { + dt_imageio_flip_buffers((char *)buf, (char *)r.get(0)->getDataUncropped(0, 0), r.get(0)->getBpp(), + dimUncropped.x, dimUncropped.y, dimUncropped.x, dimUncropped.y, r.get(0)->pitch, + ORIENTATION_NONE); + } } - // Check if the camera is missing samples - const Camera *cam = meta->getCamera(r.metadata.make.c_str(), - r.metadata.model.c_str(), - r.metadata.mode.c_str()); - if(cam && cam->supportStatus == Camera::SupportStatus::NoSamples) - img->camera_missing_sample = TRUE; } catch(const std::exception &exc) { diff --git a/src/develop/format.c b/src/develop/format.c index d9f6c62d63f7..4ae9ee3b226a 100644 --- a/src/develop/format.c +++ b/src/develop/format.c @@ -21,7 +21,7 @@ size_t dt_iop_buffer_dsc_to_bpp(const struct dt_iop_buffer_dsc_t *dsc) { - size_t bpp = dsc->channels; + size_t bpp = dsc->channels * dsc->frames; switch(dsc->datatype) { diff --git a/src/develop/format.h b/src/develop/format.h index 8f0f35b61b84..3bf592ee0dd8 100644 --- a/src/develop/format.h +++ b/src/develop/format.h @@ -36,6 +36,8 @@ typedef struct dt_iop_buffer_dsc_t { /** how many channels the data has? 1 or 4 */ unsigned int channels; + /** how many frames in multiframe images */ + unsigned frames; /** what is the datatype? */ dt_iop_buffer_type_t datatype; /** Bayer demosaic pattern */ diff --git a/src/external/rawspeed b/src/external/rawspeed index 154081cbcf9a..ad48a712b949 160000 --- a/src/external/rawspeed +++ b/src/external/rawspeed @@ -1 +1 @@ -Subproject commit 154081cbcf9a9141aa3508bbbe88fe8a810fcb6e +Subproject commit ad48a712b9499cdbf644133c953b419a65dda98f From 6fbdbb7450569d40e56ec1d0cf691025dd9c2287 Mon Sep 17 00:00:00 2001 From: maruncz Date: Tue, 5 Apr 2022 19:12:38 +0200 Subject: [PATCH 03/27] corrected handling of number of frames --- src/common/mipmap_cache.c | 2 +- src/develop/format.c | 3 ++- src/develop/pixelpipe_hb.c | 2 +- src/external/rawspeed | 2 +- src/iop/rawprepare.c | 2 +- src/tests/integration | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/common/mipmap_cache.c b/src/common/mipmap_cache.c index 622bd9837b70..374cf6867ec3 100644 --- a/src/common/mipmap_cache.c +++ b/src/common/mipmap_cache.c @@ -257,7 +257,7 @@ void *dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img) const int ht = img->height; const size_t bpp = dt_iop_buffer_dsc_to_bpp(&img->buf_dsc); - const size_t buffer_size = (size_t)wd * ht * bpp + sizeof(*dsc); + const size_t buffer_size = (size_t)wd * ht * bpp * img->buf_dsc.frames + sizeof(*dsc); // buf might have been alloc'ed before, // so only check size and re-alloc if necessary: diff --git a/src/develop/format.c b/src/develop/format.c index 4ae9ee3b226a..f7246bbb5077 100644 --- a/src/develop/format.c +++ b/src/develop/format.c @@ -21,7 +21,7 @@ size_t dt_iop_buffer_dsc_to_bpp(const struct dt_iop_buffer_dsc_t *dsc) { - size_t bpp = dsc->channels * dsc->frames; + size_t bpp = dsc->channels; switch(dsc->datatype) { @@ -60,6 +60,7 @@ void default_input_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_de void default_output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc) { + dsc->frames = 1; dsc->channels = 4; dsc->datatype = TYPE_FLOAT; dsc->cst = self->output_colorspace(self, pipe, piece); diff --git a/src/develop/pixelpipe_hb.c b/src/develop/pixelpipe_hb.c index 6c0f36572e01..921f412bb3ba 100644 --- a/src/develop/pixelpipe_hb.c +++ b/src/develop/pixelpipe_hb.c @@ -1097,7 +1097,7 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * if(module) g_strlcpy(module_name, module->op, MIN(sizeof(module_name), sizeof(module->op))); get_output_format(module, pipe, piece, dev, *out_format); const size_t bpp = dt_iop_buffer_dsc_to_bpp(*out_format); - const size_t bufsize = (size_t)bpp * roi_out->width * roi_out->height; + const size_t bufsize = (size_t)bpp * roi_out->width * roi_out->height * pipe->image.buf_dsc.frames; // 1) if cached buffer is still available, return data if(dt_atomic_get_int(&pipe->shutdown)) diff --git a/src/external/rawspeed b/src/external/rawspeed index ad48a712b949..b7d51d51ec17 160000 --- a/src/external/rawspeed +++ b/src/external/rawspeed @@ -1 +1 @@ -Subproject commit ad48a712b9499cdbf644133c953b419a65dda98f +Subproject commit b7d51d51ec17a738cb455a82eec0fe49b857d4d0 diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index eaec280e02dc..f1eb3db17a73 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -231,7 +231,7 @@ void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixel dt_iop_buffer_dsc_t *dsc) { default_output_format(self, pipe, piece, dsc); - + dsc->frames = pipe->image.buf_dsc.frames; dt_iop_rawprepare_data_t *d = (dt_iop_rawprepare_data_t *)piece->data; dsc->rawprepare.raw_black_level = d->rawprepare.raw_black_level; diff --git a/src/tests/integration b/src/tests/integration index 7e085356a3f6..f8ac222b1315 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit 7e085356a3f60e43b3b34ea2c74c6ca6ce7901bb +Subproject commit f8ac222b13155e77231f15ee7181cbfd1e705973 From 97e0afcf3f6be2e74f40b3ff6763463d4e77b913 Mon Sep 17 00:00:00 2001 From: maruncz Date: Wed, 6 Apr 2022 10:26:23 +0200 Subject: [PATCH 04/27] added pipe debug output --- src/bauhaus/bauhaus.c | 2 +- src/develop/pixelpipe_hb.c | 55 ++++++++++++++++++++++++++++++++++++++ src/tests/integration | 2 +- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/bauhaus/bauhaus.c b/src/bauhaus/bauhaus.c index 07b396bc3c52..c865b66b1b62 100644 --- a/src/bauhaus/bauhaus.c +++ b/src/bauhaus/bauhaus.c @@ -799,7 +799,7 @@ static gboolean dt_bauhaus_combobox_motion_notify(GtkWidget *widget, GdkEventMot // common initialization static void _bauhaus_widget_init(dt_bauhaus_widget_t *w, dt_iop_module_t *self) { - w->module = DT_ACTION(self); + if(self) w->module = DT_ACTION(self); w->field = NULL; w->section = NULL; diff --git a/src/develop/pixelpipe_hb.c b/src/develop/pixelpipe_hb.c index 921f412bb3ba..3248ecd017e4 100644 --- a/src/develop/pixelpipe_hb.c +++ b/src/develop/pixelpipe_hb.c @@ -41,6 +41,7 @@ #include #include #include +#include typedef enum dt_pixelpipe_flow_t { @@ -106,6 +107,57 @@ static char *_pipe_type_to_str(int pipe_type) return r; } +static void save_debug_bitmap(dt_dev_pixelpipe_t *pipe, const char *name, void *out, const dt_iop_roi_t *roi_out) +{ + char filename[128]; + snprintf(filename, 128, "save_debug_bitmap_%s_%s.pfm", name, _pipe_type_to_str(pipe->type)); + for(int i = 0; i < 128; ++i) + { + if(filename[i] == '\0') + { + break; + } + if((filename[i] == ' ') || (filename[i] == '/')) + { + filename[i] = '_'; + } + } + + FILE *file = g_fopen(filename, "w"); + if(file == NULL) + { + fprintf(stderr, "error opening debug file: %s, %s\n", filename, strerror(errno)); + return; + } + if(pipe->dsc.channels > 1) + { + fprintf(file, "PF\n"); + } + else + { + fprintf(file, "Pf\n"); + } + fprintf(file, "%i %i\n", roi_out->width, roi_out->height * pipe->dsc.frames); + fprintf(file, "-1.0\n"); + float *ptr = (float *)out; + if((pipe->dsc.channels == 1) || (pipe->dsc.channels == 3)) + { + fwrite(ptr, sizeof(float), roi_out->height * roi_out->width * pipe->dsc.channels * pipe->dsc.frames, file); + } + else + { + for(size_t i = 0; i < roi_out->height * roi_out->width * pipe->dsc.frames * pipe->dsc.channels; + i += pipe->dsc.channels) + { + for(size_t j = 0; j < 3; ++j) + { + fwrite(ptr + i + j, sizeof(float), 1, file); + } + } + } + fclose(file); +} + int dt_dev_pixelpipe_init_export(dt_dev_pixelpipe_t *pipe, int32_t width, int32_t height, int levels, gboolean store_masks) { @@ -2031,6 +2083,9 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * } } + save_debug_bitmap(pipe,dt_history_item_get_name(module),*output,roi_out); + + // 4) colorpicker and scopes: if(dt_atomic_get_int(&pipe->shutdown)) { diff --git a/src/tests/integration b/src/tests/integration index f8ac222b1315..1acf3d6461c8 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit f8ac222b13155e77231f15ee7181cbfd1e705973 +Subproject commit 1acf3d6461c84218b3e1a4224978812d0ef95781 From 18f24583241e479e645ae7bfa15da2de4a7d33d5 Mon Sep 17 00:00:00 2001 From: maruncz Date: Wed, 6 Apr 2022 11:21:09 +0200 Subject: [PATCH 05/27] modified rawprepare to handle multiple frames --- src/iop/rawprepare.c | 133 +++++++++++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 48 deletions(-) diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index f1eb3db17a73..c7ed7bcb652c 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -256,6 +256,74 @@ static int BL(const dt_iop_roi_t *const roi_out, const dt_iop_rawprepare_data_t return ((((row + roi_out->y + d->y) & 1) << 1) + ((col + roi_out->x + d->x) & 1)); } +static void convert_uint_float(const uint16_t *const in, float *const out, const dt_iop_roi_t *const roi_in, + const dt_iop_roi_t *const roi_out, int csx, int csy, + const dt_iop_rawprepare_data_t *const d) +{ +#ifdef _OPENMP +#pragma omp parallel for SIMD() default(none) \ + dt_omp_firstprivate(csx, csy, d, in, out, roi_in, roi_out) \ + schedule(static) collapse(2) +#endif + for(int j = 0; j < roi_out->height; j++) + { + for(int i = 0; i < roi_out->width; i++) + { + const size_t pin = (size_t)(roi_in->width * (j + csy) + csx) + i; + const size_t pout = (size_t)j * roi_out->width + i; + + const int id = BL(roi_out, d, j, i); + out[pout] = (in[pin] - d->sub[id]) / d->div[id]; + } + } +} + +static void convert_float_float(const float *const in, float *const out, const dt_iop_roi_t *const roi_in, + const dt_iop_roi_t *const roi_out, int csx, int csy, + const dt_iop_rawprepare_data_t *const d) +{ +#ifdef _OPENMP +#pragma omp parallel for SIMD() default(none) \ + dt_omp_firstprivate(csx, csy, d, in, out, roi_in, roi_out) \ + schedule(static) collapse(2) +#endif + for(int j = 0; j < roi_out->height; j++) + { + for(int i = 0; i < roi_out->width; i++) + { + const size_t pin = (size_t)(roi_in->width * (j + csy) + csx) + i; + const size_t pout = (size_t)j * roi_out->width + i; + + const int id = BL(roi_out, d, j, i); + out[pout] = (in[pin] - d->sub[id]) / d->div[id]; + } + } +} + +static void convert_float_downsampled(const float *const in, float *const out, const dt_iop_roi_t *const roi_in, + const dt_iop_roi_t *const roi_out, int csx, int csy, + const dt_iop_rawprepare_data_t *const d, int ch, float sub, float div) +{ +#ifdef _OPENMP +#pragma omp parallel for SIMD() default(none) \ + dt_omp_firstprivate(ch, csx, csy, div, in, out, roi_in, roi_out, sub) \ + schedule(static) collapse(3) +#endif + for(int j = 0; j < roi_out->height; j++) + { + for(int i = 0; i < roi_out->width; i++) + { + for(int c = 0; c < ch; c++) + { + const size_t pin = (size_t)ch * (roi_in->width * (j + csy) + csx + i) + c; + const size_t pout = (size_t)ch * (j * roi_out->width + i) + c; + + out[pout] = (in[pin] - sub) / div; + } + } + } +} + /* Some comments about the cpu code path; tests with gcc 10.x show a clear performance gain for the compile generated code vs SSE specific code. This depends slightly on the cpu but it's 1.2 to 3-fold better for all tested cases. @@ -277,22 +345,11 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const const uint16_t *const in = (const uint16_t *const)ivoid; float *const out = (float *const)ovoid; -#ifdef _OPENMP -#pragma omp parallel for SIMD() default(none) \ - dt_omp_firstprivate(csx, csy, d, in, out, roi_in, roi_out) \ - schedule(static) \ - collapse(2) -#endif - for(int j = 0; j < roi_out->height; j++) + for(size_t f = 0; f < piece->dsc_in.frames; ++f) { - for(int i = 0; i < roi_out->width; i++) - { - const size_t pin = (size_t)(roi_in->width * (j + csy) + csx) + i; - const size_t pout = (size_t)j * roi_out->width + i; - - const int id = BL(roi_out, d, j, i); - out[pout] = (in[pin] - d->sub[id]) / d->div[id]; - } + const uint16_t *const frame_in = in + (f * roi_in->width * roi_in->height); + float *const frame_out = out + (f * roi_out->width * roi_out->height); + convert_uint_float(frame_in, frame_out, roi_in, roi_out, csx, csy, d); } piece->pipe->dsc.filters = dt_rawspeed_crop_dcraw_filters(self->dev->image_storage.buf_dsc.filters, csx, csy); @@ -301,26 +358,16 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const else if(piece->pipe->dsc.filters && piece->dsc_in.channels == 1 && piece->dsc_in.datatype == TYPE_FLOAT) { // raw mosaic, fp, unnormalized + ///TODO test const float *const in = (const float *const)ivoid; float *const out = (float *const)ovoid; -#ifdef _OPENMP -#pragma omp parallel for SIMD() default(none) \ - dt_omp_firstprivate(csx, csy, d, in, out, roi_in, roi_out) \ - schedule(static) \ - collapse(2) -#endif - for(int j = 0; j < roi_out->height; j++) + for(size_t f = 0; f < piece->dsc_in.frames; ++f) { - for(int i = 0; i < roi_out->width; i++) - { - const size_t pin = (size_t)(roi_in->width * (j + csy) + csx) + i; - const size_t pout = (size_t)j * roi_out->width + i; - - const int id = BL(roi_out, d, j, i); - out[pout] = (in[pin] - d->sub[id]) / d->div[id]; - } + const float *const frame_in = in + (f * roi_in->width * roi_in->height); + float *const frame_out = out + (f * roi_out->width * roi_out->height); + convert_float_float(frame_in, frame_out, roi_in, roi_out, csx, csy, d); } piece->pipe->dsc.filters = dt_rawspeed_crop_dcraw_filters(self->dev->image_storage.buf_dsc.filters, csx, csy); @@ -328,32 +375,22 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const } else { // pre-downsampled buffer that needs black/white scaling + ///TODO test const float *const in = (const float *const)ivoid; float *const out = (float *const)ovoid; - const float sub = d->sub[0], div = d->div[0]; - + const float sub = d->sub[0]; + const float div = d->div[0]; const int ch = piece->colors; -#ifdef _OPENMP -#pragma omp parallel for SIMD() default(none) \ - dt_omp_firstprivate(ch, csx, csy, div, in, out, roi_in, roi_out, sub) \ - schedule(static) collapse(3) -#endif - for(int j = 0; j < roi_out->height; j++) + for(size_t f = 0; f < piece->dsc_in.frames; ++f) { - for(int i = 0; i < roi_out->width; i++) - { - for(int c = 0; c < ch; c++) - { - const size_t pin = (size_t)ch * (roi_in->width * (j + csy) + csx + i) + c; - const size_t pout = (size_t)ch * (j * roi_out->width + i) + c; - - out[pout] = (in[pin] - sub) / div; - } - } + const float *const frame_in = in + (f * roi_in->width * roi_in->height); + float *const frame_out = out + (f * roi_out->width * roi_out->height); + convert_float_downsampled(frame_in, frame_out, roi_in, roi_out, csx, csy, d,ch,sub,div); } + } dt_dev_write_rawdetail_mask(piece, (float *const)ovoid, roi_in, DT_DEV_DETAIL_MASK_RAWPREPARE); From d66fd5c9593bd343835c2dc20ed718501fd815a1 Mon Sep 17 00:00:00 2001 From: maruncz Date: Wed, 6 Apr 2022 11:27:29 +0200 Subject: [PATCH 06/27] attempt to disable rawprepase opencl version --- src/iop/rawprepare.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index c7ed7bcb652c..ace20679f0d6 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -398,6 +398,7 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const for(int k = 0; k < 4; k++) piece->pipe->dsc.processed_maximum[k] = 1.0f; } +#if 0 ///TODO modify to handle multiframe #ifdef HAVE_OPENCL int process_cl(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out) @@ -473,6 +474,7 @@ int process_cl(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_mem dev_ return FALSE; } #endif +#endif static int image_is_normalized(const dt_image_t *const image) { From b2925b553c48499f56ef37507c7076d98e79998b Mon Sep 17 00:00:00 2001 From: maruncz Date: Wed, 6 Apr 2022 14:24:47 +0200 Subject: [PATCH 07/27] hide debug function --- src/develop/pixelpipe_hb.c | 6 ++++++ src/iop/demosaic.c | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/develop/pixelpipe_hb.c b/src/develop/pixelpipe_hb.c index 3248ecd017e4..45620e70cff7 100644 --- a/src/develop/pixelpipe_hb.c +++ b/src/develop/pixelpipe_hb.c @@ -43,6 +43,8 @@ #include #include +//#define DEBUG_PIXELPIPE + typedef enum dt_pixelpipe_flow_t { PIXELPIPE_FLOW_NONE = 0, @@ -107,6 +109,7 @@ static char *_pipe_type_to_str(int pipe_type) return r; } +#ifdef DEBUG_PIXELPIPE static void save_debug_bitmap(dt_dev_pixelpipe_t *pipe, const char *name, void *out, const dt_iop_roi_t *roi_out) { char filename[128]; @@ -157,6 +160,7 @@ static void save_debug_bitmap(dt_dev_pixelpipe_t *pipe, const char *name, void * } fclose(file); } +#endif int dt_dev_pixelpipe_init_export(dt_dev_pixelpipe_t *pipe, int32_t width, int32_t height, int levels, gboolean store_masks) @@ -2083,7 +2087,9 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * } } +#ifdef DEBUG_PIXELPIPE save_debug_bitmap(pipe,dt_history_item_get_name(module),*output,roi_out); +#endif // 4) colorpicker and scopes: diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 6613edc049c8..8a311bb1e180 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -52,6 +52,7 @@ DT_MODULE_INTROSPECTION(4, dt_iop_demosaic_params_t) #define DEMOSAIC_XTRANS 1024 // masks for non-Bayer demosaic ops #define DEMOSAIC_DUAL 2048 // masks for dual demosaicing methods +#define DEMOSAIC_PIXELSHIFT 4096 // masks for Pentax PixelShift #define REDUCESIZE 64 #define XTRANS_SNAPPER 3 @@ -69,6 +70,8 @@ typedef enum dt_iop_demosaic_method_t DT_IOP_DEMOSAIC_AMAZE_VNG = DEMOSAIC_DUAL | DT_IOP_DEMOSAIC_AMAZE, // $DESCRIPTION: "AMaZE + VNG4" DT_IOP_DEMOSAIC_PASSTHROUGH_MONOCHROME = 3, // $DESCRIPTION: "passthrough (monochrome)" DT_IOP_DEMOSAIC_PASSTHROUGH_COLOR = 4, // $DESCRIPTION: "photosite color (debug)" + // Pentax PixelShift + DT_IOP_DEMOSAIC_PENTAX_PIXELSHIFT = DEMOSAIC_PIXELSHIFT | DT_IOP_DEMOSAIC_AMAZE, // $DESCRIPTION "Pentax PixelShift + AMAZE" // methods for x-trans images DT_IOP_DEMOSAIC_VNG = DEMOSAIC_XTRANS | 0, // $DESCRIPTION: "VNG" DT_IOP_DEMOSAIC_MARKESTEIJN = DEMOSAIC_XTRANS | 1, // $DESCRIPTION: "Markesteijn 1-pass" @@ -5782,11 +5785,11 @@ void gui_init(struct dt_iop_module_t *self) GtkWidget *box_raw = self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); g->demosaic_method_bayer = dt_bauhaus_combobox_from_params(self, "demosaicing_method"); - for(int i=0;i<7;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_bayer, 9); + //for(int i=0;i<7;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_bayer, 10); gtk_widget_set_tooltip_text(g->demosaic_method_bayer, _("Bayer sensor demosaicing method, PPG and RCD are fast, AMaZE and LMMSE are slow.\nLMMSE is suited best for high ISO images.\ndual demosaicers double processing time.")); g->demosaic_method_xtrans = dt_bauhaus_combobox_from_params(self, "demosaicing_method"); - for(int i=0;i<9;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_xtrans, 0); + //for(int i=0;i<10;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_xtrans, 0); gtk_widget_set_tooltip_text(g->demosaic_method_xtrans, _("X-Trans sensor demosaicing method, Markesteijn 3-pass and frequency domain chroma are slow.\ndual demosaicers double processing time.")); g->median_thrs = dt_bauhaus_slider_from_params(self, "median_thrs"); From 390344317f6b0b5020f8fcafe02257c9c5306353 Mon Sep 17 00:00:00 2001 From: maruncz Date: Thu, 7 Apr 2022 07:45:31 +0200 Subject: [PATCH 08/27] revert unintended change --- src/iop/demosaic.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 8a311bb1e180..dc3ab5123f32 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -52,7 +52,6 @@ DT_MODULE_INTROSPECTION(4, dt_iop_demosaic_params_t) #define DEMOSAIC_XTRANS 1024 // masks for non-Bayer demosaic ops #define DEMOSAIC_DUAL 2048 // masks for dual demosaicing methods -#define DEMOSAIC_PIXELSHIFT 4096 // masks for Pentax PixelShift #define REDUCESIZE 64 #define XTRANS_SNAPPER 3 @@ -70,8 +69,6 @@ typedef enum dt_iop_demosaic_method_t DT_IOP_DEMOSAIC_AMAZE_VNG = DEMOSAIC_DUAL | DT_IOP_DEMOSAIC_AMAZE, // $DESCRIPTION: "AMaZE + VNG4" DT_IOP_DEMOSAIC_PASSTHROUGH_MONOCHROME = 3, // $DESCRIPTION: "passthrough (monochrome)" DT_IOP_DEMOSAIC_PASSTHROUGH_COLOR = 4, // $DESCRIPTION: "photosite color (debug)" - // Pentax PixelShift - DT_IOP_DEMOSAIC_PENTAX_PIXELSHIFT = DEMOSAIC_PIXELSHIFT | DT_IOP_DEMOSAIC_AMAZE, // $DESCRIPTION "Pentax PixelShift + AMAZE" // methods for x-trans images DT_IOP_DEMOSAIC_VNG = DEMOSAIC_XTRANS | 0, // $DESCRIPTION: "VNG" DT_IOP_DEMOSAIC_MARKESTEIJN = DEMOSAIC_XTRANS | 1, // $DESCRIPTION: "Markesteijn 1-pass" @@ -5785,7 +5782,7 @@ void gui_init(struct dt_iop_module_t *self) GtkWidget *box_raw = self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); g->demosaic_method_bayer = dt_bauhaus_combobox_from_params(self, "demosaicing_method"); - //for(int i=0;i<7;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_bayer, 10); + for(int i=0;i<7;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_bayer, 9); gtk_widget_set_tooltip_text(g->demosaic_method_bayer, _("Bayer sensor demosaicing method, PPG and RCD are fast, AMaZE and LMMSE are slow.\nLMMSE is suited best for high ISO images.\ndual demosaicers double processing time.")); g->demosaic_method_xtrans = dt_bauhaus_combobox_from_params(self, "demosaicing_method"); From a2435e14ee6d852a9f79bb18eff15b0ded3f40d1 Mon Sep 17 00:00:00 2001 From: maruncz Date: Fri, 8 Apr 2022 13:11:42 +0200 Subject: [PATCH 09/27] rawprepare probably fixed --- src/common/mipmap_cache.c | 7 ++++--- src/iop/rawprepare.c | 25 ++++++++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/common/mipmap_cache.c b/src/common/mipmap_cache.c index 374cf6867ec3..3ad6c79c102b 100644 --- a/src/common/mipmap_cache.c +++ b/src/common/mipmap_cache.c @@ -337,7 +337,7 @@ void dt_mipmap_cache_allocate_dynamic(void *data, dt_cache_entry_t *entry) entry->data = dt_alloc_align(64, entry->data_size); - // fprintf(stderr, "[mipmap cache] alloc dynamic for key %u %p\n", key, *buf); + fprintf(stderr, "[mipmap cache] alloc dynamic for key %u %p %lu\n", entry->key, entry->data, entry->data_size); if(!(entry->data)) { fprintf(stderr, "[mipmap cache] memory allocation failed!\n"); @@ -1285,10 +1285,11 @@ static void _init_8(uint8_t *buf, uint32_t *width, uint32_t *height, float *isca *iscale = 1.0f; *color_space = dt_mipmap_cache_get_colorspace(); } + fprintf(stderr, "[mipmap init 8] export image %u finished (sizes %d %d => %d %d)!\n", imgid, wd, ht, + dat.head.width, dat.head.height); } - // fprintf(stderr, "[mipmap init 8] export image %u finished (sizes %d %d => %d %d)!\n", imgid, wd, ht, - // dat.head.width, dat.head.height); + // any errors? if(res) diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index ace20679f0d6..e369e2425acf 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -231,7 +231,15 @@ void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixel dt_iop_buffer_dsc_t *dsc) { default_output_format(self, pipe, piece, dsc); - dsc->frames = pipe->image.buf_dsc.frames; + // multiframe not needed for subsampled images + if(pipe->type == (DT_DEV_PIXELPIPE_FULL | DT_DEV_PIXELPIPE_EXPORT)) + { + dsc->frames = pipe->image.buf_dsc.frames; + } + else + { + dsc->frames = 1; + } dt_iop_rawprepare_data_t *d = (dt_iop_rawprepare_data_t *)piece->data; dsc->rawprepare.raw_black_level = d->rawprepare.raw_black_level; @@ -260,6 +268,8 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const const dt_iop_roi_t *const roi_out, int csx, int csy, const dt_iop_rawprepare_data_t *const d) { + fprintf(stderr,"in: %p - %p, size %i\n",in, in + (roi_in->height * roi_in->width), (roi_in->height * roi_in->width)); + fprintf(stderr,"out: %p - %p, size %i\n",out, out + (roi_out->height * roi_out->width),(roi_out->height * roi_out->width)); #ifdef _OPENMP #pragma omp parallel for SIMD() default(none) \ dt_omp_firstprivate(csx, csy, d, in, out, roi_in, roi_out) \ @@ -333,10 +343,15 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const { const dt_iop_rawprepare_data_t *const d = (dt_iop_rawprepare_data_t *)piece->data; - // fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); - // fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); + fprintf(stderr,"frame size iout: %d\n", roi_out->width * roi_out->height); + fprintf(stderr,"i: %p\n",ivoid); + fprintf(stderr,"o: %p\n",ovoid); - const int csx = compute_proper_crop(piece, roi_in, d->x), csy = compute_proper_crop(piece, roi_in, d->y); + const int csx = compute_proper_crop(piece, roi_in, d->x); + const int csy = compute_proper_crop(piece, roi_in, d->y); if(piece->pipe->dsc.filters && piece->dsc_in.channels == 1 && piece->dsc_in.datatype == TYPE_UINT16) @@ -345,7 +360,7 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const const uint16_t *const in = (const uint16_t *const)ivoid; float *const out = (float *const)ovoid; - for(size_t f = 0; f < piece->dsc_in.frames; ++f) + for(size_t f = 0; f < piece->dsc_out.frames; ++f) { const uint16_t *const frame_in = in + (f * roi_in->width * roi_in->height); float *const frame_out = out + (f * roi_out->width * roi_out->height); From a52d8669ef09722762d1e5434fcf41db24bfe436 Mon Sep 17 00:00:00 2001 From: maruncz Date: Thu, 14 Apr 2022 15:00:32 +0200 Subject: [PATCH 10/27] some work in demosaic --- src/iop/demosaic.c | 87 +++++++++++++++++++++++++++++++++++++++++++- src/iop/rawprepare.c | 10 ++--- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index dc3ab5123f32..79c8777987c2 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -124,6 +124,7 @@ typedef struct dt_iop_demosaic_params_t dt_iop_demosaic_method_t demosaicing_method; // $DEFAULT: DT_IOP_DEMOSAIC_RCD $DESCRIPTION: "demosaicing method" dt_iop_demosaic_lmmse_t lmmse_refine; // $DEFAULT: LMMSE_REFINE_1 $DESCRIPTION: "lmmse refine" float dual_thrs; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.20 $DESCRIPTION: "dual threshold" + gboolean pixelshift_enable; // $DEFAULT: 0 $DESCRIPTION: "enable pixelshift" } dt_iop_demosaic_params_t; typedef struct dt_iop_demosaic_gui_data_t @@ -135,6 +136,10 @@ typedef struct dt_iop_demosaic_gui_data_t GtkWidget *demosaic_method_xtrans; GtkWidget *dual_thrs; GtkWidget *lmmse_refine; + GtkWidget *pixelshift_enable; + GtkWidget *pixelshift_select_frame; + GtkWidget *pixelshift_motion_correction; + GtkWidget *pixelshift_show_motion_mask; gboolean visual_mask; } dt_iop_demosaic_gui_data_t; @@ -204,6 +209,7 @@ typedef struct dt_iop_demosaic_data_t float median_thrs; double CAM_to_RGB[3][4]; float dual_thrs; + gboolean pixelshift_enable; } dt_iop_demosaic_data_t; // Implemented on amaze_demosaic_RT.cc @@ -2936,6 +2942,47 @@ static int demosaic_qual_flags(const dt_dev_pixelpipe_iop_t *const piece, #include "dual_demosaic.c" +void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const i, float *const o, const dt_iop_roi_t *const roi_in, + const dt_iop_roi_t *const roi_out) +{ + float const * frames_in[4]; + for(int f = 0; f < 4; ++f) + { + /// TODO need original size here + frames_in[f] = i + (f * roi_in->width * roi_in->height); + } + + if(piece->dsc_out.channels != 4) + { + fprintf(stderr, "unsuported number of output channels, got: %i\n", piece->dsc_out.channels); + } + + fprintf(stderr, "demosaic enabled\n"); + fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + + //const size_t row_offset = roi_out->height; + + for(size_t idx = 0; idx < roi_out->width * roi_out->height * piece->dsc_out.channels; + idx += piece->dsc_out.channels) + { + // R + o[idx + 0] = frames_in[0][idx/piece->dsc_out.channels]; + // G + o[idx + 1] = frames_in[1][idx/piece->dsc_out.channels]; + o[idx + 1] += frames_in[2][idx/piece->dsc_out.channels]; + o[idx + 1] /= 2.0; + // B + o[idx + 2] = frames_in[3][idx/piece->dsc_out.channels]; + /*for(size_t c = 0; c < 3; ++c) + { + o[idx + c] = i[idx / piece->dsc_out.channels]; + }*/ + } + +} + + void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *const i, void *const o, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out) { @@ -2945,6 +2992,9 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_dev_clear_rawdetail_mask(piece->pipe); + /*fprintf(stderr, "demosaic, %s\n", dt_pixelpipe_name(piece->pipe->type)); + fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height);*/ dt_iop_roi_t roi = *roi_in; dt_iop_roi_t roo = *roi_out; roo.x = roo.y = 0; @@ -3019,6 +3069,10 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const else vng_interpolate(tmp, pixels, &roo, &roi, piece->pipe->dsc.filters, xtrans, qual_flags & DEMOSAIC_ONLY_VNG_LINEAR); } + else if(data->pixelshift_enable) + { + process_pixelshift(piece, pixels, tmp, &roi, &roo); + } else { float *in = (float *)pixels; @@ -3132,7 +3186,7 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const color_smoothing(o, roi_out, data->color_smoothing); } -#ifdef HAVE_OPENCL +#if 0 //#ifdef HAVE_OPENCL // color smoothing step by multiple passes of median filtering static int color_smoothing_cl(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out, const dt_iop_roi_t *const roi_out, const int passes) @@ -5559,6 +5613,19 @@ void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *params, dt_dev d->median_thrs = p->median_thrs; d->dual_thrs = p->dual_thrs; d->lmmse_refine = p->lmmse_refine; + if(pipe->type & (DT_DEV_PIXELPIPE_FULL | DT_DEV_PIXELPIPE_EXPORT)) + { + d->pixelshift_enable = (p->pixelshift_enable && (piece->dsc_in.frames == 4)); + ///TODO this should also change checkbox + + //fprintf(stderr, "demosaic ,commit_params, %s, pixelshift: %i\n", dt_pixelpipe_name(pipe->type), d->pixelshift_enable); + } + else + { + d->pixelshift_enable = FALSE; + } + + dt_iop_demosaic_method_t use_method = p->demosaicing_method; const gboolean xmethod = use_method & DEMOSAIC_XTRANS; const gboolean bayer = (self->dev->image_storage.buf_dsc.filters != 9u); @@ -5711,6 +5778,8 @@ void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous) (use_method == DT_IOP_DEMOSAIC_PASSTHROUGH_COLOR) || (use_method == DT_IOP_DEMOSAIC_PASSTHR_MONOX) || (use_method == DT_IOP_DEMOSAIC_PASSTHR_COLORX)); + ///TODO doesn't take into account previous modules? + const gboolean ispixelshift = (self->dev->image_storage.buf_dsc.frames == 4); gtk_widget_set_visible(g->demosaic_method_bayer, bayer); gtk_widget_set_visible(g->demosaic_method_xtrans, !bayer); @@ -5724,6 +5793,12 @@ void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous) gtk_widget_set_visible(g->color_smoothing, !passing && !isdual); gtk_widget_set_visible(g->dual_thrs, isdual); gtk_widget_set_visible(g->lmmse_refine, islmmse); + gtk_widget_set_visible(g->pixelshift_enable, bayer && ispixelshift); + /*if(!bayer || !ispixelshift) + { + gtk_set_active(g->pixelshift_enable, FALSE); + }*/ + //gtk_widget_set_visible(g->pixelshift_select_frame, bayer && ispixelshift); dt_image_t *img = dt_image_cache_get(darktable.image_cache, self->dev->image_storage.id, 'w'); int changed = img->flags & DT_IMAGE_MONOCHROME_BAYER; @@ -5793,7 +5868,6 @@ void gui_init(struct dt_iop_module_t *self) dt_bauhaus_slider_set_digits(g->median_thrs, 3); gtk_widget_set_tooltip_text(g->median_thrs, _("threshold for edge-aware median.\nset to 0.0 to switch off\n" "set to 1.0 to ignore edges")); - g->dual_thrs = dt_bauhaus_slider_from_params(self, "dual_thrs"); dt_bauhaus_slider_set_digits(g->dual_thrs, 2); gtk_widget_set_tooltip_text(g->dual_thrs, _("contrast threshold for dual demosaic.\nset to 0.0 for high frequency content\n" @@ -5812,6 +5886,15 @@ void gui_init(struct dt_iop_module_t *self) g->greeneq = dt_bauhaus_combobox_from_params(self, "green_eq"); gtk_widget_set_tooltip_text(g->greeneq, _("green channels matching method")); + g->pixelshift_enable = dt_bauhaus_toggle_from_params(self, "pixelshift_enable"); + + /*g->pixelshift_select_frame = dt_bauhaus_combobox_new(self); + dt_bauhaus_widget_set_label(g->pixelshift_select_frame,NULL,"input frames"); + gtk_widget_set_tooltip_text(g->pixelshift_select_frame,"input frames"); + dt_bauhaus_combobox_add(g->pixelshift_select_frame,"all"); + dt_bauhaus_combobox_add(g->pixelshift_select_frame,"test"); + gtk_box_pack_start(GTK_BOX(self->widget), g->pixelshift_select_frame, FALSE, FALSE, 0);*/ + // start building top level widget self->widget = gtk_stack_new(); gtk_stack_set_homogeneous(GTK_STACK(self->widget), FALSE); diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index e369e2425acf..a877e4eea5bd 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -232,7 +232,7 @@ void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixel { default_output_format(self, pipe, piece, dsc); // multiframe not needed for subsampled images - if(pipe->type == (DT_DEV_PIXELPIPE_FULL | DT_DEV_PIXELPIPE_EXPORT)) + if(pipe->type & (DT_DEV_PIXELPIPE_FULL | DT_DEV_PIXELPIPE_EXPORT)) { dsc->frames = pipe->image.buf_dsc.frames; } @@ -268,8 +268,8 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const const dt_iop_roi_t *const roi_out, int csx, int csy, const dt_iop_rawprepare_data_t *const d) { - fprintf(stderr,"in: %p - %p, size %i\n",in, in + (roi_in->height * roi_in->width), (roi_in->height * roi_in->width)); - fprintf(stderr,"out: %p - %p, size %i\n",out, out + (roi_out->height * roi_out->width),(roi_out->height * roi_out->width)); + /*fprintf(stderr,"in: %p - %p, size %i\n",in, in + (roi_in->height * roi_in->width), (roi_in->height * roi_in->width)); + fprintf(stderr,"out: %p - %p, size %i\n",out, out + (roi_out->height * roi_out->width),(roi_out->height * roi_out->width));*/ #ifdef _OPENMP #pragma omp parallel for SIMD() default(none) \ dt_omp_firstprivate(csx, csy, d, in, out, roi_in, roi_out) \ @@ -343,12 +343,12 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const { const dt_iop_rawprepare_data_t *const d = (dt_iop_rawprepare_data_t *)piece->data; - fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + /*fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); fprintf(stderr,"frame size iout: %d\n", roi_out->width * roi_out->height); fprintf(stderr,"i: %p\n",ivoid); - fprintf(stderr,"o: %p\n",ovoid); + fprintf(stderr,"o: %p\n",ovoid);*/ const int csx = compute_proper_crop(piece, roi_in, d->x); const int csy = compute_proper_crop(piece, roi_in, d->y); From ee1c14b4befb72c45eb9ee3d8761b0dba33493b2 Mon Sep 17 00:00:00 2001 From: maruncz Date: Tue, 19 Apr 2022 15:26:05 +0200 Subject: [PATCH 11/27] some demosaic experiments --- src/external/rawspeed | 2 +- src/iop/demosaic.c | 61 +++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/external/rawspeed b/src/external/rawspeed index b7d51d51ec17..a7cf21a5ef48 160000 --- a/src/external/rawspeed +++ b/src/external/rawspeed @@ -1 +1 @@ -Subproject commit b7d51d51ec17a738cb455a82eec0fe49b857d4d0 +Subproject commit a7cf21a5ef487f47f11e0228af645b876e2d560a diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 79c8777987c2..7e665513e058 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2942,14 +2942,16 @@ static int demosaic_qual_flags(const dt_dev_pixelpipe_iop_t *const piece, #include "dual_demosaic.c" -void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const i, float *const o, const dt_iop_roi_t *const roi_in, +void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, float *const out, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out) { + assert(roi_in->width >= roi_out->width); + assert(roi_in->height >= roi_out->height); float const * frames_in[4]; for(int f = 0; f < 4; ++f) { /// TODO need original size here - frames_in[f] = i + (f * roi_in->width * roi_in->height); + frames_in[f] = in + (f * piece->buf_in.width * piece->buf_in.height); } if(piece->dsc_out.channels != 4) @@ -2957,29 +2959,47 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const i, flo fprintf(stderr, "unsuported number of output channels, got: %i\n", piece->dsc_out.channels); } - fprintf(stderr, "demosaic enabled\n"); + fprintf(stderr, "pixelshift enabled, pipe type: %s\n", dt_pixelpipe_name(piece->pipe->type)); fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); - //const size_t row_offset = roi_out->height; + const size_t ox = roi_in->x; + const size_t oy = roi_in->y; - for(size_t idx = 0; idx < roi_out->width * roi_out->height * piece->dsc_out.channels; - idx += piece->dsc_out.channels) + + size_t pout = 0; + size_t pin = 0; + for(size_t j = 0; j < roi_out->height; j++) { - // R - o[idx + 0] = frames_in[0][idx/piece->dsc_out.channels]; - // G - o[idx + 1] = frames_in[1][idx/piece->dsc_out.channels]; - o[idx + 1] += frames_in[2][idx/piece->dsc_out.channels]; - o[idx + 1] /= 2.0; - // B - o[idx + 2] = frames_in[3][idx/piece->dsc_out.channels]; - /*for(size_t c = 0; c < 3; ++c) + for(size_t i = 0; i < roi_out->width; i++) { - o[idx + c] = i[idx / piece->dsc_out.channels]; - }*/ - } + pout = 4 * ((roi_out->width * j) + i); + pin = (roi_in->width * (j + oy)) + ox + i; + + for(size_t c=0;c<3;++c) + { + out[pout+c] = (frames_in[0])[pin]; + } + + out[pout + 0] = (float) j / (float) roi_out->height; + out[pout + 1] = (float) i / (float) roi_out->width; + out[pout + 2] = 0.0f; + out[pout + 3] = 0.0f; + + + //out[pout + 0] = frames_in[0][pin]; + + /*out[pout + 1] = (frames_in[0][pin] + frames_in[0][pin]) / 2.0f; + + out[pout + 2] = frames_in[0][pin];*/ + + /*out[pout] = 1.0f; + out[pout+1] = 0.0f; + out[pout+2] = 0.0f; + out[pout+3] = 0.0f;*/ + } + } } @@ -2992,9 +3012,9 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_dev_clear_rawdetail_mask(piece->pipe); - /*fprintf(stderr, "demosaic, %s\n", dt_pixelpipe_name(piece->pipe->type)); + fprintf(stderr, "demosaic, %s\n", dt_pixelpipe_name(piece->pipe->type)); fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); - fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height);*/ + fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); dt_iop_roi_t roi = *roi_in; dt_iop_roi_t roo = *roi_out; roo.x = roo.y = 0; @@ -3046,6 +3066,7 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const roo.height = roi_in->height; roo.scale = 1.0f; tmp = (float *)dt_alloc_align_float((size_t)4 * roo.width * roo.height); + fprintf(stderr,"scaled\n"); } if(info) dt_get_times(&start_time); From ed12c601b5de38301d09a53823953c3117fb925b Mon Sep 17 00:00:00 2001 From: maruncz Date: Tue, 19 Apr 2022 18:46:39 +0200 Subject: [PATCH 12/27] this should behave like monochrome passthru but doesn't --- src/iop/demosaic.c | 23 ++++++++++++++++++++--- src/iop/rawprepare.c | 1 + src/tests/integration | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 7e665513e058..e32f0eee0620 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2973,18 +2973,34 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl { for(size_t i = 0; i < roi_out->width; i++) { - pout = 4 * ((roi_out->width * j) + i); + pout = (size_t)4 * ((roi_out->width * j) + i); pin = (roi_in->width * (j + oy)) + ox + i; + if(pin >= 24000000) + { + fprintf(stderr,"input overflow\n"); + } + + if(pin >= 24000000) + { + fprintf(stderr,"input overflow\n"); + } + + if(pout >= ((size_t)4*roi_out->height*roi_out->width)) + { + fprintf(stderr,"output overflow\n"); + } + for(size_t c=0;c<3;++c) { out[pout+c] = (frames_in[0])[pin]; + //out[pout+c] = (float) pin / ((float) roi_out->height * roi_out->width); } - out[pout + 0] = (float) j / (float) roi_out->height; + /*out[pout + 0] = (float) j / (float) roi_out->height; out[pout + 1] = (float) i / (float) roi_out->width; out[pout + 2] = 0.0f; - out[pout + 3] = 0.0f; + out[pout + 3] = 0.0f;*/ @@ -3000,6 +3016,7 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl out[pout+3] = 0.0f;*/ } } + fprintf(stderr,"pout: %lu\n", pout+4); } diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index a877e4eea5bd..833c42cd9708 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -284,6 +284,7 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const const int id = BL(roi_out, d, j, i); out[pout] = (in[pin] - d->sub[id]) / d->div[id]; + //out[pout] = ((j/10)%2)?1.0f:0.0f; } } } diff --git a/src/tests/integration b/src/tests/integration index 1acf3d6461c8..f8ac222b1315 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit 1acf3d6461c84218b3e1a4224978812d0ef95781 +Subproject commit f8ac222b13155e77231f15ee7181cbfd1e705973 From 302ac0cb7f0e4e9b1c756c55f5778e9349af8c75 Mon Sep 17 00:00:00 2001 From: maruncz Date: Wed, 20 Apr 2022 13:01:09 +0200 Subject: [PATCH 13/27] there is some systematic error, htat i cannot see --- src/common/imageio_rawspeed.cc | 2 +- src/develop/pixelpipe_hb.c | 10 +++++-- src/iop/demosaic.c | 49 +++++++++------------------------- src/iop/rawprepare.c | 2 +- src/tests/integration | 2 +- 5 files changed, 24 insertions(+), 41 deletions(-) diff --git a/src/common/imageio_rawspeed.cc b/src/common/imageio_rawspeed.cc index 02c728674b39..d405457dd74f 100644 --- a/src/common/imageio_rawspeed.cc +++ b/src/common/imageio_rawspeed.cc @@ -515,7 +515,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena const size_t bufSize_mipmap = (size_t)img->width * img->height * img->buf_dsc.frames * r.get(0)->getBpp(); const size_t bufSize_rawspeed = (size_t)r.get(0)->pitch * dimUncropped.y * r.size(); const size_t frame_size = bufSize_mipmap / r.size(); - printf("size mipmap: %lu\n size raw: %lu\nsize frame: %lu\n",bufSize_mipmap,bufSize_rawspeed,frame_size); + fprintf(stderr,"[rawspeed] size mipmap: %lu, size raw: %lu, size frame: %lu\n",bufSize_mipmap,bufSize_rawspeed,frame_size); for(size_t i = 0; i < r.size(); ++i) { dt_imageio_flip_buffers(((char *)buf) + (i * frame_size), (char *)r.get(i)->getDataUncropped(0, 0), diff --git a/src/develop/pixelpipe_hb.c b/src/develop/pixelpipe_hb.c index 45620e70cff7..d51b0b7f22c3 100644 --- a/src/develop/pixelpipe_hb.c +++ b/src/develop/pixelpipe_hb.c @@ -43,7 +43,7 @@ #include #include -//#define DEBUG_PIXELPIPE +#define DEBUG_PIXELPIPE typedef enum dt_pixelpipe_flow_t { @@ -112,6 +112,11 @@ static char *_pipe_type_to_str(int pipe_type) #ifdef DEBUG_PIXELPIPE static void save_debug_bitmap(dt_dev_pixelpipe_t *pipe, const char *name, void *out, const dt_iop_roi_t *roi_out) { + /*if(pipe->type != DT_DEV_PIXELPIPE_FULL) + { + return; + }*/ + char filename[128]; snprintf(filename, 128, "save_debug_bitmap_%s_%s.pfm", name, _pipe_type_to_str(pipe->type)); for(int i = 0; i < 128; ++i) @@ -1227,6 +1232,7 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * const int in_y = MAX(roi_in.y, 0); const int cp_width = MAX(0, MIN(roi_out->width, pipe->iwidth - in_x)); const int cp_height = MIN(roi_out->height, pipe->iheight - in_y); + const int frames = pipe->dsc.frames; if (cp_width > 0) { @@ -1236,7 +1242,7 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * shared(pipe, roi_out, roi_in, output) \ schedule(static) #endif - for(int j = 0; j < cp_height; j++) + for(int j = 0; j < cp_height * frames; j++) memcpy(((char *)*output) + (size_t)bpp * j * roi_out->width, ((char *)pipe->input) + (size_t)bpp * (in_x + (in_y + j) * pipe->iwidth), (size_t)bpp * cp_width); diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index e32f0eee0620..b2204fc727a5 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2963,57 +2963,34 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); - const size_t ox = roi_in->x; - const size_t oy = roi_in->y; + /*__asan_describe_address((void*)in); + fflush(stdout); + fflush(stderr);*/ + //const size_t ox = roi_in->x; + //const size_t oy = roi_in->y; size_t pout = 0; - size_t pin = 0; + //size_t pin = 0; + size_t pin3 = 0; for(size_t j = 0; j < roi_out->height; j++) { for(size_t i = 0; i < roi_out->width; i++) { - pout = (size_t)4 * ((roi_out->width * j) + i); - pin = (roi_in->width * (j + oy)) + ox + i; + pout = (size_t)4 * (((size_t)roi_out->width * j) + i); + //pin = (roi_in->width * (j + oy)) + ox + i; + ///TODO why do i ignore offset of input roi? + pin3 = (roi_in->width * j) + i; - if(pin >= 24000000) - { - fprintf(stderr,"input overflow\n"); - } - - if(pin >= 24000000) - { - fprintf(stderr,"input overflow\n"); - } - - if(pout >= ((size_t)4*roi_out->height*roi_out->width)) + if(pout+3 >= ((size_t)4*((size_t)roi_out->height*roi_out->width))) { fprintf(stderr,"output overflow\n"); } for(size_t c=0;c<3;++c) { - out[pout+c] = (frames_in[0])[pin]; - //out[pout+c] = (float) pin / ((float) roi_out->height * roi_out->width); + out[pout+c] = (frames_in[1])[pin3]; } - - /*out[pout + 0] = (float) j / (float) roi_out->height; - out[pout + 1] = (float) i / (float) roi_out->width; - out[pout + 2] = 0.0f; - out[pout + 3] = 0.0f;*/ - - - - //out[pout + 0] = frames_in[0][pin]; - - /*out[pout + 1] = (frames_in[0][pin] + frames_in[0][pin]) / 2.0f; - - out[pout + 2] = frames_in[0][pin];*/ - - /*out[pout] = 1.0f; - out[pout+1] = 0.0f; - out[pout+2] = 0.0f; - out[pout+3] = 0.0f;*/ } } fprintf(stderr,"pout: %lu\n", pout+4); diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index 833c42cd9708..9f1931d1144e 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -284,7 +284,6 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const const int id = BL(roi_out, d, j, i); out[pout] = (in[pin] - d->sub[id]) / d->div[id]; - //out[pout] = ((j/10)%2)?1.0f:0.0f; } } } @@ -344,6 +343,7 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const { const dt_iop_rawprepare_data_t *const d = (dt_iop_rawprepare_data_t *)piece->data; + //fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); /*fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); diff --git a/src/tests/integration b/src/tests/integration index f8ac222b1315..1acf3d6461c8 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit f8ac222b13155e77231f15ee7181cbfd1e705973 +Subproject commit 1acf3d6461c84218b3e1a4224978812d0ef95781 From 4ef692e492397ceabdaaa55b2d423655da70734e Mon Sep 17 00:00:00 2001 From: maruncz Date: Wed, 20 Apr 2022 15:07:31 +0200 Subject: [PATCH 14/27] looks ok, but still issues with frame offset --- src/develop/imageop.h | 1 + src/iop/demosaic.c | 7 ++++--- src/iop/rawprepare.c | 18 +++++++++++++----- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/develop/imageop.h b/src/develop/imageop.h index a66be77c71d5..2b4c5f7f84ba 100644 --- a/src/develop/imageop.h +++ b/src/develop/imageop.h @@ -28,6 +28,7 @@ typedef struct dt_iop_roi_t { int x, y, width, height; float scale; + int frame_offset; } dt_iop_roi_t; #include "common/darktable.h" diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index b2204fc727a5..5bbbf2eb1286 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2950,8 +2950,7 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl float const * frames_in[4]; for(int f = 0; f < 4; ++f) { - /// TODO need original size here - frames_in[f] = in + (f * piece->buf_in.width * piece->buf_in.height); + frames_in[f] = in + (f * roi_in->width * roi_in->height); } if(piece->dsc_out.channels != 4) @@ -2962,6 +2961,8 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl fprintf(stderr, "pixelshift enabled, pipe type: %s\n", dt_pixelpipe_name(piece->pipe->type)); fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + fprintf(stderr, "i: %p\n",in); + fprintf(stderr, "o: %p\n",out); /*__asan_describe_address((void*)in); fflush(stdout); @@ -2989,7 +2990,7 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl for(size_t c=0;c<3;++c) { - out[pout+c] = (frames_in[1])[pin3]; + out[pout+c] = (frames_in[0])[pin3]; } } } diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index 9f1931d1144e..e3cfa85088bb 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -212,6 +212,14 @@ void modify_roi_out(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, dt_iop const float scale = roi_in->scale / piece->iscale; roi_out->width -= (int)roundf((float)x * scale); roi_out->height -= (int)roundf((float)y * scale); + + if(piece->pipe->type & (DT_DEV_PIXELPIPE_FULL | DT_DEV_PIXELPIPE_EXPORT)) + { + if(piece->pipe->image.buf_dsc.frames > 1) + { + roi_out->frame_offset = roi_out->width * roi_out->height; + } + } } void modify_roi_in(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out, @@ -343,13 +351,13 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const { const dt_iop_rawprepare_data_t *const d = (dt_iop_rawprepare_data_t *)piece->data; - //fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); - /*fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); + fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); - fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); - fprintf(stderr,"frame size iout: %d\n", roi_out->width * roi_out->height); + /*fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); + fprintf(stderr,"frame size iout: %d\n", roi_out->width * roi_out->height);*/ fprintf(stderr,"i: %p\n",ivoid); - fprintf(stderr,"o: %p\n",ovoid);*/ + fprintf(stderr,"o: %p\n",ovoid); const int csx = compute_proper_crop(piece, roi_in, d->x); const int csy = compute_proper_crop(piece, roi_in, d->y); From 27a81cb1b61d438c70983d290652865151644e36 Mon Sep 17 00:00:00 2001 From: maruncz Date: Wed, 20 Apr 2022 19:33:15 +0200 Subject: [PATCH 15/27] looks like issue with frame offset input to rawprepare --- src/common/imageio_rawspeed.cc | 1 + src/develop/imageop.h | 1 - src/develop/pixelpipe_hb.c | 17 ++++++++++++++--- src/iop/demosaic.c | 3 ++- src/iop/rawprepare.c | 27 ++++++++++++++++++--------- src/tests/integration | 2 +- 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/common/imageio_rawspeed.cc b/src/common/imageio_rawspeed.cc index d405457dd74f..94f66124949b 100644 --- a/src/common/imageio_rawspeed.cc +++ b/src/common/imageio_rawspeed.cc @@ -518,6 +518,7 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena fprintf(stderr,"[rawspeed] size mipmap: %lu, size raw: %lu, size frame: %lu\n",bufSize_mipmap,bufSize_rawspeed,frame_size); for(size_t i = 0; i < r.size(); ++i) { + fprintf(stderr,"[rawspeed] frame %lu, %p\n",i, (void*)((char *)buf + (i*frame_size))); dt_imageio_flip_buffers(((char *)buf) + (i * frame_size), (char *)r.get(i)->getDataUncropped(0, 0), r.get(i)->getBpp(), dimUncropped.x, dimUncropped.y, dimUncropped.x, dimUncropped.y, r.get(i)->pitch, ORIENTATION_NONE); diff --git a/src/develop/imageop.h b/src/develop/imageop.h index 2b4c5f7f84ba..a66be77c71d5 100644 --- a/src/develop/imageop.h +++ b/src/develop/imageop.h @@ -28,7 +28,6 @@ typedef struct dt_iop_roi_t { int x, y, width, height; float scale; - int frame_offset; } dt_iop_roi_t; #include "common/darktable.h" diff --git a/src/develop/pixelpipe_hb.c b/src/develop/pixelpipe_hb.c index d51b0b7f22c3..c55c6ffd23cf 100644 --- a/src/develop/pixelpipe_hb.c +++ b/src/develop/pixelpipe_hb.c @@ -112,10 +112,10 @@ static char *_pipe_type_to_str(int pipe_type) #ifdef DEBUG_PIXELPIPE static void save_debug_bitmap(dt_dev_pixelpipe_t *pipe, const char *name, void *out, const dt_iop_roi_t *roi_out) { - /*if(pipe->type != DT_DEV_PIXELPIPE_FULL) + if(pipe->type != DT_DEV_PIXELPIPE_FULL) { return; - }*/ + } char filename[128]; snprintf(filename, 128, "save_debug_bitmap_%s_%s.pfm", name, _pipe_type_to_str(pipe->type)); @@ -150,7 +150,18 @@ static void save_debug_bitmap(dt_dev_pixelpipe_t *pipe, const char *name, void * float *ptr = (float *)out; if((pipe->dsc.channels == 1) || (pipe->dsc.channels == 3)) { - fwrite(ptr, sizeof(float), roi_out->height * roi_out->width * pipe->dsc.channels * pipe->dsc.frames, file); + for(size_t f = 0; f < pipe->dsc.frames; ++f) + { + float *tmp = ptr + (f * roi_out->width * roi_out->height); + for(size_t i = 0; i < roi_out->width; ++i) + { + for(size_t j = 0; j < roi_out->height; ++j) + { + const size_t pout = j + (roi_out->height * (i)); + fwrite(tmp + pout, sizeof(float) * pipe->dsc.channels, 1, file); + } + } + } } else { diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 5bbbf2eb1286..77bb38156113 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2951,6 +2951,7 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl for(int f = 0; f < 4; ++f) { frames_in[f] = in + (f * roi_in->width * roi_in->height); + fprintf(stderr, "frame %i: %p\n", f, frames_in[f]); } if(piece->dsc_out.channels != 4) @@ -2990,7 +2991,7 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl for(size_t c=0;c<3;++c) { - out[pout+c] = (frames_in[0])[pin3]; + out[pout+c] = (frames_in[2])[pin3]; } } } diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index e3cfa85088bb..21136c6f4710 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -212,14 +212,6 @@ void modify_roi_out(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, dt_iop const float scale = roi_in->scale / piece->iscale; roi_out->width -= (int)roundf((float)x * scale); roi_out->height -= (int)roundf((float)y * scale); - - if(piece->pipe->type & (DT_DEV_PIXELPIPE_FULL | DT_DEV_PIXELPIPE_EXPORT)) - { - if(piece->pipe->image.buf_dsc.frames > 1) - { - roi_out->frame_offset = roi_out->width * roi_out->height; - } - } } void modify_roi_in(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out, @@ -283,7 +275,7 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const dt_omp_firstprivate(csx, csy, d, in, out, roi_in, roi_out) \ schedule(static) collapse(2) #endif - for(int j = 0; j < roi_out->height; j++) + for(int j = 0; j < roi_out->height-100; j++) { for(int i = 0; i < roi_out->width; i++) { @@ -294,6 +286,18 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const out[pout] = (in[pin] - d->sub[id]) / d->div[id]; } } + + for(int j = roi_out->height-100; j < roi_out->height; j++) + { + for(int i = 0; i < roi_out->width; i++) + { + //const size_t pin = (size_t)(roi_in->width * (j + csy) + csx) + i; + const size_t pout = (size_t)j * roi_out->width + i; + + + out[pout] = 0.0f; + } + } } static void convert_float_float(const float *const in, float *const out, const dt_iop_roi_t *const roi_in, @@ -374,6 +378,11 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const const uint16_t *const frame_in = in + (f * roi_in->width * roi_in->height); float *const frame_out = out + (f * roi_out->width * roi_out->height); convert_uint_float(frame_in, frame_out, roi_in, roi_out, csx, csy, d); + fprintf(stderr, "frame %lu: %p\n", f, frame_in); + /*for(size_t i=0;iwidth * roi_out->height;++i) + { + frame_out[i] = (float)f / (float)piece->dsc_out.frames; + }*/ } piece->pipe->dsc.filters = dt_rawspeed_crop_dcraw_filters(self->dev->image_storage.buf_dsc.filters, csx, csy); diff --git a/src/tests/integration b/src/tests/integration index 1acf3d6461c8..f8ac222b1315 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit 1acf3d6461c84218b3e1a4224978812d0ef95781 +Subproject commit f8ac222b13155e77231f15ee7181cbfd1e705973 From 24c6ac7720779084d7fcbad6e17b719956a09b48 Mon Sep 17 00:00:00 2001 From: maruncz Date: Thu, 21 Apr 2022 13:08:05 +0200 Subject: [PATCH 16/27] looks like issue fixed copy between imageio and pixelpipe was wrong --- src/common/imageio_rawspeed.cc | 13 ++++ src/develop/pixelpipe_hb.c | 124 +++++++++++++++++++++++++++------ src/iop/demosaic.c | 2 +- src/iop/rawprepare.c | 22 +++--- src/tests/integration | 2 +- 5 files changed, 127 insertions(+), 36 deletions(-) diff --git a/src/common/imageio_rawspeed.cc b/src/common/imageio_rawspeed.cc index 94f66124949b..1d55557a5b76 100644 --- a/src/common/imageio_rawspeed.cc +++ b/src/common/imageio_rawspeed.cc @@ -512,6 +512,19 @@ dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filena */ if(isMultiFrame) { + /*for(size_t f = 0; f < r.size(); ++f) + { + char *ptr = (char *)r.get(f)->getDataUncropped(0, 0); + int value = (((float)f+1) / ((float)(r.size()+2))) * img->raw_white_point; + for(int j = 0; j < dimUncropped.y; ++j) + { + uint16_t * start = (uint16_t*)(ptr + (j * r.get(f)->pitch)); + for(int i=0;iwidth * img->height * img->buf_dsc.frames * r.get(0)->getBpp(); const size_t bufSize_rawspeed = (size_t)r.get(0)->pitch * dimUncropped.y * r.size(); const size_t frame_size = bufSize_mipmap / r.size(); diff --git a/src/develop/pixelpipe_hb.c b/src/develop/pixelpipe_hb.c index c55c6ffd23cf..092b9a329f10 100644 --- a/src/develop/pixelpipe_hb.c +++ b/src/develop/pixelpipe_hb.c @@ -117,8 +117,29 @@ static void save_debug_bitmap(dt_dev_pixelpipe_t *pipe, const char *name, void * return; } + int single_channel = pipe->dsc.channels == 1; + int floating = pipe->dsc.datatype == TYPE_FLOAT; + + + char ext[8]; + if(floating) + { + snprintf(ext,8,"pfm"); + } + else + { + if(single_channel) + { + snprintf(ext,8,"pgm"); + } + else + { + snprintf(ext,8,"ppm"); + } + } + char filename[128]; - snprintf(filename, 128, "save_debug_bitmap_%s_%s.pfm", name, _pipe_type_to_str(pipe->type)); + snprintf(filename, 128, "save_debug_bitmap_%s_%s.%s", name, _pipe_type_to_str(pipe->type), ext); for(int i = 0; i < 128; ++i) { if(filename[i] == '\0') @@ -137,40 +158,85 @@ static void save_debug_bitmap(dt_dev_pixelpipe_t *pipe, const char *name, void * fprintf(stderr, "error opening debug file: %s, %s\n", filename, strerror(errno)); return; } - if(pipe->dsc.channels > 1) + if(floating) { - fprintf(file, "PF\n"); + if(!single_channel) + { + fprintf(file, "PF\n"); + } + else + { + fprintf(file, "Pf\n"); + } } else { - fprintf(file, "Pf\n"); + if(single_channel) + { + fprintf(file, "P2\n"); + } + else + { + fprintf(file, "P3\n"); + } } fprintf(file, "%i %i\n", roi_out->width, roi_out->height * pipe->dsc.frames); - fprintf(file, "-1.0\n"); - float *ptr = (float *)out; - if((pipe->dsc.channels == 1) || (pipe->dsc.channels == 3)) + if(floating) + { + fprintf(file, "-1.0\n"); + } + else + { + fprintf(file,"%i\n", 16384); + } + if(floating) { - for(size_t f = 0; f < pipe->dsc.frames; ++f) + float *ptr = (float *)out; + if((pipe->dsc.channels == 1) || (pipe->dsc.channels == 3)) { - float *tmp = ptr + (f * roi_out->width * roi_out->height); - for(size_t i = 0; i < roi_out->width; ++i) + for(size_t f = 0; f < pipe->dsc.frames; ++f) { - for(size_t j = 0; j < roi_out->height; ++j) + float *tmp = ptr + (f * roi_out->width * roi_out->height); + for(size_t i = 0; i < roi_out->width; ++i) { - const size_t pout = j + (roi_out->height * (i)); - fwrite(tmp + pout, sizeof(float) * pipe->dsc.channels, 1, file); + for(size_t j = 0; j < roi_out->height; ++j) + { + const size_t pout = j + (roi_out->height * (i)); + fwrite(tmp + pout, sizeof(float) * pipe->dsc.channels, 1, file); + } + } + } + } + else + { + for(size_t i = 0; i < roi_out->height * roi_out->width * pipe->dsc.frames * pipe->dsc.channels; + i += pipe->dsc.channels) + { + for(size_t j = 0; j < 3; ++j) + { + fwrite(ptr + i + j, sizeof(float), 1, file); } } } } else { - for(size_t i = 0; i < roi_out->height * roi_out->width * pipe->dsc.frames * pipe->dsc.channels; - i += pipe->dsc.channels) + if(single_channel) { - for(size_t j = 0; j < 3; ++j) + uint16_t *ptr = (uint16_t *)out; + for(size_t f = 0; f < pipe->dsc.frames; ++f) { - fwrite(ptr + i + j, sizeof(float), 1, file); + uint16_t *tmp = ptr + (f * roi_out->width * roi_out->height); + for(size_t i = 0; i < roi_out->width; ++i) + { + for(size_t j = 0; j < roi_out->height; ++j) + { + const size_t pout = j + (roi_out->height * (i)); + fprintf(file,"%hu ",tmp[pout]); + //fwrite(tmp + pout, sizeof(uint16_t), 1, file); + } + fprintf(file,"\n"); + } } } } @@ -1245,6 +1311,9 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * const int cp_height = MIN(roi_out->height, pipe->iheight - in_y); const int frames = pipe->dsc.frames; + //fprintf(stderr, "[pipe] %s, input: %p\n", _pipe_type_to_str(pipe->type), pipe->input); + //fprintf(stderr, "[pipe] %s, output: %p\n", _pipe_type_to_str(pipe->type), *output); + if (cp_width > 0) { #ifdef _OPENMP @@ -1253,10 +1322,18 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * shared(pipe, roi_out, roi_in, output) \ schedule(static) #endif - for(int j = 0; j < cp_height * frames; j++) - memcpy(((char *)*output) + (size_t)bpp * j * roi_out->width, - ((char *)pipe->input) + (size_t)bpp * (in_x + (in_y + j) * pipe->iwidth), - (size_t)bpp * cp_width); + for(int f = 0; f < frames; ++f) + { + char *ptr = ((char *)pipe->input) + (f * bpp * pipe->iheight * pipe->iwidth); + char *outptr = ((char *)*output) + (f * bpp * roi_out->height * roi_out->width); + for(int j = 0; j < cp_height; j++) + memcpy(outptr + (size_t)bpp * j * roi_out->width, + ptr + (size_t)bpp * (in_x + (in_y + j) * pipe->iwidth), (size_t)bpp * cp_width); + } + +#ifdef DEBUG_PIXELPIPE + save_debug_bitmap(pipe,"load",*output,roi_out); +#endif } } else @@ -1303,6 +1380,8 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * g_list_previous(modules), g_list_previous(pieces), pos - 1)) return 1; + //fprintf(stderr,"[pipe] %s, module: %s, input: %p\n",_pipe_type_to_str(pipe->type), module->op ,input); + const size_t in_bpp = dt_iop_buffer_dsc_to_bpp(input_format); piece->dsc_out = piece->dsc_in = *input_format; @@ -1332,6 +1411,8 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * // if(module) printf("reserving new buf in cache for module %s %s: %ld buf %p\n", module->op, pipe == // dev->preview_pipe ? "[preview]" : "", hash, *output); + //fprintf(stderr,"[pipe] %s, module: %s, output: %p\n",_pipe_type_to_str(pipe->type), module->op ,*output); + if(dt_atomic_get_int(&pipe->shutdown)) { return 1; @@ -1983,6 +2064,7 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * return 1; } #else // HAVE_OPENCL + if (pixelpipe_process_on_CPU(pipe, dev, input, input_format, &roi_in, output, out_format, roi_out, module, piece, &tiling, &pixelpipe_flow)) return 1; diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 77bb38156113..520f66699393 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2995,7 +2995,7 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl } } } - fprintf(stderr,"pout: %lu\n", pout+4); + //fprintf(stderr,"pout: %lu\n", pout+4); } diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index 21136c6f4710..550ce344b582 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -275,7 +275,7 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const dt_omp_firstprivate(csx, csy, d, in, out, roi_in, roi_out) \ schedule(static) collapse(2) #endif - for(int j = 0; j < roi_out->height-100; j++) + for(int j = 0; j < roi_out->height; j++) { for(int i = 0; i < roi_out->width; i++) { @@ -287,7 +287,7 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const } } - for(int j = roi_out->height-100; j < roi_out->height; j++) + /*for(int j = roi_out->height-100; j < roi_out->height; j++) { for(int i = 0; i < roi_out->width; i++) { @@ -297,7 +297,7 @@ static void convert_uint_float(const uint16_t *const in, float *const out, const out[pout] = 0.0f; } - } + }*/ } static void convert_float_float(const float *const in, float *const out, const dt_iop_roi_t *const roi_in, @@ -355,13 +355,13 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const { const dt_iop_rawprepare_data_t *const d = (dt_iop_rawprepare_data_t *)piece->data; - fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); - fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); - fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + //fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); + //fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + //fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); /*fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); fprintf(stderr,"frame size iout: %d\n", roi_out->width * roi_out->height);*/ - fprintf(stderr,"i: %p\n",ivoid); - fprintf(stderr,"o: %p\n",ovoid); + //fprintf(stderr,"i: %p\n",ivoid); + //fprintf(stderr,"o: %p\n",ovoid); const int csx = compute_proper_crop(piece, roi_in, d->x); const int csy = compute_proper_crop(piece, roi_in, d->y); @@ -378,11 +378,7 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const const uint16_t *const frame_in = in + (f * roi_in->width * roi_in->height); float *const frame_out = out + (f * roi_out->width * roi_out->height); convert_uint_float(frame_in, frame_out, roi_in, roi_out, csx, csy, d); - fprintf(stderr, "frame %lu: %p\n", f, frame_in); - /*for(size_t i=0;iwidth * roi_out->height;++i) - { - frame_out[i] = (float)f / (float)piece->dsc_out.frames; - }*/ + //fprintf(stderr, "frame %lu: %p\n", f, frame_in); } piece->pipe->dsc.filters = dt_rawspeed_crop_dcraw_filters(self->dev->image_storage.buf_dsc.filters, csx, csy); diff --git a/src/tests/integration b/src/tests/integration index f8ac222b1315..1acf3d6461c8 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit f8ac222b13155e77231f15ee7181cbfd1e705973 +Subproject commit 1acf3d6461c84218b3e1a4224978812d0ef95781 From d56a04267331aefac926d42bfa0e6f894a2ccca2 Mon Sep 17 00:00:00 2001 From: maruncz Date: Thu, 21 Apr 2022 14:46:16 +0200 Subject: [PATCH 17/27] first non working pixelshift debayer candidate --- src/develop/pixelpipe_hb.c | 2 +- src/iop/demosaic.c | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/develop/pixelpipe_hb.c b/src/develop/pixelpipe_hb.c index 092b9a329f10..2fb0a49ec81c 100644 --- a/src/develop/pixelpipe_hb.c +++ b/src/develop/pixelpipe_hb.c @@ -1318,7 +1318,7 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * { #ifdef _OPENMP #pragma omp parallel for default(none) \ - dt_omp_firstprivate(bpp, cp_height, cp_width, in_x, in_y) \ + dt_omp_firstprivate(bpp, cp_height, cp_width, in_x, in_y, frames) \ shared(pipe, roi_out, roi_in, output) \ schedule(static) #endif diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 520f66699393..95b8d96a2728 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2951,7 +2951,7 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl for(int f = 0; f < 4; ++f) { frames_in[f] = in + (f * roi_in->width * roi_in->height); - fprintf(stderr, "frame %i: %p\n", f, frames_in[f]); + //fprintf(stderr, "frame %i: %p\n", f, frames_in[f]); } if(piece->dsc_out.channels != 4) @@ -2972,30 +2972,33 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl //const size_t ox = roi_in->x; //const size_t oy = roi_in->y; + const size_t col_offset = 1; + const size_t row_offset = roi_out->width; + size_t pout = 0; //size_t pin = 0; size_t pin3 = 0; - for(size_t j = 0; j < roi_out->height; j++) + for(size_t j = 1; j < roi_out->height-1; j++) { - for(size_t i = 0; i < roi_out->width; i++) + for(size_t i = 1; i < roi_out->width-1; i++) { pout = (size_t)4 * (((size_t)roi_out->width * j) + i); //pin = (roi_in->width * (j + oy)) + ox + i; ///TODO why do i ignore offset of input roi? pin3 = (roi_in->width * j) + i; - if(pout+3 >= ((size_t)4*((size_t)roi_out->height*roi_out->width))) { - fprintf(stderr,"output overflow\n"); + out[pout+0] = frames_in[0][pin3]; + out[pout+1] = (frames_in[1][pin3-col_offset] + frames_in[2][pin3-col_offset-row_offset])/2.0f; + out[pout+2] = frames_in[3][pin3-row_offset]; } - for(size_t c=0;c<3;++c) + /*for(size_t c=0;c<3;++c) { - out[pout+c] = (frames_in[2])[pin3]; - } + out[pout+c] = (frames_in[c])[pin3]; + }*/ } } - //fprintf(stderr,"pout: %lu\n", pout+4); } From a4829d9a5b9e8a9bf2e18e90c61762c8f503de20 Mon Sep 17 00:00:00 2001 From: maruncz Date: Thu, 21 Apr 2022 14:55:45 +0200 Subject: [PATCH 18/27] cleanup --- src/iop/demosaic.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 95b8d96a2728..3e10fb3e1bc0 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2975,22 +2975,17 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl const size_t col_offset = 1; const size_t row_offset = roi_out->width; - size_t pout = 0; - //size_t pin = 0; - size_t pin3 = 0; for(size_t j = 1; j < roi_out->height-1; j++) { for(size_t i = 1; i < roi_out->width-1; i++) { - pout = (size_t)4 * (((size_t)roi_out->width * j) + i); - //pin = (roi_in->width * (j + oy)) + ox + i; - ///TODO why do i ignore offset of input roi? - pin3 = (roi_in->width * j) + i; + size_t pout = (size_t)4 * (((size_t)roi_out->width * j) + i); + size_t pin = (roi_in->width * j) + i; { - out[pout+0] = frames_in[0][pin3]; - out[pout+1] = (frames_in[1][pin3-col_offset] + frames_in[2][pin3-col_offset-row_offset])/2.0f; - out[pout+2] = frames_in[3][pin3-row_offset]; + out[pout+0] = frames_in[0][pin]; + out[pout+1] = (frames_in[1][pin-col_offset] + frames_in[2][pin-col_offset-row_offset])/2.0f; + out[pout+2] = frames_in[3][pin-row_offset]; } /*for(size_t c=0;c<3;++c) From 843622814756195c89b1a0d06c4b623bec57dbe4 Mon Sep 17 00:00:00 2001 From: maruncz Date: Thu, 21 Apr 2022 19:14:21 +0200 Subject: [PATCH 19/27] probably working algorithm, pixelshift checkbox unreliable, doesn't work with whitebalance --- src/iop/demosaic.c | 20 ++++++++++++++++---- src/iop/rawprepare.c | 6 +++--- src/tests/integration | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 3e10fb3e1bc0..23cd937a428f 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2983,9 +2983,21 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl size_t pin = (roi_in->width * j) + i; { - out[pout+0] = frames_in[0][pin]; - out[pout+1] = (frames_in[1][pin-col_offset] + frames_in[2][pin-col_offset-row_offset])/2.0f; - out[pout+2] = frames_in[3][pin-row_offset]; + const uint32_t ch[4] = { FC(j + 0 + roi_out->y, i + 0 + roi_out->x, piece->pipe->dsc.filters), + FC(j + 1 + roi_out->y, i + 0 + roi_out->x, piece->pipe->dsc.filters), + FC(j + 1 + roi_out->y, i + 1 + roi_out->x, piece->pipe->dsc.filters), + FC(j + 0 + roi_out->y, i + 1 + roi_out->x, piece->pipe->dsc.filters) }; + for(int k = 0; k < 4; ++k) + { + out[pout + k] = 0.0f; + } + + out[pout + ch[0]] += frames_in[0][pin]; + out[pout + ch[1]] += frames_in[1][pin + row_offset]; + out[pout + ch[2]] += frames_in[2][pin + col_offset + row_offset]; + out[pout + ch[3]] += frames_in[3][pin + col_offset]; + + out[pout + 1] /= 2.0f; } /*for(size_t c=0;c<3;++c) @@ -5633,7 +5645,7 @@ void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *params, dt_dev d->pixelshift_enable = (p->pixelshift_enable && (piece->dsc_in.frames == 4)); ///TODO this should also change checkbox - //fprintf(stderr, "demosaic ,commit_params, %s, pixelshift: %i\n", dt_pixelpipe_name(pipe->type), d->pixelshift_enable); + fprintf(stderr, "demosaic ,commit_params, %s, pixelshift: %i\n", dt_pixelpipe_name(pipe->type), d->pixelshift_enable); } else { diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index 550ce344b582..9c71150910d8 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -355,9 +355,9 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const { const dt_iop_rawprepare_data_t *const d = (dt_iop_rawprepare_data_t *)piece->data; - //fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); - //fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); - //fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); + fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); /*fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); fprintf(stderr,"frame size iout: %d\n", roi_out->width * roi_out->height);*/ //fprintf(stderr,"i: %p\n",ivoid); diff --git a/src/tests/integration b/src/tests/integration index 1acf3d6461c8..f8ac222b1315 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit 1acf3d6461c84218b3e1a4224978812d0ef95781 +Subproject commit f8ac222b13155e77231f15ee7181cbfd1e705973 From a4a9d78fead2448c587e271ec726d5c9c2360485 Mon Sep 17 00:00:00 2001 From: maruncz Date: Fri, 22 Apr 2022 12:26:37 +0200 Subject: [PATCH 20/27] bumped version of demosaic --- src/iop/demosaic.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 23cd937a428f..026f656d5c26 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -137,9 +137,9 @@ typedef struct dt_iop_demosaic_gui_data_t GtkWidget *dual_thrs; GtkWidget *lmmse_refine; GtkWidget *pixelshift_enable; - GtkWidget *pixelshift_select_frame; - GtkWidget *pixelshift_motion_correction; - GtkWidget *pixelshift_show_motion_mask; + //GtkWidget *pixelshift_select_frame; + //GtkWidget *pixelshift_motion_correction; + //GtkWidget *pixelshift_show_motion_mask; gboolean visual_mask; } dt_iop_demosaic_gui_data_t; @@ -254,7 +254,18 @@ int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_p int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version) { - typedef struct dt_iop_demosaic_params_t dt_iop_demosaic_params_v4_t; + typedef struct dt_iop_demosaic_params_t dt_iop_demosaic_params_v5_t; + + typedef struct dt_iop_demosaic_params_v4_t + { + dt_iop_demosaic_greeneq_t green_eq; + float median_thrs; + dt_iop_demosaic_smooth_t color_smoothing; + dt_iop_demosaic_method_t demosaicing_method; + dt_iop_demosaic_lmmse_t lmmse_refine; + float dual_thrs; + } dt_iop_demosaic_params_v4_t; + typedef struct dt_iop_demosaic_params_v3_t { dt_iop_demosaic_greeneq_t green_eq; @@ -264,6 +275,15 @@ int legacy_params(dt_iop_module_t *self, const void *const old_params, const int dt_iop_demosaic_lmmse_t lmmse_refine; } dt_iop_demosaic_params_v3_t; + if(old_version == 4 && new_version == 5) + { + dt_iop_demosaic_params_v4_t *o = (dt_iop_demosaic_params_v4_t *)old_params; + dt_iop_demosaic_params_v5_t *n = (dt_iop_demosaic_params_v5_t *)new_params; + memcpy(n, o, sizeof *o); + n->pixelshift_enable = 0; + return 0; + } + if(old_version == 3 && new_version == 4) { dt_iop_demosaic_params_v3_t *o = (dt_iop_demosaic_params_v3_t *)old_params; @@ -5730,6 +5750,12 @@ void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *params, dt_dev piece->process_cl_ready = 0; } + ///TODO make this better + if(d->pixelshift_enable) + { + piece->process_cl_ready = 0; + } + // green-equilibrate over full image excludes tiling // The details mask is written inside process, this does not allow tiling. if((d->green_eq == DT_IOP_GREEN_EQ_FULL From 31f059117da7ffde1a6f84eb0350b541bf4373be Mon Sep 17 00:00:00 2001 From: maruncz Date: Fri, 22 Apr 2022 13:42:42 +0200 Subject: [PATCH 21/27] wb supports multiframe --- src/develop/pixelpipe_hb.c | 2 +- src/iop/temperature.c | 88 +++++++++++++++++++++++++------------- src/tests/integration | 2 +- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/src/develop/pixelpipe_hb.c b/src/develop/pixelpipe_hb.c index 2fb0a49ec81c..9b4827f8b8ed 100644 --- a/src/develop/pixelpipe_hb.c +++ b/src/develop/pixelpipe_hb.c @@ -1332,7 +1332,7 @@ static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, dt_develop_t * } #ifdef DEBUG_PIXELPIPE - save_debug_bitmap(pipe,"load",*output,roi_out); + //save_debug_bitmap(pipe,"load",*output,roi_out); #endif } } diff --git a/src/iop/temperature.c b/src/iop/temperature.c index 6bf008f732c1..cb65d68d216f 100644 --- a/src/iop/temperature.c +++ b/src/iop/temperature.c @@ -221,6 +221,14 @@ int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_p return IOP_CS_RAW; } +void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, + dt_iop_buffer_dsc_t *dsc) +{ + default_output_format(self, pipe, piece, dsc); + ///TODO is this correct? + dsc->frames = pipe->dsc.frames; +} + /* * Spectral power distribution functions * https://en.wikipedia.org/wiki/Spectral_power_distribution @@ -466,6 +474,8 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const float *const out = (float *const)ovoid; const float *const d_coeffs = d->coeffs; + fprintf(stderr, "temperature, %s\n", dt_pixelpipe_name(piece->pipe->type)); + if(filters == 9u) { // xtrans float mosaiced #ifdef _OPENMP @@ -503,39 +513,55 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const } else if(filters) { // bayer float mosaiced - const int width = roi_out->width; + for(int f=0;fdsc_in.frames;++f) + { + float const *const frame_in = in + (f * roi_in->width * roi_in->height); + float *const frame_out = out + (f * roi_out->width * roi_out->height); + fprintf(stderr,"frame in %p\n", frame_in); + fprintf(stderr,"frame out %p\n", frame_out); + const int width = roi_out->width; #ifdef _OPENMP #pragma omp parallel for default(none) \ - dt_omp_firstprivate(d_coeffs, filters, in, out, roi_out, width) \ - schedule(static) + dt_omp_firstprivate(d_coeffs, filters, frame_in, frame_out, roi_out, width) \ + schedule(static) #endif - for(int j = 0; j < roi_out->height; j++) - { - int i = 0; - const int alignment = ((4 - (j * width & (4 - 1))) & (4 - 1)); - const int offset_j = j + roi_out->y; - - // process the unaligned sensels at the start of the row (when width is not a multiple of 4) - for( ; i < alignment; i++) - { - const size_t p = (size_t)j * width + i; - out[p] = in[p] * d_coeffs[FC(offset_j, i + roi_out->x, filters)]; - } - const dt_aligned_pixel_t coeffs = { d_coeffs[FC(offset_j, i + roi_out->x, filters)], - d_coeffs[FC(offset_j, i + roi_out->x + 1,filters)], - d_coeffs[FC(offset_j, i + roi_out->x + 2, filters)], - d_coeffs[FC(offset_j, i + roi_out->x + 3, filters)] }; - // process sensels four at a time - for(; i < (width & ~3); i += 4) - { - const size_t p = (size_t)j * width + i; - scaled_copy_4wide(out + p,in + p, coeffs); - } - // process the leftover sensels - for(i = width & ~3; i < width; i++) + for(int j = 0; j < roi_out->height; j++) { - const size_t p = (size_t)j * width + i; - out[p] = in[p] * d_coeffs[FC(j + roi_out->y, i + roi_out->x, filters)]; +#if 0 +// this optimization does not work for multiframe + int i = 0; + const int alignment = ((4 - (j * width & (4 - 1))) & (4 - 1)); + const int offset_j = j + roi_out->y; + + // process the unaligned sensels at the start of the row (when width is not a multiple of 4) + for( ; i < alignment; i++) + { + const size_t p = (size_t)j * width + i; + frame_out[p] = frame_in[p] * d_coeffs[FC(offset_j, i + roi_out->x, filters)]; + } + const dt_aligned_pixel_t coeffs = { d_coeffs[FC(offset_j, i + roi_out->x, filters)], + d_coeffs[FC(offset_j, i + roi_out->x + 1,filters)], + d_coeffs[FC(offset_j, i + roi_out->x + 2, filters)], + d_coeffs[FC(offset_j, i + roi_out->x + 3, filters)] }; + // process sensels four at a time + for(; i < (width & ~3); i += 4) + { + const size_t p = (size_t)j * width + i; + scaled_copy_4wide(frame_out + p,frame_in + p, coeffs); + } + // process the leftover sensels + for(i = width & ~3; i < width; i++) + { + const size_t p = (size_t)j * width + i; + frame_out[p] = frame_in[p] * d_coeffs[FC(j + roi_out->y, i + roi_out->x, filters)]; + } +#endif + for(int i = 0; i < roi_out->width; i++) + { + const size_t p = (size_t)j * width + i; + frame_out[p] = frame_in[p] * d_coeffs[FC(j + roi_out->y, i + roi_out->x, filters)]; + } + } } } @@ -571,6 +597,7 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const } } +#if 0 #if defined(__SSE__) void process_sse2(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out) @@ -621,7 +648,9 @@ void process_sse2(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, c } } #endif +#endif +#if 0 #ifdef HAVE_OPENCL int process_cl(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out) @@ -694,6 +723,7 @@ int process_cl(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_m return FALSE; } #endif +#endif void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece) diff --git a/src/tests/integration b/src/tests/integration index f8ac222b1315..1acf3d6461c8 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit f8ac222b13155e77231f15ee7181cbfd1e705973 +Subproject commit 1acf3d6461c84218b3e1a4224978812d0ef95781 From ebb32ea0d76540e999e1b30de0bba88be343b53c Mon Sep 17 00:00:00 2001 From: maruncz Date: Sat, 23 Apr 2022 12:35:44 +0200 Subject: [PATCH 22/27] cleanup --- src/iop/demosaic.c | 11 +++-------- src/iop/rawprepare.c | 4 ++-- src/tests/integration | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 026f656d5c26..4b8dd064c508 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -3019,11 +3019,6 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl out[pout + 1] /= 2.0f; } - - /*for(size_t c=0;c<3;++c) - { - out[pout+c] = (frames_in[c])[pin3]; - }*/ } } } @@ -3039,8 +3034,8 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_dev_clear_rawdetail_mask(piece->pipe); fprintf(stderr, "demosaic, %s\n", dt_pixelpipe_name(piece->pipe->type)); - fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); - fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + //fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + //fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); dt_iop_roi_t roi = *roi_in; dt_iop_roi_t roo = *roi_out; roo.x = roo.y = 0; @@ -5665,7 +5660,7 @@ void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *params, dt_dev d->pixelshift_enable = (p->pixelshift_enable && (piece->dsc_in.frames == 4)); ///TODO this should also change checkbox - fprintf(stderr, "demosaic ,commit_params, %s, pixelshift: %i\n", dt_pixelpipe_name(pipe->type), d->pixelshift_enable); + fprintf(stderr, "demosaic ,commit_params, %s, pixelshift in: %i out: %i\n", dt_pixelpipe_name(pipe->type), p->pixelshift_enable, d->pixelshift_enable); } else { diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index 9c71150910d8..57d7f62510da 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -356,8 +356,8 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const const dt_iop_rawprepare_data_t *const d = (dt_iop_rawprepare_data_t *)piece->data; fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); - fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); - fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + //fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + //fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); /*fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); fprintf(stderr,"frame size iout: %d\n", roi_out->width * roi_out->height);*/ //fprintf(stderr,"i: %p\n",ivoid); diff --git a/src/tests/integration b/src/tests/integration index 1acf3d6461c8..7e085356a3f6 160000 --- a/src/tests/integration +++ b/src/tests/integration @@ -1 +1 @@ -Subproject commit 1acf3d6461c84218b3e1a4224978812d0ef95781 +Subproject commit 7e085356a3f60e43b3b34ea2c74c6ca6ce7901bb From 55563d49d448f81605b5f7473f129989c34a3bce Mon Sep 17 00:00:00 2001 From: maruncz Date: Sat, 23 Apr 2022 13:28:39 +0200 Subject: [PATCH 23/27] checkbox now correctly respond, but demosaic is not reprocesing --- src/iop/demosaic.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 4b8dd064c508..32b87c0e3eba 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -5657,9 +5657,7 @@ void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *params, dt_dev d->lmmse_refine = p->lmmse_refine; if(pipe->type & (DT_DEV_PIXELPIPE_FULL | DT_DEV_PIXELPIPE_EXPORT)) { - d->pixelshift_enable = (p->pixelshift_enable && (piece->dsc_in.frames == 4)); - ///TODO this should also change checkbox - + d->pixelshift_enable = p->pixelshift_enable; fprintf(stderr, "demosaic ,commit_params, %s, pixelshift in: %i out: %i\n", dt_pixelpipe_name(pipe->type), p->pixelshift_enable, d->pixelshift_enable); } else @@ -5842,11 +5840,12 @@ void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous) gtk_widget_set_visible(g->dual_thrs, isdual); gtk_widget_set_visible(g->lmmse_refine, islmmse); gtk_widget_set_visible(g->pixelshift_enable, bayer && ispixelshift); - /*if(!bayer || !ispixelshift) + if(!bayer || !ispixelshift) { - gtk_set_active(g->pixelshift_enable, FALSE); - }*/ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->pixelshift_enable), FALSE); + } //gtk_widget_set_visible(g->pixelshift_select_frame, bayer && ispixelshift); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->pixelshift_enable), p->pixelshift_enable && bayer && ispixelshift); dt_image_t *img = dt_image_cache_get(darktable.image_cache, self->dev->image_storage.id, 'w'); int changed = img->flags & DT_IMAGE_MONOCHROME_BAYER; From ece9ac3b6efa2f5ff539a45288ac51f84e1d6ab8 Mon Sep 17 00:00:00 2001 From: maruncz Date: Sat, 23 Apr 2022 15:05:09 +0200 Subject: [PATCH 24/27] demosaic gui is now correctly showing and hiding controls --- src/iop/demosaic.c | 35 +++++++++++++++++++++-------------- src/iop/temperature.c | 4 ++-- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 32b87c0e3eba..63453aa0a145 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -3087,7 +3087,6 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const roo.height = roi_in->height; roo.scale = 1.0f; tmp = (float *)dt_alloc_align_float((size_t)4 * roo.width * roo.height); - fprintf(stderr,"scaled\n"); } if(info) dt_get_times(&start_time); @@ -5825,27 +5824,35 @@ void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous) (use_method == DT_IOP_DEMOSAIC_PASSTHR_MONOX) || (use_method == DT_IOP_DEMOSAIC_PASSTHR_COLORX)); ///TODO doesn't take into account previous modules? - const gboolean ispixelshift = (self->dev->image_storage.buf_dsc.frames == 4); + const gboolean ispixelshift = bayer && (self->dev->image_storage.buf_dsc.frames == 4); - gtk_widget_set_visible(g->demosaic_method_bayer, bayer); + gtk_widget_set_visible(g->pixelshift_enable, bayer && ispixelshift); + + if(!bayer || !ispixelshift) + { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->pixelshift_enable), FALSE); + p->pixelshift_enable = FALSE; + } + else + { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->pixelshift_enable), + p->pixelshift_enable && bayer && ispixelshift); + } + + //gtk_widget_set_visible(g->pixelshift_select_frame, bayer && ispixelshift); + + gtk_widget_set_visible(g->demosaic_method_bayer, bayer && !p->pixelshift_enable); gtk_widget_set_visible(g->demosaic_method_xtrans, !bayer); if(bayer) dt_bauhaus_combobox_set_from_value(g->demosaic_method_bayer, p->demosaicing_method); else dt_bauhaus_combobox_set_from_value(g->demosaic_method_xtrans, p->demosaicing_method); - gtk_widget_set_visible(g->median_thrs, bayer && isppg); - gtk_widget_set_visible(g->greeneq, !passing); + gtk_widget_set_visible(g->median_thrs, bayer && isppg && !p->pixelshift_enable); + gtk_widget_set_visible(g->greeneq, !passing && !p->pixelshift_enable); gtk_widget_set_visible(g->color_smoothing, !passing && !isdual); gtk_widget_set_visible(g->dual_thrs, isdual); gtk_widget_set_visible(g->lmmse_refine, islmmse); - gtk_widget_set_visible(g->pixelshift_enable, bayer && ispixelshift); - if(!bayer || !ispixelshift) - { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->pixelshift_enable), FALSE); - } - //gtk_widget_set_visible(g->pixelshift_select_frame, bayer && ispixelshift); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->pixelshift_enable), p->pixelshift_enable && bayer && ispixelshift); dt_image_t *img = dt_image_cache_get(darktable.image_cache, self->dev->image_storage.id, 'w'); int changed = img->flags & DT_IMAGE_MONOCHROME_BAYER; @@ -5903,6 +5910,8 @@ void gui_init(struct dt_iop_module_t *self) GtkWidget *box_raw = self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); + g->pixelshift_enable = dt_bauhaus_toggle_from_params(self, "pixelshift_enable"); + g->demosaic_method_bayer = dt_bauhaus_combobox_from_params(self, "demosaicing_method"); for(int i=0;i<7;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_bayer, 9); gtk_widget_set_tooltip_text(g->demosaic_method_bayer, _("Bayer sensor demosaicing method, PPG and RCD are fast, AMaZE and LMMSE are slow.\nLMMSE is suited best for high ISO images.\ndual demosaicers double processing time.")); @@ -5933,8 +5942,6 @@ void gui_init(struct dt_iop_module_t *self) g->greeneq = dt_bauhaus_combobox_from_params(self, "green_eq"); gtk_widget_set_tooltip_text(g->greeneq, _("green channels matching method")); - g->pixelshift_enable = dt_bauhaus_toggle_from_params(self, "pixelshift_enable"); - /*g->pixelshift_select_frame = dt_bauhaus_combobox_new(self); dt_bauhaus_widget_set_label(g->pixelshift_select_frame,NULL,"input frames"); gtk_widget_set_tooltip_text(g->pixelshift_select_frame,"input frames"); diff --git a/src/iop/temperature.c b/src/iop/temperature.c index cb65d68d216f..a37b63d132c3 100644 --- a/src/iop/temperature.c +++ b/src/iop/temperature.c @@ -517,8 +517,8 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const { float const *const frame_in = in + (f * roi_in->width * roi_in->height); float *const frame_out = out + (f * roi_out->width * roi_out->height); - fprintf(stderr,"frame in %p\n", frame_in); - fprintf(stderr,"frame out %p\n", frame_out); + //fprintf(stderr,"frame in %p\n", frame_in); + //fprintf(stderr,"frame out %p\n", frame_out); const int width = roi_out->width; #ifdef _OPENMP #pragma omp parallel for default(none) \ From 97dbf5248e177aa519bb34737193fb62dc3b641c Mon Sep 17 00:00:00 2001 From: maruncz Date: Sat, 23 Apr 2022 15:10:23 +0200 Subject: [PATCH 25/27] added tooltip for pixelshift --- src/iop/demosaic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 63453aa0a145..744a9534ac74 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -5911,6 +5911,7 @@ void gui_init(struct dt_iop_module_t *self) GtkWidget *box_raw = self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); g->pixelshift_enable = dt_bauhaus_toggle_from_params(self, "pixelshift_enable"); + gtk_widget_set_tooltip_text(g->pixelshift_enable, _("Enable Pentax PixelShift.\nThis feature is beta stage might not work correctly.\nThis also doesn't support motion correction yet.")); g->demosaic_method_bayer = dt_bauhaus_combobox_from_params(self, "demosaicing_method"); for(int i=0;i<7;i++) dt_bauhaus_combobox_remove_at(g->demosaic_method_bayer, 9); From 0ef76d31430e9f3a86d38be6a59aead9e9acda98 Mon Sep 17 00:00:00 2001 From: maruncz Date: Sun, 24 Apr 2022 13:54:04 +0200 Subject: [PATCH 26/27] corrected problem with margins --- src/iop/demosaic.c | 18 ++++++++++++------ src/iop/rawprepare.c | 4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/iop/demosaic.c b/src/iop/demosaic.c index 744a9534ac74..78fce52d7934 100644 --- a/src/iop/demosaic.c +++ b/src/iop/demosaic.c @@ -2853,9 +2853,15 @@ void modify_roi_in(struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t * const gboolean passthrough = (method == DT_IOP_DEMOSAIC_PASSTHROUGH_MONOCHROME) || (method == DT_IOP_DEMOSAIC_PASSTHR_MONOX); - // set position to closest sensor pattern snap - if(!passthrough) + if(data->pixelshift_enable) { + //pixelshift requires 1px margin + roi_in->width = MIN(roi_in->width + 1, piece->pipe->image.width); + roi_in->height = MIN(roi_in->height + 1, piece->pipe->image.height); + } + else if(!passthrough) + { + // set position to closest sensor pattern snap const int aligner = (piece->pipe->dsc.filters != 9u) ? BAYER_SNAPPER : XTRANS_SNAPPER; const int dx = roi_in->x % aligner; const int dy = roi_in->y % aligner; @@ -2995,9 +3001,9 @@ void process_pixelshift(dt_dev_pixelpipe_iop_t *piece, const float *const in, fl const size_t col_offset = 1; const size_t row_offset = roi_out->width; - for(size_t j = 1; j < roi_out->height-1; j++) + for(size_t j = 0; j < roi_out->height-1; j++) { - for(size_t i = 1; i < roi_out->width-1; i++) + for(size_t i = 0; i < roi_out->width-1; i++) { size_t pout = (size_t)4 * (((size_t)roi_out->width * j) + i); size_t pin = (roi_in->width * j) + i; @@ -3034,8 +3040,8 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_dev_clear_rawdetail_mask(piece->pipe); fprintf(stderr, "demosaic, %s\n", dt_pixelpipe_name(piece->pipe->type)); - //fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); - //fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); dt_iop_roi_t roi = *roi_in; dt_iop_roi_t roo = *roi_out; roo.x = roo.y = 0; diff --git a/src/iop/rawprepare.c b/src/iop/rawprepare.c index 57d7f62510da..9c71150910d8 100644 --- a/src/iop/rawprepare.c +++ b/src/iop/rawprepare.c @@ -356,8 +356,8 @@ void process(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const const dt_iop_rawprepare_data_t *const d = (dt_iop_rawprepare_data_t *)piece->data; fprintf(stderr,"rawprepare %s\n", dt_pixelpipe_name(piece->pipe->type)); - //fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); - //fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); + fprintf(stderr, "roi in %d %d %d %d\n", roi_in->x, roi_in->y, roi_in->width, roi_in->height); + fprintf(stderr, "roi out %d %d %d %d\n", roi_out->x, roi_out->y, roi_out->width, roi_out->height); /*fprintf(stderr,"frame size in: %d\n", roi_in->width * roi_in->height); fprintf(stderr,"frame size iout: %d\n", roi_out->width * roi_out->height);*/ //fprintf(stderr,"i: %p\n",ivoid); From 2d5402a10f059007f988507ef3579b53a43995ee Mon Sep 17 00:00:00 2001 From: maruncz Date: Mon, 25 Apr 2022 07:26:53 +0200 Subject: [PATCH 27/27] revert temporary workaround --- src/bauhaus/bauhaus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bauhaus/bauhaus.c b/src/bauhaus/bauhaus.c index c865b66b1b62..07b396bc3c52 100644 --- a/src/bauhaus/bauhaus.c +++ b/src/bauhaus/bauhaus.c @@ -799,7 +799,7 @@ static gboolean dt_bauhaus_combobox_motion_notify(GtkWidget *widget, GdkEventMot // common initialization static void _bauhaus_widget_init(dt_bauhaus_widget_t *w, dt_iop_module_t *self) { - if(self) w->module = DT_ACTION(self); + w->module = DT_ACTION(self); w->field = NULL; w->section = NULL;