Commit b2bdf2d7 authored by Tiago de Freitas Pereira's avatar Tiago de Freitas Pereira

Merge branch '19-cannot-read-cmyk-jpeg-images' into 'master'

Resolve "Cannot read CMYK jpeg images"

Closes #19

See merge request !31
parents 7306e4f9 b7588b31
Pipeline #12159 passed with stages
in 15 minutes and 24 seconds
......@@ -94,16 +94,6 @@ static void im_peek(const std::string& path, bob::io::base::array::typeinfo& inf
// 5. Start decompression and get information
jpeg_start_decompress(&cinfo);
if( cinfo.output_components != 1 && cinfo.output_components != 3)
{
// 6. clean up
jpeg_destroy_decompress(&cinfo);
boost::format m("unsupported number of planes (%d) when reading file. Image depth must be 1 or 3.");
m % cinfo.output_components;
throw std::runtime_error(m.str());
}
// Set depth and number of dimensions
info.dtype = bob::io::base::array::t_uint8;
info.nd = (cinfo.output_components == 1? 2 : 3);
......@@ -147,6 +137,27 @@ void imbuffer_to_rgb(size_t size, const T* im, T* r, T* g, T* b) {
}
}
template <typename T> static
void cmyk_imbuffer_to_rgb(size_t size, const T* im, T* r, T* g, T* b, bool adobe_marker) {
T C,M,Y,K;
for (size_t k=0; k<size; ++k) {
if (adobe_marker){
C = *im++;
M = *im++;
Y = *im++;
K = *im++;
} else {
C = 255-*im++;
M = 255-*im++;
Y = 255-*im++;
K = 255-*im++;
}
*r++ = C * K / 255;
*g++ = M * K / 255;
*b++ = Y * K / 255;
}
}
template <typename T> static
void im_load_color(struct jpeg_decompress_struct *cinfo, bob::io::base::array::interface& b) {
const bob::io::base::array::typeinfo& info = b.type();
......@@ -162,7 +173,11 @@ void im_load_color(struct jpeg_decompress_struct *cinfo, bob::io::base::array::i
buffer_pptr[0] = buffer.get();
while (cinfo->output_scanline < cinfo->output_height) {
jpeg_read_scanlines(cinfo, buffer_pptr, 1);
imbuffer_to_rgb<T>(info.shape[2], reinterpret_cast<T*>(buffer_pptr[0]), element_r, element_g, element_b);
if (cinfo->output_components == 3)
imbuffer_to_rgb<T>(info.shape[2], reinterpret_cast<T*>(buffer_pptr[0]), element_r, element_g, element_b);
else
cmyk_imbuffer_to_rgb<T>(info.shape[2], reinterpret_cast<T*>(buffer_pptr[0]), element_r, element_g, element_b, cinfo->saw_Adobe_marker);
element_r += cinfo->output_width;
element_g += cinfo->output_width;
element_b += cinfo->output_width;
......@@ -188,6 +203,10 @@ static void im_load(const std::string& filename, bob::io::base::array::interface
jpeg_read_header(&cinfo, TRUE);
// 4. Set parameters for decompression
if (cinfo.output_components == 4){
// assure to get CMYK output
cinfo.out_color_space = JCS_CMYK;
}
// 5. Start decompression and get information
jpeg_start_decompress(&cinfo);
......
......@@ -107,7 +107,7 @@ def test_netpbm():
def test_image_load():
# test that the generic bob.io.image.load function works as expected
for filename in ('test.jpg', 'test.pbm', 'test.pgm', 'test.ppm', 'img_rgba_color.png'):
for filename in ('test.jpg', 'cmyk.jpg', 'test.pbm', 'test.pgm', 'test.ppm', 'img_rgba_color.png'):
full_file = test_utils.datafile(filename, __name__)
# load with just image name
i1 = bob.io.image.load(full_file)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment