Commit ca56116b authored by johannes hanika's avatar johannes hanika

hdr input more careful with cache allocation.

parent dca1505a
......@@ -3,6 +3,9 @@ webpage updates:
0.6 release:
- make sure no preview import uses full buffers!
- processed images fight for resources during import and get processed twice?
- BUG: mem leak in ldr import??
- BUG: full image stays locked?
- BUG: linked list mru/lru in image cache broken sometimes after load?
......
......@@ -264,7 +264,7 @@ dt_imageio_retval_t dt_image_preview_to_raw(dt_image_t *img)
return DT_IMAGEIO_OK;
}
dt_imageio_retval_t dt_image_raw_to_preview(dt_image_t *img)
dt_imageio_retval_t dt_image_raw_to_preview(dt_image_t *img, const float *raw)
{
const int raw_wd = img->width;
const int raw_ht = img->height;
......@@ -280,7 +280,7 @@ dt_imageio_retval_t dt_image_raw_to_preview(dt_image_t *img)
{ // use 1:1
for(int j=0;j<raw_ht;j++) for(int i=0;i<raw_wd;i++)
{
float *cam = img->pixels + 3*(j*raw_wd + i);
const float *cam = raw + 3*(j*raw_wd + i);
for(int k=0;k<3;k++) img->mipf[3*(j*p_wd + i) + k] = cam[k];
}
}
......@@ -290,7 +290,7 @@ dt_imageio_retval_t dt_image_raw_to_preview(dt_image_t *img)
const float scale = fmaxf(raw_wd/f_wd, raw_ht/f_ht);
for(int j=0;j<p_ht && (int)(scale*j)<raw_ht;j++) for(int i=0;i<p_wd && (int)(scale*i) < raw_wd;i++)
{
float *cam = img->pixels + 3*((int)(scale*j)*raw_wd + (int)(scale*i));
const float *cam = raw + 3*((int)(scale*j)*raw_wd + (int)(scale*i));
for(int k=0;k<3;k++) img->mipf[3*(j*p_wd + i) + k] = cam[k];
}
}
......@@ -663,7 +663,7 @@ int dt_image_load(dt_image_t *img, dt_image_buffer_t mip)
}
else
{
ret = dt_image_raw_to_preview(img);
ret = dt_image_raw_to_preview(img, img->pixels);
dt_image_release(img, DT_IMAGE_FULL, 'r');
}
dt_image_release(img, mip, 'w');
......@@ -671,7 +671,7 @@ int dt_image_load(dt_image_t *img, dt_image_buffer_t mip)
else if(mip == DT_IMAGE_FULL)
{
ret = dt_imageio_open(img, filename);
ret = dt_image_raw_to_preview(img);
ret = dt_image_raw_to_preview(img, img->pixels);
dt_image_release(img, mip, 'w');
}
else
......
......@@ -190,7 +190,7 @@ void dt_image_release(dt_image_t *img, dt_image_buffer_t mip, const char mode);
int dt_image_lock_if_available(dt_image_t *img, const dt_image_buffer_t mip_in, const char mode);
/** converts img->pixels to img->mipf to img->mip[4--0]. needs full image buffer r locked. */
dt_imageio_retval_t dt_image_raw_to_preview(dt_image_t *img);
dt_imageio_retval_t dt_image_raw_to_preview(dt_image_t *img, const float *raw);
/** up-converts mip4 to mipf using guessed gamma values. needs mip4 r locked. */
dt_imageio_retval_t dt_image_preview_to_raw(dt_image_t *img);
#endif
......@@ -88,12 +88,17 @@ int dt_imageio_write_pos(int i, int j, int wd, int ht, float fwd, float fht, int
dt_imageio_retval_t dt_imageio_open_hdr_preview(dt_image_t *img, const char *filename)
{
dt_imageio_retval_t ret = dt_imageio_open_hdr(img, filename);
if(ret != DT_IMAGEIO_OK) return ret;
ret = dt_image_raw_to_preview(img);
dt_image_release(img, DT_IMAGE_FULL, 'r'); // drop open_raw lock on full buffer.
// this updates mipf/mip4..0 from raw pixels.
int p_wd, p_ht;
dt_imageio_retval_t ret;
ret = dt_imageio_open_rgbe_preview(img, filename);
if(ret == DT_IMAGEIO_OK) goto all_good;
if(ret == DT_IMAGEIO_CACHE_FULL) return ret;
ret = dt_imageio_open_pfm_preview(img, filename);
if(ret == DT_IMAGEIO_OK) goto all_good;
if(ret == DT_IMAGEIO_CACHE_FULL) return ret;
all_good:
// this updates mipf/mip4..0 from raw pixels.
dt_image_get_mip_size(img, DT_IMAGE_MIPF, &p_wd, &p_ht);
if(dt_image_alloc(img, DT_IMAGE_MIP4)) return DT_IMAGEIO_CACHE_FULL;
dt_image_get(img, DT_IMAGE_MIPF, 'r');
......
......@@ -65,6 +65,7 @@ dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img, const char *filename)
}
free(line);
dt_image_release(img, DT_IMAGE_FULL, 'w');
fclose(f);
return DT_IMAGEIO_OK;
error_corrupt:
......@@ -74,3 +75,52 @@ error_cache_full:
fclose(f);
return DT_IMAGEIO_CACHE_FULL;
}
dt_imageio_retval_t dt_imageio_open_pfm_preview(dt_image_t *img, const char *filename)
{
const char *ext = filename + strlen(filename);
while(*ext != '.' && ext > filename) ext--;
if(strncmp(ext, ".pfm", 4) && strncmp(ext, ".PFM", 4) && strncmp(ext, ".Pfm", 4)) return DT_IMAGEIO_FILE_CORRUPTED;
FILE *f = fopen(filename, "rb");
if(!f) return DT_IMAGEIO_FILE_CORRUPTED;
int ret = 0;
int cols = 3;
char head[2] = {'X', 'X'};
ret = fscanf(f, "%c%c\n", head, head+1);
if(ret != 2 || head[0] != 'P') goto error_corrupt;
if(head[1] == 'F') cols = 3;
else if(head[1] == 'f') cols = 1;
else goto error_corrupt;
ret = fscanf(f, "%d %d\n%*[^\n]\n", &img->width, &img->height);
if(ret != 2) goto error_corrupt;
float *buf = (float *)malloc(3*sizeof(float)*img->width*img->height);
if(!buf) goto error_corrupt;
if(cols == 3) ret = fread(buf, 3*sizeof(float), img->width*img->height, f);
else for(int j=0; j < img->height; j++)
for(int i=0; i < img->width; i++)
{
ret = fread(buf + 3*(img->width*j + i), sizeof(float), 1, f);
buf[3*(img->width*j + i) + 2] =
buf[3*(img->width*j + i) + 1] =
buf[3*(img->width*j + i) + 0];
}
// repair nan/inf etc
for(int i=0; i < img->width*img->height*3; i++) buf[i] = fmaxf(0.0f, fminf(10000.0, buf[i]));
float *line = (float *)malloc(sizeof(float)*3*img->width);
for(int j=0; j < img->height/2; j++)
{
memcpy(line, buf + img->width*j*3, 3*sizeof(float)*img->width);
memcpy(buf + img->width*j*3, buf + img->width*(img->height-1-j)*3, 3*sizeof(float)*img->width);
memcpy(buf + img->width*(img->height-1-j)*3, line, 3*sizeof(float)*img->width);
}
free(line);
dt_imageio_retval_t retv = dt_image_raw_to_preview(img, buf);
free(buf);
fclose(f);
return retv;
error_corrupt:
fclose(f);
return DT_IMAGEIO_FILE_CORRUPTED;
}
......@@ -21,5 +21,6 @@
#include "common/image.h"
dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img, const char *filename);
dt_imageio_retval_t dt_imageio_open_pfm_preview(dt_image_t *img, const char *filename);
#endif
......@@ -488,3 +488,32 @@ error_cache_full:
fclose(f);
return DT_IMAGEIO_CACHE_FULL;
}
dt_imageio_retval_t dt_imageio_open_rgbe_preview(dt_image_t *img, const char *filename)
{
const char *ext = filename + strlen(filename);
while(*ext != '.' && ext > filename) ext--;
if(strncmp(ext, ".hdr", 4) && strncmp(ext, ".HDR", 4) && strncmp(ext, ".Hdr", 4)) return DT_IMAGEIO_FILE_CORRUPTED;
FILE *f = fopen(filename, "rb");
if(!f) return DT_IMAGEIO_FILE_CORRUPTED;
if(RGBE_ReadHeader(f, &img->width, &img->height, NULL)) goto error_corrupt;
float *buf = (float *)malloc(3*sizeof(float)*img->width*img->height);
if(!buf) goto error_corrupt;
if(RGBE_ReadPixels_RLE(f, buf, img->width, img->height))
{
free(buf);
goto error_corrupt;
}
// repair nan/inf etc
for(int i=0; i < img->width*img->height*3; i++) buf[i] = fmaxf(0.0f, fminf(10000.0, img->pixels[i]));
dt_imageio_retval_t retv = dt_image_raw_to_preview(img, buf);
free(buf);
fclose(f);
return retv;
error_corrupt:
fclose(f);
return DT_IMAGEIO_FILE_CORRUPTED;
}
......@@ -21,5 +21,6 @@
#include "common/image.h"
dt_imageio_retval_t dt_imageio_open_rgbe(dt_image_t *img, const char *filename);
dt_imageio_retval_t dt_imageio_open_rgbe_preview(dt_image_t *img, const char *filename);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment