Skip to content

Commit 39b5e36

Browse files
jenshannoschwalmTurboGit
authored andcommitted
Imageio PFM fixes
1. Allocate temp buffer only for what we need 2. Check for correct size of read data from file and possibly report as corrupted 3. some constify and simplifications
1 parent eab2a3e commit 39b5e36

File tree

1 file changed

+21
-30
lines changed

1 file changed

+21
-30
lines changed

src/imageio/imageio_pfm.c

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img,
4141

4242
int ret = 0;
4343
int channels = 3;
44-
float scale_factor;
4544
char head[2] = { 'X', 'X' };
4645

4746
ret = fscanf(f, "%c%c\n", head, head + 1);
@@ -56,7 +55,6 @@ dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img,
5655
else
5756
goto error_corrupt;
5857

59-
int read_byte;
6058
gboolean made_by_photoshop = TRUE;
6159
// We expect metadata with a newline character at the end.
6260
// If there is no whitespace in the first line, then this file
@@ -65,7 +63,7 @@ dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img,
6563
// to the file in a different order.
6664
for(;;)
6765
{
68-
read_byte = fgetc(f);
66+
int read_byte = fgetc(f);
6967
if((read_byte == '\n') || (read_byte == EOF))
7068
break;
7169
if(read_byte < '0') // easy way to match all whitespaces
@@ -87,22 +85,18 @@ dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img,
8785
if(ret != 3)
8886
goto error_corrupt;
8987

90-
errno = 0;
9188
img->width = strtol(width_string, NULL, 0);
9289
img->height = strtol(height_string, NULL, 0);
93-
scale_factor = g_ascii_strtod(scale_factor_string, NULL);
90+
const float scale_factor = g_ascii_strtod(scale_factor_string, NULL);
9491

95-
if(errno != 0)
96-
goto error_corrupt;
9792
if(img->width <= 0 || img->height <= 0 )
9893
goto error_corrupt;
9994

10095
ret = fread(&ret, sizeof(char), 1, f);
10196
if(ret != 1)
10297
goto error_corrupt;
103-
ret = 0;
10498

105-
int swap_byte_order = (scale_factor >= 0.0) ^ (G_BYTE_ORDER == G_BIG_ENDIAN);
99+
const int swap_byte_order = (scale_factor >= 0.0) ^ (G_BYTE_ORDER == G_BIG_ENDIAN);
106100

107101
img->buf_dsc.channels = 4;
108102
img->buf_dsc.datatype = TYPE_FLOAT;
@@ -112,10 +106,15 @@ dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img,
112106

113107
const size_t npixels = (size_t)img->width * img->height;
114108

115-
float *readbuf = dt_alloc_align_float(npixels * 4);
109+
float *readbuf = dt_alloc_align_float(npixels * channels);
116110
if(!readbuf)
117111
goto error_cache_full;
118-
112+
ret = fread(readbuf, sizeof(float) * channels, npixels, f);
113+
if(ret != npixels)
114+
{
115+
dt_free_align(readbuf);
116+
goto error_corrupt;
117+
}
119118
// We use this union to swap the byte order in the float value if needed
120119
union { float as_float; guint32 as_int; } value;
121120

@@ -124,45 +123,37 @@ dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img,
124123
// the rows in the process of filling the output buffer with data
125124
if(channels == 3)
126125
{
127-
ret = fread(readbuf, 3 * sizeof(float), npixels, f);
128-
size_t target_row = 0;
129-
130-
DT_OMP_FOR(collapse(2))
126+
DT_OMP_FOR(collapse(2))
131127
for(size_t row = 0; row < img->height; row++)
128+
{
129+
const size_t target_row = made_by_photoshop ? row : img->height - 1 - row;
132130
for(size_t column = 0; column < img->width; column++)
133131
{
134132
dt_aligned_pixel_t pix = {0.0f, 0.0f, 0.0f, 0.0f};
135-
if(made_by_photoshop)
136-
target_row = row;
137-
else
138-
target_row = img->height - 1 - row;
139133
for_three_channels(c)
140134
{
141-
value.as_float = readbuf[3 * (target_row * img->width + column) + c];
142-
if(swap_byte_order) value.as_int = GUINT32_SWAP_LE_BE(value.as_int);
143-
pix[c] = value.as_float;
135+
value.as_float = readbuf[3 * (target_row * img->width + column) + c];
136+
if(swap_byte_order) value.as_int = GUINT32_SWAP_LE_BE(value.as_int);
137+
pix[c] = value.as_float;
144138
}
145139
copy_pixel_nontemporal(&buf[4 * (img->width * row + column)], pix);
146140
}
141+
}
147142
}
148143
else
149144
{
150-
ret = fread(readbuf, sizeof(float), npixels, f);
151-
size_t target_row = 0;
152-
153-
DT_OMP_FOR(collapse(2))
145+
DT_OMP_FOR(collapse(2))
154146
for(size_t row = 0; row < img->height; row++)
147+
{
148+
const size_t target_row = made_by_photoshop ? row : img->height - 1 - row;
155149
for(size_t column = 0; column < img->width; column++)
156150
{
157-
if(made_by_photoshop)
158-
target_row = row;
159-
else
160-
target_row = img->height - 1 - row;
161151
value.as_float = readbuf[target_row * img->width + column];
162152
if(swap_byte_order) value.as_int = GUINT32_SWAP_LE_BE(value.as_int);
163153
buf[4 * (img->width * row + column) + 2] = buf[4 * (img->width * row + column) + 1]
164154
= buf[4 * (img->width * row + column) + 0] = value.as_float;
165155
}
156+
}
166157
}
167158

168159
fclose(f);

0 commit comments

Comments
 (0)