Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Olena
pylene
Commits
9c318e8e
Commit
9c318e8e
authored
Sep 15, 2019
by
Edwin Carlinet
Browse files
Support for load/save in any dimension.
parent
e46c04fd
Changes
8
Hide whitespace changes
Inline
Side-by-side
pylene/include/mln/core/canvas/private/traverse2d.hpp
View file @
9c318e8e
#pragma once
#include
<mln/core/box.hpp>
#include
<mln/core/image/experimental/ndimage_fwd.hpp>
#include
<functional>
...
...
@@ -13,4 +13,7 @@ namespace mln::canvas::details
void
traverse_along_direction
(
mln
::
experimental
::
box2d
roi
,
mln
::
experimental
::
point2d
direction
,
std
::
function
<
void
(
mln
::
experimental
::
point2d
,
mln
::
experimental
::
point2d
,
std
::
size_t
n
)
>
callback
);
/// \brief Traverse an image and calls f with a pointer to the data of each line
void
apply_line
(
mln
::
ndbuffer_image
&
input
,
std
::
function
<
void
(
std
::
byte
*
)
>
);
}
pylene/include/mln/io/private/freeimage_plugin.hpp
View file @
9c318e8e
...
...
@@ -5,7 +5,7 @@
namespace
mln
::
io
::
internal
{
class
freeimage_reader_plugin
:
public
plugin
2d
_reader
class
freeimage_reader_plugin
:
public
plugin_reader
{
public:
~
freeimage_reader_plugin
()
final
;
...
...
@@ -13,11 +13,11 @@ namespace mln::io::internal
void
close
()
final
;
};
class
freeimage_writer_plugin
:
public
plugin
2d
_writer
class
freeimage_writer_plugin
:
public
plugin_writer
{
public:
~
freeimage_writer_plugin
()
final
;
void
open
(
const
char
*
filename
,
sample_type_id
sample_type
,
int
width
,
int
height
)
final
;
void
open
(
const
char
*
filename
,
sample_type_id
sample_type
,
int
nfim
,
const
int
dims
[]
)
final
;
void
close
()
final
;
private:
...
...
pylene/include/mln/io/private/io.hpp
View file @
9c318e8e
...
...
@@ -11,20 +11,22 @@
namespace
mln
::
io
::
internal
{
void
load2d
(
plugin2d_reader
*
p
,
const
char
*
filename
,
mln
::
ndbuffer_image
&
output
);
template
<
class
I
>
void
save2d
(
mln
::
experimental
::
Image
<
I
>&
input
,
plugin
2d
_writer
*
p
,
const
char
*
filename
);
void
save2d
(
mln
::
experimental
::
Image
<
I
>&
input
,
plugin_writer
*
p
,
const
char
*
filename
);
template
<
class
I
>
void
save2d
(
mln
::
experimental
::
Image
<
I
>&&
input
,
plugin
2d
_writer
*
p
,
const
char
*
filename
);
void
save2d
(
mln
::
experimental
::
Image
<
I
>&&
input
,
plugin_writer
*
p
,
const
char
*
filename
);
template
<
class
I
>
void
save2d
(
const
mln
::
experimental
::
Image
<
I
>&
input
,
plugin
2d
_writer
*
p
,
const
char
*
filename
);
void
save2d
(
const
mln
::
experimental
::
Image
<
I
>&
input
,
plugin_writer
*
p
,
const
char
*
filename
);
// Specialization for types convertible to mln::ndbuffer_image
void
save2d
(
const
mln
::
ndbuffer_image
&
input
,
plugin2d_writer
*
p
,
const
char
*
filename
);
inline
void
save2d
(
const
mln
::
ndbuffer_image
&
input
,
plugin_writer
*
p
,
const
char
*
filename
);
// Generic ndimension algorithm for buffer encoded image
void
load
(
plugin_reader
*
p
,
const
char
*
filename
,
mln
::
ndbuffer_image
&
output
);
void
save
(
const
mln
::
ndbuffer_image
&
input
,
plugin_writer
*
p
,
const
char
*
filename
);
}
...
...
@@ -34,7 +36,7 @@ namespace mln::io::internal
{
template
<
class
Image
>
void
save2d
(
Image
&&
input
,
plugin
2d
_writer
*
p
,
const
char
*
filename
)
void
save2d
(
Image
&&
input
,
plugin_writer
*
p
,
const
char
*
filename
)
{
using
I
=
std
::
remove_reference_t
<
Image
>
;
using
V
=
image_value_t
<
I
>
;
...
...
@@ -49,7 +51,8 @@ namespace mln::io::internal
sample_type_id
tid
=
sample_type_traits
<
V
>::
id
();
// Read header
p
->
open
(
filename
,
tid
,
width
,
height
);
int
dims
[
2
]
=
{
width
,
height
};
p
->
open
(
filename
,
tid
,
2
,
dims
);
auto
buffer
=
std
::
make_unique
<
V
[]
>
(
width
);
...
...
@@ -71,22 +74,27 @@ namespace mln::io::internal
}
// namespace impl
template
<
class
I
>
void
save2d
(
mln
::
experimental
::
Image
<
I
>&&
input
,
plugin
2d
_writer
*
p
,
const
char
*
filename
)
void
save2d
(
mln
::
experimental
::
Image
<
I
>&&
input
,
plugin_writer
*
p
,
const
char
*
filename
)
{
impl
::
save2d
(
static_cast
<
I
&&>
(
input
),
p
,
filename
);
}
template
<
class
I
>
void
save2d
(
mln
::
experimental
::
Image
<
I
>&
input
,
plugin
2d
_writer
*
p
,
const
char
*
filename
)
void
save2d
(
mln
::
experimental
::
Image
<
I
>&
input
,
plugin_writer
*
p
,
const
char
*
filename
)
{
impl
::
save2d
(
static_cast
<
I
&>
(
input
),
p
,
filename
);
}
template
<
class
I
>
void
save2d
(
const
mln
::
experimental
::
Image
<
I
>&
input
,
plugin
2d
_writer
*
p
,
const
char
*
filename
)
void
save2d
(
const
mln
::
experimental
::
Image
<
I
>&
input
,
plugin_writer
*
p
,
const
char
*
filename
)
{
impl
::
save2d
(
static_cast
<
const
I
&>
(
input
),
p
,
filename
);
}
void
save2d
(
const
mln
::
ndbuffer_image
&
input
,
plugin_writer
*
p
,
const
char
*
filename
)
{
save
(
input
,
p
,
filename
);
}
}
// namespace mln::io::internal
pylene/include/mln/io/private/plugin.hpp
View file @
9c318e8e
...
...
@@ -7,15 +7,16 @@
namespace
mln
::
io
::
internal
{
class
plugin2d_base
class
plugin_base
{
public:
virtual
~
plugin
2d
_base
()
=
default
;
virtual
~
plugin_base
()
=
default
;
struct
impl_t
{
int
m_
width
;
int
m_
height
;
int
m_
ndim
;
int
m_
dims
[
16
]
;
sample_type_id
m_sample_type_id
;
virtual
~
impl_t
()
=
default
;
...
...
@@ -28,26 +29,28 @@ namespace mln::io::internal
};
class
plugin
2d
_reader
:
public
plugin
2d
_base
class
plugin_reader
:
public
plugin_base
{
public:
virtual
void
open
(
const
char
*
filename
)
=
0
;
virtual
void
close
()
=
0
;
int
width
()
const
{
return
m_impl
->
m_width
;
}
int
height
()
const
{
return
m_impl
->
m_height
;
}
int
get_ndim
()
const
{
return
m_impl
->
m_ndim
;
}
int
get_dim
(
int
k
)
const
{
return
m_impl
->
m_dims
[
k
];
}
const
int
*
get_dim_array
()
const
{
return
m_impl
->
m_dims
;
}
sample_type_id
get_sample_type_id
()
const
{
return
m_impl
->
m_sample_type_id
;
}
void
read_next_line
(
std
::
byte
*
buffer
)
{
return
m_impl
->
read_next_line
(
buffer
);
}
};
class
plugin
2d
_writer
:
public
plugin
2d
_base
class
plugin_writer
:
public
plugin_base
{
public:
virtual
void
open
(
const
char
*
filename
,
sample_type_id
sample_type
,
int
width
,
int
height
)
=
0
;
virtual
void
close
()
=
0
;
virtual
void
open
(
const
char
*
filename
,
sample_type_id
sample_type
,
int
ndim
,
const
int
sizes
[]
)
=
0
;
virtual
void
close
()
=
0
;
void
write_next_line
(
const
std
::
byte
*
buffer
)
{
return
m_impl
->
write_next_line
(
buffer
);
}
};
}
// namespace mln::io::internal
pylene/src/core/traverse2d.cpp
View file @
9c318e8e
#include
<mln/core/canvas/private/traverse2d.hpp>
#include
<mln/core/image/experimental/ndimage.hpp>
namespace
mln
::
canvas
::
details
{
...
...
@@ -71,4 +72,36 @@ namespace mln::canvas::details
}
}
}
}
/// \brief Traverse an image and calls f with a pointer to the data of each line
void
apply_line
(
mln
::
ndbuffer_image
&
input
,
std
::
function
<
void
(
std
::
byte
*
)
>
fun
)
{
int
pdim
=
input
.
pdim
();
if
(
pdim
>
4
)
throw
std
::
runtime_error
(
"Not implemented for this number of dimensions."
);
std
::
ptrdiff_t
strides
[
4
]
=
{
0
};
int
dims
[
4
]
=
{
1
,
1
,
1
,
1
};
for
(
int
k
=
0
;
k
<
pdim
;
++
k
)
{
dims
[
k
]
=
input
.
size
(
k
);
strides
[
k
]
=
input
.
byte_stride
(
k
);
}
for
(
int
w
=
0
;
w
<
dims
[
3
];
++
w
)
for
(
int
z
=
0
;
z
<
dims
[
2
];
++
z
)
{
std
::
byte
*
lineptr
=
input
.
buffer
()
+
w
*
strides
[
3
]
+
z
*
strides
[
2
];
for
(
int
y
=
0
;
y
<
dims
[
1
];
++
y
)
{
fun
(
lineptr
);
lineptr
+=
strides
[
1
];
}
}
}
}
// namespace mln::canvas::details
pylene/src/io/freeimage_plugin.cpp
View file @
9c318e8e
...
...
@@ -82,7 +82,7 @@ namespace mln::io::internal
struct
impl_base_t
:
plugin
2d
_base
::
impl_t
struct
impl_base_t
:
plugin_base
::
impl_t
{
const
char
*
m_filename
;
FIBITMAP
*
m_dib
;
...
...
@@ -97,14 +97,14 @@ namespace mln::io::internal
void
read_next_line
(
std
::
byte
*
buffer
)
final
{
BYTE
*
lineptr
=
FreeImage_GetScanLine
(
m_dib
,
m_y
);
std
::
memcpy
(
buffer
,
lineptr
,
m_
width
*
m_bpp
/
8
);
std
::
memcpy
(
buffer
,
lineptr
,
m_
dims
[
0
]
*
m_bpp
/
8
);
m_y
--
;
}
void
write_next_line
(
const
std
::
byte
*
buffer
)
final
{
BYTE
*
lineptr
=
FreeImage_GetScanLine
(
m_dib
,
m_y
);
std
::
memcpy
(
lineptr
,
buffer
,
m_
width
*
m_bpp
/
8
);
std
::
memcpy
(
lineptr
,
buffer
,
m_
dims
[
0
]
*
m_bpp
/
8
);
m_y
--
;
}
};
...
...
@@ -116,7 +116,7 @@ namespace mln::io::internal
void
read_next_line
(
std
::
byte
*
__restrict
buffer
)
final
{
std
::
uint8_t
*
lineptr
=
(
std
::
uint8_t
*
)
FreeImage_GetScanLine
(
m_dib
,
m_y
);
for
(
int
x
=
0
,
t
=
0
;
x
<
m_
width
;
x
+=
8
,
t
++
)
for
(
int
x
=
0
,
t
=
0
;
x
<
m_
dims
[
0
]
;
x
+=
8
,
t
++
)
{
buffer
[
x
]
=
std
::
byte
((
lineptr
[
t
]
&
0x80
)
!=
0
);
buffer
[
x
+
1
]
=
std
::
byte
((
lineptr
[
t
]
&
0x40
)
!=
0
);
...
...
@@ -136,11 +136,11 @@ namespace mln::io::internal
std
::
uint8_t
*
lineptr
=
(
std
::
uint8_t
*
)
FreeImage_GetScanLine
(
m_dib
,
m_y
);
int
x
,
t
;
for
(
x
=
0
,
t
=
0
;
x
+
8
<
m_
width
;
x
+=
8
,
t
++
)
for
(
x
=
0
,
t
=
0
;
x
+
8
<
m_
dims
[
0
]
;
x
+=
8
,
t
++
)
lineptr
[
t
]
=
buffer
[
x
+
0
]
<<
7
|
buffer
[
x
+
1
]
<<
6
|
buffer
[
x
+
2
]
<<
5
|
buffer
[
x
+
3
]
<<
4
|
buffer
[
x
+
4
]
<<
3
|
buffer
[
x
+
5
]
<<
2
|
buffer
[
x
+
6
]
<<
1
|
buffer
[
x
+
7
]
<<
0
;
int
remainder
=
m_
width
-
x
;
int
remainder
=
m_
dims
[
0
]
-
x
;
if
(
remainder
>
0
)
{
lineptr
[
t
]
=
0
;
...
...
@@ -165,7 +165,7 @@ namespace mln::io::internal
void
read_next_line
(
std
::
byte
*
__restrict
buffer
)
final
{
std
::
uint8_t
*
lineptr
=
(
std
::
uint8_t
*
)
FreeImage_GetScanLine
(
m_dib
,
m_y
);
for
(
int
x
=
0
,
t
=
0
;
x
<
m_
width
;
x
+=
8
,
t
++
)
for
(
int
x
=
0
,
t
=
0
;
x
<
m_
dims
[
0
]
;
x
+=
8
,
t
++
)
{
buffer
[
x
]
=
std
::
byte
((
lineptr
[
t
]
&
0x80
)
==
0
);
buffer
[
x
+
1
]
=
std
::
byte
((
lineptr
[
t
]
&
0x40
)
==
0
);
...
...
@@ -191,7 +191,7 @@ namespace mln::io::internal
void
read_next_line
(
std
::
byte
*
__restrict
buffer
)
final
{
uint8_t
*
lineptr
=
(
uint8_t
*
)
FreeImage_GetScanLine
(
m_dib
,
m_y
);
for
(
int
x
=
0
;
x
<
m_
width
;
++
x
)
for
(
int
x
=
0
;
x
<
m_
dims
[
0
]
;
++
x
)
{
buffer
[
3
*
x
+
0
]
=
std
::
byte
(
m_palette
[
lineptr
[
x
]].
rgbRed
);
buffer
[
3
*
x
+
1
]
=
std
::
byte
(
m_palette
[
lineptr
[
x
]].
rgbGreen
);
...
...
@@ -209,7 +209,7 @@ namespace mln::io::internal
void
read_next_line
(
std
::
byte
*
__restrict
buffer
)
final
{
std
::
byte
*
lineptr
=
(
std
::
byte
*
)
FreeImage_GetScanLine
(
m_dib
,
m_y
);
for
(
int
x
=
0
;
x
<
m_
width
;
++
x
)
for
(
int
x
=
0
;
x
<
m_
dims
[
0
]
;
++
x
)
{
buffer
[
3
*
x
+
0
]
=
lineptr
[
3
*
x
+
FI_RGBA_RED
];
buffer
[
3
*
x
+
1
]
=
lineptr
[
3
*
x
+
FI_RGBA_GREEN
];
...
...
@@ -221,7 +221,7 @@ namespace mln::io::internal
void
write_next_line
(
const
std
::
byte
*
__restrict
buffer
)
final
{
std
::
byte
*
lineptr
=
(
std
::
byte
*
)
FreeImage_GetScanLine
(
m_dib
,
m_y
);
for
(
int
x
=
0
;
x
<
m_
width
;
++
x
)
for
(
int
x
=
0
;
x
<
m_
dims
[
0
]
;
++
x
)
{
lineptr
[
3
*
x
+
FI_RGBA_RED
]
=
buffer
[
3
*
x
+
0
];
lineptr
[
3
*
x
+
FI_RGBA_GREEN
]
=
buffer
[
3
*
x
+
1
];
...
...
@@ -237,7 +237,7 @@ namespace mln::io::internal
void
read_next_line
(
std
::
byte
*
__restrict
buffer
)
final
{
std
::
byte
*
lineptr
=
(
std
::
byte
*
)
FreeImage_GetScanLine
(
m_dib
,
m_y
);
for
(
int
x
=
0
;
x
<
m_
width
;
++
x
)
for
(
int
x
=
0
;
x
<
m_
dims
[
0
]
;
++
x
)
{
buffer
[
4
*
x
+
0
]
=
lineptr
[
4
*
x
+
FI_RGBA_RED
];
buffer
[
4
*
x
+
1
]
=
lineptr
[
4
*
x
+
FI_RGBA_GREEN
];
...
...
@@ -250,7 +250,7 @@ namespace mln::io::internal
void
write_next_line
(
const
std
::
byte
*
__restrict
buffer
)
final
{
std
::
byte
*
lineptr
=
(
std
::
byte
*
)
FreeImage_GetScanLine
(
m_dib
,
m_y
);
for
(
int
x
=
0
;
x
<
m_
width
;
++
x
)
for
(
int
x
=
0
;
x
<
m_
dims
[
0
]
;
++
x
)
{
lineptr
[
4
*
x
+
FI_RGBA_RED
]
=
buffer
[
4
*
x
+
0
];
lineptr
[
4
*
x
+
FI_RGBA_GREEN
]
=
buffer
[
4
*
x
+
1
];
...
...
@@ -306,12 +306,13 @@ namespace mln::io::internal
impl
->
m_dib
=
dib
;
impl
->
m_fif
=
fif
;
impl
->
m_height
=
FreeImage_GetHeight
(
dib
);
impl
->
m_width
=
FreeImage_GetWidth
(
dib
);
impl
->
m_ndim
=
2
;
impl
->
m_dims
[
0
]
=
FreeImage_GetWidth
(
dib
);
impl
->
m_dims
[
1
]
=
FreeImage_GetHeight
(
dib
);
impl
->
m_sample_type_id
=
sid
;
impl
->
m_bpp
=
bits_per_pixel
;
impl
->
m_palette
=
FreeImage_GetPalette
(
dib
);
impl
->
m_y
=
impl
->
m_
height
-
1
;
impl
->
m_y
=
impl
->
m_
dims
[
1
]
-
1
;
m_impl
=
std
::
move
(
impl
);
return
;
...
...
@@ -362,8 +363,14 @@ namespace mln::io::internal
this
->
close
();
}
void
freeimage_writer_plugin
::
open
(
const
char
*
filename
,
sample_type_id
sample_type
,
int
width
,
int
height
)
void
freeimage_writer_plugin
::
open
(
const
char
*
filename
,
sample_type_id
sample_type
,
int
ndim
,
const
int
dims
[]
)
{
if
(
ndim
!=
2
)
throw
std
::
runtime_error
(
fmt
::
format
(
"Unsupported number of dimension (ndim={}, should be 2)."
,
ndim
));
const
int
width
=
dims
[
0
];
const
int
height
=
dims
[
1
];
std
::
unique_ptr
<
impl_base_t
>
impl
;
FREE_IMAGE_FORMAT
fif
=
FreeImage_GetFIFFromFilename
(
filename
);
...
...
@@ -412,7 +419,7 @@ namespace mln::io::internal
if
(
!
dib
)
throw
std
::
runtime_error
(
fmt
::
format
(
"Unable to allocate image (type={}, bpp={})."
,
FreeImage_GetFormatFromFIF
(
fif
),
bits_per_pixel
));
fmt
::
format
(
"Unable to allocate image (type={}, bpp={})."
,
FreeImage_GetFormatFromFIF
(
fif
),
bits_per_pixel
));
// Set the palette
RGBQUAD
*
palette
=
FreeImage_GetPalette
(
dib
);
...
...
@@ -427,8 +434,9 @@ namespace mln::io::internal
palette
[
i
]
=
{(
BYTE
)
i
,
(
BYTE
)
i
,
(
BYTE
)
i
,
0u
};
}
impl
->
m_width
=
width
;
impl
->
m_height
=
height
;
impl
->
m_ndim
=
2
;
impl
->
m_dims
[
0
]
=
width
;
impl
->
m_dims
[
1
]
=
height
;
impl
->
m_sample_type_id
=
sample_type
;
impl
->
m_bpp
=
bits_per_pixel
;
impl
->
m_dib
=
dib
;
...
...
pylene/src/io/imread.cpp
View file @
9c318e8e
...
...
@@ -16,6 +16,6 @@ namespace mln::io::experimental
void
imread
(
const
std
::
string
&
filename
,
mln
::
ndbuffer_image
&
out
)
{
internal
::
freeimage_reader_plugin
p
;
internal
::
load
2d
(
&
p
,
filename
.
c_str
(),
out
);
internal
::
load
(
&
p
,
filename
.
c_str
(),
out
);
}
}
pylene/src/io/io.cpp
View file @
9c318e8e
#include
<mln/io/private/io.hpp>
#include
<mln/core/canvas/private/traverse2d.hpp>
#include
<mln/core/image/experimental/ndimage.hpp>
#include
<mln/io/private/plugin.hpp>
#include
<functional>
#include
<fmt/core.h>
namespace
mln
::
io
::
internal
{
void
load
2d
(
plugin
2d
_reader
*
p
,
const
char
*
filename
,
mln
::
ndbuffer_image
&
output
)
void
load
(
plugin_reader
*
p
,
const
char
*
filename
,
mln
::
ndbuffer_image
&
output
)
{
// Read header
p
->
open
(
filename
);
// Allocate image
int
height
=
p
->
height
();
int
width
=
p
->
width
();
int
pdim
=
p
->
get_ndim
();
sample_type_id
tid
=
p
->
get_sample_type_id
();
if
(
output
.
sample_type
()
!=
sample_type_id
::
OTHER
&&
output
.
sample_type
()
!=
tid
)
throw
std
::
runtime_error
(
fmt
::
format
(
"Sample type mismatch. The input is {} (requested: {})."
,
(
int
)
tid
,
(
int
)
output
.
sample_type
()));
fmt
::
format
(
"Sample type mismatch. The input is {} (requested: {})."
,
(
int
)
tid
,
(
int
)
output
.
sample_type
()));
if
(
output
.
pdim
()
!=
0
&&
output
.
pdim
()
!=
2
)
throw
std
::
runtime_error
(
fmt
::
format
(
"Number of dimensions mismath (={}) (should be
2
)."
,
output
.
pdim
()));
if
(
output
.
pdim
()
!=
0
&&
output
.
pdim
()
!=
pdim
)
throw
std
::
runtime_error
(
fmt
::
format
(
"Number of dimensions mismath (={}) (should be
{}
)."
,
output
.
pdim
()
,
pdim
));
output
.
resize
(
tid
,
width
,
height
);
output
.
resize
(
tid
,
pdim
,
p
->
get_dim_array
(),
image_build_params
{}
);
// Fill content
{
std
::
byte
*
lineptr
=
output
.
buffer
();
std
::
ptrdiff_t
stride
=
output
.
byte_stride
();
for
(
int
y
=
0
;
y
<
height
;
++
y
)
{
p
->
read_next_line
(
lineptr
);
lineptr
+=
stride
;
}
}
// Fill content (up to 4 dimensions for now)
mln
::
canvas
::
details
::
apply_line
(
output
,
std
::
bind
(
&
plugin_reader
::
read_next_line
,
p
,
std
::
placeholders
::
_1
));
// Close handle
p
->
close
();
}
void
save2d
(
const
mln
::
ndbuffer_image
&
input
,
plugin2d_writer
*
p
,
const
char
*
filename
)
void
save
(
const
mln
::
ndbuffer_image
&
input
,
plugin_writer
*
p
,
const
char
*
filename
)
{
i
f
(
input
.
pdim
()
!=
2
)
throw
std
::
runtime_error
(
fmt
::
format
(
"Invalid number of dimensions (={}) (should be 2)."
,
input
.
pdim
()))
;
i
nt
ndim
=
input
.
pdim
()
;
int
sizes
[
16
]
;
// Allocate image
int
height
=
input
.
size
(
1
);
int
width
=
input
.
size
(
0
);
sample_type_id
tid
=
input
.
sample_type
();
for
(
int
k
=
0
;
k
<
ndim
;
++
k
)
sizes
[
k
]
=
input
.
size
(
k
);
// Read header
p
->
open
(
filename
,
tid
,
width
,
height
);
p
->
open
(
filename
,
input
.
sample_type
(),
ndim
,
sizes
);
// Fill content
{
const
std
::
byte
*
lineptr
=
input
.
buffer
();
std
::
ptrdiff_t
stride
=
input
.
byte_stride
();
for
(
int
y
=
0
;
y
<
height
;
++
y
)
{
p
->
write_next_line
(
lineptr
);
lineptr
+=
stride
;
}
}
mln
::
canvas
::
details
::
apply_line
(
const_cast
<
mln
::
ndbuffer_image
&>
(
input
),
std
::
bind
(
&
plugin_writer
::
write_next_line
,
p
,
std
::
placeholders
::
_1
));
// Close handle
p
->
close
();
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment