Write jpeg with header comment – boost generic image library (gil)
I had to hack the living daylights out of something today, and although I am not proud of it, needs must where the devil drives!
I was using the boost generic image library (gil) for managing some camera images and using jpeg_write_view() for saving them as JPEGs. A requirement emerged to insert a comment into the header of the saved images, but the gil does not support this out of the box.
The gil uses libjpeg for writing its JPEGs and adding a comment in libjped is as easy as calling jpeg_write_marker(). The problem was that the gil buries libjpeg calls under a few classes so I had to copy and paste some of this in order to redefine a new writer which supports comments.
Anyway I have included the extra code inline below, it adds a new helper function called jpeg_write_view_comment()
Use this new function like this:
int quality = 70;
jpeg_write_view_comment("image1.jpg", view, quality, "a comment damn it!!!");
Here is the extra code which I placed in a file called jpeg_writer_comment.h
#pragma once
#include "boost/gil/extension/io/dynamic_io.hpp"
using namespace boost;
using namespace boost::gil;
using namespace boost::gil::detail;
class jpeg_writer_comment : public file_mgr {
jpeg_compress_struct _cinfo;
jpeg_error_mgr _jerr;
void init() {
_cinfo.err=jpeg_std_error(&_jerr);
jpeg_create_compress(&_cinfo);
jpeg_stdio_dest(&_cinfo,_fp.get());
}
public:
jpeg_writer_comment(FILE* file) : file_mgr(file) { init(); }
jpeg_writer_comment(const char* filename) : file_mgr(filename, "wb") { init(); }
~jpeg_writer_comment() { jpeg_destroy_compress(&_cinfo); }
template
void apply(const View& view,int quality=100, const char* comment = NULL) {
_cinfo.image_width = (JDIMENSION)view.width();
_cinfo.image_height = (JDIMENSION)view.height();
_cinfo.input_components=num_channels::value;
_cinfo.in_color_space = jpeg_write_support_private::type,
typename color_space_type::type>::color_type;
jpeg_set_defaults(&_cinfo);
jpeg_set_quality(&_cinfo, quality, TRUE);
jpeg_start_compress(&_cinfo, TRUE);
if (comment) {
jpeg_write_marker(&_cinfo, JPEG_COM, (const JOCTET*)comment, strlen(comment));
}
std::vector::type> > > row(view.width());
JSAMPLE* row_address=(JSAMPLE*)&row.front();
for (int y=0;y
void write_view(const any_image_view& runtime_view) {
dynamic_io_fnobj op(this);
apply_operation(runtime_view,op);
}
};
template
inline void jpeg_write_view_comment(const char* filename,const View& view,int quality=100, const char* comment = NULL) {
BOOST_STATIC_ASSERT(jpeg_write_support::is_supported);
jpeg_writer_comment m(filename);
m.apply(view, quality, comment);
}
