3434#include <time.h>
3535#include <unistd.h>
3636
37- dt_imageio_retval_t dt_imageio_open_pfm (dt_image_t * img , const char * filename , dt_mipmap_buffer_t * mbuf )
37+ dt_imageio_retval_t dt_imageio_open_pfm (dt_image_t * img ,
38+ const char * filename ,
39+ dt_mipmap_buffer_t * mbuf )
3840{
3941 const char * ext = filename + strlen (filename );
40- while (* ext != '.' && ext > filename ) ext -- ;
41- if (strcasecmp (ext , ".pfm" )) return DT_IMAGEIO_LOAD_FAILED ;
42+
43+ while (* ext != '.' && ext > filename )
44+ ext -- ;
45+
46+ if (strcasecmp (ext , ".pfm" ))
47+ return DT_IMAGEIO_LOAD_FAILED ;
4248
4349 FILE * f = g_fopen (filename , "rb" );
44- if (!f ) return DT_IMAGEIO_FILE_NOT_FOUND ;
50+ if (!f )
51+ return DT_IMAGEIO_FILE_NOT_FOUND ;
4552
4653 int ret = 0 ;
4754 int cols = 3 ;
4855 float scale_factor ;
4956 char head [2 ] = { 'X' , 'X' };
57+
5058 ret = fscanf (f , "%c%c\n" , head , head + 1 );
51- if (ret != 2 || head [0 ] != 'P' ) goto error_corrupt ;
59+
60+ if (ret != 2 || head [0 ] != 'P' )
61+ goto error_corrupt ;
62+
5263 if (head [1 ] == 'F' )
5364 cols = 3 ;
5465 else if (head [1 ] == 'f' )
@@ -59,63 +70,78 @@ dt_imageio_retval_t dt_imageio_open_pfm(dt_image_t *img, const char *filename, d
5970 char width_string [10 ] = { 0 };
6071 char height_string [10 ] = { 0 };
6172 char scale_factor_string [64 ] = { 0 };
73+
6274 ret = fscanf (f , "%9s %9s %63s%*[^\n]" , width_string , height_string , scale_factor_string );
63- if (ret != 3 ) goto error_corrupt ;
75+
76+ if (ret != 3 )
77+ goto error_corrupt ;
6478
6579 errno = 0 ;
6680 img -> width = strtol (width_string , NULL , 0 );
6781 img -> height = strtol (height_string , NULL , 0 );
6882 scale_factor = g_ascii_strtod (scale_factor_string , NULL );
69- if (errno != 0 ) goto error_corrupt ;
70- if (img -> width <= 0 || img -> height <= 0 ) goto error_corrupt ;
83+
84+ if (errno != 0 )
85+ goto error_corrupt ;
86+ if (img -> width <= 0 || img -> height <= 0 )
87+ goto error_corrupt ;
7188
7289 ret = fread (& ret , sizeof (char ), 1 , f );
73- if (ret != 1 ) goto error_corrupt ;
90+ if (ret != 1 )
91+ goto error_corrupt ;
7492 ret = 0 ;
7593
7694 int swap_byte_order = (scale_factor >= 0.0 ) ^ (G_BYTE_ORDER == G_BIG_ENDIAN );
7795
7896 img -> buf_dsc .channels = 4 ;
7997 img -> buf_dsc .datatype = TYPE_FLOAT ;
8098 float * buf = (float * )dt_mipmap_cache_alloc (mbuf , img );
81- if (!buf ) goto error_cache_full ;
99+ if (!buf )
100+ goto error_cache_full ;
101+
102+ const size_t npixels = (size_t )img -> width * img -> height ;
103+
104+ float * readbuf = dt_alloc_align_float (npixels * 4 );
105+ if (!readbuf )
106+ goto error_cache_full ;
107+
108+ union { float f ; guint32 i ; } value ;
82109
83110 if (cols == 3 )
84111 {
85- ret = fread (buf , 3 * sizeof (float ), (size_t )img -> width * img -> height , f );
86- for (size_t i = (size_t )img -> width * img -> height ; i > 0 ; i -- )
87- for (int c = 0 ; c < 3 ; c ++ )
112+ ret = fread (readbuf , 3 * sizeof (float ), npixels , f );
113+
114+ DT_OMP_FOR (collapse (2 ))
115+ for (size_t j = 0 ; j < img -> height ; j ++ )
116+ for (size_t i = 0 ; i < img -> width ; i ++ )
88117 {
89- union { float f ; guint32 i ; } v ;
90- v .f = buf [3 * (i - 1 ) + c ];
91- if (swap_byte_order ) v .i = GUINT32_SWAP_LE_BE (v .i );
92- buf [4 * (i - 1 ) + c ] = v .f ;
118+ dt_aligned_pixel_t pix = {0.0f , 0.0f , 0.0f , 0.0f };
119+ for_three_channels (c )
120+ {
121+ value .f = readbuf [3 * ((img -> height - 1 - j ) * img -> width + i ) + c ];
122+ if (swap_byte_order ) value .i = GUINT32_SWAP_LE_BE (value .i );
123+ pix [c ] = value .f ;
124+ }
125+ copy_pixel_nontemporal (& buf [4 * (img -> width * j + i )], pix );
93126 }
94127 }
95128 else
129+ {
130+ ret = fread (readbuf , sizeof (float ), npixels , f );
131+
132+ DT_OMP_FOR (collapse (2 ))
96133 for (size_t j = 0 ; j < img -> height ; j ++ )
97134 for (size_t i = 0 ; i < img -> width ; i ++ )
98135 {
99- union { float f ; guint32 i ; } v ;
100- ret = fread (& v .f , sizeof (float ), 1 , f );
101- if (swap_byte_order ) v .i = GUINT32_SWAP_LE_BE (v .i );
136+ value .f = readbuf [((img -> height - 1 - j ) * img -> width + i )];
137+ if (swap_byte_order ) value .i = GUINT32_SWAP_LE_BE (value .i );
102138 buf [4 * (img -> width * j + i ) + 2 ] = buf [4 * (img -> width * j + i ) + 1 ]
103- = buf [4 * (img -> width * j + i ) + 0 ] = v .f ;
139+ = buf [4 * (img -> width * j + i ) + 0 ] = value .f ;
104140 }
105-
106- float * line = (float * )calloc (4 * img -> width , sizeof (float ));
107- if (line == NULL ) goto error_cache_full ;
108-
109- for (size_t j = 0 ; j < img -> height / 2 ; j ++ )
110- {
111- memcpy (line , buf + img -> width * j * 4 , sizeof (float ) * 4 * img -> width );
112- memcpy (buf + img -> width * j * 4 , buf + img -> width * (img -> height - 1 - j ) * 4 ,
113- sizeof (float ) * 4 * img -> width );
114- memcpy (buf + img -> width * (img -> height - 1 - j ) * 4 , line , sizeof (float ) * 4 * img -> width );
115141 }
116142
117- free (line );
118143 fclose (f );
144+ dt_free_align (readbuf );
119145
120146 img -> buf_dsc .cst = IOP_CS_RGB ;
121147 img -> buf_dsc .filters = 0u ;
0 commit comments