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
bob
bob.io.image
Commits
4ec6d607
Commit
4ec6d607
authored
Sep 08, 2016
by
Manuel Günther
Browse files
Step 1: get image extension based on file content
parent
f1a67da0
Pipeline
#3620
failed with stage
in 36 minutes and 31 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
bob/io/image/include/bob.io.image/image.h
View file @
4ec6d607
...
...
@@ -29,12 +29,75 @@
#include
<bob.io.image/tiff.h>
#include
<boost/filesystem/path.hpp>
#include
<boost/algorithm/string.hpp>
#include
<fstream>
#include
<algorithm>
namespace
bob
{
namespace
io
{
namespace
image
{
inline
bool
is_color_image
(
const
std
::
string
&
filename
){
std
::
string
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
inline
const
std
::
string
&
get_correct_image_extension
(
const
std
::
string
&
image_name
){
// global map of known magic numbers
// these numbers are based on: http://stackoverflow.com/questions/26350342/determining-the-extension-type-of-an-image-file-using-binary/26350431#26350431
static
std
::
map
<
std
::
string
,
std
::
vector
<
std
::
vector
<
std
::
uint8_t
>>>
known_magic_numbers
;
// initialize list, if not done yet
if
(
known_magic_numbers
.
empty
()){
// BMP
known_magic_numbers
[
".bmp"
].
push_back
({
0x42
,
0x4D
});
// NetPBM, see https://en.wikipedia.org/wiki/Netpbm_format
known_magic_numbers
[
".pbm"
].
push_back
({
0x50
,
0x31
});
// P1
known_magic_numbers
[
".pbm"
].
push_back
({
0x50
,
0x34
});
// P4
known_magic_numbers
[
".pgm"
].
push_back
({
0x50
,
0x32
});
// P2
known_magic_numbers
[
".pgm"
].
push_back
({
0x50
,
0x35
});
// P5
known_magic_numbers
[
".ppm"
].
push_back
({
0x50
,
0x33
});
// P3
known_magic_numbers
[
".ppm"
].
push_back
({
0x50
,
0x36
});
// P6
// TODO: what about P7?
#ifdef HAVE_GIFLIB
// GIF
known_magic_numbers
[
".gif"
].
push_back
({
0x47
,
0x49
,
0x46
,
0x38
,
0x37
,
0x61
});
known_magic_numbers
[
".gif"
].
push_back
({
0x47
,
0x49
,
0x46
,
0x38
,
0x39
,
0x61
});
#endif // HAVE_GIFLIB
#ifdef HAVE_LIBPNG
// PNG
known_magic_numbers
[
".png"
].
push_back
({
0x89
,
0x50
,
0x4E
,
0x47
,
0x0D
,
0x0A
,
0x1A
,
0x0A
});
#endif // HAVE_LIB_PNG
#ifdef HAVE_LIBJPEG
// JPEG
known_magic_numbers
[
".jpg"
].
push_back
({
0xFF
,
0xD8
,
0xFF
});
known_magic_numbers
[
".jpg"
].
push_back
({
0x00
,
0x00
,
0x00
,
0x0C
,
0x6A
,
0x50
,
0x20
,
0x20
});
#endif // HAVE_LIBJPEG
#ifdef HAVE_LIBTIFF
// TIFF
known_magic_numbers
[
".tiff"
].
push_back
({
0x0C
,
0xED
});
known_magic_numbers
[
".tiff"
].
push_back
({
0x49
,
0x20
,
0x49
});
known_magic_numbers
[
".tiff"
].
push_back
({
0x49
,
0x49
,
0x2A
,
0x00
});
known_magic_numbers
[
".tiff"
].
push_back
({
0x4D
,
0x4D
,
0x00
,
0x2A
});
known_magic_numbers
[
".tiff"
].
push_back
({
0x4D
,
0x4D
,
0x00
,
0x2B
});
#endif // HAVE_LIBTIFF
}
// read first 8 bytes from file
static
uint8_t
image_bytes
[
8
];
std
::
ifstream
f
(
image_name
);
if
(
!
f
)
throw
std
::
runtime_error
(
"The given image '"
+
image_name
+
"' could not be opened for reading"
);
f
.
read
(
reinterpret_cast
<
char
*>
(
image_bytes
),
8
);
// iterate over all extensions
for
(
auto
eit
=
known_magic_numbers
.
begin
();
eit
!=
known_magic_numbers
.
end
();
++
eit
){
// iterate over all magic bytes
for
(
auto
mit
=
eit
->
second
.
begin
();
mit
!=
eit
->
second
.
end
();
++
mit
){
// check magic number
if
(
std
::
equal
(
mit
->
begin
(),
mit
->
end
(),
image_bytes
))
return
eit
->
first
;
}
}
throw
std
::
runtime_error
(
"The given image '"
+
image_name
+
"' does not contain an image of a known type"
);
}
inline
bool
is_color_image
(
const
std
::
string
&
filename
,
std
::
string
extension
=
""
){
if
(
extension
.
empty
())
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
boost
::
algorithm
::
to_lower
(
extension
);
if
(
extension
==
".bmp"
)
return
true
;
#ifdef HAVE_GIFLIB
...
...
@@ -55,8 +118,9 @@ inline bool is_color_image(const std::string& filename){
throw
std
::
runtime_error
(
"The filename extension '"
+
extension
+
"' is not known"
);
}
inline
blitz
::
Array
<
uint8_t
,
3
>
read_color_image
(
const
std
::
string
&
filename
){
std
::
string
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
inline
blitz
::
Array
<
uint8_t
,
3
>
read_color_image
(
const
std
::
string
&
filename
,
std
::
string
extension
=
""
){
if
(
extension
.
empty
())
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
boost
::
algorithm
::
to_lower
(
extension
);
if
(
extension
==
".bmp"
)
return
read_bmp
(
filename
);
#ifdef HAVE_GIFLIB
...
...
@@ -76,8 +140,9 @@ inline blitz::Array<uint8_t,3> read_color_image(const std::string& filename){
throw
std
::
runtime_error
(
"The filename extension '"
+
extension
+
"' is not known or not supported for color images"
);
}
blitz
::
Array
<
uint8_t
,
2
>
read_gray_image
(
const
std
::
string
&
filename
){
std
::
string
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
blitz
::
Array
<
uint8_t
,
2
>
read_gray_image
(
const
std
::
string
&
filename
,
std
::
string
extension
=
""
){
if
(
extension
.
empty
())
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
boost
::
algorithm
::
to_lower
(
extension
);
#ifdef HAVE_LIBPNG
if
(
extension
==
".png"
)
return
read_png
<
uint8_t
,
2
>
(
filename
);
...
...
@@ -95,8 +160,9 @@ blitz::Array<uint8_t,2> read_gray_image(const std::string& filename){
}
void
write_color_image
(
const
blitz
::
Array
<
uint8_t
,
3
>&
image
,
const
std
::
string
&
filename
){
std
::
string
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
void
write_color_image
(
const
blitz
::
Array
<
uint8_t
,
3
>&
image
,
const
std
::
string
&
filename
,
std
::
string
extension
=
""
){
if
(
extension
.
empty
())
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
boost
::
algorithm
::
to_lower
(
extension
);
if
(
extension
==
".bmp"
)
return
write_bmp
(
image
,
filename
);
// this will only work for T=uint8_t
#ifdef HAVE_GIFLIB
...
...
@@ -116,8 +182,9 @@ void write_color_image(const blitz::Array<uint8_t,3>& image, const std::string&
throw
std
::
runtime_error
(
"The filename extension '"
+
extension
+
"' is not known or not supported for color images"
);
}
void
write_gray_image
(
const
blitz
::
Array
<
uint8_t
,
2
>&
image
,
const
std
::
string
&
filename
){
std
::
string
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
void
write_gray_image
(
const
blitz
::
Array
<
uint8_t
,
2
>&
image
,
const
std
::
string
&
filename
,
std
::
string
extension
=
""
){
if
(
extension
.
empty
())
extension
=
boost
::
filesystem
::
path
(
filename
).
extension
().
string
();
boost
::
algorithm
::
to_lower
(
extension
);
#ifdef HAVE_LIBPNG
if
(
extension
==
".png"
)
return
write_png
(
image
,
filename
);
...
...
bob/io/image/main.cpp
View file @
4ec6d607
...
...
@@ -59,8 +59,12 @@ BOB_TRY
// BMP; only color images are supported
boost
::
filesystem
::
path
bmp
(
tempdir
);
bmp
/=
std
::
string
(
"color.bmp"
);
bob
::
io
::
image
::
write_color_image
(
color_image
,
bmp
.
string
());
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
bmp
.
string
())
!=
".bmp"
)
throw
std
::
runtime_error
(
"BMP image type check did not succeed, check "
+
bmp
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_image
(
bmp
.
string
()))
throw
std
::
runtime_error
(
"BMP image "
+
bmp
.
string
()
+
" is not color as expected"
);
blitz
::
Array
<
uint8_t
,
3
>
color_bmp
=
bob
::
io
::
image
::
read_color_image
(
bmp
.
string
());
blitz
::
Array
<
uint8_t
,
3
>
color_bmp
=
bob
::
io
::
image
::
read_color_image
(
bmp
.
string
()
,
".bmp"
);
if
(
blitz
::
any
(
blitz
::
abs
(
color_image
-
color_bmp
)
>
0
))
throw
std
::
runtime_error
(
"BMP image IO did not succeed, check "
+
bmp
.
string
());
...
...
@@ -69,8 +73,12 @@ BOB_TRY
// GIF; only color images are supported
boost
::
filesystem
::
path
gif
(
tempdir
);
gif
/=
std
::
string
(
"color.gif"
);
bob
::
io
::
image
::
write_color_image
(
color_image
,
gif
.
string
());
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
gif
.
string
())
!=
".gif"
)
throw
std
::
runtime_error
(
"GIF image type check did not succeed, check "
+
gif
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_image
(
gif
.
string
(),
".gif"
))
throw
std
::
runtime_error
(
"GIF image "
+
gif
.
string
()
+
" is not color as expected"
);
blitz
::
Array
<
uint8_t
,
3
>
color_gif
=
bob
::
io
::
image
::
read_color_image
(
gif
.
string
());
blitz
::
Array
<
uint8_t
,
3
>
color_gif
=
bob
::
io
::
image
::
read_color_image
(
gif
.
string
()
,
".gif"
);
if
(
blitz
::
any
(
blitz
::
abs
(
color_image
-
color_gif
)
>
8
))
// TODO: why is GIF not lossless?
throw
std
::
runtime_error
(
"GIF image IO did not succeed, check "
+
gif
.
string
());
#endif
...
...
@@ -78,19 +86,23 @@ BOB_TRY
// NetPBM
boost
::
filesystem
::
path
pgm
(
tempdir
);
pgm
/=
std
::
string
(
"gray.pgm"
);
bob
::
io
::
image
::
write_gray_image
(
gray_image
,
pgm
.
string
());
if
(
bob
::
io
::
image
::
is_color_p_m
(
pgm
.
string
()))
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
pgm
.
string
())
!=
".pgm"
)
throw
std
::
runtime_error
(
"PGM image type check did not succeed, check "
+
pgm
.
string
());
if
(
bob
::
io
::
image
::
is_color_p_m
(
pgm
.
string
())
||
bob
::
io
::
image
::
is_color_image
(
pgm
.
string
(),
".pgm"
))
throw
std
::
runtime_error
(
"PGM image "
+
pgm
.
string
()
+
" is not gray as expected"
);
blitz
::
Array
<
uint8_t
,
2
>
gray_pgm
=
bob
::
io
::
image
::
read_gray_image
(
pgm
.
string
());
blitz
::
Array
<
uint8_t
,
2
>
gray_pgm
=
bob
::
io
::
image
::
read_gray_image
(
pgm
.
string
()
,
".pgm"
);
if
(
blitz
::
any
(
blitz
::
abs
(
gray_image
-
gray_pgm
)
>
0
))
throw
std
::
runtime_error
(
"PGM image IO did not succeed, check "
+
pgm
.
string
());
boost
::
filesystem
::
path
ppm
(
tempdir
);
ppm
/=
std
::
string
(
"color.ppm"
);
bob
::
io
::
image
::
write_color_image
(
color_image
,
ppm
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_p_m
(
ppm
.
string
()))
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
ppm
.
string
())
!=
".ppm"
)
throw
std
::
runtime_error
(
"PPM image type check did not succeed, check "
+
ppm
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_p_m
(
ppm
.
string
())
||
!
bob
::
io
::
image
::
is_color_image
(
ppm
.
string
()))
throw
std
::
runtime_error
(
"PPM image "
+
ppm
.
string
()
+
" is not color as expected"
);
blitz
::
Array
<
uint8_t
,
3
>
color_ppm
=
bob
::
io
::
image
::
read_color_image
(
ppm
.
string
());
blitz
::
Array
<
uint8_t
,
3
>
color_ppm
=
bob
::
io
::
image
::
read_color_image
(
ppm
.
string
()
,
".ppm"
);
if
(
blitz
::
any
(
blitz
::
abs
(
color_image
-
color_ppm
)
>
0
))
throw
std
::
runtime_error
(
"PPM image IO did not succeed, check "
+
ppm
.
string
());
...
...
@@ -99,7 +111,9 @@ BOB_TRY
// JPEG
boost
::
filesystem
::
path
jpeg_gray
(
tempdir
);
jpeg_gray
/=
std
::
string
(
"gray.jpg"
);
bob
::
io
::
image
::
write_gray_image
(
gray_image
,
jpeg_gray
.
string
());
if
(
bob
::
io
::
image
::
is_color_image
(
jpeg_gray
.
string
()))
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
jpeg_gray
.
string
())
!=
".jpg"
)
throw
std
::
runtime_error
(
"JPEG image type check did not succeed, check "
+
jpeg_gray
.
string
());
if
(
bob
::
io
::
image
::
is_color_image
(
jpeg_gray
.
string
())
||
bob
::
io
::
image
::
is_color_image
(
jpeg_gray
.
string
()))
throw
std
::
runtime_error
(
"JPEG image "
+
jpeg_gray
.
string
()
+
" is not gray as expected"
);
blitz
::
Array
<
uint8_t
,
2
>
gray_jpeg
=
bob
::
io
::
image
::
read_gray_image
(
jpeg_gray
.
string
());
...
...
@@ -108,7 +122,9 @@ BOB_TRY
boost
::
filesystem
::
path
jpeg_color
(
tempdir
);
jpeg_color
/=
std
::
string
(
"color.jpg"
);
bob
::
io
::
image
::
write_color_image
(
color_image
,
jpeg_color
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_image
(
jpeg_color
.
string
()))
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
jpeg_color
.
string
())
!=
".jpg"
)
throw
std
::
runtime_error
(
"JPEG image type check did not succeed, check "
+
jpeg_color
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_image
(
jpeg_color
.
string
())
||
!
bob
::
io
::
image
::
is_color_image
(
jpeg_color
.
string
(),
".jpeg"
))
throw
std
::
runtime_error
(
"JPEG image "
+
jpeg_color
.
string
()
+
" is not color as expected"
);
blitz
::
Array
<
uint8_t
,
3
>
color_jpeg
=
bob
::
io
::
image
::
read_color_image
(
jpeg_color
.
string
());
...
...
@@ -120,7 +136,9 @@ BOB_TRY
// PNG
boost
::
filesystem
::
path
png_gray
(
tempdir
);
png_gray
/=
std
::
string
(
"gray.png"
);
bob
::
io
::
image
::
write_gray_image
(
gray_image
,
png_gray
.
string
());
if
(
bob
::
io
::
image
::
is_color_image
(
png_gray
.
string
()))
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
png_gray
.
string
())
!=
".png"
)
throw
std
::
runtime_error
(
"PNG image type check did not succeed, check "
+
png_gray
.
string
());
if
(
bob
::
io
::
image
::
is_color_image
(
png_gray
.
string
())
||
bob
::
io
::
image
::
is_color_image
(
png_gray
.
string
(),
".png"
))
throw
std
::
runtime_error
(
"PNG image "
+
png_gray
.
string
()
+
" is not gray as expected"
);
blitz
::
Array
<
uint8_t
,
2
>
gray_png
=
bob
::
io
::
image
::
read_gray_image
(
png_gray
.
string
());
...
...
@@ -129,7 +147,9 @@ BOB_TRY
boost
::
filesystem
::
path
png_color
(
tempdir
);
png_color
/=
std
::
string
(
"color.png"
);
bob
::
io
::
image
::
write_color_image
(
color_image
,
png_color
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_png
(
png_color
.
string
()))
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
png_color
.
string
())
!=
".png"
)
throw
std
::
runtime_error
(
"PNG image type check did not succeed, check "
+
png_color
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_png
(
png_color
.
string
())
||
!
bob
::
io
::
image
::
is_color_image
(
png_color
.
string
()))
throw
std
::
runtime_error
(
"PNG image "
+
png_color
.
string
()
+
" is not color as expected"
);
blitz
::
Array
<
uint8_t
,
3
>
color_png
=
bob
::
io
::
image
::
read_color_image
(
png_color
.
string
());
...
...
@@ -141,7 +161,9 @@ BOB_TRY
// TIFF
boost
::
filesystem
::
path
tiff_gray
(
tempdir
);
tiff_gray
/=
std
::
string
(
"gray.tiff"
);
bob
::
io
::
image
::
write_gray_image
(
gray_image
,
tiff_gray
.
string
());
if
(
bob
::
io
::
image
::
is_color_image
(
tiff_gray
.
string
()))
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
tiff_gray
.
string
())
!=
".tiff"
)
throw
std
::
runtime_error
(
"TIFF image type check did not succeed, check "
+
tiff_gray
.
string
());
if
(
bob
::
io
::
image
::
is_color_image
(
tiff_gray
.
string
())
||
bob
::
io
::
image
::
is_color_image
(
tiff_gray
.
string
(),
".tif"
))
throw
std
::
runtime_error
(
"TIFF image "
+
tiff_gray
.
string
()
+
" is not gray as expected"
);
blitz
::
Array
<
uint8_t
,
2
>
gray_tiff
=
bob
::
io
::
image
::
read_gray_image
(
tiff_gray
.
string
());
...
...
@@ -150,7 +172,9 @@ BOB_TRY
boost
::
filesystem
::
path
tiff_color
(
tempdir
);
tiff_color
/=
std
::
string
(
"color.tiff"
);
bob
::
io
::
image
::
write_color_image
(
color_image
,
tiff_color
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_image
(
tiff_color
.
string
()))
if
(
bob
::
io
::
image
::
get_correct_image_extension
(
tiff_color
.
string
())
!=
".tiff"
)
throw
std
::
runtime_error
(
"TIFF image type check did not succeed, check "
+
tiff_color
.
string
());
if
(
!
bob
::
io
::
image
::
is_color_image
(
tiff_color
.
string
())
||
!
bob
::
io
::
image
::
is_color_image
(
tiff_color
.
string
(),
".tiff"
))
throw
std
::
runtime_error
(
"TIFF image "
+
tiff_color
.
string
()
+
" is not color as expected"
);
blitz
::
Array
<
uint8_t
,
3
>
color_tiff
=
bob
::
io
::
image
::
read_color_image
(
tiff_color
.
string
());
...
...
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