Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
76fca0e7
Commit
76fca0e7
authored
May 31, 2019
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
imgcodecs: sanitize PAM decoding
oss-fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13282
parent
db900af8
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
118 additions
and
113 deletions
+118
-113
grfmt_pam.cpp
modules/imgcodecs/src/grfmt_pam.cpp
+118
-113
No files found.
modules/imgcodecs/src/grfmt_pam.cpp
View file @
76fca0e7
...
@@ -56,7 +56,7 @@
...
@@ -56,7 +56,7 @@
#include "utils.hpp"
#include "utils.hpp"
#include "grfmt_pam.hpp"
#include "grfmt_pam.hpp"
using
namespace
cv
;
namespace
cv
{
/* the PAM related fields */
/* the PAM related fields */
#define MAX_PAM_HEADER_IDENITFIER_LENGTH 8
#define MAX_PAM_HEADER_IDENITFIER_LENGTH 8
...
@@ -220,14 +220,14 @@ basic_conversion (void *src, const struct channel_layout *layout, int src_sampe_
...
@@ -220,14 +220,14 @@ basic_conversion (void *src, const struct channel_layout *layout, int src_sampe_
}
}
static
bool
ReadPAMHeaderLine
(
cv
::
RLByteStream
&
strm
,
static
PamHeaderFieldType
&
fieldtype
,
bool
ReadPAMHeaderLine
(
char
value
[
MAX_PAM_HEADER_VALUE_LENGTH
+
1
])
cv
::
RLByteStream
&
strm
,
CV_OUT
PamHeaderFieldType
&
fieldtype
,
CV_OUT
char
value
[
MAX_PAM_HEADER_VALUE_LENGTH
+
1
])
{
{
int
code
,
pos
;
int
code
;
bool
ident_found
=
false
;
char
ident
[
MAX_PAM_HEADER_IDENITFIER_LENGTH
+
1
]
=
{};
uint
i
;
char
ident
[
MAX_PAM_HEADER_IDENITFIER_LENGTH
+
1
]
=
{
0
};
do
{
do
{
code
=
strm
.
getByte
();
code
=
strm
.
getByte
();
...
@@ -246,82 +246,95 @@ static bool ReadPAMHeaderLine (cv::RLByteStream& strm,
...
@@ -246,82 +246,95 @@ static bool ReadPAMHeaderLine (cv::RLByteStream& strm,
return
true
;
return
true
;
}
}
/* nul-ify buffers before writing to them */
int
ident_sz
=
0
;
memset
(
ident
,
'\0'
,
sizeof
(
char
)
*
MAX_PAM_HEADER_IDENITFIER_LENGTH
);
for
(;
ident_sz
<
MAX_PAM_HEADER_IDENITFIER_LENGTH
;
ident_sz
++
)
for
(
i
=
0
;
i
<
MAX_PAM_HEADER_IDENITFIER_LENGTH
;
i
++
)
{
{
if
(
!
isspace
(
code
))
if
(
isspace
(
code
))
ident
[
i
]
=
(
char
)
code
;
else
break
;
break
;
ident
[
ident_sz
]
=
(
char
)
code
;
code
=
strm
.
getByte
();
code
=
strm
.
getByte
();
}
}
CV_DbgAssert
(
ident_sz
<=
MAX_PAM_HEADER_IDENITFIER_LENGTH
);
ident
[
ident_sz
]
=
0
;
/* we may have filled the buffer and still have data */
/* we may have filled the buffer and still have data */
if
(
!
isspace
(
code
))
if
(
!
isspace
(
code
))
return
false
;
return
false
;
for
(
i
=
0
;
i
<
PAM_FIELDS_NO
;
i
++
)
{
bool
ident_found
=
false
;
if
(
strncmp
(
fields
[
i
].
identifier
,
ident
,
MAX_PAM_HEADER_IDENITFIER_LENGTH
+
1
)
==
0
)
{
for
(
uint
i
=
0
;
i
<
PAM_FIELDS_NO
;
i
++
)
{
if
(
0
==
strncmp
(
fields
[
i
].
identifier
,
ident
,
std
::
min
(
ident_sz
,
MAX_PAM_HEADER_IDENITFIER_LENGTH
)
+
1
))
{
fieldtype
=
fields
[
i
].
type
;
fieldtype
=
fields
[
i
].
type
;
ident_found
=
true
;
ident_found
=
true
;
break
;
}
}
}
}
if
(
!
ident_found
)
if
(
!
ident_found
)
return
false
;
return
false
;
memset
(
value
,
'\0'
,
sizeof
(
char
)
*
MAX_PAM_HEADER_VALUE_LENGTH
);
memset
(
value
,
0
,
sizeof
(
char
)
*
(
MAX_PAM_HEADER_VALUE_LENGTH
+
1
)
);
/* we may have an identifier that has no value */
/* we may have an identifier that has no value */
if
(
code
==
'\n'
||
code
==
'\r'
)
if
(
code
==
'\n'
||
code
==
'\r'
)
return
true
;
return
true
;
do
{
do
{
code
=
strm
.
getByte
();
code
=
strm
.
getByte
();
}
while
(
isspace
(
code
)
);
}
while
(
isspace
(
code
));
/* read identifier value */
/* read identifier value */
for
(
i
=
0
;
i
<
MAX_PAM_HEADER_VALUE_LENGTH
;
i
++
)
{
int
value_sz
=
0
;
if
(
code
!=
'\n'
&&
code
!=
'\r'
)
{
for
(;
value_sz
<
MAX_PAM_HEADER_VALUE_LENGTH
;
value_sz
++
)
value
[
i
]
=
(
char
)
code
;
{
}
else
if
(
code
!=
'\n'
||
code
!
=
'\r'
)
if
(
code
==
'\n'
||
code
=
=
'\r'
)
break
;
break
;
value
[
value_sz
]
=
(
char
)
code
;
code
=
strm
.
getByte
();
code
=
strm
.
getByte
();
}
}
pos
=
i
;
CV_DbgAssert
(
value_sz
<=
MAX_PAM_HEADER_VALUE_LENGTH
);
value
[
value_sz
]
=
0
;
int
pos
=
value_sz
;
/* should be terminated */
/* should be terminated */
if
(
code
!=
'\n'
&&
code
!=
'\r'
)
if
(
code
!=
'\n'
&&
code
!=
'\r'
)
return
false
;
return
false
;
/* remove trailing white spaces */
/* remove trailing white spaces */
while
(
pos
>=
0
&&
isspace
(
value
[
pos
]))
while
(
--
pos
>=
0
&&
isspace
(
value
[
pos
]))
value
[
pos
--
]
=
'\0'
;
value
[
pos
]
=
0
;
return
true
;
return
true
;
}
}
static
bool
ParseNumber
(
char
*
str
,
int
*
retval
)
static
int
ParseInt
(
const
char
*
str
,
int
len
)
{
{
char
*
endptr
;
CV_Assert
(
len
>
0
);
long
lval
=
strtol
(
str
,
&
endptr
,
0
);
if
((
errno
==
ERANGE
&&
(
lval
==
LONG_MAX
||
lval
==
LONG_MIN
))
||
(
errno
!=
0
&&
lval
==
0
))
{
return
false
;
}
if
(
endptr
==
str
)
{
return
false
;
}
*
retval
=
(
int
)
lval
;
return
true
;
int
pos
=
0
;
bool
is_negative
=
false
;
if
(
str
[
0
]
==
'-'
)
{
is_negative
=
true
;
pos
++
;
CV_Assert
(
isdigit
(
str
[
pos
]));
}
uint64_t
number
=
0
;
while
(
pos
<
len
&&
isdigit
(
str
[
pos
]))
{
char
ch
=
str
[
pos
];
number
=
(
number
*
10
)
+
(
uint64_t
)((
int
)
ch
-
(
int
)
'0'
);
CV_Assert
(
number
<
INT_MAX
);
pos
++
;
}
if
(
pos
<
len
)
CV_Assert
(
str
[
pos
]
==
0
);
return
(
is_negative
)
?
-
(
int
)
number
:
(
int
)
number
;
}
}
namespace
cv
{
PAMDecoder
::
PAMDecoder
()
PAMDecoder
::
PAMDecoder
()
{
{
...
@@ -357,21 +370,12 @@ ImageDecoder PAMDecoder::newDecoder() const
...
@@ -357,21 +370,12 @@ ImageDecoder PAMDecoder::newDecoder() const
return
makePtr
<
PAMDecoder
>
();
return
makePtr
<
PAMDecoder
>
();
}
}
struct
parsed_fields
bool
PAMDecoder
::
readHeader
()
{
bool
endhdr
,
height
,
width
,
depth
,
maxval
;
};
#define HEADER_READ_CORRECT(pf) (pf.endhdr && pf.height && pf.width \
&& pf.depth && pf.maxval)
bool
PAMDecoder
::
readHeader
()
{
{
PamHeaderFieldType
fieldtype
=
PAM_HEADER_NONE
;
PamHeaderFieldType
fieldtype
=
PAM_HEADER_NONE
;
char
value
[
MAX_PAM_HEADER_VALUE_LENGTH
+
1
];
char
value
[
MAX_PAM_HEADER_VALUE_LENGTH
+
1
];
int
byte
;
int
byte
;
struct
parsed_fields
flds
;
if
(
!
m_buf
.
empty
()
)
if
(
!
m_buf
.
empty
()
)
{
{
if
(
!
m_strm
.
open
(
m_buf
)
)
if
(
!
m_strm
.
open
(
m_buf
)
)
...
@@ -379,6 +383,7 @@ bool PAMDecoder::readHeader()
...
@@ -379,6 +383,7 @@ bool PAMDecoder::readHeader()
}
}
else
if
(
!
m_strm
.
open
(
m_filename
))
else
if
(
!
m_strm
.
open
(
m_filename
))
return
false
;
return
false
;
try
try
{
{
byte
=
m_strm
.
getByte
();
byte
=
m_strm
.
getByte
();
...
@@ -393,70 +398,72 @@ bool PAMDecoder::readHeader()
...
@@ -393,70 +398,72 @@ bool PAMDecoder::readHeader()
if
(
byte
!=
'\n'
&&
byte
!=
'\r'
)
if
(
byte
!=
'\n'
&&
byte
!=
'\r'
)
throw
RBS_BAD_HEADER
;
throw
RBS_BAD_HEADER
;
uint
i
;
bool
flds_endhdr
=
false
,
flds_height
=
false
,
flds_width
=
false
,
flds_depth
=
false
,
flds_maxval
=
false
;
memset
(
&
flds
,
0x00
,
sizeof
(
struct
parsed_fields
));
do
{
do
{
if
(
!
ReadPAMHeaderLine
(
m_strm
,
fieldtype
,
value
))
if
(
!
ReadPAMHeaderLine
(
m_strm
,
fieldtype
,
value
))
throw
RBS_BAD_HEADER
;
throw
RBS_BAD_HEADER
;
switch
(
fieldtype
)
{
switch
(
fieldtype
)
{
case
PAM_HEADER_NONE
:
case
PAM_HEADER_NONE
:
case
PAM_HEADER_COMMENT
:
case
PAM_HEADER_COMMENT
:
continue
;
continue
;
case
PAM_HEADER_ENDHDR
:
case
PAM_HEADER_ENDHDR
:
flds
.
endhdr
=
true
;
flds
_
endhdr
=
true
;
break
;
break
;
case
PAM_HEADER_HEIGHT
:
case
PAM_HEADER_HEIGHT
:
if
(
flds
.
height
)
if
(
flds_height
)
throw
RBS_BAD_HEADER
;
if
(
!
ParseNumber
(
value
,
&
m_height
))
throw
RBS_BAD_HEADER
;
throw
RBS_BAD_HEADER
;
flds
.
height
=
true
;
m_height
=
ParseInt
(
value
,
MAX_PAM_HEADER_VALUE_LENGTH
);
flds_height
=
true
;
break
;
break
;
case
PAM_HEADER_WIDTH
:
case
PAM_HEADER_WIDTH
:
if
(
flds
.
width
)
if
(
flds
_
width
)
throw
RBS_BAD_HEADER
;
throw
RBS_BAD_HEADER
;
if
(
!
ParseNumber
(
value
,
&
m_width
))
m_width
=
ParseInt
(
value
,
MAX_PAM_HEADER_VALUE_LENGTH
);
throw
RBS_BAD_HEADER
;
flds_width
=
true
;
flds
.
width
=
true
;
break
;
break
;
case
PAM_HEADER_DEPTH
:
case
PAM_HEADER_DEPTH
:
if
(
flds
.
depth
)
if
(
flds_depth
)
throw
RBS_BAD_HEADER
;
if
(
!
ParseNumber
(
value
,
&
m_channels
))
throw
RBS_BAD_HEADER
;
throw
RBS_BAD_HEADER
;
flds
.
depth
=
true
;
m_channels
=
ParseInt
(
value
,
MAX_PAM_HEADER_VALUE_LENGTH
);
flds_depth
=
true
;
break
;
break
;
case
PAM_HEADER_MAXVAL
:
case
PAM_HEADER_MAXVAL
:
if
(
flds
.
maxval
)
if
(
flds_maxval
)
throw
RBS_BAD_HEADER
;
if
(
!
ParseNumber
(
value
,
&
m_maxval
))
throw
RBS_BAD_HEADER
;
throw
RBS_BAD_HEADER
;
m_maxval
=
ParseInt
(
value
,
MAX_PAM_HEADER_VALUE_LENGTH
);
if
(
m_maxval
>
65535
)
if
(
m_maxval
>
65535
)
throw
RBS_BAD_HEADER
;
throw
RBS_BAD_HEADER
;
if
(
m_maxval
>
255
)
{
m_sampledepth
=
(
m_maxval
>
255
)
?
CV_16U
:
CV_8U
;
m_sampledepth
=
CV_16U
;
}
else
m_sampledepth
=
CV_8U
;
if
(
m_maxval
==
1
)
if
(
m_maxval
==
1
)
bit_mode
=
true
;
bit_mode
=
true
;
flds
.
maxval
=
true
;
flds
_
maxval
=
true
;
break
;
break
;
case
PAM_HEADER_TUPLTYPE
:
case
PAM_HEADER_TUPLTYPE
:
for
(
i
=
0
;
i
<
PAM_FORMATS_NO
;
i
++
)
{
{
if
(
strncmp
(
formats
[
i
].
name
,
bool
format_found
=
false
;
value
,
MAX_PAM_HEADER_VALUE_LENGTH
+
1
)
==
0
)
{
for
(
uint
i
=
0
;
i
<
PAM_FORMATS_NO
;
i
++
)
{
if
(
0
==
strncmp
(
formats
[
i
].
name
,
value
,
MAX_PAM_HEADER_VALUE_LENGTH
+
1
))
{
selected_fmt
=
formats
[
i
].
fmt
;
selected_fmt
=
formats
[
i
].
fmt
;
format_found
=
true
;
break
;
}
}
}
}
CV_Assert
(
format_found
);
break
;
break
;
}
default
:
default
:
throw
RBS_BAD_HEADER
;
throw
RBS_BAD_HEADER
;
}
}
}
while
(
fieldtype
!=
PAM_HEADER_ENDHDR
);
}
while
(
fieldtype
!=
PAM_HEADER_ENDHDR
);
if
(
HEADER_READ_CORRECT
(
flds
))
{
if
(
flds_endhdr
&&
flds_height
&&
flds_width
&&
flds_depth
&&
flds_maxval
)
if
(
selected_fmt
==
CV_IMWRITE_PAM_FORMAT_NULL
)
{
{
if
(
selected_fmt
==
CV_IMWRITE_PAM_FORMAT_NULL
)
{
if
(
m_channels
==
1
&&
m_maxval
==
1
)
if
(
m_channels
==
1
&&
m_maxval
==
1
)
selected_fmt
=
CV_IMWRITE_PAM_FORMAT_BLACKANDWHITE
;
selected_fmt
=
CV_IMWRITE_PAM_FORMAT_BLACKANDWHITE
;
else
if
(
m_channels
==
1
&&
m_maxval
<
256
)
else
if
(
m_channels
==
1
&&
m_maxval
<
256
)
...
@@ -469,28 +476,32 @@ bool PAMDecoder::readHeader()
...
@@ -469,28 +476,32 @@ bool PAMDecoder::readHeader()
return
true
;
return
true
;
}
}
}
catch
(...)
// failed
m_offset
=
-
1
;
m_width
=
m_height
=
-
1
;
m_strm
.
close
();
return
false
;
}
catch
(...)
{
{
m_offset
=
-
1
;
m_width
=
m_height
=
-
1
;
m_strm
.
close
();
throw
;
}
}
m_offset
=
-
1
;
m_width
=
m_height
=
-
1
;
m_strm
.
close
();
return
false
;
}
}
bool
PAMDecoder
::
readData
(
Mat
&
img
)
bool
PAMDecoder
::
readData
(
Mat
&
img
)
{
{
uchar
*
data
=
img
.
ptr
();
uchar
*
data
=
img
.
ptr
();
int
target_channels
=
img
.
channels
();
const
int
target_channels
=
img
.
channels
();
size_t
imp_stride
=
img
.
step
;
size_t
imp_stride
=
img
.
step
;
int
sample_depth
=
CV_ELEM_SIZE1
(
m_type
);
const
int
sample_depth
=
CV_ELEM_SIZE1
(
m_type
);
int
src_elems_per_row
=
m_width
*
m_channels
;
const
int
src_elems_per_row
=
m_width
*
m_channels
;
int
src_stride
=
src_elems_per_row
*
sample_depth
;
const
int
src_stride
=
src_elems_per_row
*
sample_depth
;
int
x
,
y
;
PaletteEntry
palette
[
256
]
=
{};
bool
res
=
false
,
funcout
;
PaletteEntry
palette
[
256
];
const
struct
pam_format
*
fmt
=
NULL
;
const
struct
pam_format
*
fmt
=
NULL
;
struct
channel_layout
layout
=
{
0
,
0
,
0
,
0
};
// normalized to 1-channel grey format
struct
channel_layout
layout
=
{
0
,
0
,
0
,
0
};
// normalized to 1-channel grey format
...
@@ -512,7 +523,6 @@ bool PAMDecoder::readData( Mat& img )
...
@@ -512,7 +523,6 @@ bool PAMDecoder::readData( Mat& img )
}
}
}
}
try
{
{
m_strm
.
setPos
(
m_offset
);
m_strm
.
setPos
(
m_offset
);
...
@@ -521,10 +531,10 @@ bool PAMDecoder::readData( Mat& img )
...
@@ -521,10 +531,10 @@ bool PAMDecoder::readData( Mat& img )
/* special case for 16bit images with wrong endianness */
/* special case for 16bit images with wrong endianness */
if
(
m_sampledepth
==
CV_16U
&&
!
isBigEndian
())
if
(
m_sampledepth
==
CV_16U
&&
!
isBigEndian
())
{
{
for
(
y
=
0
;
y
<
m_height
;
y
++
,
data
+=
imp_stride
)
for
(
int
y
=
0
;
y
<
m_height
;
y
++
,
data
+=
imp_stride
)
{
{
m_strm
.
getBytes
(
src
,
src_stride
);
m_strm
.
getBytes
(
src
,
src_stride
);
for
(
x
=
0
;
x
<
src_elems_per_row
;
x
++
)
for
(
int
x
=
0
;
x
<
src_elems_per_row
;
x
++
)
{
{
uchar
v
=
src
[
x
*
2
];
uchar
v
=
src
[
x
*
2
];
data
[
x
*
2
]
=
src
[
x
*
2
+
1
];
data
[
x
*
2
]
=
src
[
x
*
2
+
1
];
...
@@ -543,7 +553,7 @@ bool PAMDecoder::readData( Mat& img )
...
@@ -543,7 +553,7 @@ bool PAMDecoder::readData( Mat& img )
if
(
target_channels
==
1
)
if
(
target_channels
==
1
)
{
{
uchar
gray_palette
[
2
]
=
{
0
,
255
};
uchar
gray_palette
[
2
]
=
{
0
,
255
};
for
(
y
=
0
;
y
<
m_height
;
y
++
,
data
+=
imp_stride
)
for
(
int
y
=
0
;
y
<
m_height
;
y
++
,
data
+=
imp_stride
)
{
{
m_strm
.
getBytes
(
src
,
src_stride
);
m_strm
.
getBytes
(
src
,
src_stride
);
FillGrayRow1
(
data
,
src
,
m_width
,
gray_palette
);
FillGrayRow1
(
data
,
src
,
m_width
,
gray_palette
);
...
@@ -551,21 +561,21 @@ bool PAMDecoder::readData( Mat& img )
...
@@ -551,21 +561,21 @@ bool PAMDecoder::readData( Mat& img )
}
else
if
(
target_channels
==
3
)
}
else
if
(
target_channels
==
3
)
{
{
FillGrayPalette
(
palette
,
1
,
false
);
FillGrayPalette
(
palette
,
1
,
false
);
for
(
y
=
0
;
y
<
m_height
;
y
++
,
data
+=
imp_stride
)
for
(
int
y
=
0
;
y
<
m_height
;
y
++
,
data
+=
imp_stride
)
{
{
m_strm
.
getBytes
(
src
,
src_stride
);
m_strm
.
getBytes
(
src
,
src_stride
);
FillColorRow1
(
data
,
src
,
m_width
,
palette
);
FillColorRow1
(
data
,
src
,
m_width
,
palette
);
}
}
}
}
}
else
{
}
else
{
for
(
y
=
0
;
y
<
m_height
;
y
++
,
data
+=
imp_stride
)
for
(
int
y
=
0
;
y
<
m_height
;
y
++
,
data
+=
imp_stride
)
{
{
m_strm
.
getBytes
(
src
,
src_stride
);
m_strm
.
getBytes
(
src
,
src_stride
);
/* endianness correction */
/* endianness correction */
if
(
m_sampledepth
==
CV_16U
&&
!
isBigEndian
()
)
if
(
m_sampledepth
==
CV_16U
&&
!
isBigEndian
()
)
{
{
for
(
x
=
0
;
x
<
src_elems_per_row
;
x
++
)
for
(
int
x
=
0
;
x
<
src_elems_per_row
;
x
++
)
{
{
uchar
v
=
src
[
x
*
2
];
uchar
v
=
src
[
x
*
2
];
src
[
x
*
2
]
=
src
[
x
*
2
+
1
];
src
[
x
*
2
]
=
src
[
x
*
2
+
1
];
...
@@ -576,7 +586,7 @@ bool PAMDecoder::readData( Mat& img )
...
@@ -576,7 +586,7 @@ bool PAMDecoder::readData( Mat& img )
/* scale down */
/* scale down */
if
(
img
.
depth
()
==
CV_8U
&&
m_sampledepth
==
CV_16U
)
if
(
img
.
depth
()
==
CV_8U
&&
m_sampledepth
==
CV_16U
)
{
{
for
(
x
=
0
;
x
<
src_elems_per_row
;
x
++
)
for
(
int
x
=
0
;
x
<
src_elems_per_row
;
x
++
)
{
{
int
v
=
((
ushort
*
)
src
)[
x
];
int
v
=
((
ushort
*
)
src
)[
x
];
src
[
x
]
=
(
uchar
)(
v
>>
8
);
src
[
x
]
=
(
uchar
)(
v
>>
8
);
...
@@ -589,7 +599,7 @@ bool PAMDecoder::readData( Mat& img )
...
@@ -589,7 +599,7 @@ bool PAMDecoder::readData( Mat& img )
}
}
/* perform correct conversion based on format */
/* perform correct conversion based on format */
else
if
(
fmt
)
{
else
if
(
fmt
)
{
funcout
=
false
;
bool
funcout
=
false
;
if
(
fmt
->
cvt_func
)
if
(
fmt
->
cvt_func
)
funcout
=
fmt
->
cvt_func
(
src
,
data
,
m_width
,
target_channels
,
funcout
=
fmt
->
cvt_func
(
src
,
data
,
m_width
,
target_channels
,
img
.
depth
());
img
.
depth
());
...
@@ -608,13 +618,8 @@ bool PAMDecoder::readData( Mat& img )
...
@@ -608,13 +618,8 @@ bool PAMDecoder::readData( Mat& img )
}
}
}
}
}
}
res
=
true
;
}
catch
(...)
{
}
}
return
true
;
return
res
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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