summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/image_loader/image_loader.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/image_loader/image_loader.h')
-rw-r--r--ml/dlib/dlib/image_loader/image_loader.h863
1 files changed, 863 insertions, 0 deletions
diff --git a/ml/dlib/dlib/image_loader/image_loader.h b/ml/dlib/dlib/image_loader/image_loader.h
new file mode 100644
index 000000000..4fa29dab2
--- /dev/null
+++ b/ml/dlib/dlib/image_loader/image_loader.h
@@ -0,0 +1,863 @@
+// Copyright (C) 2006 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_IMAGE_LOADEr_
+#define DLIB_IMAGE_LOADEr_
+
+#include "image_loader_abstract.h"
+#include <iostream>
+#include <sstream>
+#include "../algs.h"
+#include "../pixel.h"
+#include "../image_saver/dng_shared.h"
+#include "../entropy_decoder_model.h"
+#include "../entropy_decoder.h"
+#include "../uintn.h"
+#include "../image_transforms/assign_image.h"
+#include <algorithm>
+#include "../vectorstream.h"
+
+namespace dlib
+{
+
+// ----------------------------------------------------------------------------------------
+
+ class image_load_error : public dlib::error {
+ public: image_load_error(const std::string& str) : error(EIMAGE_LOAD,str){}
+ };
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_type
+ >
+ void load_bmp (
+ image_type& image_,
+ std::istream& in_
+ )
+ {
+ image_view<image_type> image(image_);
+ try
+ {
+ unsigned long bytes_read_so_far = 0;
+ unsigned long bfSize;
+ unsigned long bfOffBits;
+ unsigned long bfReserved;
+ unsigned long biSize;
+ unsigned long biWidth;
+ unsigned long biHeight;
+ unsigned short biBitCount;
+ unsigned long biCompression;
+ /*
+ unsigned long biSizeImage;
+ unsigned long biClrUsed;
+ unsigned long biClrImportant;
+ */
+ unsigned long a, b, c, d, i;
+
+ using namespace std;
+
+ streambuf& in = *in_.rdbuf();
+ // streamsize num;
+ unsigned char buf[100];
+
+
+ // first make sure the BMP starts with BM
+ if (in.sgetn(reinterpret_cast<char*>(buf),2) != 2)
+ throw image_load_error("bmp load error 1: header error");
+ bytes_read_so_far += 2;
+
+ if (buf[0] != 'B' || buf[1] != 'M')
+ throw image_load_error("bmp load error 2: header error");
+
+ // now read the BITMAPFILEHEADER
+ if (in.sgetn(reinterpret_cast<char*>(buf),12) != 12)
+ throw image_load_error("bmp load error 3: header error");
+
+ bytes_read_so_far += 12;
+
+ i = 0;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ bfSize = a | (b<<8) | (c<<16) | (d<<24);
+
+ i = 4;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ bfReserved = a | (b<<8) | (c<<16) | (d<<24);
+
+ i = 8;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ bfOffBits = a | (b<<8) | (c<<16) | (d<<24);
+
+ // if this value isn't zero then there is something wrong
+ // with this bitmap.
+ if (bfReserved != 0)
+ throw image_load_error("bmp load error 4: reserved area not zero");
+
+
+ // load the BITMAPINFOHEADER
+ if (in.sgetn(reinterpret_cast<char*>(buf),40) != 40)
+ throw image_load_error("bmp load error 5: file too short");
+ bytes_read_so_far += 40;
+
+
+ i = 0;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ biSize = a | (b<<8) | (c<<16) | (d<<24);
+
+ i += 4;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ biWidth = a | (b<<8) | (c<<16) | (d<<24);
+
+ i += 4;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ biHeight = a | (b<<8) | (c<<16) | (d<<24);
+
+ i += 4+2;
+ a = buf[i]; b = buf[i+1];
+ biBitCount = static_cast<unsigned short>(a | (b<<8));
+
+ i += 2;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ biCompression = a | (b<<8) | (c<<16) | (d<<24);
+
+ /*
+ i += 4;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ biSizeImage = a | (b<<8) | (c<<16) | (d<<24);
+
+ i += 4+4+4;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ biClrUsed = a | (b<<8) | (c<<16) | (d<<24);
+
+ i += 4;
+ a = buf[i]; b = buf[i+1]; c = buf[i+2]; d = buf[i+3];
+ biClrImportant = a | (b<<8) | (c<<16) | (d<<24);
+ */
+
+
+ if (biSize != 40)
+ throw image_load_error("bmp load error 6: header too small");
+
+ // read and discard any extra bytes that are part of the header
+ if (biSize > 40)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),biSize-40) != static_cast<long>(biSize - 40))
+ {
+ throw image_load_error("bmp load error 7: header too small");
+ }
+ bytes_read_so_far += biSize-40;
+ }
+
+ image.set_size(biHeight, biWidth);
+
+ switch (biBitCount)
+ {
+ case 1:
+ {
+ // figure out how the pixels are packed
+ long padding;
+ if (bfSize - bfOffBits == biWidth*biHeight/8)
+ padding = 0;
+ else
+ padding = 4 - ((biWidth+7)/8)%4;
+
+ const unsigned int palette_size = 2;
+ unsigned char red[palette_size];
+ unsigned char green[palette_size];
+ unsigned char blue[palette_size];
+
+ for (unsigned int i = 0; i < palette_size; ++i)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),4) != 4)
+ {
+ throw image_load_error("bmp load error 20: color palette missing");
+ }
+ bytes_read_so_far += 4;
+ blue[i] = buf[0];
+ green[i] = buf[1];
+ red[i] = buf[2];
+ }
+
+
+ // seek to the start of the pixel data
+ while (bytes_read_so_far != bfOffBits)
+ {
+ const long to_read = (long)std::min(bfOffBits - bytes_read_so_far, (unsigned long)sizeof(buf));
+ if (in.sgetn(reinterpret_cast<char*>(buf), to_read) != to_read)
+ {
+ throw image_load_error("bmp load error: missing data");
+ }
+ bytes_read_so_far += to_read;
+ }
+
+ // load the image data
+ for (long row = biHeight-1; row >= 0; --row)
+ {
+ for (unsigned long col = 0; col < biWidth; col+=8)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),1) != 1)
+ {
+ throw image_load_error("bmp load error 21.6: file too short");
+ }
+
+ unsigned char pixels[8];
+
+ pixels[0] = (buf[0]>>7);
+ pixels[1] = ((buf[0]>>6)&0x01);
+ pixels[2] = ((buf[0]>>5)&0x01);
+ pixels[3] = ((buf[0]>>4)&0x01);
+ pixels[4] = ((buf[0]>>3)&0x01);
+ pixels[5] = ((buf[0]>>2)&0x01);
+ pixels[6] = ((buf[0]>>1)&0x01);
+ pixels[7] = ((buf[0])&0x01);
+
+ for (int i = 0; i < 8 && col+i < biWidth; ++i)
+ {
+ rgb_pixel p;
+ p.red = red[pixels[i]];
+ p.green = green[pixels[i]];
+ p.blue = blue[pixels[i]];
+ assign_pixel(image[row][col+i],p);
+ }
+ }
+ if (in.sgetn(reinterpret_cast<char*>(buf),padding) != padding)
+ throw image_load_error("bmp load error 9: file too short");
+ }
+
+
+
+ } break;
+ case 4:
+ {
+ // figure out how the pixels are packed
+ long padding;
+ if (bfSize - bfOffBits == biWidth*biHeight/2)
+ padding = 0;
+ else
+ padding = 4 - ((biWidth+1)/2)%4;
+
+ const unsigned int palette_size = 16;
+ unsigned char red[palette_size];
+ unsigned char green[palette_size];
+ unsigned char blue[palette_size];
+
+ for (unsigned int i = 0; i < palette_size; ++i)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),4) != 4)
+ {
+ throw image_load_error("bmp load error 20: color palette missing");
+ }
+ bytes_read_so_far += 4;
+ blue[i] = buf[0];
+ green[i] = buf[1];
+ red[i] = buf[2];
+ }
+
+
+ // seek to the start of the pixel data
+ while (bytes_read_so_far != bfOffBits)
+ {
+ const long to_read = (long)std::min(bfOffBits - bytes_read_so_far, (unsigned long)sizeof(buf));
+ if (in.sgetn(reinterpret_cast<char*>(buf), to_read) != to_read)
+ {
+ throw image_load_error("bmp load error: missing data");
+ }
+ bytes_read_so_far += to_read;
+ }
+
+ // load the image data
+ for (long row = biHeight-1; row >= 0; --row)
+ {
+ for (unsigned long col = 0; col < biWidth; col+=2)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),1) != 1)
+ {
+ throw image_load_error("bmp load error 21.7: file too short");
+ }
+
+ const unsigned char pixel1 = (buf[0]>>4);
+ const unsigned char pixel2 = (buf[0]&0x0F);
+
+ rgb_pixel p;
+ p.red = red[pixel1];
+ p.green = green[pixel1];
+ p.blue = blue[pixel1];
+ assign_pixel(image[row][col], p);
+
+ if (col+1 < biWidth)
+ {
+ p.red = red[pixel2];
+ p.green = green[pixel2];
+ p.blue = blue[pixel2];
+ assign_pixel(image[row][col+1], p);
+ }
+ }
+ if (in.sgetn(reinterpret_cast<char*>(buf),padding) != padding)
+ throw image_load_error("bmp load error 9: file too short");
+ }
+
+
+
+ } break;
+ case 8:
+ {
+ // figure out how the pixels are packed
+ long padding;
+ if (bfSize - bfOffBits == biWidth*biHeight)
+ padding = 0;
+ else
+ padding = 4 - biWidth%4;
+
+ // check for this case. It shouldn't happen but some BMP writers screw up the files
+ // so we have to do this.
+ if (biHeight*(biWidth+padding) > bfSize - bfOffBits)
+ padding = 0;
+
+ const unsigned int palette_size = 256;
+ unsigned char red[palette_size];
+ unsigned char green[palette_size];
+ unsigned char blue[palette_size];
+
+ for (unsigned int i = 0; i < palette_size; ++i)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),4) != 4)
+ {
+ throw image_load_error("bmp load error 20: color palette missing");
+ }
+ bytes_read_so_far += 4;
+ blue[i] = buf[0];
+ green[i] = buf[1];
+ red[i] = buf[2];
+ }
+
+
+ // seek to the start of the pixel data
+ while (bytes_read_so_far != bfOffBits)
+ {
+ const long to_read = (long)std::min(bfOffBits - bytes_read_so_far, (unsigned long)sizeof(buf));
+ if (in.sgetn(reinterpret_cast<char*>(buf), to_read) != to_read)
+ {
+ throw image_load_error("bmp load error: missing data");
+ }
+ bytes_read_so_far += to_read;
+ }
+
+ // Next we load the image data.
+
+ // if there is no RLE compression
+ if (biCompression == 0)
+ {
+ for (long row = biHeight-1; row >= 0; --row)
+ {
+ for (unsigned long col = 0; col < biWidth; ++col)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),1) != 1)
+ {
+ throw image_load_error("bmp load error 21.8: file too short");
+ }
+
+ rgb_pixel p;
+ p.red = red[buf[0]];
+ p.green = green[buf[0]];
+ p.blue = blue[buf[0]];
+ assign_pixel(image[row][col],p);
+ }
+ if (in.sgetn(reinterpret_cast<char*>(buf),padding) != padding)
+ throw image_load_error("bmp load error 9: file too short");
+ }
+ }
+ else
+ {
+ // Here we deal with the psychotic RLE used by BMP files.
+
+ // First zero the image since the RLE sometimes jumps over
+ // pixels and assumes the image has been zero initialized.
+ assign_all_pixels(image, 0);
+
+ long row = biHeight-1;
+ long col = 0;
+ while (true)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),2) != 2)
+ {
+ throw image_load_error("bmp load error 21.9: file too short");
+ }
+
+ const unsigned char count = buf[0];
+ const unsigned char command = buf[1];
+
+ if (count == 0 && command == 0)
+ {
+ // This is an escape code that means go to the next row
+ // of the image
+ --row;
+ col = 0;
+ continue;
+ }
+ else if (count == 0 && command == 1)
+ {
+ // This is the end of the image. So quit this loop.
+ break;
+ }
+ else if (count == 0 && command == 2)
+ {
+ // This is the escape code for the command to jump to
+ // a new part of the image relative to where we are now.
+ if (in.sgetn(reinterpret_cast<char*>(buf),2) != 2)
+ {
+ throw image_load_error("bmp load error 21.1: file too short");
+ }
+ col += buf[0];
+ row -= buf[1];
+ continue;
+ }
+ else if (count == 0)
+ {
+ // This is the escape code for a run of uncompressed bytes
+
+ if (row < 0 || col + command > image.nc())
+ {
+ // If this is just some padding bytes at the end then ignore them
+ if (row >= 0 && col + count <= image.nc() + padding)
+ continue;
+
+ throw image_load_error("bmp load error 21.2: file data corrupt");
+ }
+
+ // put the bytes into the image
+ for (unsigned int i = 0; i < command; ++i)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),1) != 1)
+ {
+ throw image_load_error("bmp load error 21.3: file too short");
+ }
+ rgb_pixel p;
+ p.red = red[buf[0]];
+ p.green = green[buf[0]];
+ p.blue = blue[buf[0]];
+ assign_pixel(image[row][col],p);
+
+ ++col;
+ }
+
+ // if we read an uneven number of bytes then we need to read and
+ // discard the next byte.
+ if ((command&1) != 1)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),1) != 1)
+ {
+ throw image_load_error("bmp load error 21.4: file too short");
+ }
+ }
+
+ continue;
+ }
+
+ rgb_pixel p;
+
+ if (row < 0 || col + count > image.nc())
+ {
+ // If this is just some padding bytes at the end then ignore them
+ if (row >= 0 && col + count <= image.nc() + padding)
+ continue;
+
+ throw image_load_error("bmp load error 21.5: file data corrupt");
+ }
+
+ // put the bytes into the image
+ for (unsigned int i = 0; i < count; ++i)
+ {
+ p.red = red[command];
+ p.green = green[command];
+ p.blue = blue[command];
+ assign_pixel(image[row][col],p);
+
+ ++col;
+ }
+ }
+ }
+
+
+
+ }
+ break;
+ case 16:
+ throw image_load_error ("16 bit BMP images not supported");
+ case 24:
+ {
+ // figure out how the pixels are packed
+ long padding;
+ if (bfSize - bfOffBits == biWidth*biHeight*3)
+ padding = 0;
+ else
+ padding = 4 - (biWidth*3)%4;
+
+ // check for this case. It shouldn't happen but some BMP writers screw up the files
+ // so we have to do this.
+ if (biHeight*(biWidth*3+padding) > bfSize - bfOffBits)
+ padding = 0;
+
+ // seek to the start of the pixel data
+ while (bytes_read_so_far != bfOffBits)
+ {
+ const long to_read = (long)std::min(bfOffBits - bytes_read_so_far, (unsigned long)sizeof(buf));
+ if (in.sgetn(reinterpret_cast<char*>(buf), to_read) != to_read)
+ {
+ throw image_load_error("bmp load error: missing data");
+ }
+ bytes_read_so_far += to_read;
+ }
+
+ // load the image data
+ for (long row = biHeight-1; row >= 0; --row)
+ {
+ for (unsigned long col = 0; col < biWidth; ++col)
+ {
+ if (in.sgetn(reinterpret_cast<char*>(buf),3) != 3)
+ {
+ throw image_load_error("bmp load error 8: file too short");
+ }
+
+ rgb_pixel p;
+ p.red = buf[2];
+ p.green = buf[1];
+ p.blue = buf[0];
+ assign_pixel(image[row][col], p);
+
+ }
+ if (in.sgetn(reinterpret_cast<char*>(buf),padding) != padding)
+ throw image_load_error("bmp load error 9: file too short");
+ }
+
+ break;
+ }
+ case 32:
+ throw image_load_error ("32 bit BMP images not supported");
+ default:
+ throw image_load_error("bmp load error 10: unknown color depth");
+
+ }
+ }
+ catch (...)
+ {
+ image.clear();
+ throw;
+ }
+
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_type
+ >
+ void load_dng (
+ image_type& image_,
+ std::istream& in
+ )
+ {
+ image_view<image_type> image(image_);
+ using namespace dng_helpers_namespace;
+ try
+ {
+ if (in.get() != 'D' || in.get() != 'N' || in.get() != 'G')
+ throw image_load_error("the stream does not contain a dng image file");
+
+ unsigned long version;
+ deserialize(version,in);
+ if (version != 1)
+ throw image_load_error("You need the new version of the dlib library to read this dng file");
+
+ unsigned long type;
+ deserialize(type,in);
+
+ long width, height;
+ deserialize(width,in);
+ deserialize(height,in);
+
+ if (width > 0 && height > 0)
+ image.set_size(height,width);
+ else
+ image.clear();
+
+ if (type != grayscale_float)
+ {
+ typedef entropy_decoder::kernel_2a decoder_type;
+ decoder_type decoder;
+ decoder.set_stream(in);
+
+ entropy_decoder_model<256,decoder_type>::kernel_5a edm(decoder);
+ unsigned long symbol;
+ rgb_pixel p_rgb;
+ rgb_alpha_pixel p_rgba;
+ hsi_pixel p_hsi;
+ switch (type)
+ {
+ case rgb_alpha_paeth:
+
+ for (long r = 0; r < image.nr(); ++r)
+ {
+ for (long c = 0; c < image.nc(); ++c)
+ {
+ p_rgba = predictor_rgb_alpha_paeth(image,r,c);
+ edm.decode(symbol);
+ p_rgba.red += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgba.green += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgba.blue += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgba.alpha += static_cast<unsigned char>(symbol);
+
+ assign_pixel(image[r][c],p_rgba);
+ }
+ }
+ break;
+
+ case rgb_alpha:
+
+ for (long r = 0; r < image.nr(); ++r)
+ {
+ for (long c = 0; c < image.nc(); ++c)
+ {
+ p_rgba = predictor_rgb_alpha(image,r,c);
+ edm.decode(symbol);
+ p_rgba.red += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgba.green += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgba.blue += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgba.alpha += static_cast<unsigned char>(symbol);
+
+ assign_pixel(image[r][c],p_rgba);
+ }
+ }
+ break;
+
+ case rgb_paeth:
+
+ for (long r = 0; r < image.nr(); ++r)
+ {
+ for (long c = 0; c < image.nc(); ++c)
+ {
+ p_rgb = predictor_rgb_paeth(image,r,c);
+ edm.decode(symbol);
+ p_rgb.red += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgb.green += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgb.blue += static_cast<unsigned char>(symbol);
+
+ assign_pixel(image[r][c],p_rgb);
+ }
+ }
+ break;
+
+ case rgb:
+
+ for (long r = 0; r < image.nr(); ++r)
+ {
+ for (long c = 0; c < image.nc(); ++c)
+ {
+ p_rgb = predictor_rgb(image,r,c);
+ edm.decode(symbol);
+ p_rgb.red += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgb.green += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_rgb.blue += static_cast<unsigned char>(symbol);
+
+ assign_pixel(image[r][c],p_rgb);
+ }
+ }
+ break;
+
+ case hsi:
+
+ for (long r = 0; r < image.nr(); ++r)
+ {
+ for (long c = 0; c < image.nc(); ++c)
+ {
+ p_hsi = predictor_hsi(image,r,c);
+ edm.decode(symbol);
+ p_hsi.h += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_hsi.s += static_cast<unsigned char>(symbol);
+
+ edm.decode(symbol);
+ p_hsi.i += static_cast<unsigned char>(symbol);
+
+ assign_pixel(image[r][c],p_hsi);
+ }
+ }
+ break;
+
+ case grayscale:
+ {
+ unsigned char p;
+ for (long r = 0; r < image.nr(); ++r)
+ {
+ for (long c = 0; c < image.nc(); ++c)
+ {
+ edm.decode(symbol);
+ p = static_cast<unsigned char>(symbol);
+ p += predictor_grayscale(image,r,c);
+ assign_pixel(image[r][c],p);
+ }
+ }
+ }
+ break;
+
+ case grayscale_16bit:
+ {
+ uint16 p;
+ for (long r = 0; r < image.nr(); ++r)
+ {
+ for (long c = 0; c < image.nc(); ++c)
+ {
+ edm.decode(symbol);
+ p = static_cast<uint16>(symbol);
+ p <<= 8;
+ edm.decode(symbol);
+ p |= static_cast<uint16>(symbol);
+
+ p += predictor_grayscale_16(image,r,c);
+ assign_pixel(image[r][c],p);
+ }
+ }
+ }
+ break;
+
+ default:
+ throw image_load_error("corruption detected in the dng file");
+ } // switch (type)
+
+ edm.decode(symbol);
+ if (symbol != dng_magic_byte)
+ throw image_load_error("corruption detected in the dng file");
+ edm.decode(symbol);
+ if (symbol != dng_magic_byte)
+ throw image_load_error("corruption detected in the dng file");
+ edm.decode(symbol);
+ if (symbol != dng_magic_byte)
+ throw image_load_error("corruption detected in the dng file");
+ edm.decode(symbol);
+ if (symbol != dng_magic_byte)
+ throw image_load_error("corruption detected in the dng file");
+ }
+ else // if this is a grayscale_float type image
+ {
+ std::vector<int64> man(image.size());
+ std::vector<char> expbuf;
+ // get the mantissa data
+ for (unsigned long j = 0; j < man.size(); ++j)
+ deserialize(man[j], in);
+ // get the compressed exponent data
+ deserialize(expbuf, in);
+ typedef entropy_decoder::kernel_2a decoder_type;
+ typedef entropy_decoder_model<256,decoder_type>::kernel_4a edm_exp_type;
+ vectorstream inexp(expbuf);
+ decoder_type decoder;
+ decoder.set_stream(inexp);
+
+ edm_exp_type edm_exp(decoder);
+ float_details prev;
+ unsigned long i = 0;
+ // fill out the image
+ for (long r = 0; r < image.nr(); ++r)
+ {
+ for (long c = 0; c < image.nc(); ++c)
+ {
+ unsigned long exp1, exp2;
+ edm_exp.decode(exp1);
+ edm_exp.decode(exp2);
+
+ float_details cur(man[i++],(exp2<<8) | exp1);
+ cur.exponent += prev.exponent;
+ cur.mantissa += prev.mantissa;
+ prev = cur;
+
+ // Only use long double precision if the target image contains long
+ // doubles because it's slower to use those.
+ if (!is_same_type<typename image_traits<image_type>::pixel_type,long double>::value)
+ {
+ double temp = cur;
+ assign_pixel(image[r][c],temp);
+ }
+ else
+ {
+ long double temp = cur;
+ assign_pixel(image[r][c],temp);
+ }
+ }
+ }
+ unsigned long symbol;
+ edm_exp.decode(symbol);
+ if (symbol != dng_magic_byte)
+ throw image_load_error("corruption detected in the dng file");
+ edm_exp.decode(symbol);
+ if (symbol != dng_magic_byte)
+ throw image_load_error("corruption detected in the dng file");
+ edm_exp.decode(symbol);
+ if (symbol != dng_magic_byte)
+ throw image_load_error("corruption detected in the dng file");
+ edm_exp.decode(symbol);
+ if (symbol != dng_magic_byte)
+ throw image_load_error("corruption detected in the dng file");
+ }
+ }
+ catch (...)
+ {
+ image.clear();
+ throw;
+ }
+
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename image_type>
+ void load_bmp (
+ image_type& image,
+ const std::string& file_name
+ )
+ {
+ std::ifstream fin(file_name.c_str(), std::ios::binary);
+ if (!fin)
+ throw image_load_error("Unable to open " + file_name + " for reading.");
+ load_bmp(image, fin);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename image_type>
+ void load_dng (
+ image_type& image,
+ const std::string& file_name
+ )
+ {
+ std::ifstream fin(file_name.c_str(), std::ios::binary);
+ if (!fin)
+ throw image_load_error("Unable to open " + file_name + " for reading.");
+ load_dng(image, fin);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_IMAGE_LOADEr_
+
+
+