SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JpegWriter.hpp
Go to the documentation of this file.
1 
10 #ifndef JPEGWRITER_HPP_
11 #define JPEGWRITER_HPP_
12 
13 #include <iostream>
14 #include <sstream>
15 
16 #include "JpegDef.hpp"
17 #include "error.hpp"
18 #include "ContainerWriter.hpp"
19 
20 
21 template <typename T>
23 {
24  template <typename T1> // T1 models type statically convertible to T
25  T operator()(const T1& x) const {
26  return static_cast<T>(x);
27  }
28 };
29 
30 namespace slip {
31 
44 template<class Container2d, typename T, std::size_t Nb_components>
45 class JpegWriter: public ContainerWriter<Container2d, T> {
46 public:
47  typedef Container2d container_type;
48  typedef T value_type;
50 
55 
60  :base(),cinfo(),jerr(),outfile(NULL),row_pointer(NULL),row_stride(0),
61  finished(0),total_nb_row(0),initialized(false),output_image_width_(0),
62  output_image_height_(0){}
63 
72  JpegWriter(std::string output_filename, std::size_t output_image_width, std::size_t output_image_height, int quality = 90)
73  :base(output_filename),cinfo(),jerr(),outfile(NULL),row_pointer(NULL),row_stride(0),
74  finished(0),total_nb_row(0),initialized(false),output_image_width_(output_image_width),
75  output_image_height_(output_image_height){
76  initialize(quality);
77  }
78 
82  virtual ~JpegWriter(){
83  release();
84  }
85 
94  void initialize(std::size_t output_image_width, std::size_t output_image_height, int quality = 90);
95 
96 
100  void release();
101 
112  int write(const container_type & data);
113 
114 private:
115  jpeg_compress_struct cinfo;
116  my_error_mgr jerr;
117  FILE * outfile;
118  JSAMPROW* row_pointer;
119  int row_stride;
120  bool finished;
121  std::size_t total_nb_row;
122  bool initialized;
123  std::size_t output_image_width_;
124  std::size_t output_image_height_;
125 
126  void initialize(int quality = 90);
127 };
128 
129 }
131 namespace slip {
132 
133 template<class Container2d, typename T, std::size_t Nb_components>
134 inline
135 void JpegWriter<Container2d,T,Nb_components>::initialize(std::size_t output_image_width, std::size_t output_image_height, int quality){
136  output_image_width_ = output_image_width;
137  output_image_height_ = output_image_height;
138  initialize(quality);
139 }
140 
141 
142 template<class Container2d, typename T, std::size_t Nb_components>
143 inline
145  if(!initialized){
146  if (Nb_components != 1 && Nb_components != 3){
147  std::ostringstream err;
148  err << FILE_WRITE_ERROR << this->output_filename_ << " | Nb_components should be 1 or 3.";
149  slip::slip_exception exc(std::string("slip"), std::string("JpegWriter::initialize()"), err.str());
150  throw (exc);
151  }
152 
153  /* Step 1: allocate and initialize JPEG compression object */
154 
155  cinfo.err = jpeg_std_error(&jerr.pub);
156  jerr.pub.error_exit = my_error_exit;
157 
158  /* Establish the setjmp return context for my_error_exit to use. */
159  if (setjmp(jerr.setjmp_buffer)) {
160  /* If we get here, the JPEG code has signaled an error.
161  * We need to clean up the JPEG object, close the input file, and throw an exception
162  */
163  char buffer[JMSG_LENGTH_MAX];
164  /* Create the message */
165  (*cinfo.err->format_message) (reinterpret_cast<j_common_ptr>(&cinfo), buffer);
166  jpeg_destroy_compress(&cinfo);
167  if (outfile != NULL)
168  fclose(outfile);
169  std::ostringstream err;
170  err << FILE_WRITE_ERROR << this->output_filename_ << " | JPEG code has signaled the error : "
171  << buffer;
172  slip::slip_exception exc(std::string("slip"), std::string("JpegWriter::initialize()"), err.str());
173  //std::cerr << ">>>>" << err.str() << "\n";
174  throw exc;
175  }
176 
177  jpeg_create_compress(&cinfo);
178 
179  /* Step 2: specify data destination (eg, a file) */
180 
181  if ((outfile = fopen(this->output_filename_.c_str(), "wb")) == NULL) {
182  std::ostringstream err;
183  err << FILE_OPEN_ERROR << this->output_filename_;
184  slip::slip_exception exc(std::string("slip"), std::string("JpegWriter::initialize()"), err.str());
185  throw (exc);
186  }
187  slip_jpeg_stdio_dest(&cinfo, outfile);
188 
189  cinfo.image_width = output_image_width_; /* image width and height, in pixels */
190  cinfo.image_height = output_image_height_;
191  cinfo.input_components = Nb_components; /* # of color components per pixel */
192  if (Nb_components == 3)
193  cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
194  else if(Nb_components == 1)
195  cinfo.in_color_space = JCS_GRAYSCALE;
196 
197  jpeg_set_defaults(&cinfo);
198  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
199 
200  /* Step 4: Start compressor */
201  jpeg_start_compress(&cinfo, TRUE);
202 
203  /* Step 5: initialized parameters*/
204  row_stride = output_image_width_ * Nb_components; /* JSAMPLEs per row in image_buffer */
205  row_pointer = new JSAMPROW[1];
206  initialized = true;
207  }
208 }
209 
210 
211 
212 template<class Container2d, typename T, std::size_t Nb_components>
213 inline
215  if(!initialized){
216  std::ostringstream err;
217  err << FILE_WRITE_ERROR << this->output_filename_ << " | The writer to be initialized before writing.";
218  slip::slip_exception exc(std::string("slip"), std::string("JpegWriter::write()"), err.str());
219  throw (exc);
220  }
221  if (finished){
222  return 0;
223  }
224 
225  total_nb_row += data.height();
226 
227  if(output_image_height_ < total_nb_row){
228  std::ostringstream err;
229  err << FILE_WRITE_ERROR << this->output_filename_ << " | Allocation problem during jpg writing.";
230  slip::slip_exception exc(std::string("slip"), std::string("JpegWriter::write()"), err.str());
231  throw (exc);
232  }
233 
234  for(std::size_t j=0; j<data.height(); ++j){
235  row_pointer[0] = new JSAMPLE[row_stride]; /* pointer to JSAMPLE row[s] */
236  const T * data_ptr_j = reinterpret_cast<const T *>(data[j]);
237  std::transform(data_ptr_j, data_ptr_j + row_stride,
238  row_pointer[0], jpg_static_cast_func<unsigned char>());
239  (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
240  delete[] row_pointer[0];
241  }
242 
243  if (total_nb_row == output_image_height_)
244  finished = true;
245 
246  return (!finished);
247 }
248 
249 template<class Container2d, typename T, std::size_t Nb_components>
250 inline
252  if(initialized){
253  /* Step 6: Finish compression */
254  if(finished)
255  jpeg_finish_compress(&cinfo);
256 
257  /* Step 7: release JPEG compression object */
258  jpeg_destroy_compress(&cinfo);
259  if (outfile != NULL)
260  fclose(outfile);
261  delete[] row_pointer;
262  row_stride = 0;
263  finished = false;
264  total_nb_row = 0;
265  output_image_width_ = 0;
266  output_image_height_ = 0;
267  initialized = false;
268  }
269 }
270 
271 }
272 #endif /* JPEGWRITER_HPP_ */
const std::string FILE_WRITE_ERROR
Definition: error.hpp:91
standard exception extension name have been changed to eliminate conflicts with QT ...
Definition: error.hpp:106
Contains the container writer base class.
JpegWriter(std::string output_filename, std::size_t output_image_width, std::size_t output_image_height, int quality=90)
Definition: JpegWriter.hpp:72
int write(const container_type &data)
write function. This function write the data within the output file after the previous one...
Definition: JpegWriter.hpp:214
Some definitions specific to libjpeg.
void initialize(std::size_t output_image_width, std::size_t output_image_height, int quality=90)
initialized the writing process. Has to be called before the first write() call of a given image...
Definition: JpegWriter.hpp:135
Container2d container_type
Definition: JpegWriter.hpp:47
const std::string FILE_OPEN_ERROR
Definition: error.hpp:82
virtual ~JpegWriter()
Definition: JpegWriter.hpp:82
Provides SLIP error messages.
T operator()(const T1 &x) const
Definition: JpegWriter.hpp:25
ContainerWriter is the base class of the writer classes. All the writers are working the same way: ...
void release()
release the writing process. Has to be called when an image has been fully written.
Definition: JpegWriter.hpp:251
ContainerWriter< Container2d, T > base
Definition: JpegWriter.hpp:49
JpegWriter is the jpeg image writer.
Definition: JpegWriter.hpp:45